Add SpirvTools::Validate that takes an options object

Add spvtools::ValidatorOptions RAII wrapper around
a spv_validator_options value.
This commit is contained in:
David Neto 2017-03-16 15:06:12 -04:00
parent 971ede33b2
commit 0066a363d6
3 changed files with 67 additions and 0 deletions

View File

@ -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.
@ -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.

View File

@ -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

View File

@ -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";
@ -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,