Vulkan编程指南翻译 第八章 图形管线 第5节 间接绘制

8.5  间接绘制

在vkCmdDraw() and vkCmdDrawIndexed()命令中,命令的参数(vertexCount,vertexOffset, 等等)以立即参数直接传递给命令本身。这意味这你需要知道在你的应用程序中构建命令缓冲区时每一次绘制调用的准确参数。然而,在一些情况下,你并不知道每一次绘制的准确参数。比如以下例子:

•几何物体的所有结构是已知的,但是顶点的个数和在顶点缓冲区的位置是未知的,一遍一个对象总是参加渲染但是LoD的层数会改变。

•绘制命令由设备生成,而非主机。在这个情况下,顶点数据的个数和布局永远被会被主机端所知。

在这些情况下,你可以使用间接绘制,此时,绘制命令可以从设备可访问的内存获取参数,而非把参数随着命令嵌入在命令缓冲区中。第一个间接绘制命令是vkCmdDrawIndirect(),它执行非索引化绘制,使用的参数包含在一个缓冲区中。它的原型是:

         voidvkCmdDrawIndirect (

VkCommandBuffer                   commandBuffer,

VkBuffer                                      buffer,

VkDeviceSize                              offset,

uint32_t                                       drawCount,

uint32_t                                       stride);

这个命令本身仍然被放入命令缓冲区中,和vkCmdDraw()是一样的。commandBuffer是命令被放入的命令缓冲区。然而,命令的参数从buffer指定的缓冲区中,offset为开始的位置开始获取。在这个缓冲区的偏移量位置,应该有一个VkDrawIndirectCommand结构,包含了命令真是的参数。VkDrawIndirectCommand的定义是:

         typedefstruct VkDrawIndirectCommand {

uint32_t           vertexCount;

uint32_t           instanceCount;

uint32_t           firstVertex;

uint32_t           firstInstance;

} VkDrawIndirectCommand;

VkDrawIndirectCommand的成员和vkCmdDraw()命令中的参数有相似的含义。vertexCountand instanceCount是顶点和索引的个数,firstVertex and firstInstance是顶点和实例索引的起始值。

vkCmdDrawIndirect()执行非索引化、间接绘制,使用缓冲区对象中数据为参数。也可以使用vkCmdDrawIndexedIndirect()执行索引化的间接绘制。该命令原型如下:

         voidvkCmdDrawIndexedIndirect (

VkCommandBuffer          commandBuffer,

VkBuffer                             buffer,

VkDeviceSize                     offset,

uint32_t                             drawCount,

uint32_t                             stride);

vkCmdDrawIndexedIndirect()的参数和vkCmdDrawIndirect()的参数是一样的。commandBuffer是命令被放入的命令缓冲区,buffer是包含参数的缓冲区对象;offset是以字节为单位的在缓冲区中参数位置的偏移量,。然而,包含vkCmdDrawIndexedIndirect()参数的数据结构不一样。它是一个VkDrawIndexedIndirectCommand类型的结构,定义是:

         typedefstruct VkDrawIndexedIndirectCommand {

uint32_t           indexCount;

uint32_t           instanceCount;

uint32_t           firstIndex;

int32_t             vertexOffset;

uint32_t           firstInstance;

} VkDrawIndexedIndirectCommand;

VkDrawIndexedIndirectCommand的参数和vkCmdDrawIndexed()中同名的参数有相同的意义。indexCountand instanceCount是发送到管线的顶点索引和实例的个数;firstIndex成员指定了从索引缓冲区中开始取出索引的位置,vertexOffset指定了叠加到索引数据的偏移值;firstInstance指定了实例计数器起始值。

需要记住的重点是,间接绘制命令是在命令没有被设备执行前,缓冲区对象和便宜值被放入命令缓冲区,绘制所需的参数不必写入到缓冲区对象。随着设备执行命令缓冲区,当进行到该命令时,它会读取缓冲区中的数据并使用,就如同这些参数已经被一个通常的绘制命令指定了一样。就管道的其余部分而言,在直接和间接绘制之间没有区别。

这意味着如下几条:

         • You canbuild command buffers with indirect draws long before they’re needed, fillingin the final parameters for the draw (in the buffer object rather than thecommand buffer) before the

command buffer is submitted for execution.

• You can create a command buffer containing an indirect draw, submitit, overwrite the

parameters in the buffer object, and submitthe same command buffer again. This effectively

patches new parameters into what could be along, complex command buffer.

• You can write parameters into a buffer object by using stores froma shader object, or by using a command such as vkCmdFillBuffer() orvkCmdCopyBuffer() to generate drawing

parameters on the device itself—either inthe same command buffer or in another submitted just

before the one containing the drawcommands.

以可能已经注意到了vkCmdDrawIndirect() and vkCmdDrawIndexedIndirect() 都接受drawCountand a stride 参数。这些参数允许你传递绘制命令的数组到Vulkan。一次vkCmdDrawIndirect() or vkCmdDrawIndexedIndirect()调用将会激发drawCount个独立的绘制,每一次绘制都各从VkDrawIndirectCommand or VkDrawIndexedIndirectCommand取出参数。

该数据类型的数组从缓冲区对象内offset字节位置开始,每一个结构都和上一个相距stride字节。如果stride是0,那么每一次绘制都是用相同的参数。[1]

         1.Note that this behavior differs from OpenGL, in which a stride of zero causesthe device to assume a tightly packed array, and it is impossible to source thesame parameters over and over.

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值