diff --git a/src/dawn/native/opengl/ShaderModuleGL.cpp b/src/dawn/native/opengl/ShaderModuleGL.cpp index e69424aa7c6..944d1a8d413 100644 --- a/src/dawn/native/opengl/ShaderModuleGL.cpp +++ b/src/dawn/native/opengl/ShaderModuleGL.cpp @@ -273,6 +273,7 @@ void GenerateTextureBuiltinFromUniformData( bool GenerateArrayLengthFromuniformData( const BindingInfoArray& moduleBindingInfo, const PipelineLayout* layout, + SingleShaderStage stage, tint::glsl::writer::ArrayLengthFromUniformOptions& options) { const PipelineLayout::BindingIndexInfo& indexInfo = layout->GetBindingIndexInfo(); @@ -282,6 +283,15 @@ bool GenerateArrayLengthFromuniformData( for (BindingIndex binding : bgl->GetBufferIndices()) { const BindingInfo& bindingInfo = bgl->GetBindingInfo(binding); + // Skip bindings that aren't visible to this stage. GenerateBindingRemapping does the + // same, so without this filter the unmapped pre-remap binding point falls through the + // remapper_data lookup in tint/lang/glsl/writer/raise/raise.cc and can collide with a + // *post*-remap binding point of a visible buffer, making arrayLength() load the wrong + // size index and defeating the Robustness clamp. + if (!(bindingInfo.visibility & StageBit(stage))) { + continue; + } + switch (std::get(bindingInfo.bindingLayout).type) { case wgpu::BufferBindingType::Storage: case kInternalStorageBufferBinding: @@ -409,7 +419,7 @@ ResultOrError ShaderModule::CompileShader( if (GetDevice()->IsToggleEnabled(Toggle::GLUseArrayLengthFromUniform)) { *needsSSBOLengthUniformBuffer = GenerateArrayLengthFromuniformData( - moduleBindingInfo, layout, req.tintOptions.array_length_from_uniform); + moduleBindingInfo, layout, stage, req.tintOptions.array_length_from_uniform); if (*needsSSBOLengthUniformBuffer) { req.tintOptions.use_array_length_from_uniform = true; req.tintOptions.array_length_from_uniform.ubo_binding = {