机翻 Vulkan参考手册 6. Synchronization and Cache Control

同步访问资源主要是Vulkan中应用程序的责任。与设备上的主机和其他命令相关的命令的执行顺序几乎没有明确的保证,并且需要明确指定。内存缓存和其他优化也被明确管理,要求通过系统的数据流主要受应用程序控制。

虽然命令之间存在一些隐含的保证,Vulkan公开了五种显式同步机制:

Fences可用于与主机通信设备上某些任务的执行已完成。

Semaphores可用于控制跨多个队列的资源访问。

Events提供了一个细粒度的同步原语,可以在命令缓冲区内或通过主机发送信号,并可以在命令缓冲区内等待或在主机上查询。

Pipeline Barriers还可以在命令缓冲区内提供同步控制,但在单点上,而不是单独的信号和等待操作。

Render Passes为大多数渲染任务提供了一个有用的同步框架,并以本章中的概念为基础。作为渲染过程的一部分,很多情况下可能需要更高效地表示否则需要应用程序使用其他同步基元的情况。


6.1。执行和内存依赖性
操作是要在主机,设备或外部实体(如演示引擎)上执行的任意数量的工作。同步命令引入了显式的执行依赖关系,以及由命令的两个同步作用域定义的两组操作之间的内存依赖关系。

同步范围定义同步命令能够创建执行依赖关系的其他操作。不在同步命令的同步范围中的任何类型的操作都不会包含在生成的依赖项中。例如,对于许多同步命令,同步范围可以仅限于在特定流水线阶段执行的操作,这允许将其他流水线阶段从依赖项中排除。其他范围选项也是可能的,具体取决于具体的命令。

执行依赖关系是保证对于两组操作,第一组必须发生 - 在第二组之前。如果发生操作 - 在另一个操作之前,则第一个操作必须在第二个操作启动之前完成。更确切地说:

  • 让A和B成为独立的操作集。
  • 设S是一个同步命令。
  • 让AS和BS成为S的同步范围。
  • 设A'为集合A和AS的交集。
  • 设B'为B和BS的交集。
  • 按照该顺序提交A,S和B执行,将导致A'和B'之间的执行依赖E.
  • 执行依赖关系E保证A'发生在B之前。
执行依赖链是一系列执行依赖关系,它们构成第一个依赖关系A'和最终依赖关系B'之间的先发生关系。 对于每个连续的执行依赖关系,如果第一个依赖关系中的BS与第二个依赖关系中的AS的交集不是空集,则存在链。 从执行依赖关系链形成单个执行依赖关系可以通过在执行依赖关系描述中替换以下内容来描述:
  • 设S是一组生成执行依赖链的同步命令。
  • 让AS成为S中第一个命令的第一个同步范围。
  • 让BS成为S中最后一个命令的第二个同步范围。
注意
执行依赖本质上也是多个执行依赖 - 在A'的每个子集和B'的每个子集之间存在依赖关系,对于执行依赖关系链也是如此。 例如,在其阶段掩码中具有多个流水线阶段的同步命令有效地在每个源阶段和每个目标阶段之间生成一个依赖关系。 当考虑如何执行链如果不涉及同步命令的依赖关系的所有部分时,这可以用于思考。 同样,执行依赖关系链中的任何一组相邻依赖关系都可以被视为一个执行依赖关系链。


单独的执行依赖性不足以保证可以从另一组操作读取由一组操作中的写入产生的值。
使用另外两种类型的操作来控制内存访问。 可用性操作会导致由指定的内存写入访问生成的值可供将来访问。 任何可用值保持可用,直到发生相同内存位置的后续写入(无论是否可用)或释放内存为止。 可见性操作会导致任何可用值对指定的内存访问变得可见。
内存依赖性是一种执行依赖性,它包括可用性和可见性操作,以便:
  • 第一组操作发生在可用性操作之前。
  • 可用性操作发生在可见性操作之前。
  • 可见性操作发生在第二组操作之前。

一旦写入值对特定类型的存储器访问可见,就可以通过该类型的存储器访问来读取或写入它们。 Vulkan中的大多数同步命令都定义了内存依赖性。


可用和可见的特定内存访问由内存依赖性的访问范围定义。 存在于存储器依赖的第一个访问范围内并出现在A'中的任何类型的访问都可用。 存储器依赖性的第二个访问范围内的任何类型的访问都存在于B'中,并且有任何可用的写入对其可见。 任何不在同步命令的访问范围内的操作都不会包含在结果依赖项中。

内存依赖性强制执行两组操作之间的内存访问和执行顺序的可用性和可见性。 添加到执行依赖关系链的描述中:
  • 设a是由A'执行的一组存储器访问。
  • 设b是由B'执行的一组存储器访问。
  • 让aS成为S中第一个命令的第一个访问范围。
  • 让bS成为S中最后一个命令的第二个访问范围。
  • 让a'是a和a的交集。
  • 令b'为b和bS的交集。
  • 按照A,B和B的顺序提交A,S和B将导致A'和B'之间的内存依赖性m。
内存依赖m保证:
  • 内存写入'是可用的。
  • 可用内存写入,包括来自a的内存写入,对b可见。
注意
执行和内存依赖性用于解决数据危害,即确保读写操作以明确定义的顺序进行。 只读执行依赖性可解决读后危险,但写后读写和写后写后危险需要在它们之间包含适当的内存依赖性。 如果应用程序不包含依赖项来解决这些危险,则存储器访问的结果和执行顺序是不确定的。

6.1.1。 image布局转换
作为存储依赖的一部分,图像子资源可以从一个布局转换到另一个布局(例如,通过使用图像存储屏障)。在内存依赖性中指定了布局转换时,会发生 - 在内存依赖性中的可用性操作之后,发生 - 在可见性操作之前。映像布局转换可以对绑定到映像子资源范围的所有内存执行读取和写入访问,因此应用程序必须确保在执行布局转换之前所有内存写入都已经可用。可用内存自动对布局转换可见,并且由布局转换执行的写入会自动提供。

布局转换始终适用于特定图像子资源范围,并指定旧布局和新布局。如果旧布局与新布局不匹配,则会发生转换。旧布局必须与图像子资源范围的当前布局匹配,但有一个例外。旧布局始终可以指定为VK_IMAGE_LAYOUT_UNDEFINED,尽管这样会使图像子资源范围的内容无效。

注意
将旧布局设置为VK_IMAGE_LAYOUT_UNDEFINED意味着图像子资源的内容不需要保留。 实现可以使用这些信息来避免执行昂贵的数据转换操作。
注意
应用程序必须确保布局转换发生在使用旧布局访问图像并发生的所有操作之后 - 在任何将使用新布局访问图像的操作之前。 布局转换可能是读/写操作,因此不定义适当的内存依赖性来保证这将导致数据竞争。


图像布局转换与内存别名相互作用。


6.1.2. Pipeline Stages

动作命令执行的工作由多个操作组成,这些操作由一系列逻辑上独立的执行单元(称为流水线阶段)执行。执行的确切流水线阶段取决于所使用的特定操作命令以及当记录操作命令时的当前命令缓冲区状态。绘图命令,调度命令,复制命令和清除命令都在不同的流水线阶段中执行。

跨越流水线阶段执行操作必须遵守隐式排序保证,特别是包括流水线阶段顺序。否则,跨越流水线阶段的执行可能会与其他阶段重叠或执行失序,除非执行依赖项另有强制。

几个同步命令包括流水线阶段参数,将该命令的同步范围限制在这些阶段。这允许精确控制动作命令执行的确切执行依赖性和访问。实现应该使用这些流水线阶段来避免不必要的停顿或缓存刷新。


可以设置的位,指定流水线阶段是:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT 指定队列最初接收任何命令的管道阶段。
  • VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX     指定管道通过vkCmdProcessCommandsNVX处理设备端生成命令的阶段。
  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT     指定消耗Draw / DispatchIndirect数据结构的管道阶段。该阶段还包括读取由vkCmdProcessCommandsNVX编写的命令。
  • VK_PIPELINE_STAGE_VERTEX_INPUT_BIT     指定消耗顶点和索引缓冲区的管道阶段。
  • VK_PIPELINE_STAGE_VERTEX_SHADER_BIT    指定顶点着色器阶段。
  • VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT    指定镶嵌控制着色器阶段。
  • VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT    指定镶嵌评估着色器阶段。
  • VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT    指定几何着色器阶段。
  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT    指定片段着色器阶段。
  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT    指定执行早期片段测试(片段着色之前的深度和模板测试)的管道阶段。此阶段还包括具有深度/模板格式的帧缓冲附件的子通道加载操作。
  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT    指定执行后期片段测试(片段着色后的深度和模板测试)的管道阶段。此阶段还包括具有深度/模板格式的帧缓冲附件的子级存储操作。
  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT    指定混合后的流水线阶段,其中最终颜色值从流水线输出。此阶段还包括带颜色格式的帧缓冲附件的子通道加载和存储操作以及多重采样解析操作。
  • VK_PIPELINE_STAGE_TRANSFER_BIT    指定执行复制命令。这包括所有复制命令产生的操作,清除命令(除vkCmdClearAttachments外)和vkCmdCopyQueryPoolResults。
  • VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT    指定计算着色器的执行。
  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT    指定管道中由所有命令生成的操作完成执行的最后阶段。
  • VK_PIPELINE_STAGE_HOST_BIT    指定一个伪级,指示在主机上执行对设备内存的读/写操作。这个阶段不会被命令缓冲区中记录的任何命令调用。
  • VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT    指定所有图形流水线阶段的执行
  • VK_PIPELINE_STAGE_ALL_COMMANDS_BIT等价于其所用队列所支持的每个其他管道阶段标志的逻辑或。
注意
目标阶段掩码中只有VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT的执行依赖项只会阻止该阶段在随后提交的命令中执行。 由于这个阶段没有执行任何实际的执行,这是不可观察的 - 实际上,它不会延迟后续命令的处理。 类似地,源级掩码中仅具有VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT的执行依赖性将不会等待任何先前的命令完成。

在定义内存依赖性时,仅使用VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT或VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT决不会使任何访问可用和/或可见,因为这些阶段不访问内存。

VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT和VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT对于通过其他方式满足所需的执行依赖关系(例如队列之间的信号量操作)来完成布局转换和队列所有权操作非常有用。

如果同步命令包含源级掩码,则其第一个同步作用域仅包含在该掩码中指定的管道级的执行,并且其第一个访问范围只包括由该掩码中指定的管道级执行的存储器访问。 如果同步命令包含目标阶段掩码,则其第二个同步范围仅包括执行该掩码中指定的流水线阶段,而其第二个访问范围仅包含由该掩码中指定的流水线阶段执行的内存访问。

注意
在命令的第一个同步作用域中包含特定的管道阶段隐式地包含同步作用域中逻辑上较早的管道阶段。 类似地,第二个同步范围包括逻辑上稍后的流水线阶段。

但是请注意,访问范围不会以这种方式受到影响 - 只有指定的精确阶段才被视为每个访问范围的一部分。

某些流水线阶段仅在支持特定操作集的队列上可用。 下表列出了每个管道阶段标志,队列必须支持哪个队列功能标志。 如果在表的第二列中枚举了多个标志,则表示队列上支持管线阶段(如果它支持列出的任何能力标志)。 有关队列功能的更多详细信息,请参阅物理设备枚举和队列。
Table 3. Supported pipeline stage flags
Pipeline stage flagRequired queue capability flag

VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT

None required

VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

VK_QUEUE_COMPUTE_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_QUEUE_GRAPHICS_BITVK_QUEUE_COMPUTE_BIT or VK_QUEUE_TRANSFER_BIT

VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

None required

VK_PIPELINE_STAGE_HOST_BIT

None required

VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT

VK_QUEUE_GRAPHICS_BIT

VK_PIPELINE_STAGE_ALL_COMMANDS_BIT

None required

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

VK_QUEUE_GRAPHICS_BIT or VK_QUEUE_COMPUTE_BIT

作为命令结果执行的流水线阶段按照特定的顺序逻辑完成执行,从而在逻辑上更早的阶段完成之前,不会发生在逻辑上稍后的流水线阶段的完成。 这意味着在特定同步命令的源级掩码中包含任何给定的阶段也意味着在该命令的AS中包含任何逻辑上较早的阶段。

同样,在逻辑上稍后的流水线阶段开始之后,不应发生逻辑上较早的流水线阶段。 包括特定同步命令的目标阶段掩码中的任何给定阶段也意味着该命令的BS中包括任何逻辑上较晚的阶段。

注意
对于每个同步操作,实现可能不支持每个管道阶段的同步。 如果某个实现不支持同步的管道阶段出现在源级掩码中,则它可能会替换其位置上的任何逻辑上后期的第一个同步作用域。 如果某个实现不支持同步的管道阶段出现在目标阶段掩码中,则它可能会替换其位置上任何逻辑上较早的阶段作为第二个同步作用域。
例如,如果实现无法在顶点着色器执行完成后立即指示事件,则可能会在彩色附件输出完成后发出事件信号。
如果实现进行了这种替换,它不得影响执行或内存依赖性或映像和缓冲区内存障碍的语义。


流水线阶段的顺序取决于特定的流水线; 图形,计算,传输或主机。

对于图形管线,以下顺序按以下顺序进行:
  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  • VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
  • VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
  • VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
  • VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
  • VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
对于计算管道,按以下顺序进行以下阶段:
  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
  • VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
  • VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

对于传输管道,按以下顺序进行以下阶段:

  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
  • VK_PIPELINE_STAGE_TRANSFER_BIT
  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

对于主机操作,仅发生一个流水线阶段,因此不保证顺序:

  • VK_PIPELINE_STAGE_HOST_BIT
对于命令处理管道,按以下顺序进行以下阶段:
  • VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
  • VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX
  • VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
6.1.3。 访问类型
Vulkan中的内存可以通过着色器调用和管道的某些固定功能阶段进行访问。 访问类型是所用描述符类型的函数,或者固定功能阶段如何访问内存。 每个访问类型对应于VkAccessFlagBits中的一个位标志。

某些同步命令将多组访问类型作为参数来定义内存依赖性的访问范围。 如果同步命令包含源访问掩码,则其第一个访问范围仅包含通过该掩码中指定的访问类型的访问。 同样,如果同步命令包含目标访问掩码,则其第二个访问范围仅包含通过该掩码中指定的访问类型的访问。

