(Naga) Add support for Descriptor Runtime Indexing when ingesting SPIR-V (#8256)

This commit is contained in:
Nils Hasenbanck 2025-09-25 14:25:04 +02:00 committed by GitHub
parent 05cc6dca82
commit 2f7ebf1401
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 110 additions and 0 deletions

View File

@ -198,6 +198,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
- For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136).
- **BREAKING**: Previously the WGSL storage-texture format `rg11b10float` was incorrectly accepted and generated by naga, but now only accepts the the correct name `rg11b10ufloat` instead. By @ErikWDev in [#8219](https://github.com/gfx-rs/wgpu/pull/8219).
- The [`source()`](https://doc.rust-lang.org/std/error/trait.Error.html#method.source) method of `ShaderError` no longer reports the error as its own source. By @andyleiserson in [#8258](https://github.com/gfx-rs/wgpu/pull/8258).
- naga correctly ingests SPIR-V that use descriptor runtime indexing, which in turn is correctly converted into WGSLs binding array. By @hasenbanck in [8256](https://github.com/gfx-rs/wgpu/pull/8256).
#### DX12

View File

@ -82,6 +82,7 @@ pub const SUPPORTED_CAPABILITIES: &[spirv::Capability] = &[
spirv::Capability::GroupNonUniformBallot,
spirv::Capability::GroupNonUniformShuffle,
spirv::Capability::GroupNonUniformShuffleRelative,
spirv::Capability::RuntimeDescriptorArray,
// tricky ones
spirv::Capability::UniformBufferArrayDynamicIndexing,
spirv::Capability::StorageBufferArrayDynamicIndexing,
@ -90,6 +91,7 @@ pub const SUPPORTED_EXTENSIONS: &[&str] = &[
"SPV_KHR_storage_buffer_storage_class",
"SPV_KHR_vulkan_memory_model",
"SPV_KHR_multiview",
"SPV_EXT_descriptor_indexing",
"SPV_EXT_shader_atomic_float_add",
"SPV_KHR_16bit_storage",
];

View File

@ -0,0 +1,19 @@
// Compiled with:
// slangc -target spirv -profile spirv_1_5 -o naga/tests/in/spv/binding-arrays.runtime.spv naga/tests/in/spv/binding-arrays.runtime.slang
// Disassembled with:
// spirv-dis naga/tests/in/spv/binding-arrays.runtime.spv -o naga/tests/in/spv/binding-arrays.runtime.spvasm
#language slang 2026
[[vk::binding(0, 0)]] var textures: Texture2D[];
[[vk::binding(1, 0)]] var linear_sampler: SamplerState;
struct VertexOutput {
var texture_coordinates: float2;
var texture_index: uint;
};
[[shader("pixel")]]
func main(input: VertexOutput) -> float4 {
return textures[input.texture_index].Sample(linear_sampler, input.texture_coordinates);
}

View File

@ -0,0 +1,60 @@
; SPIR-V
; Version: 1.5
; Generator: Khronos Slang Compiler; 0
; Bound: 33
; Schema: 0
OpCapability RuntimeDescriptorArray
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %textures %linear_sampler %entryPointParam_main %input_texture_coordinates %input_texture_index
OpExecutionMode %main OriginUpperLeft
OpSource Slang 1
OpName %input_texture_coordinates "input.texture_coordinates"
OpName %input_texture_index "input.texture_index"
OpName %textures "textures"
OpName %linear_sampler "linear_sampler"
OpName %sampledImage "sampledImage"
OpName %sampled "sampled"
OpName %entryPointParam_main "entryPointParam_main"
OpName %main "main"
OpDecorate %input_texture_coordinates Location 0
OpDecorate %input_texture_index Location 1
OpDecorate %input_texture_index Flat
OpDecorate %textures Binding 0
OpDecorate %textures DescriptorSet 0
OpDecorate %linear_sampler Binding 1
OpDecorate %linear_sampler DescriptorSet 0
OpDecorate %entryPointParam_main Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%uint = OpTypeInt 32 0
%_ptr_Input_uint = OpTypePointer Input %uint
%15 = OpTypeImage %float 2D 2 0 0 1 Unknown
%_runtimearr_15 = OpTypeRuntimeArray %15
%_ptr_UniformConstant__runtimearr_15 = OpTypePointer UniformConstant %_runtimearr_15
%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
%22 = OpTypeSampler
%_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
%26 = OpTypeSampledImage %15
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%input_texture_coordinates = OpVariable %_ptr_Input_v2float Input
%input_texture_index = OpVariable %_ptr_Input_uint Input
%textures = OpVariable %_ptr_UniformConstant__runtimearr_15 UniformConstant
%linear_sampler = OpVariable %_ptr_UniformConstant_22 UniformConstant
%entryPointParam_main = OpVariable %_ptr_Output_v4float Output
%main = OpFunction %void None %3
%4 = OpLabel
%7 = OpLoad %v2float %input_texture_coordinates
%11 = OpLoad %uint %input_texture_index
%19 = OpAccessChain %_ptr_UniformConstant_15 %textures %11
%21 = OpLoad %15 %19
%23 = OpLoad %22 %linear_sampler
%sampledImage = OpSampledImage %26 %21 %23
%sampled = OpImageSampleImplicitLod %v4float %sampledImage %7 None
OpStore %entryPointParam_main %sampled
OpReturn
OpFunctionEnd

View File

@ -0,0 +1,4 @@
god_mode = true
[spv-in]
adjust_coordinate_space = true

View File

@ -0,0 +1,24 @@
var<private> inputtexture_coordinates_1: vec2<f32>;
var<private> inputtexture_index_1: u32;
@group(0) @binding(0)
var textures: binding_array<texture_2d<f32>>;
@group(0) @binding(1)
var linear_sampler: sampler;
var<private> entryPointParam_main: vec4<f32>;
fn main_1() {
let _e5 = inputtexture_coordinates_1;
let _e6 = inputtexture_index_1;
let _e8 = textureSample(textures[_e6], linear_sampler, _e5);
entryPointParam_main = _e8;
return;
}
@fragment
fn main(@location(0) inputtexture_coordinates: vec2<f32>, @location(1) @interpolate(flat) inputtexture_index: u32) -> @location(0) vec4<f32> {
inputtexture_coordinates_1 = inputtexture_coordinates;
inputtexture_index_1 = inputtexture_index;
main_1();
let _e5 = entryPointParam_main;
return _e5;
}