您的位置:首页 > 编程语言

Vulkan编程指南翻译 第四章 队列和命令 第1节 管理资源的状态

2017-02-22 22:35 661 查看
在本章,你将学到:

l 如何管理资源被Vulkan使用时的状态

l 如何在资源间复制数据,用已知数据填充缓冲区和图像

l 如何进行位块操作以拉伸或缩放图像数据

 

图形和计算操作总体上是数据密集型的。Vulkan引入了几个对象,可以提供存储和操纵数据的途径。经常需要把数据移入或者转出这些对象,有几个命令可以用来做这个工作:复制数据,填充缓冲区和图像对象。进一步,在任何时刻,一个资源可能出狱多个状态,Vulkan管线的多个部分可能需要访问他们。本章将讲解数据移动命令—可以用来复制数据与填充内存—当它们被应用程序访问的时候,命令需要用来管理资源的状态。

第三章,展示了命令被放在了一个命令缓冲区中并提交到设备的某一个队列以被执行。这非常重要,因为这表示命令并不是你的应用程序调用它们的时候就被执行的,却是当你把它们提交到队列,队列进入设备的时候被执行的。之前介绍给你的第一个相关函数,vkCmdCopyBuffer(),在两个buffer之间或者同一buffer不同的区域之间复制数据。这是众多能够改变buffer,图像,其他的Vulkan对象的命令之一。本章将讲解填充、复制、清除buffer与图像的相关命令。

 

4.1 管理资源状态

在一个程序执行中在任何给定的时刻,每一个资源都可以处于一个或者多个不同的状态。例如,如果图形管线正在绘制一个图像或者使用它作为一个贴图,或者Vulkan正在从CPU端复制数据到一个图像,这些场景都是不同的。对于一些Vulkan实现,上述的一些状态之间也许没有任何差别,对于其他的,准确的知道一个时间点资源所处的状态会决定你的应用程序正常的工作或者是做垃圾工作。

因为命令缓冲区内的命令负责访问资源,且多个命令缓冲区被创建的顺序有可能不同于他们被提交执行的顺序,故由Vulkan跟踪资源的状态并且保证在每一场景都正确的工作是不现实的。特别是,一个资源会因命令缓冲区的执行从一个状态转为另一个状态。驱动无法跟踪资源的状态,当命令缓冲区被提交执行的时候,在命令缓冲区之间跟踪状态有显著的损耗。因此,这个责任落到了应用程序身上。资源的状态,对图像来说可能非常重要,因为他们是复制、结构化的资源。

一个图像的状态可以粗略的分为两种正交的集合:布局,记录。布局决定了数据在内存中的存放布局,在本书前面讲过。记录,谁最后一次写入信息,将影响cache和数据的一致性。图像初始的布局是在创建时被指定的,然后在其生命周期内发生改变,要么显式的使用barriers或者隐式的使用renderpass。Barriers掌控这Vulkan渲染管线的不同部分对资源的访问,在某些情况下,在另一个midpipeline同步工作中,barriers可以一个资源从一个布局转变到另一布局。

每一种布局的准确使用将在本书后面详细讲到。然而,转移数据从一个状态到另一状态的基础操作就是barrier,且,在应用程序中准确的理解并高效率的使用它,是极其重要的。

 

4.1.1 管线屏障

屏障是同步机制的一种,被用来管理内存访问和资源的在Vulkan管线的一个stage内状态迁移。资源访问同步和状态迁移主要的命令是vkCmdPipelineBarrier(),原型如下:

 

 

void vkCmdPipelineBarrier (

VkCommandBuffer commandBuffer,

VkPipelineStageFlags srcStageMask,

VkPipelineStageFlags dstStageMask,

VkDependencyFlags dependencyFlags,

uint32_t memoryBarrierCount,

const VkMemoryBarrier* pMemoryBarriers,

uint32_t bufferMemoryBarrierCount,

const VkBufferMemoryBarrier* pBufferMemoryBarriers,

uint32_t imageMemoryBarrierCount,

const VkImageMemoryBarrier* pImageMemoryBarriers);

需要执行屏障的命令缓冲区是通过commandBuffer指定的。接下来的两个参数,srcStageMask 和 dstStageMask,指定了哪个阶段的管线最后向资源写入和哪个阶段接下来要从资源读数据。亦即,屏障通过它们指定了数据流通的源和目的地。每一个值都是VkPipelineStageFlagBits枚举类型的值构造的。

• VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT: The top of pipe is considered to be hit as soon

as the device starts processing the command.

• VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT: When the pipeline executes an

indirect command, it fetches some of the parameters for the command from memory. This

is the stage that fetches those parameters.

• VK_PIPELINE_STAGE_VERTEX_INPUT_BIT: This is the stage where vertex attributes are

fetched from their respective buffers. After this, content of vertex buffers can be overwritten,

even if the resulting vertex shaders have not yet completed execution.

• VK_PIPELINE_STAGE_VERTEX_SHADER_BIT: This stage is passed when all vertex

shader work resulting from a drawing command is completed.

• VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT: This stage is passed

when all tessellation control shader invocations produced as the result of a drawing command

have completed execution.

• VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT: This stage is

passed when all tessellation evaluation shader invocations produced as the result of a drawing

command have completed execution.

• VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT: This stage is passed when all geometry

shader invocations produced as the result of a drawing command have completed execution.

• VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT: This stage is passed when all fragment

shader invocations produced as the result of a drawing command have completed execution.

Note that there is no way to know that a primitive has been completely rasterized while the

resulting fragment shaders have not yet completed. However, rasterization does not access

memory, so no information is lost here.

• VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT: All per-fragment tests that

might occur before the fragment shader is launched have completed.

• VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT: All per-fragment tests that might

occur after the fragment shader is executed have completed. Note that outputs to the depth and

stencil attachments happen as part of the test, so this stage and the early fragment test stage

include the depth and stencil outputs.

• VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT: Fragments produced by the

pipeline have been written to the color attachments.

• VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT: Compute shader invocations produced as

the result of a dispatch have completed.

• VK_PIPELINE_STAGE_TRANSFER_BIT: Any pending transfers triggered as a result of calls

to vkCmdCopyImage() or vkCmdCopyBuffer(), for example, have completed.

• VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT: All operations considered to be part of

the graphics pipeline have completed.

• VK_PIPELINE_STAGE_HOST_BIT: This pipeline stage corresponds to access from the host.

• VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT: When used as a destination, this special flag

means that any pipeline stage may access memory. As a source, it’s effectively equivalent to

VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT.

• VK_PIPELINE_STAGE_ALL_COMMANDS_BIT: This stage is the big hammer. Whenever

you just don’t know what’s going on, use this; it will synchronize everything with everything.

Just use it wisely

因为srcStageMask 和 dstStageMask内的标志位用来指示事情什么时候发生,Vulkan实现把它们放在一边或者多种方式解读它们。srcStageMask指定了什么时候源阶段已经完成了向资源读或写数据。结果,在管线中稍后移动这个阶段有效的位置并不改变访问已经完成的事实。

这意味着实现等待的时间比它需要完成的时间还久。

同样的,dstStageMask指定了管线在处理之前等着的时间点。如果一个Vulkan实现把等待的时间点提前了,也是能够工作的。在逻辑上后面的管线部分开始执行前,被等待的事件也最终会被完成。这种实现仅仅是失去了当它在等待时却能够工作的机会。

dependencyFlags参数指定了标志位的一个集合,描述了由屏障表示的依赖关系如何影响到屏障引用的资源。唯一被定义的标志类型是VK_DEPENDENCY_BY_REGION_BIT,它表示屏障只影响被source
stage改变的区域,此区域被目标阶段所消耗。

vkCmdPipelineBarrier()调用可用来触发多个屏障操作。有三种类型的屏障操作:全局内存屏障,buffer屏障,图像屏障。全局内存屏障影响到诸如映射内存被CPU、GPU同步访问之类的工作。Buffer和image屏障主要影响设备对buffer和images资源的访问。、

 

4.1.2  全局内存屏障

vkCmdPipelineBarrier()可触发的全局内存屏障是通过memoryBarrierCount参数指定的。如果这是一个非零值,那么pMemoryBarriers指向一个大小为memoryBarrierCount的VkMemoryBarrier类型的数组,每一个都代表一个内存屏障。VkMemoryBarrier定义如下:

typedef struct VkMemoryBarrier {

VkStructureType sType;

const void* pNext;

VkAccessFlags srcAccessMask;

VkAccessFlags dstAccessMask;

} VkMemoryBarrier; 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: