|
Para enviar a la GPU la orden de generar las imágenes siguiendo la
configuración reflejada en los objetos VkRenderPass y
VkPipeline hay que rellenar un buffer de comandos con los
comandos adecuados. Para ello hay que inicializarlo, llenarlo de
comandos y lanzarlo. Para inicializar el buffer se utiliza la función
vkBeginCommandBuffer().
VkResult vkBeginCommandBuffer (
VkCommandBuffer commandBuffer,
const VkCommandBufferBeginInfo* pBeginInfo);
|
La configuración de esta función se realiza con una estructura
VkCommandBufferBeginInfo.
typedef struct VkCommandBufferBeginInfo {
VkStructureType sType;
const void* pNext;
VkCommandBufferUsageFlags flags;
const VkCommandBufferInheritanceInfo* pInheritanceInfo;
} VkCommandBufferBeginInfo;
|
El campo sType debe tener el valor
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO.
El campo pNext debe dejarse nulo.
El campo
flags indica el uso que se puede dar al buffer. Si se deja nulo
indica que se puede lanzar varias veces. Los otros valores son
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT (para indicar que solo
se ejecutará una vez),
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT (para indicar que
un buffer secundario se ejecutará completamente dentro de un
subpase) y VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT (para
indicar que se puede lanzar el buffer de comando de forma simultanea
en varias colas).
El campo pInheritanceInfo se utiliza en los buffers
secundarios para especificar las propiedades que se heredan del
buffer primario.
Una vez inicializado el buffer de comandos hay que iniciar el renderpass
por medio de la función vkCmdBeginRenderPass().
void vkCmdBeginRenderPass (
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
VkSubpassContents contents);
|
La información contenida en la estructura VkRenderPassBeginInfo incluye las referencias al
renderpass,
al framebuffer, al área de dibujo y a el color utilizado para
inicializar la imagen.
typedef struct VkRenderPassBeginInfo {
VkStructureType sType;
const void* pNext;
VkRenderPass renderPass;
VkFramebuffer framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
const VkClearValue* pClearValues;
} VkRenderPassBeginInfo;
|
El siguiente paso es enlazar el pipeline a utilizar por medio de la
función vkCmdBindPipeline(). El parámetro pipelineBindPoint indica el
tipo de pipeline que estamos utilizando y puede tomar los valores
VK_PIPELINE_BIND_POINT_COMPUTE o VK_PIPELINE_BIND_POINT_GRAPHICS.
void vkCmdBindPipeline (
VkCommandBuffer commandBuffer,
VkPipelineBindPoint pipelineBindPoint,
VkPipeline pipeline);
|
A continuación hay que enlazar las entradas del pipeline. Para eso
hay que utilizar las siguientes funciones: vkCmdBindVertexBuffers(),
vkCmdBindIndexBuffer() y vkCmdBindDescriptorSets(). En este proyecto
no se han incluido estas entradas en el pipeline.
Para lanzar el pipeline y realizar el dibujo se utilizan los comandos
vkCmdDraw() o vkCmdDrawIndexed(). En el primer caso los vértices se leen
secuencialmente. En el segundo caso se utiliza el buffer de índices para
leer los vértices de forma indirecta.
void vkCmdDraw (
VkCommandBuffer commandBuffer,
uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance);
void vkCmdDrawIndexed (
VkCommandBuffer commandBuffer,
uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t vertexOffset,
uint32_t firstInstance);
|
Para declarar el final de la descripción del renderpass se utiliza
la función vkCmdEndRenderPass().
void vkCmdEndRenderPass (
VkCommandBuffer commandBuffer);
|
Para finalizar la creación del buffer de comandos se utiliza la función
vkEndCommandBuffer().
VkResult vkEndCommandBuffer (
VkCommandBuffer commandBuffer);
|
El esquema de generación de un bloque de comandos es el siguiente:

|