spirv-reader: support OpImageQuerySize
Change-Id: I27ad580ae84f18a69b31700f56bbbcf59d3818e6 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/39680 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: David Neto <dneto@google.com> Auto-Submit: David Neto <dneto@google.com>
This commit is contained in:
parent
4cec1429d7
commit
7ecf92a53c
|
@ -524,6 +524,18 @@ bool IsRawImageAccess(SpvOp opcode) {
|
||||||
case SpvOpImageRead:
|
case SpvOpImageRead:
|
||||||
case SpvOpImageWrite:
|
case SpvOpImageWrite:
|
||||||
case SpvOpImageFetch:
|
case SpvOpImageFetch:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @param opcode a SPIR-V opcode
|
||||||
|
// @returns true if the given instruction is an image query instruction
|
||||||
|
bool IsImageQuery(SpvOp opcode) {
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpImageQuerySize:
|
||||||
case SpvOpImageQuerySizeLod:
|
case SpvOpImageQuerySizeLod:
|
||||||
case SpvOpImageQueryLevels:
|
case SpvOpImageQueryLevels:
|
||||||
case SpvOpImageQuerySamples:
|
case SpvOpImageQuerySamples:
|
||||||
|
@ -2937,6 +2949,10 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
return EmitImageAccess(inst);
|
return EmitImageAccess(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsImageQuery(inst.opcode())) {
|
||||||
|
return EmitImageQuery(inst);
|
||||||
|
}
|
||||||
|
|
||||||
switch (inst.opcode()) {
|
switch (inst.opcode()) {
|
||||||
case SpvOpNop:
|
case SpvOpNop:
|
||||||
return true;
|
return true;
|
||||||
|
@ -4349,6 +4365,48 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FunctionEmitter::EmitImageQuery(const spvtools::opt::Instruction& inst) {
|
||||||
|
const spvtools::opt::Instruction* image = GetImage(inst);
|
||||||
|
if (!image) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto* texture_type = GetImageType(*image);
|
||||||
|
if (!texture_type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto opcode = inst.opcode();
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpImageQuerySize: {
|
||||||
|
ast::ExpressionList exprs;
|
||||||
|
// Invoke textureDimensions.
|
||||||
|
// If the texture is arrayed, combine with the result from
|
||||||
|
// textureNumLayers.
|
||||||
|
auto* dims_ident = create<ast::IdentifierExpression>(
|
||||||
|
Source{}, builder_.Symbols().Register("textureDimensions"));
|
||||||
|
exprs.push_back(create<ast::CallExpression>(
|
||||||
|
Source{}, dims_ident, ast::ExpressionList{GetImageExpression(inst)}));
|
||||||
|
if (type::IsTextureArray(texture_type->dim())) {
|
||||||
|
auto* layers_ident = create<ast::IdentifierExpression>(
|
||||||
|
Source{}, builder_.Symbols().Register("textureNumLayers"));
|
||||||
|
exprs.push_back(create<ast::CallExpression>(
|
||||||
|
Source{}, layers_ident, ast::ExpressionList{GetImageExpression(inst)}));
|
||||||
|
}
|
||||||
|
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
|
TypedExpression expr = {
|
||||||
|
result_type,
|
||||||
|
create<ast::TypeConstructorExpression>(Source{}, result_type, exprs)};
|
||||||
|
return EmitConstDefOrWriteToHoistedVar(inst, expr);
|
||||||
|
}
|
||||||
|
case SpvOpImageQuerySizeLod: // TODO(dneto)
|
||||||
|
case SpvOpImageQueryLevels: // TODO(dneto)
|
||||||
|
case SpvOpImageQuerySamples: // TODO(dneto)
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Fail() << "unhandled image query: " << inst.PrettyPrint();
|
||||||
|
}
|
||||||
|
|
||||||
ast::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
|
ast::ExpressionList FunctionEmitter::MakeCoordinateOperandsForImageAccess(
|
||||||
const spvtools::opt::Instruction& inst) {
|
const spvtools::opt::Instruction& inst) {
|
||||||
if (!parser_impl_.success()) {
|
if (!parser_impl_.success()) {
|
||||||
|
|
|
@ -897,6 +897,11 @@ class FunctionEmitter {
|
||||||
/// @returns an expression
|
/// @returns an expression
|
||||||
bool EmitImageAccess(const spvtools::opt::Instruction& inst);
|
bool EmitImageAccess(const spvtools::opt::Instruction& inst);
|
||||||
|
|
||||||
|
/// Emits statements to implement a SPIR-V image query.
|
||||||
|
/// @param inst the SPIR-V instruction
|
||||||
|
/// @returns an expression
|
||||||
|
bool EmitImageQuery(const spvtools::opt::Instruction& inst);
|
||||||
|
|
||||||
/// Converts the given texel to match the type required for the storage
|
/// Converts the given texel to match the type required for the storage
|
||||||
/// texture with the given type. This can generate a swizzle to retain
|
/// texture with the given type. This can generate a swizzle to retain
|
||||||
/// only the first few components of the texel vector, and maybe a bitcast
|
/// only the first few components of the texel vector, and maybe a bitcast
|
||||||
|
|
|
@ -3670,6 +3670,260 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
}
|
}
|
||||||
})"}}));
|
})"}}));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
ImageQuerySize_NonArrayed_SignedResult,
|
||||||
|
// ImageQuerySize requires storage image or multisampled
|
||||||
|
// For storage image, use another instruction to indicate whether it
|
||||||
|
// is readonly or writeonly.
|
||||||
|
SpvParserTest_SampledImageAccessTest,
|
||||||
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
|
// 1D storage image
|
||||||
|
{"%float 1D 0 0 0 2 Rgba32f",
|
||||||
|
"%99 = OpImageQuerySize %int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %i1\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__access_control_read_only__storage_texture_1d_rgba32float
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"},
|
||||||
|
// 2D storage image
|
||||||
|
{"%float 2D 0 0 0 2 Rgba32f",
|
||||||
|
"%99 = OpImageQuerySize %v2int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi12\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__access_control_read_only__storage_texture_2d_rgba32float
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"},
|
||||||
|
// 3D storage image
|
||||||
|
{"%float 3D 0 0 0 2 Rgba32f",
|
||||||
|
"%99 = OpImageQuerySize %v3int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi123\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__access_control_read_only__storage_texture_3d_rgba32float
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_3__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_3__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"},
|
||||||
|
|
||||||
|
// Multisampled
|
||||||
|
{"%float 2D 0 0 1 1 Unknown",
|
||||||
|
"%99 = OpImageQuerySize %v2int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi12\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__multisampled_texture_2d__f32
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"}}));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
ImageQuerySize_Arrayed_SignedResult,
|
||||||
|
// ImageQuerySize requires storage image or multisampled
|
||||||
|
// For storage image, use another instruction to indicate whether it
|
||||||
|
// is readonly or writeonly.
|
||||||
|
SpvParserTest_SampledImageAccessTest,
|
||||||
|
::testing::ValuesIn(std::vector<ImageAccessCase>{
|
||||||
|
// 1D array storage image
|
||||||
|
{"%float 1D 0 1 0 2 Rgba32f",
|
||||||
|
"%99 = OpImageQuerySize %v2int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi12\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__access_control_read_only__storage_texture_1d_array_rgba32float
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureNumLayers}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"},
|
||||||
|
// 2D array storage image
|
||||||
|
{"%float 2D 0 1 0 2 Rgba32f",
|
||||||
|
"%99 = OpImageQuerySize %v3int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi123\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__access_control_read_only__storage_texture_2d_array_rgba32float
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_3__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_3__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureNumLayers}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"},
|
||||||
|
// 3D array storage image doesn't exist.
|
||||||
|
|
||||||
|
// Multisampled array
|
||||||
|
{"%float 2D 0 1 1 1 Unknown",
|
||||||
|
"%99 = OpImageQuerySize %v3int %im \n"
|
||||||
|
"%98 = OpImageRead %v4float %im %vi123\n",
|
||||||
|
R"(Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
uniform_constant
|
||||||
|
__multisampled_texture_2d_array__f32
|
||||||
|
})",
|
||||||
|
R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_99
|
||||||
|
none
|
||||||
|
__vec_3__i32
|
||||||
|
{
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_3__i32
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureDimensions}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureNumLayers}
|
||||||
|
(
|
||||||
|
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;
|
||||||
|
|
Loading…
Reference in New Issue