spirv-reader: handle tests, valid SPIR-V, part 5
Bug: tint:765
Change-Id: I77772e8105da9d52baa996919a39dc7a85dbedcd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50460
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: Alan Baker <alanbaker@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 778d1d9..62ce771 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -4811,7 +4811,7 @@
if (!image) {
return {};
}
- if (image->NumInOperands() < 1) {
+ if (inst.NumInOperands() < 1) {
Fail() << "image access is missing a coordinate parameter: "
<< inst.PrettyPrint();
return {};
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index d3f05af..2052a7a 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -317,6 +317,9 @@
ASSERT_TRUE(image != nullptr);
EXPECT_EQ(image->result_id(), 20u);
+
+ // WGSL does not support arrays of textures and samplers.
+ p->DeliberatelyInvalidSpirv();
}
TEST_F(SpvParserHandleTest,
@@ -353,6 +356,9 @@
ASSERT_TRUE(image != nullptr);
EXPECT_EQ(image->result_id(), 20u);
+
+ // WGSL does not support arrays of textures and samplers.
+ p->DeliberatelyInvalidSpirv();
}
TEST_F(SpvParserHandleTest,
@@ -545,7 +551,7 @@
%s = OpLoad %sampler %10
%im = OpLoad %f_texture_1d %20
%100 = OpSampledImage %sampled_image_type %im %s
- %200 = OpImage %im %100
+ %200 = OpImage %f_texture_1d %100
OpReturn
OpFunctionEnd
@@ -619,6 +625,9 @@
ASSERT_TRUE(image != nullptr);
EXPECT_EQ(image->result_id(), 20u);
+
+ // WGSL does not support arrays of textures or samplers
+ p->DeliberatelyInvalidSpirv();
}
TEST_F(SpvParserHandleTest,
@@ -654,6 +663,9 @@
ASSERT_TRUE(image != nullptr);
EXPECT_EQ(image->result_id(), 20u);
+
+ // WGSL does not support arrays of textures or samplers
+ p->DeliberatelyInvalidSpirv();
}
TEST_F(SpvParserHandleTest,
@@ -841,7 +853,7 @@
%s = OpLoad %sampler %10
%im = OpLoad %f_texture_1d %20
%100 = OpSampledImage %sampled_image_type %im %s
- %200 = OpImage %im %100
+ %200 = OpImage %f_texture_1d %100
OpReturn
OpFunctionEnd
@@ -873,6 +885,7 @@
SpvParserTestBase<::testing::TestWithParam<UsageImageAccessCase>>;
TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, Variable) {
+ const std::string inst = GetParam().inst;
const auto assembly = Preamble() + FragMain() + Bindings({10, 20}) +
CommonTypes() + R"(
%si_ty = OpTypeSampledImage %f_texture_2d
@@ -902,9 +915,31 @@
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
+
+ if (inst.find("Gather") != std::string::npos) {
+ // WGSL does not support Gather instructions yet.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ if (inst.find("Proj") != std::string::npos) {
+ // WGSL does not support Projection variants of image sampling.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ if (inst.find("ImageQueryLod") != std::string::npos) {
+ // WGSL does not support querying image level of detail.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ if (inst.find("ImageSampleDrefExplicitLod") != std::string::npos) {
+ // WGSL does not support querying image level of detail.
+ // So don't emit them as part of a "passing" corpus.
+ p->SkipDumpingPending("crbug.com/tint/425"); // gpuweb issue #1319
+ }
}
TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, FunctionParam) {
+ const std::string inst = GetParam().inst;
const auto assembly = Preamble() + FragMain() + Bindings({10, 20}) +
CommonTypes() + R"(
%f_ty = OpTypeFunction %void %ptr_sampler %ptr_f_texture_2d
@@ -924,7 +959,7 @@
%im = OpLoad %f_texture_2d %120
%sampled_image = OpSampledImage %si_ty %im %sam
-)" + GetParam().inst + R"(
+)" + inst + R"(
OpReturn
OpFunctionEnd
@@ -944,6 +979,23 @@
EXPECT_THAT(su.to_str(), Eq(GetParam().expected_sampler_usage));
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
+
+ if (inst.find("Gather") != std::string::npos) {
+ // WGSL does not support Gather instructions yet.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ if (inst.find("Proj") != std::string::npos) {
+ // WGSL does not support Projection variants of image sampling.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ if (inst.find("ImageQueryLod") != std::string::npos) {
+ // WGSL does not support querying image level of detail.
+ // So don't emit them as part of a "passing" corpus.
+ p->DeliberatelyInvalidSpirv();
+ }
+ p->SkipDumpingPending("crbug.com/tint/785");
}
INSTANTIATE_TEST_SUITE_P(
@@ -951,8 +1003,18 @@
SpvParserHandleTest_RegisterHandleUsage_SampledImage,
::testing::Values(
- // TODO(dneto): OpImageGather
- // TODO(dneto): OpImageDrefGather
+ // Test image gather even though WGSL doesn't support it yet.
+
+ // OpImageGather
+ UsageImageAccessCase{"%result = OpImageGather "
+ "%v4float %sampled_image %coords %uint_1",
+ "Usage(Sampler( ))",
+ "Usage(Texture( is_sampled ))"},
+ // OpImageDrefGather
+ UsageImageAccessCase{"%result = OpImageDrefGather "
+ "%v4float %sampled_image %coords %depth",
+ "Usage(Sampler( comparison ))",
+ "Usage(Texture( is_sampled depth ))"},
// Sample the texture.
@@ -1027,8 +1089,14 @@
SpvParserTestBase<::testing::TestWithParam<UsageRawImageCase>>;
TEST_P(SpvParserHandleTest_RegisterHandleUsage_RawImage, Variable) {
+ const bool is_storage = GetParam().type.find("storage") != std::string::npos;
+ const bool is_write = GetParam().inst.find("ImageWrite") != std::string::npos;
const auto assembly = Preamble() + FragMain() + Bindings({20}) +
- CommonTypes() + R"(
+ (is_storage ? std::string("OpDecorate %20 ") +
+ std::string(is_write ? "NonReadable"
+ : "NonWritable")
+ : std::string("")) +
+ " " + CommonTypes() + R"(
%20 = OpVariable %ptr_)" +
GetParam().type + R"( UniformConstant
@@ -1054,8 +1122,14 @@
}
TEST_P(SpvParserHandleTest_RegisterHandleUsage_RawImage, FunctionParam) {
+ const bool is_storage = GetParam().type.find("storage") != std::string::npos;
+ const bool is_write = GetParam().inst.find("ImageWrite") != std::string::npos;
const auto assembly = Preamble() + FragMain() + Bindings({20}) +
- CommonTypes() + R"(
+ (is_storage ? std::string("OpDecorate %20 ") +
+ std::string(is_write ? "NonReadable"
+ : "NonWritable")
+ : std::string("")) +
+ " " + CommonTypes() + R"(
%f_ty = OpTypeFunction %void %ptr_)" +
GetParam().type + R"(
@@ -1087,6 +1161,9 @@
Usage iu = p->GetHandleUsage(20);
EXPECT_THAT(iu.to_str(), Eq(GetParam().expected_image_usage));
+
+ // Textures and samplers not yet supported as function parameters.
+ p->SkipDumpingPending("crbug.com/tint/785");
}
INSTANTIATE_TEST_SUITE_P(
@@ -1113,7 +1190,7 @@
// Image queries
// OpImageQuerySizeLod
- UsageRawImageCase{"f_storage_2d",
+ UsageRawImageCase{"f_texture_2d",
"%result = OpImageQuerySizeLod "
"%v2uint %im %uint_1",
"Usage(Texture( is_sampled ))"},
@@ -1510,6 +1587,19 @@
<< "DECLARATIONS ARE BAD " << program;
EXPECT_THAT(program, HasSubstr(GetParam().texture_builtin))
<< "TEXTURE BUILTIN IS BAD " << program << assembly;
+
+ const bool is_query_size =
+ GetParam().spirv_image_access.find("ImageQuerySize") != std::string::npos;
+ const bool is_1d =
+ GetParam().spirv_image_type_details.find("1D") != std::string::npos;
+ const bool is_cube =
+ GetParam().spirv_image_type_details.find("Cube") != std::string::npos;
+ if (is_query_size && is_cube) {
+ p->SkipDumpingPending("crbug.com/tint/787");
+ }
+ if (is_query_size && is_1d) {
+ p->SkipDumpingPending("crbug.com/tint/788");
+ }
}
// TODO(dneto): Test variable declaration and texture builtins provoked by
@@ -3865,7 +3955,8 @@
// 1D storage image
{"%float 1D 0 0 0 2 Rgba32f",
"%99 = OpImageQuerySize %int %im \n"
- "%98 = OpImageRead %v4float %im %i1\n",
+ "%98 = OpImageRead %v4float %im %i1\n", // Implicitly mark as
+ // NonWritable
R"(Variable{
Decorations{
GroupDecoration{2}
@@ -3896,7 +3987,8 @@
// 2D storage image
{"%float 2D 0 0 0 2 Rgba32f",
"%99 = OpImageQuerySize %v2int %im \n"
- "%98 = OpImageRead %v4float %im %vi12\n",
+ "%98 = OpImageRead %v4float %im %vi12\n", // Implicitly mark as
+ // NonWritable
R"(Variable{
Decorations{
GroupDecoration{2}
@@ -3927,7 +4019,8 @@
// 3D storage image
{"%float 3D 0 0 0 2 Rgba32f",
"%99 = OpImageQuerySize %v3int %im \n"
- "%98 = OpImageRead %v4float %im %vi123\n",
+ "%98 = OpImageRead %v4float %im %vi123\n", // Implicitly mark as
+ // NonWritable
R"(Variable{
Decorations{
GroupDecoration{2}
@@ -3957,9 +4050,7 @@
})"},
// Multisampled
- {"%float 2D 0 0 1 1 Unknown",
- "%99 = OpImageQuerySize %v2int %im \n"
- "%98 = OpImageRead %v4float %im %vi12\n",
+ {"%float 2D 0 0 1 1 Unknown", "%99 = OpImageQuerySize %v2int %im \n",
R"(Variable{
Decorations{
GroupDecoration{2}
@@ -4992,6 +5083,21 @@
EXPECT_TRUE(result.empty());
}
}
+
+ const bool is_sample_level =
+ GetParam().spirv_image_access.find("ImageSampleExplicitLod") !=
+ std::string::npos;
+ const bool is_comparison_sample_level =
+ GetParam().spirv_image_access.find("ImageSampleDrefExplicitLod") !=
+ std::string::npos;
+ const bool is_1d =
+ GetParam().spirv_image_type_details.find("1D") != std::string::npos;
+ if (is_sample_level && is_1d) {
+ p->SkipDumpingPending("crbug.com/tint/789");
+ }
+ if (is_comparison_sample_level) {
+ p->SkipDumpingPending("crbug.com/tint/425");
+ }
}
INSTANTIATE_TEST_SUITE_P(Good_1D,
@@ -5348,28 +5454,28 @@
::testing::ValuesIn(std::vector<ImageCoordsCase>{
// Scalar cases
{"%float 1D 0 0 0 1 Unknown",
- "%result = OpImageFetch %float %im %i1",
+ "%result = OpImageFetch %v4float %im %i1",
"",
{"Identifier[not set]{i1}\n"}},
{"%float 1D 0 0 0 2 R32f",
- "%result = OpImageRead %float %im %i1",
+ "%result = OpImageRead %v4float %im %i1",
"",
{"Identifier[not set]{i1}\n"}},
{"%float 1D 0 0 0 2 R32f",
- "OpImageWrite %im %i1 %float_1",
+ "OpImageWrite %im %i1 %vf1234",
"",
{"Identifier[not set]{i1}\n"}},
// Vector cases
{"%float 2D 0 0 0 1 Unknown",
- "%result = OpImageFetch %float %im %vi12",
+ "%result = OpImageFetch %v4float %im %vi12",
"",
{"Identifier[not set]{vi12}\n"}},
{"%float 2D 0 0 0 2 R32f",
- "%result = OpImageRead %float %im %vi12",
+ "%result = OpImageRead %v4float %im %vi12",
"",
{"Identifier[not set]{vi12}\n"}},
{"%float 2D 0 0 0 2 R32f",
- "OpImageWrite %im %vi12 %float_1",
+ "OpImageWrite %im %vi12 %vf1234",
"",
{"Identifier[not set]{vi12}\n"}}}));
@@ -5380,7 +5486,7 @@
SpvParserHandleTest_ImageCoordsTest,
::testing::ValuesIn(std::vector<ImageCoordsCase>{
{"%float 2D 0 1 0 1 Unknown",
- "%result = OpImageFetch %float %im %vi123",
+ "%result = OpImageFetch %v4float %im %vi123",
"",
{
R"(MemberAccessor[not set]{
@@ -5394,7 +5500,7 @@
}
)"}},
{"%float 2D 0 1 0 2 R32f",
- "%result = OpImageRead %float %im %vi123",
+ "%result = OpImageRead %v4float %im %vi123",
"",
{
R"(MemberAccessor[not set]{
@@ -5408,7 +5514,7 @@
}
)"}},
{"%float 2D 0 1 0 2 R32f",
- "OpImageWrite %im %vi123 %float_1",
+ "OpImageWrite %im %vi123 %vf1234",
"",
{
R"(MemberAccessor[not set]{
diff --git a/src/reader/spirv/parser_impl_test_helper.cc b/src/reader/spirv/parser_impl_test_helper.cc
index 158ecfd..234c869 100644
--- a/src/reader/spirv/parser_impl_test_helper.cc
+++ b/src/reader/spirv/parser_impl_test_helper.cc
@@ -27,7 +27,7 @@
: impl_(input) {}
ParserImplWrapperForTest::~ParserImplWrapperForTest() {
- if (dump_successfully_converted_spirv_ && !deliberately_invalid_spirv_ &&
+ if (dump_successfully_converted_spirv_ && !skip_dumping_spirv_ &&
!impl_.spv_binary().empty() && impl_.success()) {
std::string disassembly = Disassemble(impl_.spv_binary());
std::cout << "BEGIN ConvertedOk:\n"
diff --git a/src/reader/spirv/parser_impl_test_helper.h b/src/reader/spirv/parser_impl_test_helper.h
index dd83ca6..ff0e7c0 100644
--- a/src/reader/spirv/parser_impl_test_helper.h
+++ b/src/reader/spirv/parser_impl_test_helper.h
@@ -51,7 +51,10 @@
dump_successfully_converted_spirv_ = true;
}
/// Marks the test has having deliberately invalid SPIR-V
- void DeliberatelyInvalidSpirv() { deliberately_invalid_spirv_ = true; }
+ void DeliberatelyInvalidSpirv() { skip_dumping_spirv_ = true; }
+ /// Marks the test's SPIR-V as not being suitable for dumping, for a stated
+ /// reason.
+ void SkipDumpingPending(std::string) { skip_dumping_spirv_ = true; }
/// @returns a new function emitter for the given function ID.
/// Assumes ParserImpl::BuildInternalRepresentation has been run and
@@ -256,10 +259,10 @@
private:
ParserImpl impl_;
- /// When true, indicates the input SPIR-V module is expected to fail
- /// validation, but the SPIR-V reader parser is permissive and lets it
- /// through.
- bool deliberately_invalid_spirv_ = false;
+ /// When true, indicates the input SPIR-V module should not be emitted.
+ /// It's either deliberately invalid, or not supported for some pending
+ /// reason.
+ bool skip_dumping_spirv_ = false;
static bool dump_successfully_converted_spirv_;
};