避免在 Vulkan 中每一帧更改纹理布局的有效方法

Effective way to avoid changing texture layout in Vulkan every frame

提问人:Angelicos Phosphoros 提问时间:11/8/2023 更新时间:11/8/2023 访问量:38

问:

我有一些很少更新的纹理数据,但我无法控制它何时更新(数据由渲染 GUI 的外部库提供)。

目前,我在每一帧中更改了两次它们的布局:

  1. 从 到 with pipeline stages 到 ,VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMALVK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMALVK_PIPELINE_STAGE_TRANSFER_BITVK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
  2. 然后从 to with stages 到 .VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMALVK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMALsrc=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BITdst=VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT

我认为,每次发生的这种转换可能是浪费,因为我几乎总是对我的纹理没有任何更新,所以我正在考虑实现此过程:

  1. 检查更新。
  2. 如果有任何更新,请记录并提交一个单独的命令缓冲区,该缓冲区将我的纹理从只读最优转换为传输 dst 最优。
  3. 如果有任何更新,请记录传输命令,并在主命令缓冲区中将转换发出回只读最佳值。
  4. 否则,只需按原样使用纹理,无需任何转换。

这是一个好方法吗?有没有其他方法可以减少此类布局转换? 我也考虑只使用 .VK_IMAGE_LAYOUT_GENERAL

纹理 Vulkan

评论

1赞 solidpixel 11/8/2023
大多数从最优到最优的布局转换都是空操作的,因此在浪费时间之前,请使用分析器来确定是否真的在优化需要优化的内容。
1赞 solidpixel 11/8/2023
尽量避免用于 GPU 端操作。它比最佳布局慢(这就是存在最佳布局的原因)。VK_IMAGE_LAYOUT_GENERAL

答:

1赞 ratchet freak 11/8/2023 #1

您确定这是一个实际问题吗?驾驶员知道,dst_optimal后的下一次布局转移很可能是read_only。因此,这些过渡不太可能真正起到任何作用。

如果在发生更改时完全覆盖纹理,则工作流程应为:

if(image_changed){
    pipeline barrier from VK_IMAGE_LAYOUT_UNDEFINED to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL 
    vkCmdCopyBufferToImage(cmd, staging_buffer, texture, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
    //copy from staging buffer to texture
    pipeline barrier from VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
}

VK_IMAGE_LAYOUT_UNDEFINEDAS 允许驱动程序完全丢弃旧数据,跳过其中一个转换。src

这假设这是一个足够体面的检查。image_changed

评论

0赞 Angelicos Phosphoros 11/9/2023
不,纹理提供程序会更新纹理块,同时保持其他部分可用。不过,这是完全改变纹理的好技巧。