spirv-reader: add conversions for image Dim and Format

Change-Id: I9ad499aaa4683ce9a3ed702f21babaf24a15a8e8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32741
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
David Neto 2020-11-16 16:44:17 +00:00 committed by Commit Bot service account
parent 4bfe461646
commit df2d92d5bb
3 changed files with 304 additions and 0 deletions

View File

@ -94,6 +94,87 @@ ast::Builtin EnumConverter::ToBuiltin(SpvBuiltIn b) {
return ast::Builtin::kNone; return ast::Builtin::kNone;
} }
ast::type::TextureDimension EnumConverter::ToDim(SpvDim dim, bool arrayed) {
if (arrayed) {
switch (dim) {
case SpvDim1D:
return ast::type::TextureDimension::k1dArray;
case SpvDim2D:
return ast::type::TextureDimension::k2dArray;
case SpvDimCube:
return ast::type::TextureDimension::kCubeArray;
default:
break;
}
Fail() << "arrayed dimension must be 1D, 2D, or Cube. Got " << int(dim);
return ast::type::TextureDimension::kNone;
}
// Assume non-arrayed
switch (dim) {
case SpvDim1D:
return ast::type::TextureDimension::k1d;
case SpvDim2D:
return ast::type::TextureDimension::k2d;
case SpvDim3D:
return ast::type::TextureDimension::k3d;
case SpvDimCube:
return ast::type::TextureDimension::kCube;
default:
break;
}
Fail() << "invalid dimension: " << int(dim);
return ast::type::TextureDimension::kNone;
}
ast::type::ImageFormat EnumConverter::ToImageFormat(SpvImageFormat fmt) {
switch (fmt) {
case SpvImageFormatUnknown:
return ast::type::ImageFormat::kNone;
// 8 bit channels
case SpvImageFormatRgba8:
return ast::type::ImageFormat::kRgba8Unorm;
case SpvImageFormatRgba8Snorm:
return ast::type::ImageFormat::kRgba8Snorm;
case SpvImageFormatRgba8ui:
return ast::type::ImageFormat::kRgba8Uint;
case SpvImageFormatRgba8i:
return ast::type::ImageFormat::kRgba8Sint;
// 16 bit channels
case SpvImageFormatRgba16ui:
return ast::type::ImageFormat::kRgba16Uint;
case SpvImageFormatRgba16i:
return ast::type::ImageFormat::kRgba16Sint;
case SpvImageFormatRgba16f:
return ast::type::ImageFormat::kRgba16Float;
// 32 bit channels
case SpvImageFormatR32ui:
return ast::type::ImageFormat::kR32Uint;
case SpvImageFormatR32i:
return ast::type::ImageFormat::kR32Sint;
case SpvImageFormatR32f:
return ast::type::ImageFormat::kR32Float;
case SpvImageFormatRg32ui:
return ast::type::ImageFormat::kRg32Uint;
case SpvImageFormatRg32i:
return ast::type::ImageFormat::kRg32Sint;
case SpvImageFormatRg32f:
return ast::type::ImageFormat::kRg32Float;
case SpvImageFormatRgba32ui:
return ast::type::ImageFormat::kRgba32Uint;
case SpvImageFormatRgba32i:
return ast::type::ImageFormat::kRgba32Sint;
case SpvImageFormatRgba32f:
return ast::type::ImageFormat::kRgba32Float;
default:
break;
}
Fail() << "invalid image format: " << int(fmt);
return ast::type::ImageFormat::kNone;
}
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader
} // namespace tint } // namespace tint

View File

