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"(