[tint][glsl] Support binding_array in the writer. Also updates GenerateBindings to make the end2end tests produce valid WGSL. Bug: 411573957 Change-Id: Ifaeed4a508c5b7775f50ccdcdc129e71c63badc5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/248054 Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tint/lang/glsl/writer/helpers/generate_bindings.cc b/src/tint/lang/glsl/writer/helpers/generate_bindings.cc index 45db8db..1998384 100644 --- a/src/tint/lang/glsl/writer/helpers/generate_bindings.cc +++ b/src/tint/lang/glsl/writer/helpers/generate_bindings.cc
@@ -33,6 +33,7 @@ #include "src/tint/api/common/binding_point.h" #include "src/tint/lang/core/ir/module.h" #include "src/tint/lang/core/ir/var.h" +#include "src/tint/lang/core/type/binding_array.h" #include "src/tint/lang/core/type/external_texture.h" #include "src/tint/lang/core/type/pointer.h" #include "src/tint/lang/core/type/storage_texture.h" @@ -81,9 +82,17 @@ binding::BindingInfo info{get_binding(bp.value())}; switch (ptr_type->AddressSpace()) { - case core::AddressSpace::kHandle: + case core::AddressSpace::kHandle: { + // Handle binding_array<handle> before logic dependent on the base handle type. + const core::type::Type* handle_type = ptr_type->StoreType(); + uint32_t count = 1; + if (auto* ba = handle_type->As<core::type::BindingArray>()) { + handle_type = ba->ElemType(); + count = ba->Count()->As<core::type::ConstantArrayCount>()->value; + } + Switch( - ptr_type->StoreType(), // + handle_type, [&](const core::type::Sampler*) { bindings.sampler.emplace(*bp, info); }, [&](const core::type::StorageTexture*) { bindings.storage_texture.emplace(*bp, info); @@ -93,10 +102,13 @@ // Add all texture variables to the texture-builtin-from-uniform map. bindings.texture_builtins_from_uniform.ubo_contents.push_back( - {.offset = texture_builtin_offset, .count = 1, .binding = info}); - texture_builtin_offset++; + {.offset = texture_builtin_offset, + .count = count, + .binding = info}); + texture_builtin_offset += count; }); break; + } case core::AddressSpace::kStorage: bindings.storage.emplace(*bp, info); break;
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc index 87a387e..5c2c200 100644 --- a/src/tint/lang/glsl/writer/printer/printer.cc +++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -65,6 +65,7 @@ #include "src/tint/lang/core/ir/validator.h" #include "src/tint/lang/core/ir/var.h" #include "src/tint/lang/core/type/array.h" +#include "src/tint/lang/core/type/binding_array.h" #include "src/tint/lang/core/type/bool.h" #include "src/tint/lang/core/type/depth_multisampled_texture.h" #include "src/tint/lang/core/type/depth_texture.h" @@ -706,6 +707,9 @@ type, // [&](const core::type::Array* ary) { EmitArrayType(out, ary, name, name_printed); }, [&](const core::type::Atomic* a) { EmitType(out, a->Type(), name, name_printed); }, + [&](const core::type::BindingArray* ary) { + EmitBindingArrayType(out, ary, name, name_printed); + }, [&](const core::type::Bool*) { out << "bool"; }, [&](const core::type::I32*) { out << "int"; }, [&](const core::type::U32*) { out << "uint"; }, @@ -873,6 +877,24 @@ out << args.str(); } + void EmitBindingArrayType(StringStream& out, + const core::type::BindingArray* ary, + const std::string& name, + bool* name_printed) { + EmitType(out, ary->ElemType()); + + if (!name.empty()) { + out << " " << name; + if (name_printed) { + *name_printed = true; + } + } + + auto* constant_count = ary->Count()->As<core::type::ConstantArrayCount>(); + TINT_ASSERT(constant_count != nullptr); + out << "[" << constant_count->value << "]"; + } + void EmitTextureType(StringStream& out, const core::type::Texture* t) { TINT_ASSERT(!t->Is<core::type::ExternalTexture>());
diff --git a/src/tint/lang/glsl/writer/writer.cc b/src/tint/lang/glsl/writer/writer.cc index b5435d4..7d29961 100644 --- a/src/tint/lang/glsl/writer/writer.cc +++ b/src/tint/lang/glsl/writer/writer.cc
@@ -45,9 +45,6 @@ if (ty->Is<core::type::SubgroupMatrix>()) { return Failure("subgroup matrices are not supported by the GLSL backend"); } - if (ty->Is<core::type::BindingArray>()) { - return Failure("binding_array are not supported by the GLSL backend"); - } } // Make sure that every texture variable is in the texture_builtins_from_uniform binding list, @@ -69,33 +66,47 @@ return Failure("pixel_local address space is not supported by the GLSL backend"); } - // Check texture types that need metadata for texture_builtins_from_uniform. - if (ptr->StoreType()->Is<core::type::Texture>() && - !ptr->StoreType()->IsAnyOf<core::type::StorageTexture, core::type::ExternalTexture>()) { - bool found = false; - auto binding = options.bindings.texture.at(var->BindingPoint().value()); - for (auto& bp : options.bindings.texture_builtins_from_uniform.ubo_contents) { - if (bp.binding == binding) { - found = true; - break; + if (ptr->AddressSpace() == core::AddressSpace::kHandle) { + const core::type::Type* handle_type = ptr->StoreType(); + uint32_t count = 1; + if (auto* ba = handle_type->As<core::type::BindingArray>()) { + handle_type = ba->ElemType(); + count = ba->Count()->As<core::type::ConstantArrayCount>()->value; + } + + // Check texture types that need metadata for texture_builtins_from_uniform. + if (handle_type->Is<core::type::Texture>() && + !handle_type->IsAnyOf<core::type::StorageTexture, core::type::ExternalTexture>()) { + bool found = false; + auto binding = options.bindings.texture.at(var->BindingPoint().value()); + for (auto& bp : options.bindings.texture_builtins_from_uniform.ubo_contents) { + if (bp.binding == binding) { + if (bp.count < count) { + return Failure( + "binding_array of textures doesn't have enough data in " + "texture_builtins_from_uniform list"); + } + found = true; + break; + } + } + if (!found) { + return Failure("texture missing from texture_builtins_from_uniform list"); } } - if (!found) { - return Failure("texture missing from texture_builtins_from_uniform list"); - } - } - // Check texel formats for read-write storage textures when targeting ES. - if (options.version.IsES()) { - if (auto* st = ptr->StoreType()->As<core::type::StorageTexture>()) { - if (st->Access() == core::Access::kReadWrite) { - switch (st->TexelFormat()) { - case core::TexelFormat::kR32Float: - case core::TexelFormat::kR32Sint: - case core::TexelFormat::kR32Uint: - break; - default: - return Failure("unsupported read-write storage texture format"); + // Check texel formats for read-write storage textures when targeting ES. + if (options.version.IsES()) { + if (auto* st = handle_type->As<core::type::StorageTexture>()) { + if (st->Access() == core::Access::kReadWrite) { + switch (st->TexelFormat()) { + case core::TexelFormat::kR32Float: + case core::TexelFormat::kR32Sint: + case core::TexelFormat::kR32Uint: + break; + default: + return Failure("unsupported read-write storage texture format"); + } } } }
diff --git a/test/tint/binding_array/access_as_function_argument.wgsl.expected.glsl b/test/tint/binding_array/access_as_function_argument.wgsl.expected.glsl index 82220c4..949427e 100644 --- a/test/tint/binding_array/access_as_function_argument.wgsl.expected.glsl +++ b/test/tint/binding_array/access_as_function_argument.wgsl.expected.glsl
@@ -1,12 +1,31 @@ SKIP: FAILED -../../src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc:137 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Access +Error parsing GLSL shader: +ERROR: 0:14: 'variable indexing sampler array' : not supported for this version or the enabled extensions +ERROR: 0:14: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. -******************************************************************** -* The tint shader compiler has encountered an unexpected error. * -* * -* Please help us fix this issue by submitting a bug report at * -* crbug.com/tint with the source program that triggered the bug. * -******************************************************************** -tint executable returned error: signal: trace/BPT trap + +#version 310 es +precision highp float; +precision highp int; + +layout(binding = 0, std140) +uniform f_TintTextureUniformData_ubo { + uvec4 metadata[1]; +} v; +uniform highp sampler2D f_sampled_textures[4]; +void do_texture_load(uint t_indices[1]) { + uint v_1 = (0u + uint(t_indices[0u])); + uint v_2 = (v.metadata[(v_1 / 4u)][(v_1 % 4u)] - 1u); + uint v_3 = min(uint(0), v_2); + uvec2 v_4 = (uvec2(textureSize(f_sampled_textures[t_indices[0u]], int(v_3))) - uvec2(1u)); + ivec2 v_5 = ivec2(min(uvec2(ivec2(0)), v_4)); + vec4 texture_load = texelFetch(f_sampled_textures[t_indices[0u]], v_5, int(v_3)); +} +void main() { + do_texture_load(uint[1](uint(0))); +} + +tint executable returned error: exit status 1
diff --git a/test/tint/binding_array/access_constant.wgsl.expected.glsl b/test/tint/binding_array/access_constant.wgsl.expected.glsl index 82220c4..ca8abe2 100644 --- a/test/tint/binding_array/access_constant.wgsl.expected.glsl +++ b/test/tint/binding_array/access_constant.wgsl.expected.glsl
@@ -1,12 +1,17 @@ -SKIP: FAILED +#version 310 es +precision highp float; +precision highp int; -../../src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc:137 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Access - -******************************************************************** -* The tint shader compiler has encountered an unexpected error. * -* * -* Please help us fix this issue by submitting a bug report at * -* crbug.com/tint with the source program that triggered the bug. * -******************************************************************** - -tint executable returned error: signal: trace/BPT trap +layout(binding = 0, std140) +uniform f_TintTextureUniformData_ubo { + uvec4 metadata[1]; +} v; +uniform highp sampler2D f_sampled_textures[4]; +void main() { + uint v_1 = (0u + uint(0)); + uint v_2 = (v.metadata[(v_1 / 4u)][(v_1 % 4u)] - 1u); + uint v_3 = min(uint(0), v_2); + uvec2 v_4 = (uvec2(textureSize(f_sampled_textures[0], int(v_3))) - uvec2(1u)); + ivec2 v_5 = ivec2(min(uvec2(ivec2(0)), v_4)); + vec4 texture_load = texelFetch(f_sampled_textures[0], v_5, int(v_3)); +}
diff --git a/test/tint/binding_array/access_uniform.wgsl.expected.glsl b/test/tint/binding_array/access_uniform.wgsl.expected.glsl index 82220c4..15a2eb7 100644 --- a/test/tint/binding_array/access_uniform.wgsl.expected.glsl +++ b/test/tint/binding_array/access_uniform.wgsl.expected.glsl
@@ -1,12 +1,33 @@ SKIP: FAILED -../../src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc:137 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Access +Error parsing GLSL shader: +ERROR: 0:19: 'variable indexing sampler array' : not supported for this version or the enabled extensions +ERROR: 0:19: '' : compilation terminated +ERROR: 2 compilation errors. No code generated. -******************************************************************** -* The tint shader compiler has encountered an unexpected error. * -* * -* Please help us fix this issue by submitting a bug report at * -* crbug.com/tint with the source program that triggered the bug. * -******************************************************************** -tint executable returned error: signal: trace/BPT trap + +#version 310 es +precision highp float; +precision highp int; + +layout(binding = 0, std140) +uniform f_index_block_ubo { + uint inner; +} v; +layout(binding = 0, std140) +uniform f_TintTextureUniformData_ubo { + uvec4 metadata[1]; +} v_1; +uniform highp sampler2D f_sampled_textures[4]; +void main() { + uint v_2 = v.inner; + uint v_3 = (0u + uint(v_2)); + uint v_4 = (v_1.metadata[(v_3 / 4u)][(v_3 % 4u)] - 1u); + uint v_5 = min(uint(0), v_4); + uvec2 v_6 = (uvec2(textureSize(f_sampled_textures[v_2], int(v_5))) - uvec2(1u)); + ivec2 v_7 = ivec2(min(uvec2(ivec2(0)), v_6)); + vec4 texture_load = texelFetch(f_sampled_textures[v_2], v_7, int(v_5)); +} + +tint executable returned error: exit status 1
diff --git a/test/tint/binding_array/as_function_parameter.wgsl.expected.glsl b/test/tint/binding_array/as_function_parameter.wgsl.expected.glsl index 82220c4..c8e288b 100644 --- a/test/tint/binding_array/as_function_parameter.wgsl.expected.glsl +++ b/test/tint/binding_array/as_function_parameter.wgsl.expected.glsl
@@ -1,12 +1,20 @@ -SKIP: FAILED +#version 310 es +precision highp float; +precision highp int; -../../src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.cc:137 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Access - -******************************************************************** -* The tint shader compiler has encountered an unexpected error. * -* * -* Please help us fix this issue by submitting a bug report at * -* crbug.com/tint with the source program that triggered the bug. * -******************************************************************** - -tint executable returned error: signal: trace/BPT trap +layout(binding = 0, std140) +uniform f_TintTextureUniformData_ubo { + uvec4 metadata[1]; +} v; +uniform highp sampler2D f_sampled_textures[4]; +void do_texture_load() { + uint v_1 = (0u + uint(0)); + uint v_2 = (v.metadata[(v_1 / 4u)][(v_1 % 4u)] - 1u); + uint v_3 = min(uint(0), v_2); + uvec2 v_4 = (uvec2(textureSize(f_sampled_textures[0], int(v_3))) - uvec2(1u)); + ivec2 v_5 = ivec2(min(uvec2(ivec2(0)), v_4)); + vec4 texture_load = texelFetch(f_sampled_textures[0], v_5, int(v_3)); +} +void main() { + do_texture_load(); +}