Vulkan编程指南翻译 第三章 队列和命令 第3节 记录命令

2017-02-20

记录命令

命令是通过使用Vulkan命令函数记录到命令缓冲区的,这些函数都接受一个命令缓冲区handle作为第一个参数。命令缓冲区的访问必须是同步的,意味着应用程序负责保证没有两个线程同时记录命令到同一个命令缓冲区中。然而下面的情形可以接受的:

一个线程可以通过调用命令缓冲区函数,依次的记录命令进入到多个命令缓冲区中

两个或多个线程可以参加建立一个命令缓冲区的过程,只要应用程序可以保证它们不同时执行命令缓冲区建立的函数。

Vulkan的一个关键的设计原则是让程序可以多线程工作。为此要保证应用程序的多个线程不会互相堵塞比如,不会因对共享资源加锁而导致堵塞其他线程。因此最好是一个线程有一个或者多个命令缓冲区,而不是共享一个命令缓冲区是从pool中分配而来,你可以进一步的为每一个线程创建命令池,允许多个命令缓冲区都是从自己线程的命令池中获取的,这样就不会有任何冲突了。

在你往一个命令缓冲区录入命令之前,需要启动命令缓冲区,这将导致它处于初始状态这需要调用vkBeginCommandBuffer()原型如下:

VkResult vkBeginCommandBuffer (

VkCommandBuffer  commandBuffer,

const VkCommandBufferBeginInfo*  pBeginInfo);

需要开始记录命令的命令缓冲区是通过commandBuffer参数传递的,记录命令需要用参数是通过一个VkCommandBufferBeginInfo类型的变量pBeginInfo通过指针传递的。VkCommandBufferBeginInfo定义如下:

typedef struct VkCommandBufferBeginInfo {

VkStructureType  sType;

const void*  pNext;

VkCommandBufferUsageFlags  flags;

const VkCommandBufferInheritanceInfo*  pInheritanceInfo;

} VkCommandBufferBeginInfo;

sType域应当被设置为VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFOpNext应被设置为nullptr。flags是用来告诉Vulkan命令缓冲区将会被如何使用。它值是VkCommandBufferUsageFlagBits枚举变量某几个值的组合得到的枚举类型有以下选项:

VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT意味着命令缓冲区就会被记录,只会被执行一次,然后销毁回收。

VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT意味着这个命令缓冲区就会被用在renderpass内部,此类型只对次级命令缓冲区有效。如果用于主命令缓冲区,那么它会无视Renderpass和次级命令缓冲区将在第十三章“”讲解。

VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT 意味着命令缓冲区有可能被多次执行或者暂停

flags设置为0是安全的,意味着我们可能多次执行命令缓冲区,不同时访问也不需要次级命令缓冲区。

pInheritanceInfo成员是用来开启次级命令缓冲区所需要,来定义被继承的主命令缓冲区的状态。对于主命令缓冲区,这个指针参数被忽略。我们将在第十三章讲解次级命令缓冲区时介绍VkCommandBufferInheritanceInfo类型的结构

现在,我们需要创建首个命令来。第二章中,已经学缓冲,图像,内存。vkCmdCopyBuffer()命令是用来两个buffer对象之间拷贝数据的,原型如下:

 

void vkCmdCopyBuffer (

VkCommandBuffer  commandBuffer,

VkBuffer  srcBuffer,

VkBuffer  dstBuffer,

uint32_t  regionCount,

const VkBufferCopy*  pRegions);

这是一个常见形式的Vulkan命令。第一个参数commandBuffer,指定命令需要追加的哪个命令缓冲区srcBufferdstBuffer指定了源地址和目的地址。最后,一个regions的数组是通过pRegions指定的。每一个region代表着一个VkBufferCopy类型的数据,定义如下:

typedef struct VkBufferCopy {

VkDeviceSize  srcOffset;

VkDeviceSize  dstOffset;

VkDeviceSize  size;

} VkBufferCopy;这个数组的每一个元素包含源和目标的偏移值,和每个region从srcOffsetdstOffset需要拷贝的大小命令被执行时,pRegions的每一个regionsize 大小的数据将会从srcBuffer的srcOffset拷贝到dstBuffer的dstOffset。这些偏移值都是以byte为单位的。

关于Vulkan操作的很基础的事实是命令在被调用时并不是被立即执行的。他们仅仅是被添加到命令缓冲区中了。如果你正在从或者到一个CPU可访问的内存区域拷贝数据,那么,你需要确认以下几件事:

保证在命令被设备执行前,数据一直都在源区域

保证在命令在设备上执行后,源区域的数据是有效的

保证直到命令在设备上执行命令后,

如果有任何意见,欢迎留言讨论。


[ 主页 ]
COMMENTS
POST A COMMENT

(optional)



(optional)