Implement textureNumSamples()
SPIR-V reader TODO
Bug: tint:140
Bug: tint:437
Change-Id: Id95855660680b12e3ff49b6340ef966dfa49f8e4
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/37848
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/intrinsic.cc b/src/ast/intrinsic.cc
index 2282650..6a16abb 100644
--- a/src/ast/intrinsic.cc
+++ b/src/ast/intrinsic.cc
@@ -215,6 +215,9 @@
case Intrinsic::kTextureNumLevels:
out << "textureNumLevels";
return out;
+ case Intrinsic::kTextureNumSamples:
+ out << "textureNumSamples";
+ return out;
case Intrinsic::kTextureSample:
out << "textureSample";
return out;
@@ -281,7 +284,9 @@
bool IsImageQueryIntrinsic(Intrinsic i) {
return i == ast::Intrinsic::kTextureDimensions ||
- i == Intrinsic::kTextureNumLayers || i == Intrinsic::kTextureNumLevels;
+ i == Intrinsic::kTextureNumLayers ||
+ i == Intrinsic::kTextureNumLevels ||
+ i == Intrinsic::kTextureNumSamples;
}
} // namespace intrinsic
diff --git a/src/ast/intrinsic.h b/src/ast/intrinsic.h
index bdf310e..90477bc 100644
--- a/src/ast/intrinsic.h
+++ b/src/ast/intrinsic.h
@@ -87,6 +87,7 @@
kTextureLoad,
kTextureNumLayers,
kTextureNumLevels,
+ kTextureNumSamples,
kTextureSample,
kTextureSampleBias,
kTextureSampleCompare,
diff --git a/src/ast/intrinsic_texture_helper_test.cc b/src/ast/intrinsic_texture_helper_test.cc
index fbeae35..00a2d05 100644
--- a/src/ast/intrinsic_texture_helper_test.cc
+++ b/src/ast/intrinsic_texture_helper_test.cc
@@ -712,6 +712,26 @@
[](Builder* b) { return b->ExprList("texture"); },
},
{
+ ValidTextureOverload::kNumSamplesMultisampled2d,
+ "textureNumSamples(t : texture_multisampled_2d<f32>) -> i32",
+ TextureKind::kMultisampled,
+ type::SamplerKind::kSampler,
+ type::TextureDimension::k2d,
+ TextureDataType::kF32,
+ "textureNumSamples",
+ [](Builder* b) { return b->ExprList("texture"); },
+ },
+ {
+ ValidTextureOverload::kNumSamplesMultisampled2dArray,
+ "textureNumSamples(t : texture_multisampled_2d_array<f32>) -> i32",
+ TextureKind::kMultisampled,
+ type::SamplerKind::kSampler,
+ type::TextureDimension::k2dArray,
+ TextureDataType::kF32,
+ "textureNumSamples",
+ [](Builder* b) { return b->ExprList("texture"); },
+ },
+ {
ValidTextureOverload::kSample1dF32,
"textureSample(t : texture_1d<f32>,\n"
" s : sampler,\n"
diff --git a/src/ast/intrinsic_texture_helper_test.h b/src/ast/intrinsic_texture_helper_test.h
index e78f9e0..bd67b9f 100644
--- a/src/ast/intrinsic_texture_helper_test.h
+++ b/src/ast/intrinsic_texture_helper_test.h
@@ -86,6 +86,8 @@
kNumLevelsDepth2dArray,
kNumLevelsDepthCube,
kNumLevelsDepthCubeArray,
+ kNumSamplesMultisampled2d,
+ kNumSamplesMultisampled2dArray,
kSample1dF32,
kSample1dArrayF32,
kSample2dF32,
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 84f9b6f..7019202 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -568,6 +568,7 @@
break;
case ast::Intrinsic::kTextureNumLayers:
case ast::Intrinsic::kTextureNumLevels:
+ case ast::Intrinsic::kTextureNumSamples:
param.idx.texture = param.count++;
break;
case ast::Intrinsic::kTextureLoad:
@@ -698,6 +699,7 @@
}
case ast::Intrinsic::kTextureNumLayers:
case ast::Intrinsic::kTextureNumLevels:
+ case ast::Intrinsic::kTextureNumSamples:
return_type = mod_->create<ast::type::I32>();
break;
case ast::Intrinsic::kTextureStore:
@@ -1038,6 +1040,8 @@
ident->set_intrinsic(ast::Intrinsic::kTextureNumLayers);
} else if (name == "textureNumLevels") {
ident->set_intrinsic(ast::Intrinsic::kTextureNumLevels);
+ } else if (name == "textureNumSamples") {
+ ident->set_intrinsic(ast::Intrinsic::kTextureNumSamples);
} else if (name == "textureLoad") {
ident->set_intrinsic(ast::Intrinsic::kTextureLoad);
} else if (name == "textureStore") {
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 1a76ae4..b05d2ee 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -1766,6 +1766,7 @@
IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers},
IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels},
+ IntrinsicData{"textureNumSamples", ast::Intrinsic::kTextureNumSamples},
IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
IntrinsicData{"textureSampleCompare",
@@ -2949,6 +2950,9 @@
case ValidTextureOverload::kNumLevelsDepthCube:
case ValidTextureOverload::kNumLevelsDepthCubeArray:
return R"(textureNumLevels(texture))";
+ case ValidTextureOverload::kNumSamplesMultisampled2d:
+ case ValidTextureOverload::kNumSamplesMultisampled2dArray:
+ return R"(textureNumSamples(texture))";
case ValidTextureOverload::kDimensions2dLevel:
case ValidTextureOverload::kDimensions2dArrayLevel:
case ValidTextureOverload::kDimensions3dLevel:
@@ -3206,6 +3210,8 @@
EXPECT_EQ(call->result_type(), ty.i32);
} else if (std::string(param.function) == "textureNumLevels") {
EXPECT_EQ(call->result_type(), ty.i32);
+ } else if (std::string(param.function) == "textureNumSamples") {
+ EXPECT_EQ(call->result_type(), ty.i32);
} else if (std::string(param.function) == "textureStore") {
EXPECT_EQ(call->result_type(), ty.void_);
} else {
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 187020d..06791db 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -698,15 +698,9 @@
switch (ident->intrinsic()) {
case ast::Intrinsic::kTextureDimensions:
case ast::Intrinsic::kTextureNumLayers:
- case ast::Intrinsic::kTextureNumLevels: {
- // Declare a variable to hold the queried texture info
- auto dims = generate_name(kTempNamePrefix);
-
- std::stringstream texture_name;
- if (!EmitExpression(pre, texture_name, texture)) {
- return false;
- }
-
+ case ast::Intrinsic::kTextureNumLevels:
+ case ast::Intrinsic::kTextureNumSamples: {
+ // All of these intrinsics use the GetDimensions() method on the texture
int num_dimensions = 0;
const char* swizzle = "";
bool add_mip_level_in = false;
@@ -783,18 +777,39 @@
break;
}
break;
+ case ast::Intrinsic::kTextureNumSamples:
+ switch (texture_type->dim()) {
+ default:
+ error_ = "texture dimension does not support multisampling";
+ return false;
+ case ast::type::TextureDimension::k2d:
+ num_dimensions = 3;
+ swizzle = ".z";
+ break;
+ case ast::type::TextureDimension::k2dArray:
+ num_dimensions = 4;
+ swizzle = ".w";
+ break;
+ }
+ break;
default:
error_ = "unexpected intrinsic";
return false;
}
+ // Declare a variable to hold the queried texture info
+ auto dims = generate_name(kTempNamePrefix);
+
if (num_dimensions == 1) {
pre << "int " << dims << ";\n";
} else {
pre << "int" << num_dimensions << " " << dims << ";\n";
}
- pre << texture_name.str() << ".GetDimensions(";
+ if (!EmitExpression(pre, pre, texture)) {
+ return false;
+ }
+ pre << ".GetDimensions(";
if (pidx.level != kNotUsed) {
pre << pidx.level << ", ";
} else if (add_mip_level_in) {
diff --git a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
index bbc5401..e0ec794 100644
--- a/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
+++ b/src/writer/hlsl/generator_impl_intrinsic_texture_test.cc
@@ -178,6 +178,20 @@
"_tint_tmp.x, _tint_tmp.y, _tint_tmp.z, _tint_tmp.w);",
"_tint_tmp.w",
};
+ case ValidTextureOverload::kNumSamplesMultisampled2d:
+ return {
+ "int3 _tint_tmp;\n"
+ "texture_tint_0."
+ "GetDimensions(_tint_tmp.x, _tint_tmp.y, _tint_tmp.z);",
+ "_tint_tmp.z",
+ };
+ case ValidTextureOverload::kNumSamplesMultisampled2dArray:
+ return {
+ "int4 _tint_tmp;\n"
+ "texture_tint_0."
+ "GetDimensions(_tint_tmp.x, _tint_tmp.y, _tint_tmp.z, _tint_tmp.w);",
+ "_tint_tmp.w",
+ };
case ValidTextureOverload::kSample1dF32:
return R"(texture_tint_0.Sample(sampler_tint_0, 1.0f))";
case ValidTextureOverload::kSample1dArrayF32:
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index f3a55e4..aa91eef 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -687,6 +687,14 @@
out_ << ".get_num_mip_levels())";
return true;
}
+ case ast::Intrinsic::kTextureNumSamples: {
+ out_ << "int(";
+ if (!EmitExpression(params[pidx.texture])) {
+ return false;
+ }
+ out_ << ".get_num_samples())";
+ return true;
+ }
default:
break;
}
diff --git a/src/writer/msl/generator_impl_intrinsic_texture_test.cc b/src/writer/msl/generator_impl_intrinsic_texture_test.cc
index ded1bfb..54c2a9e 100644
--- a/src/writer/msl/generator_impl_intrinsic_texture_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_texture_test.cc
@@ -90,6 +90,9 @@
case ValidTextureOverload::kNumLevelsDepthCube:
case ValidTextureOverload::kNumLevelsDepthCubeArray:
return R"(int(texture_tint_0.get_num_mip_levels()))";
+ case ValidTextureOverload::kNumSamplesMultisampled2d:
+ case ValidTextureOverload::kNumSamplesMultisampled2dArray:
+ return R"(int(texture_tint_0.get_num_samples()))";
case ValidTextureOverload::kSample1dF32:
return R"(texture_tint_0.sample(sampler_tint_0, 1.0f))";
case ValidTextureOverload::kSample1dArrayF32:
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index 7f913a5..e6d11fd 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -2251,6 +2251,12 @@
spirv_params.emplace_back(gen_param(pidx.texture));
break;
}
+ case ast::Intrinsic::kTextureNumSamples: {
+ op = spv::Op::OpImageQuerySamples;
+ append_result_type_and_id_to_spirv_params();
+ spirv_params.emplace_back(gen_param(pidx.texture));
+ break;
+ }
case ast::Intrinsic::kTextureLoad: {
op = texture_type->Is<ast::type::StorageTexture>()
? spv::Op::OpImageRead
diff --git a/src/writer/spirv/builder_intrinsic_texture_test.cc b/src/writer/spirv/builder_intrinsic_texture_test.cc
index bf4c87f..9c1e251 100644
--- a/src/writer/spirv/builder_intrinsic_texture_test.cc
+++ b/src/writer/spirv/builder_intrinsic_texture_test.cc
@@ -1074,6 +1074,42 @@
OpCapability SampledCubeArray
OpCapability ImageQuery
)"};
+ case ValidTextureOverload::kNumSamplesMultisampled2d:
+ return {R"(
+%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 0 1 1 Unknown
+%2 = OpTypePointer UniformConstant %3
+%1 = OpVariable %2 UniformConstant
+%7 = OpTypeSampler
+%6 = OpTypePointer UniformConstant %7
+%5 = OpVariable %6 UniformConstant
+%9 = OpTypeInt 32 1
+)",
+ R"(
+%10 = OpLoad %3 %1
+%8 = OpImageQuerySamples %9 %10
+)",
+ R"(
+OpCapability ImageQuery
+)"};
+ case ValidTextureOverload::kNumSamplesMultisampled2dArray:
+ return {R"(
+%4 = OpTypeFloat 32
+%3 = OpTypeImage %4 2D 0 1 1 1 Unknown
+%2 = OpTypePointer UniformConstant %3
+%1 = OpVariable %2 UniformConstant
+%7 = OpTypeSampler
+%6 = OpTypePointer UniformConstant %7
+%5 = OpVariable %6 UniformConstant
+%9 = OpTypeInt 32 1
+)",
+ R"(
+%10 = OpLoad %3 %1
+%8 = OpImageQuerySamples %9 %10
+)",
+ R"(
+OpCapability ImageQuery
+)"};
case ValidTextureOverload::kSample1dF32:
return {
R"(