动态索引到 sampler2D 的统一数组不起作用

Dynamic indexing into uniform array of sampler2D doesn't work

我需要索引到包含 2 个统一采样器 2D 的数组。每个 frame.That 的索引都是动态的,我有一个动态统一缓冲区,它为片段着色器提供该索引。我使用 Vulkan API 1.2。在设备功能列表中,我有:

shaderSampledImageArrayDynamicIndexing = 1

我不确定 100%,但看起来这个功能是 1 的核心。2.Nevertheless我确实在设备创建期间尝试启用它,如下所示:

       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)。不知道还有什么 missing.Validation layers say nothing.

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

更新:

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

正确

错误

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

Vulkan specs 是这样说的:

If the combined image sampler enables sampler Y′CBCR conversion or samples a subsampled image, it must be indexed only by constant integral expressions when aggregated into arrays in shader code, irrespective of the shaderSampledImageArrayDynamicIndexing feature.

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