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>
This commit is contained in:
Ben Clayton 2021-04-09 17:50:08 +00:00 committed by Commit Bot service account
parent 6a802cd3e4
commit 804a699ea5
2 changed files with 123 additions and 35 deletions

View File

@ -2442,24 +2442,26 @@ bool GeneratorImpl::EmitType(std::ostream& out,
} else if (auto* str = type->As<type::Struct>()) { } else if (auto* str = type->As<type::Struct>()) {
out << builder_.Symbols().NameFor(str->symbol()); out << builder_.Symbols().NameFor(str->symbol());
} else if (auto* tex = type->As<type::Texture>()) { } 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()) { if (access && !access->IsReadOnly()) {
out << "RW"; out << "RW";
} }
} }
out << "Texture"; out << "Texture";
auto* ms = tex->As<type::MultisampledTexture>();
switch (tex->dim()) { switch (tex->dim()) {
case type::TextureDimension::k1d: case type::TextureDimension::k1d:
out << "1D"; out << "1D";
break; break;
case type::TextureDimension::k2d: case type::TextureDimension::k2d:
out << (ms ? "2DMS" : "2D"); out << (multism ? "2DMS" : "2D");
break; break;
case type::TextureDimension::k2dArray: case type::TextureDimension::k2dArray:
out << (ms ? "2DMSArray" : "2DArray"); out << (multism ? "2DMSArray" : "2DArray");
break; break;
case type::TextureDimension::k3d: case type::TextureDimension::k3d:
out << "3D"; out << "3D";
@ -2476,33 +2478,28 @@ bool GeneratorImpl::EmitType(std::ostream& out,
return false; 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 << "<"; out << "<";
if (ms->type()->Is<type::F32>()) { if (subtype->Is<type::F32>()) {
out << "float4"; out << "float4";
} else if (ms->type()->Is<type::I32>()) { } else if (subtype->Is<type::I32>()) {
out << "int4"; out << "int4";
} else if (ms->type()->Is<type::U32>()) { } else if (subtype->Is<type::U32>()) {
out << "uint4"; out << "uint4";
} else { } else {
TINT_ICE(diagnostics_) << "Unsupported multisampled texture type"; TINT_ICE(diagnostics_) << "Unsupported multisampled texture type";
return false; 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 << ">"; 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>()) { } else if (type->Is<type::U32>()) {
out << "uint"; out << "uint";

View File

@ -355,8 +355,10 @@ INSTANTIATE_TEST_SUITE_P(
HlslDepthTextureData{type::TextureDimension::kCubeArray, HlslDepthTextureData{type::TextureDimension::kCubeArray,
"TextureCubeArray tex : register(t1, space2);"})); "TextureCubeArray tex : register(t1, space2);"}));
enum class TextureDataType { F32, U32, I32 };
struct HlslSampledTextureData { struct HlslSampledTextureData {
type::TextureDimension dim; type::TextureDimension dim;
TextureDataType datatype;
std::string result; std::string result;
}; };
inline std::ostream& operator<<(std::ostream& out, inline std::ostream& operator<<(std::ostream& out,
@ -368,7 +370,19 @@ using HlslSampledTexturesTest = TestParamHelper<HlslSampledTextureData>;
TEST_P(HlslSampledTexturesTest, Emit) { TEST_P(HlslSampledTexturesTest, Emit) {
auto params = GetParam(); 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, Global("tex", t, ast::StorageClass::kUniformConstant, nullptr,
ast::DecorationList{ ast::DecorationList{
@ -391,19 +405,96 @@ INSTANTIATE_TEST_SUITE_P(
HlslGeneratorImplTest_Type, HlslGeneratorImplTest_Type,
HlslSampledTexturesTest, HlslSampledTexturesTest,
testing::Values( testing::Values(
HlslSampledTextureData{type::TextureDimension::k1d, HlslSampledTextureData{
"Texture1D tex : register(t1, space2);"}, type::TextureDimension::k1d,
HlslSampledTextureData{type::TextureDimension::k2d, TextureDataType::F32,
"Texture2D tex : register(t1, space2);"}, "Texture1D<float4> tex : register(t1, space2);",
HlslSampledTextureData{type::TextureDimension::k2dArray, },
"Texture2DArray tex : register(t1, space2);"}, HlslSampledTextureData{
HlslSampledTextureData{type::TextureDimension::k3d, type::TextureDimension::k2d,
"Texture3D tex : register(t1, space2);"}, TextureDataType::F32,
HlslSampledTextureData{type::TextureDimension::kCube, "Texture2D<float4> tex : register(t1, space2);",
"TextureCube 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{ HlslSampledTextureData{
type::TextureDimension::kCubeArray, 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) { TEST_F(HlslGeneratorImplTest_Type, EmitMultisampledTexture) {
type::MultisampledTexture s(type::TextureDimension::k2d, ty.f32()); type::MultisampledTexture s(type::TextureDimension::k2d, ty.f32());