Vulkan GLSL非均匀纹理访问触发SampledImageArrayNonUniformIndexing报错如何解决
问题原因
这个错误是因为着色器声明了SampledImageArrayNonUniformIndexing SPIR-V能力,但Vulkan逻辑设备创建时没有开启对应硬件特性,且描述符集布局没有配置非均匀索引标志。
解决步骤
1. 确认物理设备支持对应特性
首先查询物理设备的描述符索引特性支持情况,你使用的AMD RADV RAVEN2核显默认支持该特性:
VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES }; // 链入特性查询结构 VkPhysicalDeviceFeatures2 features2 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, .pNext = &indexingFeatures }; vkGetPhysicalDeviceFeatures2(physicalDevice, &features2); // 确认非均匀采样图像数组索引能力可用 assert(indexingFeatures.sampledImageArrayNonUniformIndexing == VK_TRUE);
如果使用Vulkan 1.1及以下版本,需要先启用VK_EXT_descriptor_indexing设备扩展;Vulkan 1.2及以上版本该特性为核心特性,无需额外开启扩展。
2. 创建设备时启用对应特性
将查询到的特性结构链入设备创建信息的pNext链,显式开启非均匀索引能力:
// 复用第一步中已确认支持的indexingFeatures结构,确保需要的特性位为VK_TRUE indexingFeatures.sampledImageArrayNonUniformIndexing = VK_TRUE; VkDeviceCreateInfo deviceCreateInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pNext = &indexingFeatures, // 关键:链入描述符索引特性结构 // 其余参数按原有逻辑填写:队列创建信息、启用扩展列表等 }; vkCreateDevice(physicalDevice, &deviceCreateInfo, NULL, &device);
3. 配置描述符集布局的非均匀索引标志
存储采样纹理的描述符绑定,需要显式开启非均匀索引标志:
// 你的纹理数组描述符绑定配置 VkDescriptorSetLayoutBinding textureBinding = { .binding = 0, // 对应着色器中的绑定号 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorCount = 2, // 你只有两张采样图,填2即可 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .pImmutableSamplers = NULL }; // 给绑定添加非均匀索引标志 VkDescriptorBindingFlags bindingFlag = VK_DESCRIPTOR_BINDING_INDEXING_DESCRIPTOR_ARRAY_NON_UNIFORM_INDEX_BIT; VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, .bindingCount = 1, .pBindingFlags = &bindingFlag }; // 创建描述符集布局 VkDescriptorSetLayoutCreateInfo layoutInfo = { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .pNext = &bindingFlagsInfo, // 链入绑定标志配置 .bindingCount = 1, .pBindings = &textureBinding }; vkCreateDescriptorSetLayout(device, &layoutInfo, NULL, &textureSetLayout);
4. 确认着色器配置正确
确保计算着色器开头已启用对应扩展,你现有代码中的nonuniformEXT修饰符使用正确:
#version 460 #extension GL_EXT_nonuniform_qualifier : require // 必须开启该扩展 layout(set = 0, binding = 0) uniform sampler2D textures[]; // 采样代码保持不变即可 texture(textures[nonuniformEXT(sampler_id)], vec2(0.5));
额外注意
如果你使用的是分离的纹理和采样器(即VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE + VK_DESCRIPTOR_TYPE_SAMPLER),还需要额外开启samplerArrayNonUniformIndexing特性,以及给采样器的描述符绑定也加上非均匀索引标志。
内容的提问来源于stack exchange,提问作者Makogan
相关产品推荐
相关产品推荐

