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:
parent
6e5b5ecc52
commit
0a68b365eb
|
@ -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
|
||||||
|
|
|
@ -87,6 +87,7 @@ enum class Intrinsic {
|
||||||
kTextureLoad,
|
kTextureLoad,
|
||||||
kTextureNumLayers,
|
kTextureNumLayers,
|
||||||
kTextureNumLevels,
|
kTextureNumLevels,
|
||||||
|
kTextureNumSamples,
|
||||||
kTextureSample,
|
kTextureSample,
|
||||||
kTextureSampleBias,
|
kTextureSampleBias,
|
||||||
kTextureSampleCompare,
|
kTextureSampleCompare,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -86,6 +86,8 @@ enum class ValidTextureOverload {
|
||||||
kNumLevelsDepth2dArray,
|
kNumLevelsDepth2dArray,
|
||||||
kNumLevelsDepthCube,
|
kNumLevelsDepthCube,
|
||||||
kNumLevelsDepthCubeArray,
|
kNumLevelsDepthCubeArray,
|
||||||
|
kNumSamplesMultisampled2d,
|
||||||
|
kNumSamplesMultisampled2dArray,
|
||||||
kSample1dF32,
|
kSample1dF32,
|
||||||
kSample1dArrayF32,
|
kSample1dArrayF32,
|
||||||
kSample2dF32,
|
kSample2dF32,
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue