spirv-reader: support OpImageQueryLevels

Bug: tint:109
Change-Id: I1bb7bbdca2322df28e7b22225e4b1bfdb74dbf73
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/39720
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
David Neto 2021-02-01 23:43:44 +00:00 committed by Commit Bot service account
parent 1d2bcb99d6
commit d277f3a85a
2 changed files with 304 additions and 1 deletions

View File

@ -4365,6 +4365,7 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
} }
bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) { bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
// TODO(dneto): Reject cases that are valid in Vulkan but invalid in WGSL.
const spvtools::opt::Instruction* image = GetImage(inst); const spvtools::opt::Instruction* image = GetImage(inst);
if (!image) { if (!image) {
return false; return false;
@ -4406,7 +4407,22 @@ bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
return Fail() << "WGSL does not support querying the level of detail of " return Fail() << "WGSL does not support querying the level of detail of "
"an image: " "an image: "
<< inst.PrettyPrint(); << inst.PrettyPrint();
case SpvOpImageQueryLevels: // TODO(dneto) case SpvOpImageQueryLevels: {
auto* levels_ident = create<ast::IdentifierExpression>(
Source{}, builder_.Symbols().Register("textureNumLevels"));
ast::Expression* ast_expr = create<ast::CallExpression>(
Source{}, levels_ident,
ast::ExpressionList{GetImageExpression(inst)});
auto* result_type = parser_impl_.ConvertType(inst.type_id());
// The SPIR-V result type must be integer scalar. The WGSL bulitin
// returns i32. If they aren't the same then convert the result.
if (result_type != i32_) {
ast_expr = create<ast::TypeConstructorExpression>(
Source{}, result_type, ast::ExpressionList{ast_expr});
}
TypedExpression expr{result_type, ast_expr};
return EmitConstDefOrWriteToHoistedVar(inst, expr);
}
case SpvOpImageQuerySamples: // TODO(dneto) case SpvOpImageQuerySamples: // TODO(dneto)
default: default:
break; break;

View File

@ -4406,6 +4406,293 @@ INSTANTIATE_TEST_SUITE_P(
} }
})"}})); })"}}));
INSTANTIATE_TEST_SUITE_P(
ImageQueryLevels_SignedResult,
SpvParserTest_SampledImageAccessTest,
::testing::ValuesIn(std::vector<ImageAccessCase>{
// In Vulkan:
// Dim must be 1D, 2D, 3D, Cube
// WGSL allows 2d, 2d_array, 3d, cube, cube_array
// depth_2d, depth_2d_array, depth_cube, depth_cube_array
// 2D
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_2d__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// 2D array
{"%float 2D 0 1 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_2d_array__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// 3D
{"%float 3D 0 0 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_3d__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// Cube
{"%float Cube 0 0 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_cube__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// Cube array
{"%float Cube 0 1 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_cube_array__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// depth 2d
{"%float 2D 1 0 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__depth_texture_2d
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// depth 2d array
{"%float 2D 1 1 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__depth_texture_2d_array
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// depth cube
{"%float Cube 1 0 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__depth_texture_cube
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"},
// depth cube array
{"%float Cube 1 1 0 1 Unknown", "%99 = OpImageQueryLevels %int %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__depth_texture_cube_array
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__i32
{
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
})"}}));
INSTANTIATE_TEST_SUITE_P(
// Spot check that a type conversion is inserted when SPIR-V asks for
// an unsigned int result.
ImageQueryLevels_UnsignedResult,
SpvParserTest_SampledImageAccessTest,
::testing::ValuesIn(std::vector<ImageAccessCase>{
{"%float 2D 0 0 0 1 Unknown", "%99 = OpImageQueryLevels %uint %im\n",
R"(Variable{
Decorations{
GroupDecoration{2}
BindingDecoration{1}
}
x_20
uniform_constant
__sampled_texture_2d__f32
})",
R"(VariableDeclStatement{
VariableConst{
x_99
none
__u32
{
TypeConstructor[not set]{
__u32
Call[not set]{
Identifier[not set]{textureNumLevels}
(
Identifier[not set]{x_20}
)
}
}
}
}
})"}}));
struct ImageCoordsCase { struct ImageCoordsCase {
// SPIR-V image type, excluding result ID and opcode // SPIR-V image type, excluding result ID and opcode
std::string spirv_image_type_details; std::string spirv_image_type_details;