可以在访问掩码中设置的访问类型包括:
VK_ACCESS_INDIRECT_COMMAND_READ_BIT指定对作为间接绘图或分派命令的一部分读取的间接命令结构的读访问。
VK_ACCESS_INDEX_READ_BIT指定对索引缓冲区的读取访问,作为由vkCmdBindIndexBuffer绑定的索引绘图命令的一部分。
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT指定对顶点缓冲区的读访问,作为绘图命令的一部分,由vkCmdBindVertexBuffers绑定。
VK_ACCESS_UNIFORM_READ_BIT指定对统一缓冲区的读访问权限。
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT指定在片段着色期间对渲染通道内的输入附件的读取访问。
VK_ACCESS_SHADER_READ_BIT指定对存储缓冲区,均匀纹理缓冲区,存储纹素缓冲区,采样图像或存储图像的读访问权限。
VK_ACCESS_SHADER_WRITE_BIT指定对存储缓冲区,存储纹素缓冲区或存储器映像的写入访问权限。
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT指定对颜色附件的读取访问权限,例如通过混合,逻辑操作或通过某些子通道加载操作。它不包括高级混合操作。
VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT    类似于VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,但也包括高级混合操作。
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT指定在渲染过程中或通过某些子通道加载和存储操作期间对颜色的写入访问权限或解析附件。
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT指定通过深度或模板操作或通过某些子通道加载操作对深度/模板附件进行读取访问。
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT指定通过深度或模板操作或通过某些子通道加载和存储操作对深度/模板附件进行写入访问。
VK_ACCESS_TRANSFER_READ_BIT指定在复制操作中对图像或缓冲区的读访问权限。
VK_ACCESS_TRANSFER_WRITE_BIT指定在清除或复制操作中对图像或缓冲区的写入权限。
VK_ACCESS_HOST_READ_BIT指定主机操作的读取访问。这种类型的访问不通过资源执行,而是直接在内存中执行。
VK_ACCESS_HOST_WRITE_BIT指定主机操作的写入权限。这种类型的访问不通过资源执行,而是直接在内存中执行。
VK_ACCESS_MEMORY_READ_BIT指定通过非特定实体的读访问。这些实体包括Vulkan设备和主机,但也可能包括Vulkan设备外部的实体或其他不属于核心Vulkan管道的实体。当包含在目标访问掩码中时,使所有可用的写入对Vulkan设备已知实体上的所有未来读访问都可见。
VK_ACCESS_MEMORY_WRITE_BIT指定通过非特定实体的写访问。这些实体包括Vulkan设备和主机,但也可能包括Vulkan设备外部的实体或其他不属于核心Vulkan管道的实体。当包含在源访问掩码中时,由Vulkan设备已知的实体执行的所有写入都可用。当包含在目标访问掩码中时,使所有可用的写入对Vulkan设备已知实体上的所有未来写入访问都可见。
VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX指定从VkBuffer输入到vkCmdProcessCommandsNVX的读取。
VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX指定在vkCmdProcessCommandsNVX中写入目标命令缓冲区。

某些访问类型仅由流水线阶段的子集执行。 任何同时使用阶段掩码和访问掩码的同步命令都使用这两个参数来定义访问作用域 - 只有指定阶段执行的指定访问类型才包含在访问作用域中。 如果应用程序不在相应的阶段掩码中包含能够执行该类型访问的流水线阶段,则不得在同步命令中指定访问标志。 下表为每个访问标志列出了哪些流水线阶段可以执行该类访问。
Table 4. Supported access types
Access flagSupported pipeline stages

VK_ACCESS_INDIRECT_COMMAND_READ_BIT

VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT

VK_ACCESS_INDEX_READ_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT

VK_PIPELINE_STAGE_VERTEX_INPUT_BIT

VK_ACCESS_UNIFORM_READ_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BITVK_PIPELINE_STAGE_GEOMETRY_SHADER_BITVK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_INPUT_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT

VK_ACCESS_SHADER_READ_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BITVK_PIPELINE_STAGE_GEOMETRY_SHADER_BITVK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_SHADER_WRITE_BIT

VK_PIPELINE_STAGE_VERTEX_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BITVK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BITVK_PIPELINE_STAGE_GEOMETRY_SHADER_BITVK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, or VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT

VK_ACCESS_COLOR_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT

VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT

VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, or VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT

VK_ACCESS_TRANSFER_READ_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_ACCESS_TRANSFER_WRITE_BIT

VK_PIPELINE_STAGE_TRANSFER_BIT

VK_ACCESS_HOST_READ_BIT

VK_PIPELINE_STAGE_HOST_BIT

VK_ACCESS_HOST_WRITE_BIT

VK_PIPELINE_STAGE_HOST_BIT

VK_ACCESS_MEMORY_READ_BIT

N/A

VK_ACCESS_MEMORY_WRITE_BIT

N/A

VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX

VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX

如果内存对象不具有VK_MEMORY_PROPERTY_HOST_COHERENT_BIT属性,则必须调用vkFlushMappedMemoryRanges以确保从主机写入内存对象对VK_ACCESS_HOST_WRITE_BIT访问类型可见,并通过同步进一步使其可用于设备命令。 同样,必须调用vkInvalidateMappedMemoryRanges才能确保VK_ACCESS_HOST_READ_BIT访问类型可见的写入对主机操作可见。

如果内存对象具有VK_MEMORY_PROPERTY_HOST_COHERENT_BIT属性标志,则从主机写入内存对象会自动对VK_ACCESS_HOST_WRITE_BIT访问类型可见。 同样,对VK_ACCESS_HOST_READ_BIT访问类型可见的写入会自动显示给主机。

注意
vkQueueSubmit命令可以自动确保刷新到VK_ACCESS_HOST_WRITE_BIT的主机写入在命令执行前被刷新,因此在大多数情况下,这种情况下不需要明确的内存屏障。 在主机写入和设备读取访问之间没有发生提交的少数情况下,通过使用显式内存屏障可以使写入可用。


6.1.4。 帧缓冲区域依赖关系
在帧缓冲器上或相对于帧缓冲器运行的流水线阶段共同是帧缓冲器空间流水线阶段。 这些阶段是:
  • VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  • VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
  • VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
  • VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
对于这些流水线阶段,从第一组操作到第二组的执行或内存依赖性可以是单个帧缓冲区全局依赖性,也可以分裂为多个帧缓冲区本地依赖性。非帧缓冲区空间流水线阶段的依赖性既不是帧缓冲区全局也不是帧缓冲区本地。
帧缓冲区是一组样本(x,y,层,样本)坐标,它是整个帧缓冲区的一个子集。
帧缓冲区本地相关性的两个同步范围仅包括在相应帧缓冲区内执行的操作(如下所定义)。对于帧缓冲区本地依赖性,在不同帧缓冲区之间没有进行顺序保证。
帧缓冲区全局依赖的两个同步范围都包括所有帧缓冲区的操作。

如果第一同步范围包括对具有N个样本的像素/片段的操作并且第二同步范围包括具有M个样本的像素/片段的操作,其中N不等于M,则包含给定(x,y)处的所有样本的帧缓冲区域,层)坐标对应于第二同步范围中包含同一坐标上所有样本的区域。换句话说,它是一种像素粒度依赖性。如果N等于M,则在第一同步范围中包含单个(x,y,层,样本)坐标的帧缓冲区域对应于在第二同步范围中的相同坐标处包含相同样本的区域。换句话说,它是一个样本粒度相关性。

注意

由于片段调用未指定在任何特定的分组中运行,因此帧缓冲区的大小取决于实现,应用程序不知道,并且必须假定它不大于上面指定的大小。

注意
实际上,像素与样本粒度依赖性意味着如果输入附件的样本数量不等于管道的栅格样本数量,则片段即使只使用帧缓冲区本地依赖性,也可以访问输入附件像素中的任何样本。 如果输入附件具有相同数量的样本,则该片段只能访问其输入SampleMask中的覆盖样本(即片段操作发生 - 对片段覆盖的每个样本的帧缓冲区 - 局部依赖关系之后)。 要访问未覆盖的样本,需要帧缓冲区全局依赖项。


如果一个同步命令包含一个dependencyFlags参数,并且指定了VK_DEPENDENCY_BY_REGION_BIT标志,那么它为所有的帧缓冲区域定义该同步命令中帧缓冲区空间流水线级的帧缓冲区本地依赖性。 如果不包含dependencyFlags参数,或者未指定VK_DEPENDENCY_BY_REGION_BIT标志,则为这些阶段指定帧缓冲区全局依赖性。 VK_DEPENDENCY_BY_REGION_BIT标志不会影响非帧缓冲区空间流水线阶段之间的依赖关系,也不会影响帧缓冲区空间和非帧缓冲区空间流水线阶段之间的依赖关系。

注意
对于大多数体系结构来说,帧缓冲区本地依赖性更加优化; 特别是基于瓦片的架构 - 可以将帧缓冲区完全保留在片上寄存器中,从而避免跨越这种依赖关系的外部带宽。 在渲染中包含帧缓冲区全局依赖项通常会强制所有实现将数据刷新到内存或更高级别的缓存中,从而打破任何潜在的局部优化。


6.1.5。 视图 - 本地依赖关系

