Add more Assemble(), Disassemble() and Validate() overloads.

This commit is contained in:
Lei Zhang 2016-09-20 18:03:37 -04:00
parent 620f05e679
commit 5edf054926
3 changed files with 87 additions and 6 deletions

View File

@ -70,17 +70,27 @@ class SpirvTools {
// Returns true on successful assembling. |binary| will be kept untouched if
// assembling is unsuccessful.
bool Assemble(const std::string& text, std::vector<uint32_t>* binary) const;
// |text_size| specifies the number of bytes in |text|. A terminating null
// character is not required to present in |text| as long as |text| is valid.
bool Assemble(const char* text, size_t text_size,
std::vector<uint32_t>* binary) const;
// Disassembles the given SPIR-V |binary| with the given |options| and writes
// the assembly to |text|. Returns ture on successful disassembling. |text|
// will be kept untouched if diassembling is unsuccessful.
bool Disassemble(const std::vector<uint32_t>& binary, std::string* text,
uint32_t options = kDefaultDisassembleOption) const;
// |binary_size| specifies the number of words in |binary|.
bool Disassemble(const uint32_t* binary, size_t binary_size,
std::string* text,
uint32_t options = kDefaultDisassembleOption) const;
// Validates the given SPIR-V |binary|. Returns true if no issues are found.
// Otherwise, returns false and communicates issues via the message consumer
// registered.
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;
private:
struct Impl; // Opaque struct for holding the data fields used by this class.

View File

@ -41,9 +41,14 @@ void SpirvTools::SetMessageConsumer(MessageConsumer consumer) {
bool SpirvTools::Assemble(const std::string& text,
std::vector<uint32_t>* binary) const {
return Assemble(text.data(), text.size(), binary);
}
bool SpirvTools::Assemble(const char* text, const size_t text_size,
std::vector<uint32_t>* binary) const {
spv_binary spvbinary = nullptr;
spv_result_t status = spvTextToBinary(impl_->context, text.data(),
text.size(), &spvbinary, nullptr);
spv_result_t status =
spvTextToBinary(impl_->context, text, text_size, &spvbinary, nullptr);
if (status == SPV_SUCCESS) {
binary->assign(spvbinary->code, spvbinary->code + spvbinary->wordCount);
}
@ -53,9 +58,14 @@ bool SpirvTools::Assemble(const std::string& text,
bool SpirvTools::Disassemble(const std::vector<uint32_t>& binary,
std::string* text, uint32_t options) const {
return Disassemble(binary.data(), binary.size(), text, options);
}
bool SpirvTools::Disassemble(const uint32_t* binary, const size_t binary_size,
std::string* text, uint32_t options) const {
spv_text spvtext = nullptr;
spv_result_t status = spvBinaryToText(
impl_->context, binary.data(), binary.size(), options, &spvtext, nullptr);
spv_result_t status = spvBinaryToText(impl_->context, binary, binary_size,
options, &spvtext, nullptr);
if (status == SPV_SUCCESS) {
text->assign(spvtext->str, spvtext->str + spvtext->length);
}
@ -64,8 +74,13 @@ bool SpirvTools::Disassemble(const std::vector<uint32_t>& binary,
}
bool SpirvTools::Validate(const std::vector<uint32_t>& binary) const {
spv_const_binary_t b = {binary.data(), binary.size()};
return spvValidate(impl_->context, &b, nullptr) == SPV_SUCCESS;
return Validate(binary.data(), binary.size());
}
bool SpirvTools::Validate(const uint32_t* binary,
const size_t binary_size) const {
return spvValidateBinary(impl_->context, binary, binary_size, nullptr) ==
SPV_SUCCESS;
}
} // namespace spvtools

View File

@ -60,6 +60,32 @@ TEST(CppInterface, AssembleEmptyModule) {
EXPECT_EQ(SpvVersion, binary[1]);
}
TEST(CppInterface, AssembleOverloads) {
const std::string input_text = "%2 = OpSizeOf %1 %3\n";
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
{
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text, &binary));
EXPECT_TRUE(binary.size() > 5u);
EXPECT_EQ(SpvMagicNumber, binary[0]);
EXPECT_EQ(SpvVersion, binary[1]);
}
{
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size(), &binary));
EXPECT_TRUE(binary.size() > 5u);
EXPECT_EQ(SpvMagicNumber, binary[0]);
EXPECT_EQ(SpvVersion, binary[1]);
}
{ // Ignore the last newline.
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text.data(), input_text.size() - 1, &binary));
EXPECT_TRUE(binary.size() > 5u);
EXPECT_EQ(SpvMagicNumber, binary[0]);
EXPECT_EQ(SpvVersion, binary[1]);
}
}
TEST(CppInterface, AssembleWithWrongTargetEnv) {
const std::string input_text = "%r = OpSizeOf %type %pointer";
SpirvTools t(SPV_ENV_UNIVERSAL_1_0);
@ -102,6 +128,25 @@ TEST(CppInterface, DisassembleEmptyModule) {
EXPECT_EQ(1, invocation_count);
}
TEST(CppInterface, DisassembleOverloads) {
const std::string input_text = "%2 = OpSizeOf %1 %3\n";
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text, &binary));
{
std::string output_text;
EXPECT_TRUE(t.Disassemble(binary, &output_text));
EXPECT_EQ(input_text, output_text);
}
{
std::string output_text;
EXPECT_TRUE(t.Disassemble(binary.data(), binary.size(), &output_text));
EXPECT_EQ(input_text, output_text);
}
}
TEST(CppInterface, DisassembleWithWrongTargetEnv) {
const std::string input_text = "%r = OpSizeOf %type %pointer";
SpirvTools t11(SPV_ENV_UNIVERSAL_1_1);
@ -143,6 +188,17 @@ TEST(CppInterface, SuccessfulValidation) {
EXPECT_EQ(0, invocation_count);
}
TEST(CppInterface, ValidateOverloads) {
const std::string input_text =
"OpCapability Shader\nOpMemoryModel Logical GLSL450";
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
std::vector<uint32_t> binary;
EXPECT_TRUE(t.Assemble(input_text, &binary));
{ EXPECT_TRUE(t.Validate(binary)); }
{ EXPECT_TRUE(t.Validate(binary.data(), binary.size())); }
}
TEST(CppInterface, ValidateEmptyModule) {
SpirvTools t(SPV_ENV_UNIVERSAL_1_1);
int invocation_count = 0;