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

99 篇文章 53 订阅
81 篇文章 2 订阅

本章,你将学到:

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

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

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

 

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

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

 

4.1 管理资源状态

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

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

一个图像状态可以粗略的分为两种正交的集合布局,记录。布局决定了数据在内存中的存放布局,在本书前面讲过。记录谁最后一次写入信息,将影响cache和数据的一致性。图像初始布局是在创建时被指定的然后其生命周期内发生改变,要么显式的使用barriers或者隐式的使用renderpassBarriers掌控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屏障,图像屏障。全局内存屏障影响到诸如映射内存被CPUGPU同步访问之类工作Bufferimage屏障主要影响设备对bufferimages资源的访问。、

 

4.1.2  全局内存屏障

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

typedef struct VkMemoryBarrier {

VkStructureType sType;

const void* pNext;

VkAccessFlags srcAccessMask;

VkAccessFlags dstAccessMask;

} VkMemoryBarrier; 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值