diff --git a/BUILD.gn b/BUILD.gn index 2ca5d047e7..6e11daefba 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -431,10 +431,10 @@ source_set("libtint_core_src") { "src/validator/validator_impl.h", "src/validator/validator_test_helper.cc", "src/validator/validator_test_helper.h", + "src/writer/append_vector.cc", + "src/writer/append_vector.h", "src/writer/float_to_string.cc", "src/writer/float_to_string.h", - "src/writer/pack_coord_arrayidx.cc", - "src/writer/pack_coord_arrayidx.h", "src/writer/text.cc", "src/writer/text.h", "src/writer/text_generator.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1f23742c65..d9636d873c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -252,10 +252,10 @@ set(TINT_LIB_SRCS validator/validator_impl.h validator/validator_test_helper.cc validator/validator_test_helper.h + writer/append_vector.cc + writer/append_vector.h writer/float_to_string.cc writer/float_to_string.h - writer/pack_coord_arrayidx.cc - writer/pack_coord_arrayidx.h writer/text.cc writer/text.h writer/text_generator.cc diff --git a/src/ast/intrinsic.h b/src/ast/intrinsic.h index ddad395657..37edca5c6e 100644 --- a/src/ast/intrinsic.h +++ b/src/ast/intrinsic.h @@ -139,6 +139,8 @@ struct TextureSignature : public Signature { size_t offset = kNotUsed; /// `sampler` parameter index. size_t sampler = kNotUsed; + /// `sample_index` parameter index. + size_t sample_index = kNotUsed; /// `texture` parameter index. size_t texture = kNotUsed; }; diff --git a/src/ast/intrinsic_texture_helper_test.cc b/src/ast/intrinsic_texture_helper_test.cc index 9fce78f205..e492e0d99b 100644 --- a/src/ast/intrinsic_texture_helper_test.cc +++ b/src/ast/intrinsic_texture_helper_test.cc @@ -14,6 +14,11 @@ #include "src/ast/intrinsic_texture_helper_test.h" +#include "src/ast/builder.h" +#include "src/ast/type/depth_texture_type.h" +#include "src/ast/type/multisampled_texture_type.h" +#include "src/ast/type/sampled_texture_type.h" +#include "src/ast/type/storage_texture_type.h" #include "src/ast/type_constructor_expression.h" namespace tint { @@ -21,1096 +26,1957 @@ namespace ast { namespace intrinsic { namespace test { -TextureOverloadCase::TextureOverloadCase() = default; +using u32 = ast::Builder::u32; +using i32 = ast::Builder::i32; +using f32 = ast::Builder::f32; + +TextureOverloadCase::TextureOverloadCase( + ValidTextureOverload o, + const char* desc, + TextureKind tk, + type::SamplerKind sk, + type::TextureDimension dims, + TextureDataType datatype, + const char* f, + std::function a) + : overload(o), + description(desc), + texture_kind(tk), + sampler_kind(sk), + texture_dimension(dims), + texture_data_type(datatype), + function(f), + args(std::move(a)) {} +TextureOverloadCase::TextureOverloadCase( + ValidTextureOverload o, + const char* desc, + TextureKind tk, + type::TextureDimension dims, + TextureDataType datatype, + const char* f, + std::function a) + : overload(o), + description(desc), + texture_kind(tk), + texture_dimension(dims), + texture_data_type(datatype), + function(f), + args(std::move(a)) {} TextureOverloadCase::TextureOverloadCase( ValidTextureOverload o, const char* d, - TextureKind tk, - type::SamplerKind sk, - type::TextureDimension td, - TextureDataType tdt, + AccessControl access, + type::ImageFormat i, + type::TextureDimension dims, + TextureDataType datatype, const char* f, std::function a) : overload(o), description(d), - texture_kind(tk), - sampler_kind(sk), - texture_dimension(td), - texture_data_type(tdt), + texture_kind(TextureKind::kStorage), + access_control(access), + image_format(i), + texture_dimension(dims), + texture_data_type(datatype), function(f), args(std::move(a)) {} TextureOverloadCase::TextureOverloadCase(const TextureOverloadCase&) = default; TextureOverloadCase::~TextureOverloadCase() = default; +std::ostream& operator<<(std::ostream& out, const TextureKind& kind) { + switch (kind) { + case TextureKind::kRegular: + out << "regular"; + break; + case TextureKind::kDepth: + out << "depth"; + break; + case TextureKind::kMultisampled: + out << "multisampled"; + break; + case TextureKind::kStorage: + out << "storage"; + break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const TextureDataType& ty) { + switch (ty) { + case TextureDataType::kF32: + out << "f32"; + break; + case TextureDataType::kU32: + out << "u32"; + break; + case TextureDataType::kI32: + out << "i32"; + break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data) { + out << "TextureOverloadCase " << static_cast(data.overload) << "\n"; + out << data.description << "\n"; + out << "texture_kind: " << data.texture_kind << "\n"; + out << "sampler_kind: "; + if (data.texture_kind != TextureKind::kStorage) { + out << data.sampler_kind; + } else { + out << ""; + } + out << "\n"; + out << "access_control: " << data.access_control << "\n"; + out << "image_format: " << data.image_format << "\n"; + out << "texture_dimension: " << data.texture_dimension << "\n"; + out << "texture_data_type: " << data.texture_data_type << "\n"; + return out; +} + +ast::type::Type* TextureOverloadCase::resultVectorComponentType( + ast::Builder* b) const { + switch (texture_data_type) { + case ast::intrinsic::test::TextureDataType::kF32: + return b->ty.f32; + case ast::intrinsic::test::TextureDataType::kU32: + return b->ty.u32; + case ast::intrinsic::test::TextureDataType::kI32: + return b->ty.i32; + } + + assert(false /* unreachable */); + return nullptr; +} + +ast::Variable* TextureOverloadCase::buildTextureVariable( + ast::Builder* b) const { + auto* datatype = resultVectorComponentType(b); + + switch (texture_kind) { + case ast::intrinsic::test::TextureKind::kRegular: + return b->Var( + "texture", ast::StorageClass::kNone, + b->create(texture_dimension, datatype)); + + case ast::intrinsic::test::TextureKind::kDepth: + return b->Var("texture", ast::StorageClass::kNone, + b->create(texture_dimension)); + + case ast::intrinsic::test::TextureKind::kMultisampled: + return b->Var("texture", ast::StorageClass::kNone, + b->create(texture_dimension, + datatype)); + + case ast::intrinsic::test::TextureKind::kStorage: + return b->Var("texture", ast::StorageClass::kNone, + b->create( + texture_dimension, access_control, image_format)); + } + + assert(false /* unreachable */); + return nullptr; +} + +ast::Variable* TextureOverloadCase::buildSamplerVariable( + ast::Builder* b) const { + return b->Var("sampler", ast::StorageClass::kNone, + b->create(sampler_kind)); +} + std::vector TextureOverloadCase::ValidCases() { - return {{ - ValidTextureOverload::kSample1dF32, - "textureSample(t : texture_1d,\n" - " s : sampler,\n" - " coords : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k1d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - return b->ExprList("texture", // t - "sampler", // s - 1.0f); // coords - }, + return { + { + ValidTextureOverload::kSample1dF32, + "textureSample(t : texture_1d,\n" + " s : sampler,\n" + " coords : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k1d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + 1.0f); // coords }, - { - ValidTextureOverload::kSample1dArrayF32, - "textureSample(t : texture_1d_array,\n" - " s : sampler,\n" - " coords : f32,\n" - " array_index : u32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k1dArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - return b->ExprList("texture", // t - "sampler", // s - 1.0f, // coords - 2); // array_index - }, + }, + { + ValidTextureOverload::kSample1dArrayF32, + "textureSample(t : texture_1d_array,\n" + " s : sampler,\n" + " coords : f32,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k1dArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + 1.0f, // coords + 2); // array_index }, - { - ValidTextureOverload::kSample2dF32, - "textureSample(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f)); // coords - }, + }, + { + ValidTextureOverload::kSample2dF32, + "textureSample(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f)); // coords }, - { - ValidTextureOverload::kSample2dOffsetF32, - "textureSample(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - b->vec2(3, 4)); // offset - }, + }, + { + ValidTextureOverload::kSample2dOffsetF32, + "textureSample(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + b->vec2(3, 4)); // offset }, - { - ValidTextureOverload::kSample2dArrayF32, - "textureSample(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3); // array_index - }, + }, + { + ValidTextureOverload::kSample2dArrayF32, + "textureSample(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3); // array_index }, - { - ValidTextureOverload::kSample2dArrayOffsetF32, - "textureSample(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSample2dArrayOffsetF32, + "textureSample(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSample3dF32, - "textureSample(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f)); // coords - }, + }, + { + ValidTextureOverload::kSample3dF32, + "textureSample(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f)); // coords }, - { - ValidTextureOverload::kSample3dOffsetF32, - "textureSample(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3\n" - " offset : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - b->vec3(4, 5, 6)); // offset - }, + }, + { + ValidTextureOverload::kSample3dOffsetF32, + "textureSample(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3\n" + " offset : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + b->vec3(4, 5, 6)); // offset }, - { - ValidTextureOverload::kSampleCubeF32, - "textureSample(t : texture_cube,\n" - " s : sampler,\n" - " coords : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f)); // coords - }, + }, + { + ValidTextureOverload::kSampleCubeF32, + "textureSample(t : texture_cube,\n" + " s : sampler,\n" + " coords : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f)); // coords }, - { - ValidTextureOverload::kSampleCubeArrayF32, - "textureSample(t : texture_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4); // array_index - }, + }, + { + ValidTextureOverload::kSampleCubeArrayF32, + "textureSample(t : texture_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4); // array_index }, - { - ValidTextureOverload::kSampleDepth2dF32, - "textureSample(t : texture_depth_2d,\n" - " s : sampler,\n" - " coords : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f)); // coords - }, + }, + { + ValidTextureOverload::kSampleDepth2dF32, + "textureSample(t : texture_depth_2d,\n" + " s : sampler,\n" + " coords : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f)); // coords }, - { - ValidTextureOverload::kSampleDepth2dOffsetF32, - "textureSample(t : texture_depth_2d,\n" - " s : sampler,\n" - " coords : vec2\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - b->vec2(3, 4)); // offset - }, + }, + { + ValidTextureOverload::kSampleDepth2dOffsetF32, + "textureSample(t : texture_depth_2d,\n" + " s : sampler,\n" + " coords : vec2\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + b->vec2(3, 4)); // offset }, - { - ValidTextureOverload::kSampleDepth2dArrayF32, - "textureSample(t : texture_depth_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3); // array_index - }, + }, + { + ValidTextureOverload::kSampleDepth2dArrayF32, + "textureSample(t : texture_depth_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3); // array_index }, - { - ValidTextureOverload::kSampleDepth2dArrayOffsetF32, - "textureSample(t : texture_depth_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSampleDepth2dArrayOffsetF32, + "textureSample(t : texture_depth_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSampleDepthCubeF32, - "textureSample(t : texture_depth_cube,\n" - " s : sampler,\n" - " coords : vec3) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f)); // coords - }, + }, + { + ValidTextureOverload::kSampleDepthCubeF32, + "textureSample(t : texture_depth_cube,\n" + " s : sampler,\n" + " coords : vec3) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f)); // coords }, - { - ValidTextureOverload::kSampleDepthCubeArrayF32, - "textureSample(t : texture_depth_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSample", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4); // array_index - }, + }, + { + ValidTextureOverload::kSampleDepthCubeArrayF32, + "textureSample(t : texture_depth_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSample", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4); // array_index }, - { - ValidTextureOverload::kSampleBias2dF32, - "textureSampleBias(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " bias : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f); // bias - }, + }, + { + ValidTextureOverload::kSampleBias2dF32, + "textureSampleBias(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " bias : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f); // bias }, - { - ValidTextureOverload::kSampleBias2dOffsetF32, - "textureSampleBias(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " bias : f32,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f, // bias - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSampleBias2dOffsetF32, + "textureSampleBias(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " bias : f32,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f, // bias + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSampleBias2dArrayF32, - "textureSampleBias(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " bias : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 4, // array_index - 3.f); // bias - }, + }, + { + ValidTextureOverload::kSampleBias2dArrayF32, + "textureSampleBias(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " bias : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 4, // array_index + 3.f); // bias }, - { - ValidTextureOverload::kSampleBias2dArrayOffsetF32, - "textureSampleBias(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " bias : f32,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - 4.f, // bias - b->vec2(5, 6)); // offset - }, + }, + { + ValidTextureOverload::kSampleBias2dArrayOffsetF32, + "textureSampleBias(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " bias : f32,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + 4.f, // bias + b->vec2(5, 6)); // offset }, - { - ValidTextureOverload::kSampleBias3dF32, - "textureSampleBias(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " bias : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f); // bias - }, + }, + { + ValidTextureOverload::kSampleBias3dF32, + "textureSampleBias(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " bias : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f); // bias }, - { - ValidTextureOverload::kSampleBias3dOffsetF32, - "textureSampleBias(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " bias : f32,\n" - " offset : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f, // bias - b->vec3(5, 6, 7)); // offset - }, + }, + { + ValidTextureOverload::kSampleBias3dOffsetF32, + "textureSampleBias(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " bias : f32,\n" + " offset : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f, // bias + b->vec3(5, 6, 7)); // offset }, - { - ValidTextureOverload::kSampleBiasCubeF32, - "textureSampleBias(t : texture_cube,\n" - " s : sampler,\n" - " coords : vec3,\n" - " bias : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f); // bias - }, + }, + { + ValidTextureOverload::kSampleBiasCubeF32, + "textureSampleBias(t : texture_cube,\n" + " s : sampler,\n" + " coords : vec3,\n" + " bias : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f); // bias }, - { - ValidTextureOverload::kSampleBiasCubeArrayF32, - "textureSampleBias(t : texture_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32,\n" - " bias : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSampleBias", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 3, // array_index - 4.f); // bias - }, + }, + { + ValidTextureOverload::kSampleBiasCubeArrayF32, + "textureSampleBias(t : texture_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32,\n" + " bias : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSampleBias", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 3, // array_index + 4.f); // bias }, - { - ValidTextureOverload::kSampleLevel2dF32, - "textureSampleLevel(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " level : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f); // level - }, + }, + { + ValidTextureOverload::kSampleLevel2dF32, + "textureSampleLevel(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " level : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f); // level }, - { - ValidTextureOverload::kSampleLevel2dOffsetF32, - "textureSampleLevel(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " level : f32,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f, // level - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSampleLevel2dOffsetF32, + "textureSampleLevel(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " level : f32,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f, // level + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSampleLevel2dArrayF32, - "textureSampleLevel(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " level : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - 4.f); // level - }, + }, + { + ValidTextureOverload::kSampleLevel2dArrayF32, + "textureSampleLevel(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + 4.f); // level }, - { - ValidTextureOverload::kSampleLevel2dArrayOffsetF32, - "textureSampleLevel(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " level : f32,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - 4.f, // level - b->vec2(5, 6)); // offset - }, + }, + { + ValidTextureOverload::kSampleLevel2dArrayOffsetF32, + "textureSampleLevel(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : f32,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + 4.f, // level + b->vec2(5, 6)); // offset }, - { - ValidTextureOverload::kSampleLevel3dF32, - "textureSampleLevel(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " level : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f); // level - }, + }, + { + ValidTextureOverload::kSampleLevel3dF32, + "textureSampleLevel(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " level : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f); // level }, - { - ValidTextureOverload::kSampleLevel3dOffsetF32, - "textureSampleLevel(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " level : f32,\n" - " offset : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f, // level - b->vec3(5, 6, 7)); // offset - }, + }, + { + ValidTextureOverload::kSampleLevel3dOffsetF32, + "textureSampleLevel(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " level : f32,\n" + " offset : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f, // level + b->vec3(5, 6, 7)); // offset }, - { - ValidTextureOverload::kSampleLevelCubeF32, - "textureSampleLevel(t : texture_cube,\n" - " s : sampler,\n" - " coords : vec3,\n" - " level : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f); // level - }, + }, + { + ValidTextureOverload::kSampleLevelCubeF32, + "textureSampleLevel(t : texture_cube,\n" + " s : sampler,\n" + " coords : vec3,\n" + " level : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f); // level }, - { - ValidTextureOverload::kSampleLevelCubeArrayF32, - "textureSampleLevel(t : texture_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32,\n" - " level : f32) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4, // array_index - 5.f); // level - }, + }, + { + ValidTextureOverload::kSampleLevelCubeArrayF32, + "textureSampleLevel(t : texture_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32,\n" + " level : f32) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4, // array_index + 5.f); // level }, - { - ValidTextureOverload::kSampleLevelDepth2dF32, - "textureSampleLevel(t : texture_depth_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " level : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3); // level - }, + }, + { + ValidTextureOverload::kSampleLevelDepth2dF32, + "textureSampleLevel(t : texture_depth_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3); // level }, - { - ValidTextureOverload::kSampleLevelDepth2dOffsetF32, - "textureSampleLevel(t : texture_depth_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " level : u32,\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // level - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSampleLevelDepth2dOffsetF32, + "textureSampleLevel(t : texture_depth_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " level : i32,\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // level + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSampleLevelDepth2dArrayF32, - "textureSampleLevel(t : texture_depth_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " level : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - 4); // level - }, + }, + { + ValidTextureOverload::kSampleLevelDepth2dArrayF32, + "textureSampleLevel(t : texture_depth_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + 4); // level }, - { - ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32, - "textureSampleLevel(t : texture_depth_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " level : u32,\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - 4, // level - b->vec2(5, 6)); // offset - }, + }, + { + ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32, + "textureSampleLevel(t : texture_depth_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32,\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + 4, // level + b->vec2(5, 6)); // offset }, - { - ValidTextureOverload::kSampleLevelDepthCubeF32, - "textureSampleLevel(t : texture_depth_cube,\n" - " s : sampler,\n" - " coords : vec3,\n" - " level : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4); // level - }, + }, + { + ValidTextureOverload::kSampleLevelDepthCubeF32, + "textureSampleLevel(t : texture_depth_cube,\n" + " s : sampler,\n" + " coords : vec3,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4); // level }, - { - ValidTextureOverload::kSampleLevelDepthCubeArrayF32, - "textureSampleLevel(t : texture_depth_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32,\n" - " level : u32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSampleLevel", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4, // array_index - 5); // level - }, + }, + { + ValidTextureOverload::kSampleLevelDepthCubeArrayF32, + "textureSampleLevel(t : texture_depth_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSampleLevel", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4, // array_index + 5); // level }, - { - ValidTextureOverload::kSampleGrad2dF32, - "textureSampleGrad(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2\n" - " ddx : vec2,\n" - " ddy : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.0f, 2.0f), // coords - b->vec2(3.0f, 4.0f), // ddx - b->vec2(5.0f, 6.0f)); // ddy - }, + }, + { + ValidTextureOverload::kSampleGrad2dF32, + "textureSampleGrad(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2\n" + " ddx : vec2,\n" + " ddy : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.0f, 2.0f), // coords + b->vec2(3.0f, 4.0f), // ddx + b->vec2(5.0f, 6.0f)); // ddy }, - { - ValidTextureOverload::kSampleGrad2dOffsetF32, - "textureSampleGrad(t : texture_2d,\n" - " s : sampler,\n" - " coords : vec2,\n" - " ddx : vec2,\n" - " ddy : vec2,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - b->vec2(3.f, 4.f), // ddx - b->vec2(5.f, 6.f), // ddy - b->vec2(7, 8)); // offset - }, + }, + { + ValidTextureOverload::kSampleGrad2dOffsetF32, + "textureSampleGrad(t : texture_2d,\n" + " s : sampler,\n" + " coords : vec2,\n" + " ddx : vec2,\n" + " ddy : vec2,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + b->vec2(3.f, 4.f), // ddx + b->vec2(5.f, 6.f), // ddy + b->vec2(7, 8)); // offset }, - { - ValidTextureOverload::kSampleGrad2dArrayF32, - "textureSampleGrad(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " ddx : vec2,\n" - " ddy : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - b->vec2(4.f, 5.f), // ddx - b->vec2(6.f, 7.f)); // ddy - }, + }, + { + ValidTextureOverload::kSampleGrad2dArrayF32, + "textureSampleGrad(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " ddx : vec2,\n" + " ddy : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + b->vec2(4.f, 5.f), // ddx + b->vec2(6.f, 7.f)); // ddy }, - { - ValidTextureOverload::kSampleGrad2dArrayOffsetF32, - "textureSampleGrad(t : texture_2d_array,\n" - " s : sampler,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " ddx : vec2,\n" - " ddy : vec2,\n" - " offset : vec2) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3, // array_index - b->vec2(4.f, 5.f), // ddx - b->vec2(6.f, 7.f), // ddy - b->vec2(8, 9)); // offset - }, + }, + { + ValidTextureOverload::kSampleGrad2dArrayOffsetF32, + "textureSampleGrad(t : texture_2d_array,\n" + " s : sampler,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " ddx : vec2,\n" + " ddy : vec2,\n" + " offset : vec2) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3, // array_index + b->vec2(4.f, 5.f), // ddx + b->vec2(6.f, 7.f), // ddy + b->vec2(8, 9)); // offset }, - { - ValidTextureOverload::kSampleGrad3dF32, - "textureSampleGrad(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " ddx : vec3,\n" - " ddy : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - b->vec3(4.f, 5.f, 6.f), // ddx - b->vec3(7.f, 8.f, 9.f)); // ddy - }, + }, + { + ValidTextureOverload::kSampleGrad3dF32, + "textureSampleGrad(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " ddx : vec3,\n" + " ddy : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + b->vec3(4.f, 5.f, 6.f), // ddx + b->vec3(7.f, 8.f, 9.f)); // ddy }, - { - ValidTextureOverload::kSampleGrad3dOffsetF32, - "textureSampleGrad(t : texture_3d,\n" - " s : sampler,\n" - " coords : vec3,\n" - " ddx : vec3,\n" - " ddy : vec3,\n" - " offset : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::k3d, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - b->vec3(4.f, 5.f, 6.f), // ddx - b->vec3(7.f, 8.f, 9.f), // ddy - b->vec3(10, 11, 12)); // offset - }, + }, + { + ValidTextureOverload::kSampleGrad3dOffsetF32, + "textureSampleGrad(t : texture_3d,\n" + " s : sampler,\n" + " coords : vec3,\n" + " ddx : vec3,\n" + " ddy : vec3,\n" + " offset : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + b->vec3(4.f, 5.f, 6.f), // ddx + b->vec3(7.f, 8.f, 9.f), // ddy + b->vec3(10, 11, 12)); // offset }, - { - ValidTextureOverload::kSampleGradCubeF32, - "textureSampleGrad(t : texture_cube,\n" - " s : sampler,\n" - " coords : vec3,\n" - " ddx : vec3,\n" - " ddy : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - b->vec3(4.f, 5.f, 6.f), // ddx - b->vec3(7.f, 8.f, 9.f)); // ddy - }, + }, + { + ValidTextureOverload::kSampleGradCubeF32, + "textureSampleGrad(t : texture_cube,\n" + " s : sampler,\n" + " coords : vec3,\n" + " ddx : vec3,\n" + " ddy : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + b->vec3(4.f, 5.f, 6.f), // ddx + b->vec3(7.f, 8.f, 9.f)); // ddy }, - { - ValidTextureOverload::kSampleGradCubeArrayF32, - "textureSampleGrad(t : texture_cube_array,\n" - " s : sampler,\n" - " coords : vec3,\n" - " array_index : u32,\n" - " ddx : vec3,\n" - " ddy : vec3) -> vec4", - TextureKind::kRegular, - type::SamplerKind::kSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSampleGrad", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4, // array_index - b->vec3(5.f, 6.f, 7.f), // ddx - b->vec3(8.f, 9.f, 10.f)); // ddy - }, + }, + { + ValidTextureOverload::kSampleGradCubeArrayF32, + "textureSampleGrad(t : texture_cube_array,\n" + " s : sampler,\n" + " coords : vec3,\n" + " array_index : i32,\n" + " ddx : vec3,\n" + " ddy : vec3) -> vec4", + TextureKind::kRegular, + type::SamplerKind::kSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSampleGrad", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4, // array_index + b->vec3(5.f, 6.f, 7.f), // ddx + b->vec3(8.f, 9.f, 10.f)); // ddy }, - { - ValidTextureOverload::kSampleGradDepth2dF32, - "textureSampleCompare(t : texture_depth_2d,\n" - " s : sampler_comparison,\n" - " coords : vec2,\n" - " depth_ref : f32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f); // depth_ref - }, + }, + { + ValidTextureOverload::kSampleGradDepth2dF32, + "textureSampleCompare(t : texture_depth_2d,\n" + " s : sampler_comparison,\n" + " coords : vec2,\n" + " depth_ref : f32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f); // depth_ref }, - { - ValidTextureOverload::kSampleGradDepth2dOffsetF32, - "textureSampleCompare(t : texture_depth_2d,\n" - " s : sampler_comparison,\n" - " coords : vec2,\n" - " depth_ref : f32,\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::k2d, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 3.f, // depth_ref - b->vec2(4, 5)); // offset - }, + }, + { + ValidTextureOverload::kSampleGradDepth2dOffsetF32, + "textureSampleCompare(t : texture_depth_2d,\n" + " s : sampler_comparison,\n" + " coords : vec2,\n" + " depth_ref : f32,\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 3.f, // depth_ref + b->vec2(4, 5)); // offset }, - { - ValidTextureOverload::kSampleGradDepth2dArrayF32, - "textureSampleCompare(t : texture_depth_2d_array,\n" - " s : sampler_comparison,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " depth_ref : f32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 4, // array_index - 3.f); // depth_ref - }, + }, + { + ValidTextureOverload::kSampleGradDepth2dArrayF32, + "textureSampleCompare(t : texture_depth_2d_array,\n" + " s : sampler_comparison,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " depth_ref : f32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 4, // array_index + 3.f); // depth_ref }, - { - ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32, - "textureSampleCompare(t : texture_depth_2d_array,\n" - " s : sampler_comparison,\n" - " coords : vec2,\n" - " array_index : u32,\n" - " depth_ref : f32,\n" - " offset : vec2) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::k2dArray, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - using i32 = Builder::i32; - return b->ExprList("texture", // t - "sampler", // s - b->vec2(1.f, 2.f), // coords - 4, // array_index - 3.f, // depth_ref - b->vec2(5, 6)); // offset - }, + }, + { + ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32, + "textureSampleCompare(t : texture_depth_2d_array,\n" + " s : sampler_comparison,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " depth_ref : f32,\n" + " offset : vec2) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec2(1.f, 2.f), // coords + 4, // array_index + 3.f, // depth_ref + b->vec2(5, 6)); // offset }, - { - ValidTextureOverload::kSampleGradDepthCubeF32, - "textureSampleCompare(t : texture_depth_cube,\n" - " s : sampler_comparison,\n" - " coords : vec3,\n" - " depth_ref : f32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::kCube, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4.f); // depth_ref - }, + }, + { + ValidTextureOverload::kSampleGradDepthCubeF32, + "textureSampleCompare(t : texture_depth_cube,\n" + " s : sampler_comparison,\n" + " coords : vec3,\n" + " depth_ref : f32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::kCube, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4.f); // depth_ref }, - { - ValidTextureOverload::kSampleGradDepthCubeArrayF32, - "textureSampleCompare(t : texture_depth_cube_array,\n" - " s : sampler_comparison,\n" - " coords : vec3,\n" - " array_index : u32,\n" - " depth_ref : f32) -> f32", - TextureKind::kDepth, - type::SamplerKind::kComparisonSampler, - type::TextureDimension::kCubeArray, - TextureDataType::kF32, - "textureSampleCompare", - [](Builder* b) { - using f32 = Builder::f32; - return b->ExprList("texture", // t - "sampler", // s - b->vec3(1.f, 2.f, 3.f), // coords - 4, // array_index - 5.f); // depth_ref - }, - }}; + }, + { + ValidTextureOverload::kSampleGradDepthCubeArrayF32, + "textureSampleCompare(t : texture_depth_cube_array,\n" + " s : sampler_comparison,\n" + " coords : vec3,\n" + " array_index : i32,\n" + " depth_ref : f32) -> f32", + TextureKind::kDepth, + type::SamplerKind::kComparisonSampler, + type::TextureDimension::kCubeArray, + TextureDataType::kF32, + "textureSampleCompare", + [](Builder* b) { + return b->ExprList("texture", // t + "sampler", // s + b->vec3(1.f, 2.f, 3.f), // coords + 4, // array_index + 5.f); // depth_ref + }, + }, + { + ValidTextureOverload::kLoad1dF32, + "textureLoad(t : texture_1d,\n" + " coords : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1); // coords + }, + }, + { + ValidTextureOverload::kLoad1dU32, + "textureLoad(t : texture_1d,\n" + " coords : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1); // coords + }, + }, + { + ValidTextureOverload::kLoad1dI32, + "textureLoad(t : texture_1d,\n" + " coords : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1); // coords + }, + }, + { + ValidTextureOverload::kLoad1dArrayF32, + "textureLoad(t : texture_1d_array,\n" + " coords : i32,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + 2); // array_index + }, + }, + { + ValidTextureOverload::kLoad1dArrayU32, + "textureLoad(t : texture_1d_array,\n" + " coords : i32,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1dArray, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + 2); // array_index + }, + }, + { + ValidTextureOverload::kLoad1dArrayI32, + "textureLoad(t : texture_1d_array,\n" + " coords : i32,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k1dArray, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + 2); // array_index + }, + }, + { + ValidTextureOverload::kLoad2dF32, + "textureLoad(t : texture_2d,\n" + " coords : vec2) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // coords + }, + }, + { + ValidTextureOverload::kLoad2dU32, + "textureLoad(t : texture_2d,\n" + " coords : vec2) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // coords + }, + }, + { + ValidTextureOverload::kLoad2dI32, + "textureLoad(t : texture_2d,\n" + " coords : vec2) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // coords + }, + }, + { + ValidTextureOverload::kLoad2dLevelF32, + "textureLoad(t : texture_2d,\n" + " coords : vec2,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // level + }, + }, + { + ValidTextureOverload::kLoad2dLevelU32, + "textureLoad(t : texture_2d,\n" + " coords : vec2,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // level + }, + }, + { + ValidTextureOverload::kLoad2dLevelI32, + "textureLoad(t : texture_2d,\n" + " coords : vec2,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // level + }, + }, + { + ValidTextureOverload::kLoad2dArrayF32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // array_index + }, + }, + { + ValidTextureOverload::kLoad2dArrayU32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // array_index + }, + }, + { + ValidTextureOverload::kLoad2dArrayI32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // array_index + }, + }, + { + ValidTextureOverload::kLoad2dArrayLevelF32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // level + }, + }, + { + ValidTextureOverload::kLoad2dArrayLevelU32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // level + }, + }, + { + ValidTextureOverload::kLoad2dArrayLevelI32, + "textureLoad(t : texture_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k2dArray, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // level + }, + }, + { + ValidTextureOverload::kLoad3dF32, + "textureLoad(t : texture_3d,\n" + " coords : vec3) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3)); // coords + }, + }, + { + ValidTextureOverload::kLoad3dU32, + "textureLoad(t : texture_3d,\n" + " coords : vec3) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3)); // coords + }, + }, + { + ValidTextureOverload::kLoad3dI32, + "textureLoad(t : texture_3d,\n" + " coords : vec3) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3)); // coords + }, + }, + { + ValidTextureOverload::kLoad3dLevelF32, + "textureLoad(t : texture_3d,\n" + " coords : vec3,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3), // coords + 4); // level + }, + }, + { + ValidTextureOverload::kLoad3dLevelU32, + "textureLoad(t : texture_3d,\n" + " coords : vec3,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3), // coords + 4); // level + }, + }, + { + ValidTextureOverload::kLoad3dLevelI32, + "textureLoad(t : texture_3d,\n" + " coords : vec3,\n" + " level : i32) -> vec4", + TextureKind::kRegular, + type::TextureDimension::k3d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3), // coords + 4); // level + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dF32, + "textureLoad(t : texture_multisampled_2d,\n" + " coords : vec2,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // sample_index + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dU32, + "textureLoad(t : texture_multisampled_2d,\n" + " coords : vec2,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // sample_index + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dI32, + "textureLoad(t : texture_multisampled_2d,\n" + " coords : vec2,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // sample_index + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dArrayF32, + "textureLoad(t : texture_multisampled_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // sample_index + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dArrayU32, + "textureLoad(t : texture_multisampled_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2dArray, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // sample_index + }, + }, + { + ValidTextureOverload::kLoadMultisampled2dArrayI32, + "textureLoad(t : texture_multisampled_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " sample_index : i32) -> vec4", + TextureKind::kMultisampled, + type::TextureDimension::k2dArray, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // sample_index + }, + }, + { + ValidTextureOverload::kLoadDepth2dF32, + "textureLoad(t : texture_depth_2d,\n" + " coords : vec2) -> f32", + TextureKind::kDepth, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // coords + }, + }, + { + ValidTextureOverload::kLoadDepth2dLevelF32, + "textureLoad(t : texture_depth_2d,\n" + " coords : vec2,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // level + }, + }, + { + ValidTextureOverload::kLoadDepth2dArrayF32, + "textureLoad(t : texture_depth_2d_array,\n" + " coords : vec2,\n" + " array_index : i32) -> f32", + TextureKind::kDepth, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // array_index + }, + }, + { + ValidTextureOverload::kLoadDepth2dArrayLevelF32, + "textureLoad(t : texture_depth_2d_array,\n" + " coords : vec2,\n" + " array_index : i32,\n" + " level : i32) -> f32", + TextureKind::kDepth, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3, // array_index + 4); // level + }, + }, + { + ValidTextureOverload::kLoadStorageRO1dRgba32float, + "textureLoad(t : texture_storage_ro_1d,\n" + " coords : i32) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k1d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1); // coords + }, + }, + { + ValidTextureOverload::kLoadStorageRO1dArrayRgba32float, + "textureLoad(t : " + "texture_storage_ro_1d_array,\n" + " coords : i32,\n" + " array_index : i32) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k1dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + 1, // coords + 2); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba8unorm, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba8Unorm, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba8snorm, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba8Snorm, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba8uint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba8Uint, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba8sint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba8Sint, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba16uint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba16Uint, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba16sint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba16Sint, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba16float, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba16Float, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dR32uint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kR32Uint, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dR32sint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kR32Sint, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dR32float, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kR32Float, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRg32uint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRg32Uint, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRg32sint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRg32Sint, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRg32float, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRg32Float, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba32uint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Uint, + type::TextureDimension::k2d, + TextureDataType::kU32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba32sint, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Sint, + type::TextureDimension::k2d, + TextureDataType::kI32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dRgba32float, + "textureLoad(t : texture_storage_ro_2d,\n" + " coords : vec2) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k2d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2)); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO2dArrayRgba32float, + "textureLoad(t : " + "texture_storage_ro_2d_array,\n" + " coords : vec2,\n" + " array_index : i32) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k2dArray, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec2(1, 2), // coords + 3); // array_index + }, + }, + { + ValidTextureOverload::kLoadStorageRO3dRgba32float, + "textureLoad(t : texture_storage_ro_3d,\n" + " coords : vec3) -> vec4", + ast::AccessControl::kReadOnly, + ast::type::ImageFormat::kRgba32Float, + type::TextureDimension::k3d, + TextureDataType::kF32, + "textureLoad", + [](Builder* b) { + return b->ExprList("texture", // t + b->vec3(1, 2, 3)); // coords + }, + }, + }; } } // namespace test diff --git a/src/ast/intrinsic_texture_helper_test.h b/src/ast/intrinsic_texture_helper_test.h index 88bac80720..cb42568ab9 100644 --- a/src/ast/intrinsic_texture_helper_test.h +++ b/src/ast/intrinsic_texture_helper_test.h @@ -20,6 +20,7 @@ #include "src/ast/builder.h" #include "src/ast/type/sampler_type.h" +#include "src/ast/type/storage_texture_type.h" #include "src/ast/type/texture_type.h" namespace tint { @@ -27,37 +28,13 @@ namespace ast { namespace intrinsic { namespace test { -enum class TextureKind { kRegular, kDepth }; - -inline std::ostream& operator<<(std::ostream& out, const TextureKind& kind) { - switch (kind) { - case TextureKind::kRegular: - out << "regular"; - break; - case TextureKind::kDepth: - out << "depth"; - break; - } - return out; -} - +enum class TextureKind { kRegular, kDepth, kMultisampled, kStorage }; enum class TextureDataType { kF32, kU32, kI32 }; -inline std::ostream& operator<<(std::ostream& out, const TextureDataType& ty) { - switch (ty) { - case TextureDataType::kF32: - out << "f32"; - break; - case TextureDataType::kU32: - out << "u32"; - break; - case TextureDataType::kI32: - out << "i32"; - break; - } - return out; -} +std::ostream& operator<<(std::ostream& out, const TextureKind& kind); +std::ostream& operator<<(std::ostream& out, const TextureDataType& ty); +/// Non-exhaustive list of valid texture overloads enum class ValidTextureOverload { kSample1dF32, kSample1dArrayF32, @@ -111,13 +88,65 @@ enum class ValidTextureOverload { kSampleGradDepth2dArrayOffsetF32, kSampleGradDepthCubeF32, kSampleGradDepthCubeArrayF32, + kLoad1dF32, + kLoad1dU32, + kLoad1dI32, + kLoad1dArrayF32, + kLoad1dArrayU32, + kLoad1dArrayI32, + kLoad2dF32, + kLoad2dU32, + kLoad2dI32, + kLoad2dLevelF32, + kLoad2dLevelU32, + kLoad2dLevelI32, + kLoad2dArrayF32, + kLoad2dArrayU32, + kLoad2dArrayI32, + kLoad2dArrayLevelF32, + kLoad2dArrayLevelU32, + kLoad2dArrayLevelI32, + kLoad3dF32, + kLoad3dU32, + kLoad3dI32, + kLoad3dLevelF32, + kLoad3dLevelU32, + kLoad3dLevelI32, + kLoadMultisampled2dF32, + kLoadMultisampled2dU32, + kLoadMultisampled2dI32, + kLoadMultisampled2dArrayF32, + kLoadMultisampled2dArrayU32, + kLoadMultisampled2dArrayI32, + kLoadDepth2dF32, + kLoadDepth2dLevelF32, + kLoadDepth2dArrayF32, + kLoadDepth2dArrayLevelF32, + kLoadStorageRO1dRgba32float, // Not permutated for all texel formats + kLoadStorageRO1dArrayRgba32float, // Not permutated for all texel formats + kLoadStorageRO2dRgba8unorm, + kLoadStorageRO2dRgba8snorm, + kLoadStorageRO2dRgba8uint, + kLoadStorageRO2dRgba8sint, + kLoadStorageRO2dRgba16uint, + kLoadStorageRO2dRgba16sint, + kLoadStorageRO2dRgba16float, + kLoadStorageRO2dR32uint, + kLoadStorageRO2dR32sint, + kLoadStorageRO2dR32float, + kLoadStorageRO2dRg32uint, + kLoadStorageRO2dRg32sint, + kLoadStorageRO2dRg32float, + kLoadStorageRO2dRgba32uint, + kLoadStorageRO2dRgba32sint, + kLoadStorageRO2dRgba32float, + kLoadStorageRO2dArrayRgba32float, // Not permutated for all texel formats + kLoadStorageRO3dRgba32float, // Not permutated for all texel formats }; /// Describes a texture intrinsic overload struct TextureOverloadCase { - /// Constructor - TextureOverloadCase(); - /// Constructor + /// Constructor for textureSample...() functions TextureOverloadCase(ValidTextureOverload, const char*, TextureKind, @@ -126,42 +155,68 @@ struct TextureOverloadCase { TextureDataType, const char*, std::function); + /// Constructor for textureLoad() functions with non-storage textures + TextureOverloadCase(ValidTextureOverload, + const char*, + TextureKind, + type::TextureDimension, + TextureDataType, + const char*, + std::function); + /// Constructor for textureLoad() with storage textures + TextureOverloadCase(ValidTextureOverload, + const char*, + AccessControl, + type::ImageFormat, + type::TextureDimension, + TextureDataType, + const char*, + std::function); /// Copy constructor TextureOverloadCase(const TextureOverloadCase&); /// Destructor ~TextureOverloadCase(); - /// @return a vector containing a large number of valid texture overloads + /// @return a vector containing a large number (non-exhaustive) of valid + /// texture overloads. static std::vector ValidCases(); + /// @param builder the AST builder used for the test + /// @returns the vector component type of the texture function return value + ast::type::Type* resultVectorComponentType(ast::Builder* builder) const; + /// @param builder the AST builder used for the test + /// @returns a Variable holding the test texture + ast::Variable* buildTextureVariable(ast::Builder* builder) const; + /// @param builder the AST builder used for the test + /// @returns a Variable holding the test sampler + ast::Variable* buildSamplerVariable(ast::Builder* builder) const; + /// The enumerator for this overload - ValidTextureOverload overload; + ValidTextureOverload const overload; /// A human readable description of the overload - const char* description; + const char* const description; /// The texture kind for the texture parameter - TextureKind texture_kind; + TextureKind const texture_kind; /// The sampler kind for the sampler parameter - type::SamplerKind sampler_kind; + /// Used only when texture_kind is not kStorage + type::SamplerKind const sampler_kind = type::SamplerKind::kSampler; + /// The access control for the storage texture + /// Used only when texture_kind is kStorage + AccessControl const access_control = AccessControl::kReadWrite; + /// The image format for the storage texture + /// Used only when texture_kind is kStorage + type::ImageFormat const image_format = type::ImageFormat::kNone; /// The dimensions of the texture parameter - type::TextureDimension texture_dimension; + type::TextureDimension const texture_dimension; /// The data type of the texture parameter - TextureDataType texture_data_type; + TextureDataType const texture_data_type; /// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc - const char* function; + const char* const function; /// A function that builds the AST arguments for the overload - std::function args; + std::function const args; }; -inline std::ostream& operator<<(std::ostream& out, - const TextureOverloadCase& data) { - out << "TextureOverloadCase" << static_cast(data.overload) << "\n"; - out << data.description << "\n"; - out << "texture_kind: " << data.texture_kind << "\n"; - out << "sampler_kind: " << data.sampler_kind << "\n"; - out << "texture_dimension: " << data.texture_dimension << "\n"; - out << "texture_data_type: " << data.texture_data_type << "\n"; - return out; -} +std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data); } // namespace test } // namespace intrinsic diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc index 61d35ec33d..607dc39cfa 100644 --- a/src/reader/spirv/function.cc +++ b/src/reader/spirv/function.cc @@ -408,7 +408,7 @@ std::string GetGlslStd450FuncName(uint32_t ext_opcode) { return "trunc"; default: - // TODO(dneto). The following are not implemented. + // TODO(dneto) - The following are not implemented. // They are grouped semantically, as in GLSL.std.450.h. case GLSLstd450RoundEven: case GLSLstd450SAbs: diff --git a/src/reader/spirv/parser_impl.h b/src/reader/spirv/parser_impl.h index f5b9689ca7..4d3b22a497 100644 --- a/src/reader/spirv/parser_impl.h +++ b/src/reader/spirv/parser_impl.h @@ -235,10 +235,10 @@ class ParserImpl : Reader { /// @returns true if parser is still successful. bool RegisterExtendedInstructionImports(); - // Returns true when the given instruction is an extended instruction - // for GLSL.std.450. - // @param inst a SPIR-V instruction - // @returns true if its an SpvOpExtInst for GLSL.std.450 + /// Returns true when the given instruction is an extended instruction + /// for GLSL.std.450. + /// @param inst a SPIR-V instruction + /// @returns true if its an SpvOpExtInst for GLSL.std.450 bool IsGlslExtendedInstruction(const spvtools::opt::Instruction& inst) const; /// Registers user names for SPIR-V objects, from OpName, and OpMemberName. diff --git a/src/transform/first_index_offset.h b/src/transform/first_index_offset.h index ae28629d9e..163bfbb090 100644 --- a/src/transform/first_index_offset.h +++ b/src/transform/first_index_offset.h @@ -1,4 +1,4 @@ -// Copyright 2020 The Tint Authors. +// Copyright 2020 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/type_determiner.cc b/src/type_determiner.cc index ab4d34c1dc..b341777407 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -555,6 +555,7 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, ->As(); bool is_array = false; + bool is_multisampled = texture->Is(); switch (texture->dim()) { case ast::type::TextureDimension::k1dArray: case ast::type::TextureDimension::k2dArray: @@ -571,13 +572,13 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, if (is_array) { param.idx.array_index = param.count++; } - - // TODO(dsinclair): Remove the LOD param from textureLoad on storage - // textures when https://github.com/gpuweb/gpuweb/pull/1032 gets merged. if (expr->params().size() > param.count) { - param.idx.level = param.count++; + if (is_multisampled) { + param.idx.sample_index = param.count++; + } else { + param.idx.level = param.count++; + } } - break; case ast::Intrinsic::kTextureSample: param.idx.texture = param.count++; @@ -659,21 +660,21 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident, if (texture->Is()) { expr->func()->set_result_type(mod_->create()); - return true; - } - - ast::type::Type* type = nullptr; - if (auto* storage = texture->As()) { - type = storage->type(); - } else if (auto* sampled = texture->As()) { - type = sampled->type(); - } else if (auto* msampled = texture->As()) { - type = msampled->type(); } else { - set_error(expr->source(), "unknown texture type for texture sampling"); - return false; + ast::type::Type* type = nullptr; + if (auto* storage = texture->As()) { + type = storage->type(); + } else if (auto* sampled = texture->As()) { + type = sampled->type(); + } else if (auto* msampled = + texture->As()) { + type = msampled->type(); + } else { + set_error(expr->source(), "unknown texture type for texture sampling"); + return false; + } + expr->func()->set_result_type(mod_->create(type, 4)); } - expr->func()->set_result_type(mod_->create(type, 4)); return true; } if (ident->intrinsic() == ast::Intrinsic::kDot) { diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index 0b217a44a1..678141e2b9 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -54,6 +54,7 @@ #include "src/ast/type/f32_type.h" #include "src/ast/type/i32_type.h" #include "src/ast/type/matrix_type.h" +#include "src/ast/type/multisampled_texture_type.h" #include "src/ast/type/pointer_type.h" #include "src/ast/type/sampled_texture_type.h" #include "src/ast/type/sampler_type.h" @@ -4510,6 +4511,7 @@ std::string to_str(const std::string& function, maybe_add_param(sig->params.idx.level, "level"); maybe_add_param(sig->params.idx.offset, "offset"); maybe_add_param(sig->params.idx.sampler, "sampler"); + maybe_add_param(sig->params.idx.sample_index, "sample_index"); maybe_add_param(sig->params.idx.texture, "texture"); std::sort( params.begin(), params.end(), @@ -4534,126 +4536,202 @@ const char* expected_texture_overload( using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload; switch (overload) { case ValidTextureOverload::kSample1dF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSample1dArrayF32: - return "textureSample(texture, sampler, coords, array_index)"; + return R"(textureSample(texture, sampler, coords, array_index))"; case ValidTextureOverload::kSample2dF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSample2dOffsetF32: - return "textureSample(texture, sampler, coords, offset)"; + return R"(textureSample(texture, sampler, coords, offset))"; case ValidTextureOverload::kSample2dArrayF32: - return "textureSample(texture, sampler, coords, array_index)"; + return R"(textureSample(texture, sampler, coords, array_index))"; case ValidTextureOverload::kSample2dArrayOffsetF32: - return "textureSample(texture, sampler, coords, array_index, offset)"; + return R"(textureSample(texture, sampler, coords, array_index, offset))"; case ValidTextureOverload::kSample3dF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSample3dOffsetF32: - return "textureSample(texture, sampler, coords, offset)"; + return R"(textureSample(texture, sampler, coords, offset))"; case ValidTextureOverload::kSampleCubeF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSampleCubeArrayF32: - return "textureSample(texture, sampler, coords, array_index)"; + return R"(textureSample(texture, sampler, coords, array_index))"; case ValidTextureOverload::kSampleDepth2dF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSampleDepth2dOffsetF32: - return "textureSample(texture, sampler, coords, offset)"; + return R"(textureSample(texture, sampler, coords, offset))"; case ValidTextureOverload::kSampleDepth2dArrayF32: - return "textureSample(texture, sampler, coords, array_index)"; + return R"(textureSample(texture, sampler, coords, array_index))"; case ValidTextureOverload::kSampleDepth2dArrayOffsetF32: - return "textureSample(texture, sampler, coords, array_index, offset)"; + return R"(textureSample(texture, sampler, coords, array_index, offset))"; case ValidTextureOverload::kSampleDepthCubeF32: - return "textureSample(texture, sampler, coords)"; + return R"(textureSample(texture, sampler, coords))"; case ValidTextureOverload::kSampleDepthCubeArrayF32: - return "textureSample(texture, sampler, coords, array_index)"; + return R"(textureSample(texture, sampler, coords, array_index))"; case ValidTextureOverload::kSampleBias2dF32: - return "textureSampleBias(texture, sampler, coords, bias)"; + return R"(textureSampleBias(texture, sampler, coords, bias))"; case ValidTextureOverload::kSampleBias2dOffsetF32: - return "textureSampleBias(texture, sampler, coords, bias, offset)"; + return R"(textureSampleBias(texture, sampler, coords, bias, offset))"; case ValidTextureOverload::kSampleBias2dArrayF32: - return "textureSampleBias(texture, sampler, coords, array_index, " - "bias)"; + return R"(textureSampleBias(texture, sampler, coords, array_index, bias))"; case ValidTextureOverload::kSampleBias2dArrayOffsetF32: - return "textureSampleBias(texture, sampler, coords, array_index, " - "bias, offset)"; + return R"(textureSampleBias(texture, sampler, coords, array_index, bias, offset))"; case ValidTextureOverload::kSampleBias3dF32: - return "textureSampleBias(texture, sampler, coords, bias)"; + return R"(textureSampleBias(texture, sampler, coords, bias))"; case ValidTextureOverload::kSampleBias3dOffsetF32: - return "textureSampleBias(texture, sampler, coords, bias, offset)"; + return R"(textureSampleBias(texture, sampler, coords, bias, offset))"; case ValidTextureOverload::kSampleBiasCubeF32: - return "textureSampleBias(texture, sampler, coords, bias)"; + return R"(textureSampleBias(texture, sampler, coords, bias))"; case ValidTextureOverload::kSampleBiasCubeArrayF32: - return "textureSampleBias(texture, sampler, coords, array_index, " - "bias)"; + return R"(textureSampleBias(texture, sampler, coords, array_index, bias))"; case ValidTextureOverload::kSampleLevel2dF32: - return "textureSampleLevel(texture, sampler, coords, level)"; + return R"(textureSampleLevel(texture, sampler, coords, level))"; case ValidTextureOverload::kSampleLevel2dOffsetF32: - return "textureSampleLevel(texture, sampler, coords, level, offset)"; + return R"(textureSampleLevel(texture, sampler, coords, level, offset))"; case ValidTextureOverload::kSampleLevel2dArrayF32: - return "textureSampleLevel(texture, sampler, coords, array_index, " - "level)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level))"; case ValidTextureOverload::kSampleLevel2dArrayOffsetF32: - return "textureSampleLevel(texture, sampler, coords, array_index, " - "level, offset)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))"; case ValidTextureOverload::kSampleLevel3dF32: - return "textureSampleLevel(texture, sampler, coords, level)"; + return R"(textureSampleLevel(texture, sampler, coords, level))"; case ValidTextureOverload::kSampleLevel3dOffsetF32: - return "textureSampleLevel(texture, sampler, coords, level, offset)"; + return R"(textureSampleLevel(texture, sampler, coords, level, offset))"; case ValidTextureOverload::kSampleLevelCubeF32: - return "textureSampleLevel(texture, sampler, coords, level)"; + return R"(textureSampleLevel(texture, sampler, coords, level))"; case ValidTextureOverload::kSampleLevelCubeArrayF32: - return "textureSampleLevel(texture, sampler, coords, array_index, " - "level)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level))"; case ValidTextureOverload::kSampleLevelDepth2dF32: - return "textureSampleLevel(texture, sampler, coords, level)"; + return R"(textureSampleLevel(texture, sampler, coords, level))"; case ValidTextureOverload::kSampleLevelDepth2dOffsetF32: - return "textureSampleLevel(texture, sampler, coords, level, offset)"; + return R"(textureSampleLevel(texture, sampler, coords, level, offset))"; case ValidTextureOverload::kSampleLevelDepth2dArrayF32: - return "textureSampleLevel(texture, sampler, coords, array_index, level)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level))"; case ValidTextureOverload::kSampleLevelDepth2dArrayOffsetF32: - return "textureSampleLevel(texture, sampler, coords, array_index, level, " - "offset)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level, offset))"; case ValidTextureOverload::kSampleLevelDepthCubeF32: - return "textureSampleLevel(texture, sampler, coords, level)"; + return R"(textureSampleLevel(texture, sampler, coords, level))"; case ValidTextureOverload::kSampleLevelDepthCubeArrayF32: - return "textureSampleLevel(texture, sampler, coords, array_index, " - "level)"; + return R"(textureSampleLevel(texture, sampler, coords, array_index, level))"; case ValidTextureOverload::kSampleGrad2dF32: - return "textureSampleGrad(texture, sampler, coords, ddx, ddy)"; + return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))"; case ValidTextureOverload::kSampleGrad2dOffsetF32: - return "textureSampleGrad(texture, sampler, coords, ddx, ddy, " - "offset)"; + return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))"; case ValidTextureOverload::kSampleGrad2dArrayF32: - return "textureSampleGrad(texture, sampler, coords, array_index, ddx, " - "ddy)"; + return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))"; case ValidTextureOverload::kSampleGrad2dArrayOffsetF32: - return "textureSampleGrad(texture, sampler, coords, array_index, ddx, " - "ddy, offset)"; + return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy, offset))"; case ValidTextureOverload::kSampleGrad3dF32: - return "textureSampleGrad(texture, sampler, coords, ddx, ddy)"; + return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))"; case ValidTextureOverload::kSampleGrad3dOffsetF32: - return "textureSampleGrad(texture, sampler, coords, ddx, ddy, " - "offset)"; + return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy, offset))"; case ValidTextureOverload::kSampleGradCubeF32: - return "textureSampleGrad(texture, sampler, coords, ddx, ddy)"; + return R"(textureSampleGrad(texture, sampler, coords, ddx, ddy))"; case ValidTextureOverload::kSampleGradCubeArrayF32: - return "textureSampleGrad(texture, sampler, coords, array_index, ddx, " - "ddy)"; + return R"(textureSampleGrad(texture, sampler, coords, array_index, ddx, ddy))"; case ValidTextureOverload::kSampleGradDepth2dF32: - return "textureSampleCompare(texture, sampler, coords, depth_ref)"; + return R"(textureSampleCompare(texture, sampler, coords, depth_ref))"; case ValidTextureOverload::kSampleGradDepth2dOffsetF32: - return "textureSampleCompare(texture, sampler, coords, depth_ref, " - "offset)"; + return R"(textureSampleCompare(texture, sampler, coords, depth_ref, offset))"; case ValidTextureOverload::kSampleGradDepth2dArrayF32: - return "textureSampleCompare(texture, sampler, coords, array_index, " - "depth_ref)"; + return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))"; case ValidTextureOverload::kSampleGradDepth2dArrayOffsetF32: - return "textureSampleCompare(texture, sampler, coords, array_index, " - "depth_ref, offset)"; + return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref, offset))"; case ValidTextureOverload::kSampleGradDepthCubeF32: - return "textureSampleCompare(texture, sampler, coords, depth_ref)"; + return R"(textureSampleCompare(texture, sampler, coords, depth_ref))"; case ValidTextureOverload::kSampleGradDepthCubeArrayF32: - return "textureSampleCompare(texture, sampler, coords, array_index, " - "depth_ref)"; + return R"(textureSampleCompare(texture, sampler, coords, array_index, depth_ref))"; + case ValidTextureOverload::kLoad1dF32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad1dU32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad1dI32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad1dArrayF32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad1dArrayU32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad1dArrayI32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad2dF32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad2dU32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad2dI32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad2dLevelF32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoad2dLevelU32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoad2dLevelI32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoad2dArrayF32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad2dArrayU32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad2dArrayI32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoad2dArrayLevelF32: + return R"(textureLoad(texture, coords, array_index, level))"; + case ValidTextureOverload::kLoad2dArrayLevelU32: + return R"(textureLoad(texture, coords, array_index, level))"; + case ValidTextureOverload::kLoad2dArrayLevelI32: + return R"(textureLoad(texture, coords, array_index, level))"; + case ValidTextureOverload::kLoad3dF32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad3dU32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad3dI32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoad3dLevelF32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoad3dLevelU32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoad3dLevelI32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoadMultisampled2dF32: + return R"(textureLoad(texture, coords, sample_index))"; + case ValidTextureOverload::kLoadMultisampled2dU32: + return R"(textureLoad(texture, coords, sample_index))"; + case ValidTextureOverload::kLoadMultisampled2dI32: + return R"(textureLoad(texture, coords, sample_index))"; + case ValidTextureOverload::kLoadMultisampled2dArrayF32: + return R"(textureLoad(texture, coords, array_index, sample_index))"; + case ValidTextureOverload::kLoadMultisampled2dArrayU32: + return R"(textureLoad(texture, coords, array_index, sample_index))"; + case ValidTextureOverload::kLoadMultisampled2dArrayI32: + return R"(textureLoad(texture, coords, array_index, sample_index))"; + case ValidTextureOverload::kLoadDepth2dF32: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoadDepth2dLevelF32: + return R"(textureLoad(texture, coords, level))"; + case ValidTextureOverload::kLoadDepth2dArrayF32: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoadDepth2dArrayLevelF32: + return R"(textureLoad(texture, coords, array_index, level))"; + case ValidTextureOverload::kLoadStorageRO1dRgba32float: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoadStorageRO2dRgba8unorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8snorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8uint: + case ValidTextureOverload::kLoadStorageRO2dRgba8sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16uint: + case ValidTextureOverload::kLoadStorageRO2dRgba16sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16float: + case ValidTextureOverload::kLoadStorageRO2dR32uint: + case ValidTextureOverload::kLoadStorageRO2dR32sint: + case ValidTextureOverload::kLoadStorageRO2dR32float: + case ValidTextureOverload::kLoadStorageRO2dRg32uint: + case ValidTextureOverload::kLoadStorageRO2dRg32sint: + case ValidTextureOverload::kLoadStorageRO2dRg32float: + case ValidTextureOverload::kLoadStorageRO2dRgba32uint: + case ValidTextureOverload::kLoadStorageRO2dRgba32sint: + case ValidTextureOverload::kLoadStorageRO2dRgba32float: + return R"(textureLoad(texture, coords))"; + case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float: + return R"(textureLoad(texture, coords, array_index))"; + case ValidTextureOverload::kLoadStorageRO3dRgba32float: + return R"(textureLoad(texture, coords))"; } return ""; } @@ -4661,56 +4739,37 @@ const char* expected_texture_overload( TEST_P(TypeDeterminerTextureIntrinsicTest, Call) { auto param = GetParam(); - ast::type::Type* datatype = nullptr; - switch (param.texture_data_type) { - case ast::intrinsic::test::TextureDataType::kF32: - datatype = ty.f32; - break; - case ast::intrinsic::test::TextureDataType::kU32: - datatype = ty.u32; - break; - case ast::intrinsic::test::TextureDataType::kI32: - datatype = ty.i32; - break; - } - - ast::type::Sampler sampler_type{param.sampler_kind}; - switch (param.texture_kind) { - case ast::intrinsic::test::TextureKind::kRegular: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension, - datatype)); - break; - - case ast::intrinsic::test::TextureKind::kDepth: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension)); - break; - } - - Var("sampler", ast::StorageClass::kNone, &sampler_type); + param.buildTextureVariable(this); + param.buildSamplerVariable(this); auto* ident = Expr(param.function); ast::CallExpression call{ident, param.args(this)}; - EXPECT_TRUE(td()->DetermineResultType(&call)) << td()->error(); + ASSERT_TRUE(td()->Determine()) << td()->error(); + ASSERT_TRUE(td()->DetermineResultType(&call)) << td()->error(); switch (param.texture_kind) { case ast::intrinsic::test::TextureKind::kRegular: + case ast::intrinsic::test::TextureKind::kMultisampled: + case ast::intrinsic::test::TextureKind::kStorage: { + auto* datatype = param.resultVectorComponentType(this); ASSERT_TRUE(call.result_type()->Is()); EXPECT_EQ(call.result_type()->As()->type(), datatype); break; - - case ast::intrinsic::test::TextureKind::kDepth: + } + case ast::intrinsic::test::TextureKind::kDepth: { EXPECT_EQ(call.result_type(), ty.f32); break; + } } auto* sig = static_cast( ident->intrinsic_signature()); + ASSERT_NE(sig, nullptr); + auto got = to_str(param.function, sig); auto* expected = expected_texture_overload(param.overload); - EXPECT_EQ(to_str(param.function, sig), expected); + EXPECT_EQ(got, expected); } } // namespace diff --git a/src/writer/pack_coord_arrayidx.cc b/src/writer/append_vector.cc similarity index 74% rename from src/writer/pack_coord_arrayidx.cc rename to src/writer/append_vector.cc index 44210993de..0436c6ff98 100644 --- a/src/writer/pack_coord_arrayidx.cc +++ b/src/writer/append_vector.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/writer/pack_coord_arrayidx.h" +#include "src/writer/append_vector.h" #include @@ -36,41 +36,46 @@ ast::TypeConstructorExpression* AsVectorConstructor(ast::Expression* expr) { } // namespace -bool PackCoordAndArrayIndex( - ast::Expression* coords, - ast::Expression* array_idx, +bool AppendVector( + ast::Expression* vector, + ast::Expression* scalar, std::function callback) { uint32_t packed_size; ast::type::Type* packed_el_ty; // Currently must be f32. - if (auto* vec = coords->result_type()->As()) { + if (auto* vec = vector->result_type()->As()) { packed_size = vec->size() + 1; packed_el_ty = vec->type(); } else { packed_size = 2; - packed_el_ty = coords->result_type(); + packed_el_ty = vector->result_type(); } if (!packed_el_ty) { return false; // missing type info } - // Cast array_idx to the vector element type - ast::TypeConstructorExpression array_index_cast(packed_el_ty, {array_idx}); - array_index_cast.set_result_type(packed_el_ty); + // Cast scalar to the vector element type + ast::TypeConstructorExpression scalar_cast(packed_el_ty, {scalar}); + scalar_cast.set_result_type(packed_el_ty); ast::type::Vector packed_ty(packed_el_ty, packed_size); // If the coordinates are already passed in a vector constructor, extract // the elements into the new vector instead of nesting a vector-in-vector. ast::ExpressionList packed; - if (auto* vc = AsVectorConstructor(coords)) { + if (auto* vc = AsVectorConstructor(vector)) { packed = vc->values(); } else { - packed.emplace_back(coords); + packed.emplace_back(vector); + } + if (packed_el_ty != scalar->result_type()) { + packed.emplace_back(&scalar_cast); + } else { + packed.emplace_back(scalar); } - packed.emplace_back(&array_index_cast); ast::TypeConstructorExpression constructor{&packed_ty, std::move(packed)}; + constructor.set_result_type(&packed_ty); return callback(&constructor); } diff --git a/src/writer/pack_coord_arrayidx.h b/src/writer/append_vector.h similarity index 60% rename from src/writer/pack_coord_arrayidx.h rename to src/writer/append_vector.h index 742ee0a862..d431336f19 100644 --- a/src/writer/pack_coord_arrayidx.h +++ b/src/writer/append_vector.h @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef SRC_WRITER_PACK_COORD_ARRAYIDX_H_ -#define SRC_WRITER_PACK_COORD_ARRAYIDX_H_ +#ifndef SRC_WRITER_APPEND_VECTOR_H_ +#define SRC_WRITER_APPEND_VECTOR_H_ #include @@ -28,25 +28,26 @@ class TypeConstructorExpression; namespace writer { -/// A helper function use to generate texture intrinsic function calls for -/// backends that expect the texture coordinate and array index to be packed -/// together into a single 'coordinate' parameter. -/// PackCoordAndArrayIndex() calls the `callback` function with a vector -/// expression containing the elements of `coords` followed by the single -/// element of `array_idx` cast to the `coords` element type. +/// A helper function used to append a vector with an additional scalar. +/// AppendVector is used to generate texture intrinsic function calls for +/// backends that expect the texture coordinates to be packed with an additional +/// mip-level or array-index parameter. +/// AppendVector() calls the `callback` function with a vector +/// expression containing the elements of `vector` followed by the single +/// element of `scalar` cast to the `vector` element type. /// All types must have been assigned to the expressions and their child nodes /// before calling. -/// @param coords the texture coordinates. May be a scalar, `vec2` or `vec3`. -/// @param array_idx the texture array index. Must be a scalar. +/// @param vector the vector to be appended. May be a scalar, `vec2` or `vec3`. +/// @param scalar the scalar to append to the vector. Must be a scalar. /// @param callback the function called with the packed result. Note that the /// pointer argument is only valid for the duration of the call. /// @returns the value returned by `callback` to indicate success -bool PackCoordAndArrayIndex( - ast::Expression* coords, - ast::Expression* array_idx, +bool AppendVector( + ast::Expression* vector, + ast::Expression* scalar, std::function callback); } // namespace writer } // namespace tint -#endif // SRC_WRITER_PACK_COORD_ARRAYIDX_H_ +#endif // SRC_WRITER_APPEND_VECTOR_H_ diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index 3bde2dad35..03d86cee5a 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -57,8 +57,8 @@ #include "src/ast/uint_literal.h" #include "src/ast/unary_op_expression.h" #include "src/ast/variable_decl_statement.h" +#include "src/writer/append_vector.h" #include "src/writer/float_to_string.h" -#include "src/writer/pack_coord_arrayidx.h" namespace tint { namespace writer { @@ -729,9 +729,14 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, auto& pidx = signature->params.idx; auto const kNotUsed = ast::intrinsic::TextureSignature::Parameters::kNotUsed; - if (!EmitExpression(pre, out, params[pidx.texture])) + auto* texture = params[pidx.texture]; + auto* texture_type = texture->result_type()->UnwrapPtrIfNeeded(); + + if (!EmitExpression(pre, out, texture)) return false; + bool pack_mip_in_coords = false; + switch (ident->intrinsic()) { case ast::Intrinsic::kTextureSample: out << ".Sample("; @@ -748,35 +753,61 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre, case ast::Intrinsic::kTextureSampleCompare: out << ".SampleCmp("; break; + case ast::Intrinsic::kTextureLoad: + out << ".Load("; + if (!texture_type->Is()) { + pack_mip_in_coords = true; + } + break; default: error_ = "Internal compiler error: Unhandled texture intrinsic '" + ident->name() + "'"; - break; + return false; } - if (!EmitExpression(pre, out, params[pidx.sampler])) - return false; + if (pidx.sampler != kNotUsed) { + if (!EmitExpression(pre, out, params[pidx.sampler])) + return false; + out << ", "; + } - out << ", "; + auto* param_coords = params[pidx.coords]; + + auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) { + auto* i32 = module_->create(); + ast::SintLiteral zero_lit(i32, 0); + ast::ScalarConstructorExpression zero(&zero_lit); + zero.set_result_type(i32); + return AppendVector(vector, &zero, + [&](ast::TypeConstructorExpression* packed) { + return EmitExpression(pre, out, packed); + }); + }; if (pidx.array_index != kNotUsed) { // Array index needs to be appended to the coordinates. - auto* param_coords = params[pidx.coords]; auto* param_array_index = params[pidx.array_index]; - if (!PackCoordAndArrayIndex(param_coords, param_array_index, - [&](ast::TypeConstructorExpression* packed) { - return EmitExpression(pre, out, packed); - })) { + if (!AppendVector(param_coords, param_array_index, + [&](ast::TypeConstructorExpression* packed) { + if (pack_mip_in_coords) { + return emit_vector_appended_with_i32_zero(packed); + } else { + return EmitExpression(pre, out, packed); + } + })) { return false; } - + } else if (pack_mip_in_coords) { + // Mip level needs to be appended to the coordinates, but is always zero. + if (!emit_vector_appended_with_i32_zero(param_coords)) + return false; } else { - if (!EmitExpression(pre, out, params[pidx.coords])) + if (!EmitExpression(pre, out, param_coords)) return false; } for (auto idx : {pidx.depth_ref, pidx.bias, pidx.level, pidx.ddx, pidx.ddy, - pidx.offset}) { + pidx.sample_index, pidx.offset}) { if (idx != kNotUsed) { out << ", "; if (!EmitExpression(pre, out, params[idx])) diff --git a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc index 47f702dc10..db1f2cd775 100644 --- a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc @@ -18,6 +18,7 @@ #include "src/ast/builder.h" #include "src/ast/intrinsic_texture_helper_test.h" #include "src/ast/type/depth_texture_type.h" +#include "src/ast/type/multisampled_texture_type.h" #include "src/ast/type/sampled_texture_type.h" #include "src/type_determiner.h" #include "src/writer/hlsl/generator_impl.h" @@ -135,9 +136,102 @@ std::string expected_texture_overload( return R"(texture_tint_0.SampleCmp(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4.0f))"; case ValidTextureOverload::kSampleGradDepthCubeArrayF32: return R"(texture_tint_0.SampleCmp(sampler_tint_0, float4(1.0f, 2.0f, 3.0f, float(4)), 5.0f))"; + case ValidTextureOverload::kLoad1dF32: + return R"(texture_tint_0.Load(int2(1, 0)))"; + case ValidTextureOverload::kLoad1dU32: + return R"(texture_tint_0.Load(int2(1, 0)))"; + case ValidTextureOverload::kLoad1dI32: + return R"(texture_tint_0.Load(int2(1, 0)))"; + case ValidTextureOverload::kLoad1dArrayF32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad1dArrayU32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad1dArrayI32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad2dF32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad2dU32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad2dI32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoad2dLevelF32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoad2dLevelU32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoad2dLevelI32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoad2dArrayF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad2dArrayU32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad2dArrayI32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad2dArrayLevelF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoad2dArrayLevelU32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoad2dArrayLevelI32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoad3dF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad3dU32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad3dI32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoad3dLevelF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoad3dLevelU32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoad3dLevelI32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoadMultisampled2dF32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoadMultisampled2dU32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoadMultisampled2dI32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoadMultisampled2dArrayF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoadMultisampled2dArrayU32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoadMultisampled2dArrayI32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoadDepth2dF32: + return R"(texture_tint_0.Load(int3(1, 2, 0)))"; + case ValidTextureOverload::kLoadDepth2dLevelF32: + return R"(texture_tint_0.Load(int3(1, 2, 0), 3))"; + case ValidTextureOverload::kLoadDepth2dArrayF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0)))"; + case ValidTextureOverload::kLoadDepth2dArrayLevelF32: + return R"(texture_tint_0.Load(int4(1, 2, 3, 0), 4))"; + case ValidTextureOverload::kLoadStorageRO1dRgba32float: + return R"(texture_tint_0.Load(1))"; + case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float: + return R"(texture_tint_0.Load(int2(1, 2)))"; + case ValidTextureOverload::kLoadStorageRO2dRgba8unorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8snorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8uint: + case ValidTextureOverload::kLoadStorageRO2dRgba8sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16uint: + case ValidTextureOverload::kLoadStorageRO2dRgba16sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16float: + case ValidTextureOverload::kLoadStorageRO2dR32uint: + case ValidTextureOverload::kLoadStorageRO2dR32sint: + case ValidTextureOverload::kLoadStorageRO2dR32float: + case ValidTextureOverload::kLoadStorageRO2dRg32uint: + case ValidTextureOverload::kLoadStorageRO2dRg32sint: + case ValidTextureOverload::kLoadStorageRO2dRg32float: + case ValidTextureOverload::kLoadStorageRO2dRgba32uint: + case ValidTextureOverload::kLoadStorageRO2dRgba32sint: + case ValidTextureOverload::kLoadStorageRO2dRgba32float: + return R"(texture_tint_0.Load(int2(1, 2)))"; + case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float: + return R"(texture_tint_0.Load(int3(1, 2, 3)))"; + case ValidTextureOverload::kLoadStorageRO3dRgba32float: + return R"(texture_tint_0.Load(int3(1, 2, 3)))"; } return ""; -} // LINT - Ignore the length of this function +} // NOLINT - Ignore the length of this function class HlslGeneratorIntrinsicTextureTest : public ast::BuilderWithModule, @@ -165,38 +259,13 @@ class HlslGeneratorIntrinsicTextureTest TEST_P(HlslGeneratorIntrinsicTextureTest, Call) { auto param = GetParam(); - ast::type::Type* datatype = nullptr; - switch (param.texture_data_type) { - case ast::intrinsic::test::TextureDataType::kF32: - datatype = ty.f32; - break; - case ast::intrinsic::test::TextureDataType::kU32: - datatype = ty.u32; - break; - case ast::intrinsic::test::TextureDataType::kI32: - datatype = ty.i32; - break; - } - - ast::type::Sampler sampler_type{param.sampler_kind}; - switch (param.texture_kind) { - case ast::intrinsic::test::TextureKind::kRegular: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension, - datatype)); - break; - - case ast::intrinsic::test::TextureKind::kDepth: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension)); - break; - } - - Var("sampler", ast::StorageClass::kNone, &sampler_type); + param.buildTextureVariable(this); + param.buildSamplerVariable(this); ast::CallExpression call{Expr(param.function), param.args(this)}; - EXPECT_TRUE(td.DetermineResultType(&call)) << td.error(); + ASSERT_TRUE(td.Determine()) << td.error(); + ASSERT_TRUE(td.DetermineResultType(&call)) << td.error(); ASSERT_TRUE(gen.EmitExpression(pre, out, &call)) << gen.error(); diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index 003401f65b..127a8a3116 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc @@ -663,6 +663,8 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { if (!EmitExpression(params[pidx.texture])) return false; + bool lod_param_is_named = true; + switch (ident->intrinsic()) { case ast::Intrinsic::kTextureSample: case ast::Intrinsic::kTextureSampleBias: @@ -673,37 +675,59 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { case ast::Intrinsic::kTextureSampleCompare: out_ << ".sample_compare("; break; + case ast::Intrinsic::kTextureLoad: + out_ << ".read("; + lod_param_is_named = false; + break; default: error_ = "Internal compiler error: Unhandled texture intrinsic '" + ident->name() + "'"; - break; + return false; } - if (!EmitExpression(params[pidx.sampler])) { - return false; - } - - for (auto idx : {pidx.coords, pidx.array_index, pidx.depth_ref}) { - if (idx != kNotUsed) { + bool first_arg = true; + auto maybe_write_comma = [&] { + if (!first_arg) { out_ << ", "; + } + first_arg = false; + }; + + if (pidx.sampler != kNotUsed) { + if (!EmitExpression(params[pidx.sampler])) { + return false; + } + first_arg = false; + } + + for (auto idx : + {pidx.coords, pidx.array_index, pidx.depth_ref, pidx.sample_index}) { + if (idx != kNotUsed) { + maybe_write_comma(); if (!EmitExpression(params[idx])) return false; } } if (pidx.bias != kNotUsed) { - out_ << ", bias("; + maybe_write_comma(); + out_ << "bias("; if (!EmitExpression(params[pidx.bias])) { return false; } out_ << ")"; } if (pidx.level != kNotUsed) { - out_ << ", level("; + maybe_write_comma(); + if (lod_param_is_named) { + out_ << "level("; + } if (!EmitExpression(params[pidx.level])) { return false; } - out_ << ")"; + if (lod_param_is_named) { + out_ << ")"; + } } if (pidx.ddx != kNotUsed) { auto dim = params[pidx.texture] @@ -714,14 +738,17 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { switch (dim) { case ast::type::TextureDimension::k2d: case ast::type::TextureDimension::k2dArray: - out_ << ", gradient2d("; + maybe_write_comma(); + out_ << "gradient2d("; break; case ast::type::TextureDimension::k3d: - out_ << ", gradient3d("; + maybe_write_comma(); + out_ << "gradient3d("; break; case ast::type::TextureDimension::kCube: case ast::type::TextureDimension::kCubeArray: - out_ << ", gradientcube("; + maybe_write_comma(); + out_ << "gradientcube("; break; default: { std::stringstream err; @@ -741,7 +768,7 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) { } if (pidx.offset != kNotUsed) { - out_ << ", "; + maybe_write_comma(); if (!EmitExpression(params[pidx.offset])) { return false; } diff --git a/src/writer/msl/generator_impl_intrinsic_texture_test.cc b/src/writer/msl/generator_impl_intrinsic_texture_test.cc index e3305ed216..ee27a3e6a3 100644 --- a/src/writer/msl/generator_impl_intrinsic_texture_test.cc +++ b/src/writer/msl/generator_impl_intrinsic_texture_test.cc @@ -18,6 +18,7 @@ #include "src/ast/builder.h" #include "src/ast/intrinsic_texture_helper_test.h" #include "src/ast/type/depth_texture_type.h" +#include "src/ast/type/multisampled_texture_type.h" #include "src/ast/type/sampled_texture_type.h" #include "src/type_determiner.h" #include "src/writer/msl/generator_impl.h" @@ -135,9 +136,102 @@ std::string expected_texture_overload( return R"(texture_tint_0.sample_compare(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4.0f))"; case ValidTextureOverload::kSampleGradDepthCubeArrayF32: return R"(texture_tint_0.sample_compare(sampler_tint_0, float3(1.0f, 2.0f, 3.0f), 4, 5.0f))"; + case ValidTextureOverload::kLoad1dF32: + return R"(texture_tint_0.read(1))"; + case ValidTextureOverload::kLoad1dU32: + return R"(texture_tint_0.read(1))"; + case ValidTextureOverload::kLoad1dI32: + return R"(texture_tint_0.read(1))"; + case ValidTextureOverload::kLoad1dArrayF32: + return R"(texture_tint_0.read(1, 2))"; + case ValidTextureOverload::kLoad1dArrayU32: + return R"(texture_tint_0.read(1, 2))"; + case ValidTextureOverload::kLoad1dArrayI32: + return R"(texture_tint_0.read(1, 2))"; + case ValidTextureOverload::kLoad2dF32: + return R"(texture_tint_0.read(int2(1, 2)))"; + case ValidTextureOverload::kLoad2dU32: + return R"(texture_tint_0.read(int2(1, 2)))"; + case ValidTextureOverload::kLoad2dI32: + return R"(texture_tint_0.read(int2(1, 2)))"; + case ValidTextureOverload::kLoad2dLevelF32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dLevelU32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dLevelI32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dArrayF32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dArrayU32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dArrayI32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoad2dArrayLevelF32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoad2dArrayLevelU32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoad2dArrayLevelI32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoad3dF32: + return R"(texture_tint_0.read(int3(1, 2, 3)))"; + case ValidTextureOverload::kLoad3dU32: + return R"(texture_tint_0.read(int3(1, 2, 3)))"; + case ValidTextureOverload::kLoad3dI32: + return R"(texture_tint_0.read(int3(1, 2, 3)))"; + case ValidTextureOverload::kLoad3dLevelF32: + return R"(texture_tint_0.read(int3(1, 2, 3), 4))"; + case ValidTextureOverload::kLoad3dLevelU32: + return R"(texture_tint_0.read(int3(1, 2, 3), 4))"; + case ValidTextureOverload::kLoad3dLevelI32: + return R"(texture_tint_0.read(int3(1, 2, 3), 4))"; + case ValidTextureOverload::kLoadMultisampled2dF32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadMultisampled2dU32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadMultisampled2dI32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadMultisampled2dArrayF32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoadMultisampled2dArrayU32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoadMultisampled2dArrayI32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoadDepth2dF32: + return R"(texture_tint_0.read(int2(1, 2)))"; + case ValidTextureOverload::kLoadDepth2dLevelF32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadDepth2dArrayF32: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadDepth2dArrayLevelF32: + return R"(texture_tint_0.read(int2(1, 2), 3, 4))"; + case ValidTextureOverload::kLoadStorageRO1dRgba32float: + return R"(texture_tint_0.read(1))"; + case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float: + return R"(texture_tint_0.read(1, 2))"; + case ValidTextureOverload::kLoadStorageRO2dRgba8unorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8snorm: + case ValidTextureOverload::kLoadStorageRO2dRgba8uint: + case ValidTextureOverload::kLoadStorageRO2dRgba8sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16uint: + case ValidTextureOverload::kLoadStorageRO2dRgba16sint: + case ValidTextureOverload::kLoadStorageRO2dRgba16float: + case ValidTextureOverload::kLoadStorageRO2dR32uint: + case ValidTextureOverload::kLoadStorageRO2dR32sint: + case ValidTextureOverload::kLoadStorageRO2dR32float: + case ValidTextureOverload::kLoadStorageRO2dRg32uint: + case ValidTextureOverload::kLoadStorageRO2dRg32sint: + case ValidTextureOverload::kLoadStorageRO2dRg32float: + case ValidTextureOverload::kLoadStorageRO2dRgba32uint: + case ValidTextureOverload::kLoadStorageRO2dRgba32sint: + case ValidTextureOverload::kLoadStorageRO2dRgba32float: + return R"(texture_tint_0.read(int2(1, 2)))"; + case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float: + return R"(texture_tint_0.read(int2(1, 2), 3))"; + case ValidTextureOverload::kLoadStorageRO3dRgba32float: + return R"(texture_tint_0.read(int3(1, 2, 3)))"; } return ""; -} // LINT - Ignore the length of this function +} // NOLINT - Ignore the length of this function class MslGeneratorIntrinsicTextureTest : public ast::BuilderWithModule, @@ -156,38 +250,13 @@ class MslGeneratorIntrinsicTextureTest TEST_P(MslGeneratorIntrinsicTextureTest, Call) { auto param = GetParam(); - ast::type::Type* datatype = nullptr; - switch (param.texture_data_type) { - case ast::intrinsic::test::TextureDataType::kF32: - datatype = ty.f32; - break; - case ast::intrinsic::test::TextureDataType::kU32: - datatype = ty.u32; - break; - case ast::intrinsic::test::TextureDataType::kI32: - datatype = ty.i32; - break; - } - - ast::type::Sampler sampler_type{param.sampler_kind}; - switch (param.texture_kind) { - case ast::intrinsic::test::TextureKind::kRegular: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension, - datatype)); - break; - - case ast::intrinsic::test::TextureKind::kDepth: - Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension)); - break; - } - - Var("sampler", ast::StorageClass::kNone, &sampler_type); + param.buildTextureVariable(this); + param.buildSamplerVariable(this); ast::CallExpression call{Expr(param.function), param.args(this)}; - EXPECT_TRUE(td.DetermineResultType(&call)) << td.error(); + ASSERT_TRUE(td.Determine()) << td.error(); + ASSERT_TRUE(td.DetermineResultType(&call)) << td.error(); ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 7a565bfaf1..20a03fb041 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -13,6 +13,7 @@ #include "src/writer/spirv/builder.h" +#include #include #include #include @@ -72,7 +73,7 @@ #include "src/ast/uint_literal.h" #include "src/ast/unary_op_expression.h" #include "src/ast/variable_decl_statement.h" -#include "src/writer/pack_coord_arrayidx.h" +#include "src/writer/append_vector.h" namespace tint { namespace writer { @@ -1946,25 +1947,50 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, spirv_params.emplace_back(std::move(result_id)); // result id // Extra image operands, appended to spirv_params. - uint32_t spirv_operand_mask = 0; - OperandList spirv_operands; - spirv_operands.reserve(4); // Enough to fit most parameter lists + struct ImageOperand { + SpvImageOperandsMask mask; + tint::writer::spirv::Operand operand; + }; + std::vector image_operands; + image_operands.reserve(4); // Enough to fit most parameter lists + + auto append_coords_to_spirv_params = [&] { + if (pidx.array_index != kNotUsed) { + // Array index needs to be appended to the coordinates. + auto* param_coords = call->params()[pidx.coords]; + auto* param_array_index = call->params()[pidx.array_index]; + + if (!AppendVector(param_coords, param_array_index, + [&](ast::TypeConstructorExpression* packed) { + auto param = + GenerateTypeConstructorExpression(packed, false); + if (param == 0) { + return false; + } + spirv_params.emplace_back(Operand::Int(param)); + return true; + })) { + return; + } + } else { + spirv_params.emplace_back(gen_param(pidx.coords)); // coordinates + } + }; if (ident->intrinsic() == ast::Intrinsic::kTextureLoad) { op = texture_type->Is() ? spv::Op::OpImageRead : spv::Op::OpImageFetch; spirv_params.emplace_back(gen_param(pidx.texture)); - spirv_params.emplace_back(gen_param(pidx.coords)); + append_coords_to_spirv_params(); - // TODO(dsinclair): Remove the LOD param from textureLoad on storage - // textures when https://github.com/gpuweb/gpuweb/pull/1032 gets merged. if (pidx.level != kNotUsed) { - if (texture_type->Is()) { - spirv_operand_mask |= SpvImageOperandsSampleMask; - } else { - spirv_operand_mask |= SpvImageOperandsLodMask; - } - spirv_operands.emplace_back(gen_param(pidx.level)); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsLodMask, gen_param(pidx.level)}); + } + + if (pidx.sample_index != kNotUsed) { + image_operands.emplace_back(ImageOperand{SpvImageOperandsSampleMask, + gen_param(pidx.sample_index)}); } } else { assert(pidx.sampler != kNotUsed); @@ -1976,27 +2002,7 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, // Populate the spirv_params with the common parameters spirv_params.emplace_back(Operand::Int(sampled_image)); // sampled image - - if (pidx.array_index != kNotUsed) { - // Array index needs to be appended to the coordinates. - auto* param_coords = call->params()[pidx.coords]; - auto* param_array_index = call->params()[pidx.array_index]; - - if (!PackCoordAndArrayIndex( - param_coords, param_array_index, - [&](ast::TypeConstructorExpression* packed) { - auto param = GenerateTypeConstructorExpression(packed, false); - if (param == 0) { - return false; - } - spirv_params.emplace_back(Operand::Int(param)); - return true; - })) { - return; - } - } else { - spirv_params.emplace_back(gen_param(pidx.coords)); // coordinates - } + append_coords_to_spirv_params(); switch (ident->intrinsic()) { case ast::Intrinsic::kTextureSample: { @@ -2006,24 +2012,25 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, case ast::Intrinsic::kTextureSampleBias: { op = spv::Op::OpImageSampleImplicitLod; assert(pidx.bias != kNotUsed); - spirv_operand_mask |= SpvImageOperandsBiasMask; - spirv_operands.emplace_back(gen_param(pidx.bias)); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsBiasMask, gen_param(pidx.bias)}); break; } case ast::Intrinsic::kTextureSampleLevel: { op = spv::Op::OpImageSampleExplicitLod; assert(pidx.level != kNotUsed); - spirv_operand_mask |= SpvImageOperandsLodMask; - spirv_operands.emplace_back(gen_param(pidx.level)); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsLodMask, gen_param(pidx.level)}); break; } case ast::Intrinsic::kTextureSampleGrad: { op = spv::Op::OpImageSampleExplicitLod; assert(pidx.ddx != kNotUsed); assert(pidx.ddy != kNotUsed); - spirv_operand_mask |= SpvImageOperandsGradMask; - spirv_operands.emplace_back(gen_param(pidx.ddx)); - spirv_operands.emplace_back(gen_param(pidx.ddy)); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddx)}); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsGradMask, gen_param(pidx.ddy)}); break; } case ast::Intrinsic::kTextureSampleCompare: { @@ -2031,11 +2038,11 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, assert(pidx.depth_ref != kNotUsed); spirv_params.emplace_back(gen_param(pidx.depth_ref)); - spirv_operand_mask |= SpvImageOperandsLodMask; ast::type::F32 f32; ast::FloatLiteral float_0(&f32, 0.0); - spirv_operands.emplace_back( - Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))); + image_operands.emplace_back(ImageOperand{ + SpvImageOperandsLodMask, + Operand::Int(GenerateLiteralIfNeeded(nullptr, &float_0))}); break; } default: @@ -2044,16 +2051,21 @@ void Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident, } if (pidx.offset != kNotUsed) { - spirv_operand_mask |= SpvImageOperandsOffsetMask; - spirv_operands.emplace_back(gen_param(pidx.offset)); + image_operands.emplace_back( + ImageOperand{SpvImageOperandsOffsetMask, gen_param(pidx.offset)}); } - if (spirv_operand_mask != 0) { - // Note: Order of operands is based on SpvImageXXXOperands value - - // smaller-numbered SpvImageXXXOperands bits appear first. - spirv_params.emplace_back(Operand::Int(spirv_operand_mask)); - spirv_params.insert(std::end(spirv_params), std::begin(spirv_operands), - std::end(spirv_operands)); + if (!image_operands.empty()) { + std::sort(image_operands.begin(), image_operands.end(), + [](auto& a, auto& b) { return a.mask < b.mask; }); + uint32_t mask = 0; + for (auto& image_operand : image_operands) { + mask |= image_operand.mask; + } + spirv_params.emplace_back(Operand::Int(mask)); + for (auto& image_operand : image_operands) { + spirv_params.emplace_back(image_operand.operand); + } } if (op == spv::Op::OpNop) { @@ -2143,8 +2155,8 @@ bool Builder::GenerateConditionalBlock( auto true_block = result_op(); auto true_block_id = true_block.to_i(); - // if there are no more else statements we branch on false to the merge block - // otherwise we branch to the false block + // if there are no more else statements we branch on false to the merge + // block otherwise we branch to the false block auto false_block_id = cur_else_idx < else_stmts.size() ? next_id() : merge_block_id; @@ -2644,12 +2656,12 @@ bool Builder::GenerateStructType(ast::type::Struct* struct_type, } // We're attaching the access control to the members of the struct instead - // of to the variable. The reason we do this is that WGSL models the access - // as part of the type. If we attach to the variable, it's no longer part - // of the type in the SPIR-V backend, but part of the variable. This differs - // from the modeling and other backends. Attaching to the struct members - // means the access control stays part of the type where it logically makes - // the most sense. + // of to the variable. The reason we do this is that WGSL models the + // access as part of the type. If we attach to the variable, it's no + // longer part of the type in the SPIR-V backend, but part of the + // variable. This differs from the modeling and other backends. Attaching + // to the struct members means the access control stays part of the type + // where it logically makes the most sense. if (access_control == ast::AccessControl::kReadOnly) { push_annot(spv::Op::OpMemberDecorate, {Operand::Int(struct_id), Operand::Int(i), diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc index 48be756db8..f8f69844ad 100644 --- a/src/writer/spirv/builder_intrinsic_test.cc +++ b/src/writer/spirv/builder_intrinsic_test.cc @@ -413,173 +413,6 @@ TEST_F(IntrinsicBuilderTest, Call_Select) { )"); } -TEST_F(IntrinsicBuilderTest, Call_TextureLoad_Storage_RO_1d) { - ast::type::StorageTexture s(ast::type::TextureDimension::k1d, - ast::AccessControl::kReadOnly, - ast::type::ImageFormat::kR16Float); - - ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error(); - - b.push_function(Function{}); - - auto* tex = Var("texture", ast::StorageClass::kNone, &s); - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - - auto expr = Call("textureLoad", "texture", 1.0f, 2); - - EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); - EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error(); - - EXPECT_EQ(DumpInstructions(b.types()), - R"(%4 = OpTypeFloat 32 -%3 = OpTypeImage %4 1D 0 0 0 2 R16f -%2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%6 = OpTypeVector %4 4 -%8 = OpConstant %4 1 -%9 = OpTypeInt 32 1 -%10 = OpConstant %9 2 -)"); - - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%5 = OpImageRead %6 %7 %8 Lod %10 -)"); -} - -TEST_F(IntrinsicBuilderTest, Call_TextureLoad_Storage_RO_2d) { - ast::type::StorageTexture s(ast::type::TextureDimension::k2d, - ast::AccessControl::kReadOnly, - ast::type::ImageFormat::kR16Float); - - ASSERT_TRUE(td.DetermineStorageTextureSubtype(&s)) << td.error(); - - b.push_function(Function{}); - - auto* tex = Var("texture", ast::StorageClass::kNone, &s); - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - - auto expr = Call("textureLoad", "texture", vec2(1.0f, 2.0f), 2); - - EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); - EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error(); - - EXPECT_EQ(DumpInstructions(b.types()), - R"(%4 = OpTypeFloat 32 -%3 = OpTypeImage %4 2D 0 0 0 2 R16f -%2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%6 = OpTypeVector %4 4 -%8 = OpTypeVector %4 2 -%9 = OpConstant %4 1 -%10 = OpConstant %4 2 -%11 = OpConstantComposite %8 %9 %10 -%12 = OpTypeInt 32 1 -%13 = OpConstant %12 2 -)"); - - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%5 = OpImageRead %6 %7 %11 Lod %13 -)"); -} - -TEST_F(IntrinsicBuilderTest, Call_TextureLoad_Sampled_1d) { - ast::type::SampledTexture s(ast::type::TextureDimension::k1d, ty.f32); - - b.push_function(Function{}); - - auto* tex = Var("texture", ast::StorageClass::kNone, &s); - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - - auto expr = Call("textureLoad", "texture", 1.0f, 2); - - EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); - EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error(); - - EXPECT_EQ(DumpInstructions(b.types()), - R"(%4 = OpTypeFloat 32 -%3 = OpTypeImage %4 1D 0 0 0 1 Unknown -%2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%6 = OpTypeVector %4 4 -%8 = OpConstant %4 1 -%9 = OpTypeInt 32 1 -%10 = OpConstant %9 2 -)"); - - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%5 = OpImageFetch %6 %7 %8 Lod %10 -)"); -} - -TEST_F(IntrinsicBuilderTest, Call_TextureLoad_Sampled_2d) { - ast::type::SampledTexture s(ast::type::TextureDimension::k2d, ty.f32); - - b.push_function(Function{}); - - auto* tex = Var("texture", ast::StorageClass::kNone, &s); - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - - auto expr = Call("textureLoad", "texture", vec2(1.0f, 2.0f), 2); - - EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); - EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error(); - - EXPECT_EQ(DumpInstructions(b.types()), - R"(%4 = OpTypeFloat 32 -%3 = OpTypeImage %4 2D 0 0 0 1 Unknown -%2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%6 = OpTypeVector %4 4 -%8 = OpTypeVector %4 2 -%9 = OpConstant %4 1 -%10 = OpConstant %4 2 -%11 = OpConstantComposite %8 %9 %10 -%12 = OpTypeInt 32 1 -%13 = OpConstant %12 2 -)"); - - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%5 = OpImageFetch %6 %7 %11 Lod %13 -)"); -} - -TEST_F(IntrinsicBuilderTest, Call_TextureLoad_Multisampled_2d) { - ast::type::MultisampledTexture s(ast::type::TextureDimension::k2d, ty.f32); - - b.push_function(Function{}); - - auto* tex = Var("texture", ast::StorageClass::kNone, &s); - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - - auto expr = Call("textureLoad", "texture", vec2(1.0f, 2.0f), 2); - - ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); - EXPECT_EQ(b.GenerateExpression(&expr), 5u) << b.error(); - - EXPECT_EQ(DumpInstructions(b.types()), - R"(%4 = OpTypeFloat 32 -%3 = OpTypeImage %4 2D 0 0 1 1 Unknown -%2 = OpTypePointer Private %3 -%1 = OpVariable %2 Private -%6 = OpTypeVector %4 4 -%8 = OpTypeVector %4 2 -%9 = OpConstant %4 1 -%10 = OpConstant %4 2 -%11 = OpConstantComposite %8 %9 %10 -%12 = OpTypeInt 32 1 -%13 = OpConstant %12 2 -)"); - - EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), - R"(%7 = OpLoad %3 %1 -%5 = OpImageFetch %6 %7 %11 Sample %13 -)"); -} - // This tests that we do not push OpTypeSampledImage and float_0 type twice. TEST_F(IntrinsicBuilderTest, Call_TextureSampleCompare_Twice) { ast::type::Sampler s(ast::type::SamplerKind::kComparisonSampler); diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc index 3d5bdd5112..106b17e34e 100644 --- a/src/writer/spirv/builder_intrinsic_texture_test.cc +++ b/src/writer/spirv/builder_intrinsic_texture_test.cc @@ -18,6 +18,7 @@ #include "src/ast/builder.h" #include "src/ast/intrinsic_texture_helper_test.h" #include "src/ast/type/depth_texture_type.h" +#include "src/ast/type/multisampled_texture_type.h" #include "src/ast/type/sampled_texture_type.h" #include "src/type_determiner.h" #include "src/writer/spirv/builder.h" @@ -1476,6 +1477,1092 @@ expected_texture_overload_spirv expected_texture_overload( %17 = OpConvertSToF %4 %19 %20 = OpCompositeConstruct %13 %14 %15 %16 %17 %8 = OpImageSampleDrefExplicitLod %4 %12 %20 %21 Lod %22 +)"}; + case ValidTextureOverload::kLoad1dF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 1D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeInt 32 1 +%12 = OpConstant %11 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %12 +)"}; + case ValidTextureOverload::kLoad1dU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 1D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeInt 32 1 +%12 = OpConstant %11 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %12 +)"}; + case ValidTextureOverload::kLoad1dI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 1D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpConstant %4 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %11 +)"}; + case ValidTextureOverload::kLoad1dArrayF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 1D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad1dArrayU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 1D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad1dArrayI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 1D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %14 +)"}; + case ValidTextureOverload::kLoad2dF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad2dU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad2dI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %14 +)"}; + case ValidTextureOverload::kLoad2dLevelF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +%16 = OpConstant %12 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Lod %16 +)"}; + case ValidTextureOverload::kLoad2dLevelU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +%16 = OpConstant %12 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Lod %16 +)"}; + case ValidTextureOverload::kLoad2dLevelI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +%15 = OpConstant %4 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %14 Lod %15 +)"}; + case ValidTextureOverload::kLoad2dArrayF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 +)"}; + case ValidTextureOverload::kLoad2dArrayU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 +)"}; + case ValidTextureOverload::kLoad2dArrayI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 3 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstant %4 3 +%15 = OpConstantComposite %11 %12 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad2dArrayLevelF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Lod %17 +)"}; + case ValidTextureOverload::kLoad2dArrayLevelU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Lod %17 +)"}; + case ValidTextureOverload::kLoad2dArrayLevelI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 3 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstant %4 3 +%15 = OpConstantComposite %11 %12 %13 %14 +%16 = OpConstant %4 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Lod %16 +)"}; + case ValidTextureOverload::kLoad3dF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 +)"}; + case ValidTextureOverload::kLoad3dU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 +)"}; + case ValidTextureOverload::kLoad3dI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 3 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstant %4 3 +%15 = OpConstantComposite %11 %12 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 +)"}; + case ValidTextureOverload::kLoad3dLevelF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Lod %17 +)"}; + case ValidTextureOverload::kLoad3dLevelU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Lod %17 +)"}; + case ValidTextureOverload::kLoad3dLevelI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 3D 0 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 3 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstant %4 3 +%15 = OpConstantComposite %11 %12 %13 %14 +%16 = OpConstant %4 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Lod %16 +)"}; + case ValidTextureOverload::kLoadMultisampled2dF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +%16 = OpConstant %12 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Sample %16 +)"}; + case ValidTextureOverload::kLoadMultisampled2dU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +%16 = OpConstant %12 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Sample %16 +)"}; + case ValidTextureOverload::kLoadMultisampled2dI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +%15 = OpConstant %4 3 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %14 Sample %15 +)"}; + case ValidTextureOverload::kLoadMultisampled2dArrayF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 1 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Sample %17 +)"}; + case ValidTextureOverload::kLoadMultisampled2dArrayU32: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 1 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +%17 = OpConstant %12 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %16 Sample %17 +)"}; + case ValidTextureOverload::kLoadMultisampled2dArrayI32: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 1 1 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 3 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstant %4 3 +%15 = OpConstantComposite %11 %12 %13 %14 +%16 = OpConstant %4 4 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageFetch %9 %10 %15 Sample %16 +)"}; + case ValidTextureOverload::kLoadDepth2dF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 2 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstantComposite %10 %12 %13 +)", + R"( +%9 = OpLoad %3 %1 +%8 = OpImageFetch %4 %9 %14 +)"}; + case ValidTextureOverload::kLoadDepth2dLevelF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 0 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 2 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstantComposite %10 %12 %13 +%15 = OpConstant %11 3 +)", + R"( +%9 = OpLoad %3 %1 +%8 = OpImageFetch %4 %9 %14 Lod %15 +)"}; + case ValidTextureOverload::kLoadDepth2dArrayF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 3 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstant %11 3 +%15 = OpConstantComposite %10 %12 %13 %14 +)", + R"( +%9 = OpLoad %3 %1 +%8 = OpImageFetch %4 %9 %15 +)"}; + case ValidTextureOverload::kLoadDepth2dArrayLevelF32: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 1 1 0 1 Unknown +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%11 = OpTypeInt 32 1 +%10 = OpTypeVector %11 3 +%12 = OpConstant %11 1 +%13 = OpConstant %11 2 +%14 = OpConstant %11 3 +%15 = OpConstantComposite %10 %12 %13 %14 +%16 = OpConstant %11 4 +)", + R"( +%9 = OpLoad %3 %1 +%8 = OpImageFetch %4 %9 %15 Lod %16 +)"}; + case ValidTextureOverload::kLoadStorageRO1dRgba32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 1D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeInt 32 1 +%12 = OpConstant %11 1 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %12 +)"}; + case ValidTextureOverload::kLoadStorageRO1dArrayRgba32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 1D 0 1 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba8unorm: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba8 +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba8snorm: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba8Snorm +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba8uint: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba8ui +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba8sint: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba8i +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %14 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba16uint: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba16ui +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba16sint: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba16i +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %14 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba16float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba16f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dR32uint: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 2 R32ui +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dR32sint: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 2 R32i +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %14 +)"}; + case ValidTextureOverload::kLoadStorageRO2dR32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 R32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRg32uint: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 2 Rg32ui +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRg32sint: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 2 Rg32i +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %14 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRg32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 Rg32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba32uint: + return {R"( +%4 = OpTypeInt 32 0 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba32ui +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba32sint: + return {R"( +%4 = OpTypeInt 32 1 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba32i +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%11 = OpTypeVector %4 2 +%12 = OpConstant %4 1 +%13 = OpConstant %4 2 +%14 = OpConstantComposite %11 %12 %13 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %14 +)"}; + case ValidTextureOverload::kLoadStorageRO2dRgba32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 2 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstantComposite %11 %13 %14 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %15 +)"}; + case ValidTextureOverload::kLoadStorageRO2dArrayRgba32float: + + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 2D 0 1 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %16 +)"}; + case ValidTextureOverload::kLoadStorageRO3dRgba32float: + return {R"( +%4 = OpTypeFloat 32 +%3 = OpTypeImage %4 3D 0 0 0 2 Rgba32f +%2 = OpTypePointer Private %3 +%1 = OpVariable %2 Private +%7 = OpTypeSampler +%6 = OpTypePointer Private %7 +%5 = OpVariable %6 Private +%9 = OpTypeVector %4 4 +%12 = OpTypeInt 32 1 +%11 = OpTypeVector %12 3 +%13 = OpConstant %12 1 +%14 = OpConstant %12 2 +%15 = OpConstant %12 3 +%16 = OpConstantComposite %11 %13 %14 %15 +)", + R"( +%10 = OpLoad %3 %1 +%8 = OpImageRead %9 %10 %16 )"}; } return {"", ""}; @@ -1503,42 +2590,17 @@ TEST_P(IntrinsicTextureTest, Call) { b.push_function(Function{}); - ast::type::Type* datatype = nullptr; - switch (param.texture_data_type) { - case ast::intrinsic::test::TextureDataType::kF32: - datatype = ty.f32; - break; - case ast::intrinsic::test::TextureDataType::kU32: - datatype = ty.u32; - break; - case ast::intrinsic::test::TextureDataType::kI32: - datatype = ty.i32; - break; - } - - ast::type::Sampler sampler_type{param.sampler_kind}; - ast::Variable* tex = nullptr; - switch (param.texture_kind) { - case ast::intrinsic::test::TextureKind::kRegular: - tex = Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension, - datatype)); - break; - - case ast::intrinsic::test::TextureKind::kDepth: - tex = Var("texture", ast::StorageClass::kNone, - mod->create(param.texture_dimension)); - break; - } - - auto* sampler = Var("sampler", ast::StorageClass::kNone, &sampler_type); - - ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error(); - ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error(); + auto* texture = param.buildTextureVariable(this); + auto* sampler = param.buildSamplerVariable(this); ast::CallExpression call{Expr(param.function), param.args(this)}; + EXPECT_TRUE(td.Determine()) << td.error(); EXPECT_TRUE(td.DetermineResultType(&call)) << td.error(); + + ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error(); + ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error(); + EXPECT_EQ(b.GenerateExpression(&call), 8u) << b.error(); auto expected = expected_texture_overload(param.overload);