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>
This commit is contained in:
Ben Clayton 2021-01-14 18:11:17 +00:00 committed by Commit Bot service account
parent 6e5b5ecc52
commit 0a68b365eb
12 changed files with 131 additions and 11 deletions

View File

@ -215,6 +215,9 @@ std::ostream& operator<<(std::ostream& out, Intrinsic i) {
case Intrinsic::kTextureNumLevels: case Intrinsic::kTextureNumLevels:
out << "textureNumLevels"; out << "textureNumLevels";
return out; return out;
case Intrinsic::kTextureNumSamples:
out << "textureNumSamples";
return out;
case Intrinsic::kTextureSample: case Intrinsic::kTextureSample:
out << "textureSample"; out << "textureSample";
return out; return out;
@ -281,7 +284,9 @@ bool IsTextureIntrinsic(Intrinsic i) {
bool IsImageQueryIntrinsic(Intrinsic i) { bool IsImageQueryIntrinsic(Intrinsic i) {
return i == ast::Intrinsic::kTextureDimensions || return i == ast::Intrinsic::kTextureDimensions ||
i == Intrinsic::kTextureNumLayers || i == Intrinsic::kTextureNumLevels; i == Intrinsic::kTextureNumLayers ||
i == Intrinsic::kTextureNumLevels ||
i == Intrinsic::kTextureNumSamples;
} }
} // namespace intrinsic } // namespace intrinsic

View File

@ -87,6 +87,7 @@ enum class Intrinsic {
kTextureLoad, kTextureLoad,
kTextureNumLayers, kTextureNumLayers,
kTextureNumLevels, kTextureNumLevels,
kTextureNumSamples,
kTextureSample, kTextureSample,
kTextureSampleBias, kTextureSampleBias,
kTextureSampleCompare, kTextureSampleCompare,

View File

@ -711,6 +711,26 @@ std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
"textureNumLevels", "textureNumLevels",
[](Builder* b) { return b->ExprList("texture"); }, [](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, ValidTextureOverload::kSample1dF32,
"textureSample(t : texture_1d<f32>,\n" "textureSample(t : texture_1d<f32>,\n"

View File

@ -86,6 +86,8 @@ enum class ValidTextureOverload {
kNumLevelsDepth2dArray, kNumLevelsDepth2dArray,
kNumLevelsDepthCube, kNumLevelsDepthCube,
kNumLevelsDepthCubeArray, kNumLevelsDepthCubeArray,
kNumSamplesMultisampled2d,
kNumSamplesMultisampled2dArray,
kSample1dF32, kSample1dF32,
kSample1dArrayF32, kSample1dArrayF32,
kSample2dF32, kSample2dF32,

View File

@ -568,6 +568,7 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
break; break;
case ast::Intrinsic::kTextureNumLayers: case ast::Intrinsic::kTextureNumLayers:
case ast::Intrinsic::kTextureNumLevels: case ast::Intrinsic::kTextureNumLevels:
case ast::Intrinsic::kTextureNumSamples:
param.idx.texture = param.count++; param.idx.texture = param.count++;
break; break;
case ast::Intrinsic::kTextureLoad: case ast::Intrinsic::kTextureLoad:
@ -698,6 +699,7 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
} }
case ast::Intrinsic::kTextureNumLayers: case ast::Intrinsic::kTextureNumLayers:
case ast::Intrinsic::kTextureNumLevels: case ast::Intrinsic::kTextureNumLevels:
case ast::Intrinsic::kTextureNumSamples:
return_type = mod_->create<ast::type::I32>(); return_type = mod_->create<ast::type::I32>();
break; break;
case ast::Intrinsic::kTextureStore: case ast::Intrinsic::kTextureStore:
@ -1038,6 +1040,8 @@ bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) {
ident->set_intrinsic(ast::Intrinsic::kTextureNumLayers); ident->set_intrinsic(ast::Intrinsic::kTextureNumLayers);
} else if (name == "textureNumLevels") { } else if (name == "textureNumLevels") {
ident->set_intrinsic(ast::Intrinsic::kTextureNumLevels); ident->set_intrinsic(ast::Intrinsic::kTextureNumLevels);
} else if (name == "textureNumSamples") {
ident->set_intrinsic(ast::Intrinsic::kTextureNumSamples);
} else if (name == "textureLoad") { } else if (name == "textureLoad") {
ident->set_intrinsic(ast::Intrinsic::kTextureLoad); ident->set_intrinsic(ast::Intrinsic::kTextureLoad);
} else if (name == "textureStore") { } else if (name == "textureStore") {

View File

@ -1766,6 +1766,7 @@ INSTANTIATE_TEST_SUITE_P(
IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad}, IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers}, IntrinsicData{"textureNumLayers", ast::Intrinsic::kTextureNumLayers},
IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels}, IntrinsicData{"textureNumLevels", ast::Intrinsic::kTextureNumLevels},
IntrinsicData{"textureNumSamples", ast::Intrinsic::kTextureNumSamples},
IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample}, IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias}, IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
IntrinsicData{"textureSampleCompare", IntrinsicData{"textureSampleCompare",
@ -2949,6 +2950,9 @@ const char* expected_texture_overload(
case ValidTextureOverload::kNumLevelsDepthCube: case ValidTextureOverload::kNumLevelsDepthCube:
case ValidTextureOverload::kNumLevelsDepthCubeArray: case ValidTextureOverload::kNumLevelsDepthCubeArray:
return R"(textureNumLevels(texture))"; return R"(textureNumLevels(texture))";
case ValidTextureOverload::kNumSamplesMultisampled2d:
case ValidTextureOverload::kNumSamplesMultisampled2dArray:
return R"(textureNumSamples(texture))";
case ValidTextureOverload::kDimensions2dLevel: case ValidTextureOverload::kDimensions2dLevel:
case ValidTextureOverload::kDimensions2dArrayLevel: case ValidTextureOverload::kDimensions2dArrayLevel:
case ValidTextureOverload::kDimensions3dLevel: case ValidTextureOverload::kDimensions3dLevel:
@ -3206,6 +3210,8 @@ TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
EXPECT_EQ(call->result_type(), ty.i32); EXPECT_EQ(call->result_type(), ty.i32);
} else if (std::string(param.function) == "textureNumLevels") { } else if (std::string(param.function) == "textureNumLevels") {
EXPECT_EQ(call->result_type(), ty.i32); 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") { } else if (std::string(param.function) == "textureStore") {
EXPECT_EQ(call->result_type(), ty.void_); EXPECT_EQ(call->result_type(), ty.void_);
} else { } else {

View File

@ -698,15 +698,9 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
switch (ident->intrinsic()) { switch (ident->intrinsic()) {
case ast::Intrinsic::kTextureDimensions: case ast::Intrinsic::kTextureDimensions:
case ast::Intrinsic::kTextureNumLayers: case ast::Intrinsic::kTextureNumLayers:
case ast::Intrinsic::kTextureNumLevels: { case ast::Intrinsic::kTextureNumLevels:
// Declare a variable to hold the queried texture info case ast::Intrinsic::kTextureNumSamples: {
auto dims = generate_name(kTempNamePrefix); // All of these intrinsics use the GetDimensions() method on the texture
std::stringstream texture_name;
if (!EmitExpression(pre, texture_name, texture)) {
return false;
}
int num_dimensions = 0; int num_dimensions = 0;
const char* swizzle = ""; const char* swizzle = "";
bool add_mip_level_in = false; bool add_mip_level_in = false;
@ -783,18 +777,39 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
break; break;
} }
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: default:
error_ = "unexpected intrinsic"; error_ = "unexpected intrinsic";
return false; return false;
} }
// Declare a variable to hold the queried texture info
auto dims = generate_name(kTempNamePrefix);
if (num_dimensions == 1) { if (num_dimensions == 1) {
pre << "int " << dims << ";\n"; pre << "int " << dims << ";\n";
} else { } else {
pre << "int" << num_dimensions << " " << dims << ";\n"; pre << "int" << num_dimensions << " " << dims << ";\n";
} }
pre << texture_name.str() << ".GetDimensions("; if (!EmitExpression(pre, pre, texture)) {
return false;
}
pre << ".GetDimensions(";
if (pidx.level != kNotUsed) { if (pidx.level != kNotUsed) {
pre << pidx.level << ", "; pre << pidx.level << ", ";
} else if (add_mip_level_in) { } else if (add_mip_level_in) {

View File

@ -178,6 +178,20 @@ ExpectedResult expected_texture_overload(
"_tint_tmp.x, _tint_tmp.y, _tint_tmp.z, _tint_tmp.w);", "_tint_tmp.x, _tint_tmp.y, _tint_tmp.z, _tint_tmp.w);",
"_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: case ValidTextureOverload::kSample1dF32:
return R"(texture_tint_0.Sample(sampler_tint_0, 1.0f))"; return R"(texture_tint_0.Sample(sampler_tint_0, 1.0f))";
case ValidTextureOverload::kSample1dArrayF32: case ValidTextureOverload::kSample1dArrayF32:

View File

@ -687,6 +687,14 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) {
out_ << ".get_num_mip_levels())"; out_ << ".get_num_mip_levels())";
return true; return true;
} }
case ast::Intrinsic::kTextureNumSamples: {
out_ << "int(";
if (!EmitExpression(params[pidx.texture])) {
return false;
}
out_ << ".get_num_samples())";
return true;
}
default: default:
break; break;
} }

View File

@ -90,6 +90,9 @@ std::string expected_texture_overload(
case ValidTextureOverload::kNumLevelsDepthCube: case ValidTextureOverload::kNumLevelsDepthCube:
case ValidTextureOverload::kNumLevelsDepthCubeArray: case ValidTextureOverload::kNumLevelsDepthCubeArray:
return R"(int(texture_tint_0.get_num_mip_levels()))"; 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: case ValidTextureOverload::kSample1dF32:
return R"(texture_tint_0.sample(sampler_tint_0, 1.0f))"; return R"(texture_tint_0.sample(sampler_tint_0, 1.0f))";
case ValidTextureOverload::kSample1dArrayF32: case ValidTextureOverload::kSample1dArrayF32:

View File

@ -2251,6 +2251,12 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
spirv_params.emplace_back(gen_param(pidx.texture)); spirv_params.emplace_back(gen_param(pidx.texture));
break; 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: { case ast::Intrinsic::kTextureLoad: {
op = texture_type->Is<ast::type::StorageTexture>() op = texture_type->Is<ast::type::StorageTexture>()
? spv::Op::OpImageRead ? spv::Op::OpImageRead

View File

@ -1073,6 +1073,42 @@ OpCapability ImageQuery
R"( R"(
OpCapability SampledCubeArray OpCapability SampledCubeArray
OpCapability ImageQuery 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: case ValidTextureOverload::kSample1dF32:
return { return {