Add --dump-spirv option to tint_unittests

The --dump-spirv option tells tint_unittests to output the
SPIR-V assembly text for a module which did not make the SPIR-V reader
fail.  This lets us get extract a corpus of SPIR-V modules, and
lets us more easily verify that the test shaders are valid in the first
place.

Also:
- Add test/extract-spvasm.py to split that output to separate SPIR-V
  assembly files
- Add optional second argument test/test-all.sh to specify a directory
  look for input files.
- BUILD.gn:  Add dependency from //test:tint_unittests_main to
  //test:tint_unittests_config to pick up source dependency on
  the internal header of the SPIRV-Tools optimizer, needed by
  the indirection through src/reader/spirv/parser_impl_test_helper.h

This is useful for bulk testing

Fixed: tint:756
Change-Id: I4fe232ac736003f7d9be35544328302d652381ea
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/49605
Auto-Submit: David Neto <dneto@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
David Neto
2021-05-05 09:46:31 +00:00
committed by Commit Bot service account
parent 02ebf0dcae
commit 58a3624935
8 changed files with 166 additions and 13 deletions

View File

@@ -0,0 +1,41 @@
// Copyright 2021 The Tint Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/reader/spirv/parser_impl_test_helper.h"
namespace tint {
namespace reader {
namespace spirv {
namespace test {
// Default to not dumping the SPIR-V assembly.
bool ParserImplWrapperForTest::dump_successfully_converted_spirv_ = false;
ParserImplWrapperForTest::ParserImplWrapperForTest(
const std::vector<uint32_t>& input)
: impl_(input) {}
ParserImplWrapperForTest::~ParserImplWrapperForTest() {
if (dump_successfully_converted_spirv_ && !impl_.spv_binary().empty() &&
impl_.success()) {
std::string disassembly = Disassemble(impl_.spv_binary());
std::cout << "BEGIN ConvertedOk:\n"
<< disassembly << "\nEND ConvertedOk" << std::endl;
}
}
} // namespace test
} // namespace spirv
} // namespace reader
} // namespace tint

View File

@@ -28,6 +28,7 @@
#include "src/reader/spirv/function.h"
#include "src/reader/spirv/namer.h"
#include "src/reader/spirv/parser_impl.h"
#include "src/reader/spirv/spirv_tools_helpers_test.h"
#include "src/reader/spirv/usage.h"
namespace tint {
@@ -38,8 +39,16 @@ namespace test {
// A test class that wraps ParseImpl
class ParserImplWrapperForTest {
public:
explicit ParserImplWrapperForTest(const std::vector<uint32_t>& input)
: impl_(input) {}
// Constructor
explicit ParserImplWrapperForTest(const std::vector<uint32_t>& input);
// Dumps SPIR-V if the conversion succeeded, then destroys the wrapper.
~ParserImplWrapperForTest();
// Sets global state to force dumping of the assembly text of succesfully
// SPIR-V.
static void DumpSuccessfullyConvertedSpirv() {
dump_successfully_converted_spirv_ = true;
}
// Returns a new function emitter for the given function ID.
// Assumes ParserImpl::BuildInternalRepresentation has been run and
@@ -57,6 +66,7 @@ class ParserImplWrapperForTest {
const std::string error() { return impl_.error(); }
FailStream& Fail() { return impl_.Fail(); }
spvtools::opt::IRContext* ir_context() { return impl_.ir_context(); }
bool BuildInternalModule() { return impl_.BuildInternalModule(); }
bool BuildAndParseInternalModuleExceptFunctions() {
return impl_.BuildAndParseInternalModuleExceptFunctions();
@@ -67,9 +77,14 @@ class ParserImplWrapperForTest {
bool RegisterUserAndStructMemberNames() {
return impl_.RegisterUserAndStructMemberNames();
}
bool RegisterTypes() { return impl_.RegisterTypes(); }
bool RegisterHandleUsage() { return impl_.RegisterHandleUsage(); }
bool EmitModuleScopeVariables() { return impl_.EmitModuleScopeVariables(); }
const std::unordered_set<uint32_t>& glsl_std_450_imports() const {
return impl_.glsl_std_450_imports();
}
sem::Type* ConvertType(uint32_t id) { return impl_.ConvertType(id); }
DecorationList GetDecorationsFor(uint32_t id) const {
return impl_.GetDecorationsFor(id);
@@ -93,12 +108,9 @@ class ParserImplWrapperForTest {
return impl_.GetEntryPointInfo(entry_point);
}
Usage GetHandleUsage(uint32_t id) const { return impl_.GetHandleUsage(id); }
bool RegisterHandleUsage() { return impl_.RegisterHandleUsage(); }
bool EmitModuleScopeVariables() { return impl_.EmitModuleScopeVariables(); }
const spvtools::opt::Instruction* GetInstructionForTest(uint32_t id) const {
return impl_.GetInstructionForTest(id);
}
bool RegisterTypes() { return impl_.RegisterTypes(); }
const ParserImpl::BuiltInPositionInfo& GetBuiltInPositionInfo() {
return impl_.GetBuiltInPositionInfo();
}
@@ -110,8 +122,15 @@ class ParserImplWrapperForTest {
private:
ParserImpl impl_;
static bool dump_successfully_converted_spirv_;
};
// Sets global state to force dumping of the assembly text of succesfully
// SPIR-V.
inline void DumpSuccessfullyConvertedSpirv() {
ParserImplWrapperForTest::DumpSuccessfullyConvertedSpirv();
}
} // namespace test
/// SPIR-V Parser test class
@@ -127,6 +146,7 @@ class SpvParserTestBase : public T {
std::unique_ptr<test::ParserImplWrapperForTest> parser(
const std::vector<uint32_t>& input) {
auto parser = std::make_unique<test::ParserImplWrapperForTest>(input);
// Don't run the Resolver when building the program.
// We're not interested in type information with these tests.
parser->builder().SetResolveOnBuild(false);

View File

@@ -75,7 +75,7 @@ std::string Disassemble(const std::vector<uint32_t>& spirv_module) {
std::string result;
const auto success = tools.Disassemble(
spirv_module, &result, 0 /* no friendly names, so we get raw IDs */);
spirv_module, &result, SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
EXPECT_TRUE(success) << errors.str();
return result;