@ -19,6 +19,8 @@
#include "src/ast/builtin.h" #include "src/ast/builtin.h"
#include "src/ast/pipeline_stage.h" #include "src/ast/pipeline_stage.h"
#include "src/ast/storage_class.h" #include "src/ast/storage_class.h"
#include "src/ast/type/storage_texture_type.h"
#include "src/ast/type/texture_type.h"
#include "src/reader/spirv/fail_stream.h" #include "src/reader/spirv/fail_stream.h"
namespace tint { namespace tint {
@ -52,6 +54,19 @@ class EnumConverter {
/// @returns a Tint AST builtin /// @returns a Tint AST builtin
ast::Builtin ToBuiltin(SpvBuiltIn b); ast::Builtin ToBuiltin(SpvBuiltIn b);
/// Converts a possibly arrayed SPIR-V Dim to a Tint texture dimension.
/// On failure, logs an error and returns kNone
/// @param dim the SPIR-V Dim value
/// @param arrayed true if the texture is arrayed
/// @returns a Tint AST texture dimension
ast::type::TextureDimension ToDim(SpvDim dim, bool arrayed);
/// Converts a SPIR-V Image Format to a Tint ImageFormat
/// On failure, logs an error and returns kNone
/// @param fmt the SPIR-V format
/// @returns a Tint AST format
ast::type::ImageFormat ToImageFormat(SpvImageFormat fmt);
private: private:
/// Registers a failure and returns a stream for log diagnostics. /// Registers a failure and returns a stream for log diagnostics.
/// @returns a failure stream /// @returns a failure stream

View File

@ -229,6 +229,214 @@ INSTANTIATE_TEST_SUITE_P(
BuiltinCase{static_cast<SpvBuiltIn>(9999), false, ast::Builtin::kNone}, BuiltinCase{static_cast<SpvBuiltIn>(9999), false, ast::Builtin::kNone},
BuiltinCase{SpvBuiltInNumWorkgroups, false, ast::Builtin::kNone})); BuiltinCase{SpvBuiltInNumWorkgroups, false, ast::Builtin::kNone}));
// Dim
struct DimCase {
SpvDim dim;
bool arrayed;
bool expect_success;
ast::type::TextureDimension expected;
};
inline std::ostream& operator<<(std::ostream& out, DimCase dc) {
out << "DimCase{ SpvDim:" << int(dc.dim) << " arrayed?:" << int(dc.arrayed)
<< " expect_success?:" << int(dc.expect_success)
<< " expected:" << int(dc.expected) << "}";
return out;
}
class SpvDimTest : public testing::TestWithParam<DimCase> {
public:
SpvDimTest()
: success_(true),
fail_stream_(&success_, &errors_),
converter_(fail_stream_) {}
std::string error() const { return errors_.str(); }
protected:
bool success_ = true;
std::stringstream errors_;
FailStream fail_stream_;
EnumConverter converter_;
};
TEST_P(SpvDimTest, Samples) {
const auto params = GetParam();
const auto result = converter_.ToDim(params.dim, params.arrayed);
EXPECT_EQ(success_, params.expect_success);
if (params.expect_success) {
EXPECT_EQ(result, params.expected);
EXPECT_TRUE(error().empty());
} else {
EXPECT_EQ(result, params.expected);
EXPECT_THAT(error(), ::testing::HasSubstr("dimension"));
}
}
INSTANTIATE_TEST_SUITE_P(
EnumConverterGood,
SpvDimTest,
testing::Values(
// Non-arrayed
DimCase{SpvDim1D, false, true, ast::type::TextureDimension::k1d},
DimCase{SpvDim2D, false, true, ast::type::TextureDimension::k2d},
DimCase{SpvDim3D, false, true, ast::type::TextureDimension::k3d},
DimCase{SpvDimCube, false, true, ast::type::TextureDimension::kCube},
// Arrayed
DimCase{SpvDim1D, true, true, ast::type::TextureDimension::k1dArray},
DimCase{SpvDim2D, true, true, ast::type::TextureDimension::k2dArray},
DimCase{SpvDimCube, true, true,
ast::type::TextureDimension::kCubeArray}));
INSTANTIATE_TEST_SUITE_P(
EnumConverterBad,
SpvDimTest,
testing::Values(
// Invalid SPIR-V dimensionality.
DimCase{SpvDimMax, false, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimMax, true, false, ast::type::TextureDimension::kNone},
// Vulkan non-arrayed dimensionalities not supported by WGSL.
DimCase{SpvDimRect, false, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimBuffer, false, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimSubpassData, false, false,
ast::type::TextureDimension::kNone},
// Arrayed dimensionalities not supported by WGSL
DimCase{SpvDim3D, true, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimRect, true, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimBuffer, true, false, ast::type::TextureDimension::kNone},
DimCase{SpvDimSubpassData, true, false,
ast::type::TextureDimension::kNone}));
// ImageFormat
struct ImageFormatCase {
SpvImageFormat format;
bool expect_success;
ast::type::ImageFormat expected;
};
inline std::ostream& operator<<(std::ostream& out, ImageFormatCase ifc) {
out << "ImageFormatCase{ SpvImageFormat:" << int(ifc.format)
<< " expect_success?:" << int(ifc.expect_success)
<< " expected:" << int(ifc.expected) << "}";
return out;
}
class SpvImageFormatTest : public testing::TestWithParam<ImageFormatCase> {
public:
SpvImageFormatTest()
: success_(true),
fail_stream_(&success_, &errors_),
converter_(fail_stream_) {}
std::string error() const { return errors_.str(); }
protected:
bool success_ = true;
std::stringstream errors_;
FailStream fail_stream_;
EnumConverter converter_;
};
TEST_P(SpvImageFormatTest, Samples) {
const auto params = GetParam();
const auto result = converter_.ToImageFormat(params.format);
EXPECT_EQ(success_, params.expect_success) << params;
if (params.expect_success) {
EXPECT_EQ(result, params.expected);
EXPECT_TRUE(error().empty());
} else {
EXPECT_EQ(result, params.expected);
EXPECT_THAT(error(), ::testing::StartsWith("invalid image format: "));
}
}
INSTANTIATE_TEST_SUITE_P(
EnumConverterGood,
SpvImageFormatTest,
testing::Values(
// Unknown. This is used for sampled images.
ImageFormatCase{SpvImageFormatUnknown, true,
ast::type::ImageFormat::kNone},
// 8 bit channels
ImageFormatCase{SpvImageFormatRgba8, true,
ast::type::ImageFormat::kRgba8Unorm},
ImageFormatCase{SpvImageFormatRgba8Snorm, true,
ast::type::ImageFormat::kRgba8Snorm},
ImageFormatCase{SpvImageFormatRgba8ui, true,
ast::type::ImageFormat::kRgba8Uint},
ImageFormatCase{SpvImageFormatRgba8i, true,
ast::type::ImageFormat::kRgba8Sint},
// 16 bit channels
ImageFormatCase{SpvImageFormatRgba16ui, true,
ast::type::ImageFormat::kRgba16Uint},
ImageFormatCase{SpvImageFormatRgba16i, true,
ast::type::ImageFormat::kRgba16Sint},
ImageFormatCase{SpvImageFormatRgba16f, true,
ast::type::ImageFormat::kRgba16Float},
// 32 bit channels
// ... 1 channel
ImageFormatCase{SpvImageFormatR32ui, true,
ast::type::ImageFormat::kR32Uint},
ImageFormatCase{SpvImageFormatR32i, true,
ast::type::ImageFormat::kR32Sint},
ImageFormatCase{SpvImageFormatR32f, true,
ast::type::ImageFormat::kR32Float},
// ... 2 channels
ImageFormatCase{SpvImageFormatRg32ui, true,
ast::type::ImageFormat::kRg32Uint},
ImageFormatCase{SpvImageFormatRg32i, true,
ast::type::ImageFormat::kRg32Sint},
ImageFormatCase{SpvImageFormatRg32f, true,
ast::type::ImageFormat::kRg32Float},
// ... 4 channels
ImageFormatCase{SpvImageFormatRgba32ui, true,
ast::type::ImageFormat::kRgba32Uint},
ImageFormatCase{SpvImageFormatRgba32i, true,
ast::type::ImageFormat::kRgba32Sint},
ImageFormatCase{SpvImageFormatRgba32f, true,
ast::type::ImageFormat::kRgba32Float}));
INSTANTIATE_TEST_SUITE_P(EnumConverterBad,
SpvImageFormatTest,
testing::Values(
// Scanning in order from the SPIR-V spec.
ImageFormatCase{SpvImageFormatRg16f, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatR11fG11fB10f, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatR16f, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRgb10A2, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg16, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg8, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatR16, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatR8, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRgba16Snorm, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg16Snorm, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg8Snorm, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg16i, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg8i, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatR8i, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRgb10a2ui, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg16ui, false,
ast::type::ImageFormat::kNone},
ImageFormatCase{SpvImageFormatRg8ui, false,
ast::type::ImageFormat::kNone}));
} // namespace } // namespace
} // namespace spirv } // namespace spirv
} // namespace reader } // namespace reader