在启用多视图的渲染通道实例中,依赖项可以是视图本地视图或视图全局视图。

视图 - 本地依赖只包括来自第一个同步范围内的源子通道的单个源视图的操作,并且仅包括来自第二个同步范围中的目标子通道的单个目标视图的操作。 视图全局依赖包括相应同步范围中的源和目标子通道的视图遮罩中的所有视图。

如果一个同步命令包含一个dependencyFlags参数并指定了VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX标志,那么它为所有视图定义该同步命令的视图本地依赖性。 如果不包含dependencyFlags参数或未指定VK_DEPENDENCY_VIEW_LOCAL_BIT_KHX标志,则指定视图全局依赖关系。

6.1.6。 设备 - 本地相关性
依赖关系可以是设备本地或非设备本地。设备本地依赖关系充当多个独立依赖关系,每个依赖关系用于执行同步命令的每个物理设备,其中每个依赖关系仅包含两个同步范围中来自该物理设备的操作。非设备本地依赖项是单一依赖项,其中两个同步范围均包含来自参与同步命令的所有物理设备的操作。对于子通道依赖性,VkDeviceGroupRenderPassBeginInfoKHX :: deviceMask中的所有物理设备都参与依赖关系,对于管道屏障,在命令缓冲区的当前设备掩码中设置的所有物理设备都参与依赖关系。

如果一个同步命令包含一个dependencyFlags参数并指定了VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX标志,那么它为该同步命令定义一个非设备本地依赖关系。如果未包含dependencyFlags参数或未指定VK_DEPENDENCY_DEVICE_GROUP_BIT_KHX标志,则它将为所有参与的物理设备定义该同步命令的设备本地依赖关系。

信号量和事件依赖关系是设备本地的,只能在执行依赖关系的一台物理设备上执行。

6.2。 隐式同步保证
Vulkan提供了少量的隐式排序保证,确保命令的提交顺序是有意义的,避免了常见操作中的不必要的复杂性。
提交顺序是Vulkan中的一个基本顺序,它赋予操作和同步命令记录并提交给单个队列的顺序的含义。 Vulkan中的命令之间的显式和隐式顺序保证都是在这个顺序有意义的前提下工作的。
任何给定命令集的提交顺序都是基于它们被记录到命令缓冲区然后提交的顺序。 该订单确定如下:
初始顺序由vkQueueSubmit命令在主机上执行的顺序决定,对于单个队列,从第一个到最后一个。
VkSubmitInfo结构在vkQueueSubmit的pSubmits参数中指定的顺序,从最低索引到最高。
命令缓冲区的顺序在VkSubmitInfo的pCommandBuffers成员中指定,从最低索引到最高。
从第一个到最后一个命令被记录到主机上的命令缓冲区的顺序:
对于在渲染通道外部记录的命令,这包括记录在渲染通道之外的所有其他命令,包括vkCmdBeginRenderPass和vkCmdEndRenderPass命令;它不直接在渲染过程中包含命令。
对于在渲染通道内记录的命令,这包括记录在同一子通道内的所有其他命令,包括划定相同渲染通道实例的vkCmdBeginRenderPass和vkCmdEndRenderPass命令;它不包括记录到其他子通道的命令。
记录到命令缓冲区的动作和同步命令以提交顺序执行VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT管道阶段,在每个命令的这个阶段之间形成隐式执行依赖关系。
记录到命令缓冲区的动作和同步命令以提交顺序执行VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT管道阶段 - 在每个命令的这个阶段之间形成隐式执行依赖关系。
状态命令不会在设备上执行任何操作,而是会按照它们被记录的顺序设置命令缓冲区在主机上执行时的状态。 动作命令在记录时消耗命令缓冲区的当前状态,并根据需要在设备上执行状态更改以匹配记录的状态。
查询命令,通过图形管道的图元顺序以及图像布局转换作为图像内存屏障的一部分,可提供基于提交顺序的额外保证。
给定命令中的流水线阶段的执行也具有松散排序,仅取决于单个命令。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值