Skip to content

Commit

Permalink
Add SpirvTools::Validate that takes an options object
Browse files Browse the repository at this point in the history
Add spvtools::ValidatorOptions RAII wrapper around
a spv_validator_options value.
  • Loading branch information
dneto0 committed Mar 17, 2017
1 parent 971ede3 commit 0066a36
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
19 changes: 19 additions & 0 deletions include/spirv-tools/libspirv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ using MessageConsumer = std::function<void(
const spv_position_t& /* position */, const char* /* message */
)>;

// A RAII wrapper around a validator options object.
class ValidatorOptions {
public:
ValidatorOptions() : options_(spvValidatorOptionsCreate()) {}
~ValidatorOptions() { spvValidatorOptionsDestroy(options_); }
// Allow implicit conversion to the underlying object.
operator spv_validator_options() const { return options_; }

// Sets a limit.
void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) {
spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit);
}

private:
spv_validator_options options_;
};

// C++ interface for SPIRV-Tools functionalities. It wraps the context
// (including target environment and the corresponding SPIR-V grammar) and
// provides methods for assembling, disassembling, and validating.
Expand Down Expand Up @@ -91,6 +108,8 @@ class SpirvTools {
bool Validate(const std::vector<uint32_t>& binary) const;
// |binary_size| specifies the number of words in |binary|.
bool Validate(const uint32_t* binary, size_t binary_size) const;
// Like the previous overload, but takes an options object.
bool Validate(const uint32_t* binary, size_t binary_size, const ValidatorOptions& options) const;

private:
struct Impl; // Opaque struct for holding the data fields used by this class.
Expand Down
7 changes: 7 additions & 0 deletions source/libspirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,11 @@ bool SpirvTools::Validate(const uint32_t* binary,
SPV_SUCCESS;
}

bool SpirvTools::Validate(const uint32_t* binary, const size_t binary_size,
const spvtools::ValidatorOptions& options) const {
spv_const_binary_t the_binary{binary, binary_size};
return spvValidateWithOptions(impl_->context, options, &the_binary,
nullptr) == SPV_SUCCESS;
}

} // namespace spvtools
41 changes: 41 additions & 0 deletions test/cpp_interface_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace {

using namespace spvtools;
using ::testing::ContainerEq;
using ::testing::HasSubstr;

TEST(CppInterface, SuccessfulRoundTrip) {
const std::string input_text = "%2 = OpSizeOf %1 %3\n";
Expand Down Expand Up @@ -221,6 +222,46 @@ TEST(CppInterface, ValidateEmptyModule) {
EXPECT_EQ(1, invocation_count);
}

// Returns the assembly for a SPIR-V module with a struct declaration
// with the given number of members.
std::string MakeModuleHavingStruct(int num_members) {
std::stringstream os;
os << R"(OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%1 = OpTypeInt 32 0
%2 = OpTypeStruct)";
for (int i = 0; i < num_members; i++) os << " %1";
return os.str();
}

TEST(CppInterface, ValidateWithOptionsPass) {
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
const spvtools::ValidatorOptions opts;

EXPECT_TRUE(t.Validate(binary.data(), binary.size(), opts));
}

TEST(CppInterface, ValidateWithOptionsFail) {
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(MakeModuleHavingStruct(10), &binary));
spvtools::ValidatorOptions opts;
opts.SetUniversalLimit(spv_validator_limit_max_struct_members, 9);
std::stringstream os;
t.SetMessageConsumer([&os](spv_message_level_t, const char*,
const spv_position_t&,
const char* message) { os << message; });

EXPECT_FALSE(t.Validate(binary.data(), binary.size(), opts));
EXPECT_THAT(
os.str(),
HasSubstr(
"Number of OpTypeStruct members (10) has exceeded the limit (9)"));
}

// Checks that after running the given optimizer |opt| on the given |original|
// source code, we can get the given |optimized| source code.
void CheckOptimization(const char* original, const char* optimized,
Expand Down

0 comments on commit 0066a36

Please sign in to comment.