writer/hlsl: Include format type for sampled textures Required for correct output of .Load() functions Bug: tint:689 Change-Id: I5e5ea068700bbe2239f04dc81da9acb7abce0210 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47225 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index c569d51..845cb70 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc
@@ -2442,24 +2442,26 @@ } else if (auto* str = type->As<type::Struct>()) { out << builder_.Symbols().NameFor(str->symbol()); } else if (auto* tex = type->As<type::Texture>()) { - if (tex->Is<type::StorageTexture>()) { + auto* storage = tex->As<type::StorageTexture>(); + auto* multism = tex->As<type::MultisampledTexture>(); + auto* sampled = tex->As<type::SampledTexture>(); + + if (storage) { if (access && !access->IsReadOnly()) { out << "RW"; } } out << "Texture"; - auto* ms = tex->As<type::MultisampledTexture>(); - switch (tex->dim()) { case type::TextureDimension::k1d: out << "1D"; break; case type::TextureDimension::k2d: - out << (ms ? "2DMS" : "2D"); + out << (multism ? "2DMS" : "2D"); break; case type::TextureDimension::k2dArray: - out << (ms ? "2DMSArray" : "2DArray"); + out << (multism ? "2DMSArray" : "2DArray"); break; case type::TextureDimension::k3d: out << "3D"; @@ -2476,33 +2478,28 @@ return false; } - if (ms) { + if (storage) { + auto* component = image_format_to_rwtexture_type(storage->image_format()); + if (component == nullptr) { + TINT_ICE(diagnostics_) << "Unsupported StorageTexture ImageFormat: " + << static_cast<int>(storage->image_format()); + return false; + } + out << "<" << component << ">"; + } else if (sampled || multism) { + auto* subtype = sampled ? sampled->type() : multism->type(); out << "<"; - if (ms->type()->Is<type::F32>()) { + if (subtype->Is<type::F32>()) { out << "float4"; - } else if (ms->type()->Is<type::I32>()) { + } else if (subtype->Is<type::I32>()) { out << "int4"; - } else if (ms->type()->Is<type::U32>()) { + } else if (subtype->Is<type::U32>()) { out << "uint4"; } else { TINT_ICE(diagnostics_) << "Unsupported multisampled texture type"; return false; } - - // TODO(ben-clayton): The HLSL docs claim that the MS texture type should - // also contain the number of samples, which is not part of the WGSL type. - // However, DXC seems to consider this optional. - // See: https://github.com/gpuweb/gpuweb/issues/1445 - out << ">"; - } else if (auto* st = tex->As<type::StorageTexture>()) { - auto* component = image_format_to_rwtexture_type(st->image_format()); - if (component == nullptr) { - TINT_ICE(diagnostics_) << "Unsupported StorageTexture ImageFormat: " - << static_cast<int>(st->image_format()); - return false; - } - out << "<" << component << ">"; } } else if (type->Is<type::U32>()) { out << "uint";
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc index bb64ba4..5a3f4bb 100644 --- a/src/writer/hlsl/generator_impl_type_test.cc +++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -355,8 +355,10 @@ HlslDepthTextureData{type::TextureDimension::kCubeArray, "TextureCubeArray tex : register(t1, space2);"})); +enum class TextureDataType { F32, U32, I32 }; struct HlslSampledTextureData { type::TextureDimension dim; + TextureDataType datatype; std::string result; }; inline std::ostream& operator<<(std::ostream& out, @@ -368,7 +370,19 @@ TEST_P(HlslSampledTexturesTest, Emit) { auto params = GetParam(); - auto* t = create<type::SampledTexture>(params.dim, ty.f32()); + type::Type* datatype = nullptr; + switch (params.datatype) { + case TextureDataType::F32: + datatype = ty.f32(); + break; + case TextureDataType::U32: + datatype = ty.u32(); + break; + case TextureDataType::I32: + datatype = ty.i32(); + break; + } + auto* t = create<type::SampledTexture>(params.dim, datatype); Global("tex", t, ast::StorageClass::kUniformConstant, nullptr, ast::DecorationList{ @@ -391,19 +405,96 @@ HlslGeneratorImplTest_Type, HlslSampledTexturesTest, testing::Values( - HlslSampledTextureData{type::TextureDimension::k1d, - "Texture1D tex : register(t1, space2);"}, - HlslSampledTextureData{type::TextureDimension::k2d, - "Texture2D tex : register(t1, space2);"}, - HlslSampledTextureData{type::TextureDimension::k2dArray, - "Texture2DArray tex : register(t1, space2);"}, - HlslSampledTextureData{type::TextureDimension::k3d, - "Texture3D tex : register(t1, space2);"}, - HlslSampledTextureData{type::TextureDimension::kCube, - "TextureCube tex : register(t1, space2);"}, + HlslSampledTextureData{ + type::TextureDimension::k1d, + TextureDataType::F32, + "Texture1D<float4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2d, + TextureDataType::F32, + "Texture2D<float4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2dArray, + TextureDataType::F32, + "Texture2DArray<float4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k3d, + TextureDataType::F32, + "Texture3D<float4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::kCube, + TextureDataType::F32, + "TextureCube<float4> tex : register(t1, space2);", + }, HlslSampledTextureData{ type::TextureDimension::kCubeArray, - "TextureCubeArray tex : register(t1, space2);"})); + TextureDataType::F32, + "TextureCubeArray<float4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k1d, + TextureDataType::U32, + "Texture1D<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2d, + TextureDataType::U32, + "Texture2D<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2dArray, + TextureDataType::U32, + "Texture2DArray<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k3d, + TextureDataType::U32, + "Texture3D<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::kCube, + TextureDataType::U32, + "TextureCube<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::kCubeArray, + TextureDataType::U32, + "TextureCubeArray<uint4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k1d, + TextureDataType::I32, + "Texture1D<int4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2d, + TextureDataType::I32, + "Texture2D<int4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k2dArray, + TextureDataType::I32, + "Texture2DArray<int4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::k3d, + TextureDataType::I32, + "Texture3D<int4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::kCube, + TextureDataType::I32, + "TextureCube<int4> tex : register(t1, space2);", + }, + HlslSampledTextureData{ + type::TextureDimension::kCubeArray, + TextureDataType::I32, + "TextureCubeArray<int4> tex : register(t1, space2);", + })); TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) { type::MultisampledTexture s(type::TextureDimension::k2d, ty.f32());