【问题标题】:Dynamic indexing into uniform array of sampler2D doesn't work动态索引到 sampler2D 的统一数组不起作用
【发布时间】:2020-07-22 09:31:45
【问题描述】:

我需要索引 2 个统一的 sampler2D 数组。该索引是每帧动态的。也就是说,我有一个动态统一缓冲区,该缓冲区将该索引提供给片段着色器。我使用 Vulkan API 1.2。在设备功能列表中,我有:

shaderSampledImageArrayDynamicIndexing = 1

我不确定 100%,但看起来这个功能是 1.2 的核心。尽管如此,我确实尝试在设备创建过程中启用它,如下所示:

       VkPhysicalDeviceFeatures features = {}; 
       features.shaderSampledImageArrayDynamicIndexing = VK_TRUE;
     

然后插入设备创建:

    VkDeviceCreateInfo deviceCreateInfo = {};
    deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    deviceCreateInfo.pQueueCreateInfos = queueCreateInfos;
    deviceCreateInfo.queueCreateInfoCount = 1;
    deviceCreateInfo.pEnabledFeatures = &features ;
    deviceCreateInfo.enabledExtensionCount = NUM_DEVICE_EXTENSIONS;
    deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;

在着色器中它看起来像这样:

   layout(std140,set=0,binding=1)uniform Material
   {
    vec4   fparams0;
    vec4   fparams1; 
    uvec4  iparams; //.z - array texture idx
    uvec4  iparams1;
   }material;


   layout (set=1,binding = 0)uniform sampler2D u_ColorMaps[2];
   layout (location = 0)in vec2 texCoord;
   layout(location = 0) out vec4 outColor;
   void main()
   {

      outColor  =  texture(u_ColorMaps[material.iparams.z],texCoord);
     
   }
   

我得到的是图像像素与一些奇怪颜色的组合。如果我更改为固定索引 - 它可以正常工作。 material.iparams.z 参数已经过验证,每帧(0 或 1)提供正确的索引号。不知道还缺少什么。验证层什么也没说。

我的设置:Windows、RTX3000、NVIDIA beta 驱动程序 443.41 (Vulkan 1.2)

更新:

我还发现动态索引采样器在红色通道 (r) 中返回一个值 在 GB 中接近 1 和 0。反正我没有设置红色,我获取的纹理也不包含红色。这是两个截图,上面是我在使用常数值索引时得到的正确结果。其次是当我使用来自动态 UBO 的动态 uint 进行索引时会发生什么:

正确

错了

【问题讨论】:

  • "nonuniformEXT" 这应该是做什么的,为什么你声称某些东西是不统一的,而它肯定是不统一的?您用作索引的值是统一的。
  • @NicolBolas 忘记了这个功能,只是试了一下看看会发生什么。将编辑这部分。没有它也无法工作。
  • 怎么样? “动态索引”是指在渲染帧之前,我通过统一缓冲区更新 material.iparams.z。当然这是动态索引!使用固定值我在这里没有问题。而且我看不出有任何理由投票结束这个问题,因为这实际上是一个定义明确的问题。
  • @NicolBolas 同样,在 Vulkan 中,至少动态索引有两种类型:1)从统一索引 2)从变化值索引。当索引在当前绘制调用中发生变化时,这两种情况都是可能的,并且 nonuniformEXT 存在。在我的情况下,它不是来自统一缓冲区,该缓冲区在运行命令缓冲区之前更新一次。
  • 嗯,我在我的一些着色器中成功地使用了这种方法。您是否在着色器中启用了GL_EXT_nonuniform_qualifier#version 460 #extension GL_EXT_nonuniform_qualifier : require 是我正在使用的。此外:您如何为采样器数组创建描述符集?也许你可以发布代码?!

标签: glsl vulkan


【解决方案1】:

问题是由于使用了 Y'CBCR 采样器。 Vulkan 似乎不允许动态索引到此类制服的数组中。

Vulkan specs 是这样说的:

如果组合图像采样器启用采样器 Y'CBCR 转换或 对子采样图像进行采样,它必须仅由常量索引 在着色器代码中聚合成数组时的整数表达式, 与 shaderSampledImageArrayDynamicIndexing 功能无关。

所以,我的解决方案是提供两个单独绑定的采样器,并使用带有 if()..else 条件的动态索引来决定使用哪个采样器。推送常量也可以,但在这种情况下,我必须一直重新记录命令缓冲区。希望这些信息对在 Vulkan API 中使用视频格式的其他人有所帮助。

【讨论】:

    猜你喜欢
    • 2017-04-14
    • 2019-06-20
    • 2012-08-21
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    相关资源
    最近更新 更多