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());