mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 14:43:31 +00:00
Add SPIR-V dump to the SPIR-V generator
This Cl adds utility classes to dump out SPIR-V disassembly of the builder and instructions. Bug: tint:5 Change-Id: Ib4c57025ac63cb0be456bd819461c98ffa94367f Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17560 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
781a4acb6f
commit
dc200f7d1d
@ -402,6 +402,8 @@ if(${TINT_BUILD_SPV_WRITER})
|
|||||||
writer/spirv/builder_entry_point_test.cc
|
writer/spirv/builder_entry_point_test.cc
|
||||||
writer/spirv/instruction_test.cc
|
writer/spirv/instruction_test.cc
|
||||||
writer/spirv/operand_test.cc
|
writer/spirv/operand_test.cc
|
||||||
|
writer/spirv/spv_dump.cc
|
||||||
|
writer/spirv/spv_dump.h
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -31,39 +31,48 @@ BinaryWriter::BinaryWriter() = default;
|
|||||||
|
|
||||||
BinaryWriter::~BinaryWriter() = default;
|
BinaryWriter::~BinaryWriter() = default;
|
||||||
|
|
||||||
bool BinaryWriter::Write(const Builder& builder) {
|
void BinaryWriter::WriteBuilder(const Builder& builder) {
|
||||||
out_.resize(builder.total_size(), 0);
|
out_.reserve(builder.total_size());
|
||||||
|
builder.iterate(
|
||||||
|
[this](const Instruction& inst) { this->process_instruction(inst); });
|
||||||
|
}
|
||||||
|
|
||||||
out_[idx_++] = spv::MagicNumber;
|
void BinaryWriter::WriteInstruction(const Instruction& inst) {
|
||||||
out_[idx_++] = 0x00010300; // Version 1.3
|
process_instruction(inst);
|
||||||
out_[idx_++] = kGeneratorId;
|
}
|
||||||
out_[idx_++] = builder.id_bound();
|
|
||||||
out_[idx_++] = 0;
|
|
||||||
|
|
||||||
builder.iterate([this](const Instruction& inst) {
|
void BinaryWriter::WriteHeader(uint32_t bound) {
|
||||||
out_[idx_++] =
|
out_.push_back(spv::MagicNumber);
|
||||||
inst.word_length() << 16 | static_cast<uint32_t>(inst.opcode());
|
out_.push_back(0x00010300); // Version 1.3
|
||||||
|
out_.push_back(kGeneratorId);
|
||||||
|
out_.push_back(bound);
|
||||||
|
out_.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& op : inst.operands()) {
|
void BinaryWriter::process_instruction(const Instruction& inst) {
|
||||||
process_op(op);
|
out_.push_back(inst.word_length() << 16 |
|
||||||
}
|
static_cast<uint32_t>(inst.opcode()));
|
||||||
});
|
|
||||||
return true;
|
for (const auto& op : inst.operands()) {
|
||||||
|
process_op(op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryWriter::process_op(const Operand& op) {
|
void BinaryWriter::process_op(const Operand& op) {
|
||||||
if (op.IsFloat()) {
|
if (op.IsFloat()) {
|
||||||
|
// Allocate space for the float
|
||||||
|
out_.push_back(0);
|
||||||
auto f = op.to_f();
|
auto f = op.to_f();
|
||||||
memcpy(out_.data() + idx_, &f, 4);
|
uint8_t* ptr = reinterpret_cast<uint8_t*>(out_.data() + (out_.size() - 1));
|
||||||
|
memcpy(ptr, &f, 4);
|
||||||
} else if (op.IsInt()) {
|
} else if (op.IsInt()) {
|
||||||
out_[idx_] = op.to_i();
|
out_.push_back(op.to_i());
|
||||||
} else {
|
} else {
|
||||||
|
auto idx = out_.size();
|
||||||
const auto& str = op.to_s();
|
const auto& str = op.to_s();
|
||||||
// This depends on the vector being initialized to 0 values so the string
|
out_.resize(out_.size() + op.length(), 0);
|
||||||
// is correctly padded.
|
memcpy(out_.data() + idx, str.c_str(), str.size() + 1);
|
||||||
memcpy(out_.data() + idx_, str.c_str(), str.size() + 1);
|
|
||||||
}
|
}
|
||||||
idx_ += op.length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
|
@ -30,19 +30,27 @@ class BinaryWriter {
|
|||||||
BinaryWriter();
|
BinaryWriter();
|
||||||
~BinaryWriter();
|
~BinaryWriter();
|
||||||
|
|
||||||
/// Writes the given builder data into a binary
|
/// Writes the SPIR-V header.
|
||||||
|
/// @param bound the bound to output
|
||||||
|
void WriteHeader(uint32_t bound);
|
||||||
|
|
||||||
|
/// Writes the given builder data into a binary. Note, this does not emit
|
||||||
|
/// the SPIR-V header. You |must| call |WriteHeader| before |WriteBuilder|
|
||||||
|
/// if you want the SPIR-V to be emitted.
|
||||||
/// @param builder the builder to assemble from
|
/// @param builder the builder to assemble from
|
||||||
/// @returns true on success
|
void WriteBuilder(const Builder& builder);
|
||||||
bool Write(const Builder& builder);
|
|
||||||
|
/// Writes the given instruction into the binary.
|
||||||
|
/// @param inst the instruction to assemble
|
||||||
|
void WriteInstruction(const Instruction& inst);
|
||||||
|
|
||||||
/// @returns the assembled SPIR-V
|
/// @returns the assembled SPIR-V
|
||||||
const std::vector<uint32_t>& result() const { return out_; }
|
const std::vector<uint32_t>& result() const { return out_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void process_instruction(const Instruction& inst);
|
||||||
void process_op(const Operand& op);
|
void process_op(const Operand& op);
|
||||||
|
|
||||||
/// Word index of the next word to fill.
|
|
||||||
size_t idx_ = 0;
|
|
||||||
std::vector<uint32_t> out_;
|
std::vector<uint32_t> out_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,14 +29,14 @@ using BinaryWriterTest = testing::Test;
|
|||||||
TEST_F(BinaryWriterTest, Preamble) {
|
TEST_F(BinaryWriterTest, Preamble) {
|
||||||
Builder b;
|
Builder b;
|
||||||
BinaryWriter bw;
|
BinaryWriter bw;
|
||||||
ASSERT_TRUE(bw.Write(b));
|
bw.WriteHeader(5);
|
||||||
|
|
||||||
auto res = bw.result();
|
auto res = bw.result();
|
||||||
ASSERT_EQ(res.size(), 5);
|
ASSERT_EQ(res.size(), 5);
|
||||||
EXPECT_EQ(res[0], spv::MagicNumber);
|
EXPECT_EQ(res[0], spv::MagicNumber);
|
||||||
EXPECT_EQ(res[1], 0x00010300); // SPIR-V 1.3
|
EXPECT_EQ(res[1], 0x00010300); // SPIR-V 1.3
|
||||||
EXPECT_EQ(res[2], 0); // Generator ID
|
EXPECT_EQ(res[2], 0); // Generator ID
|
||||||
EXPECT_EQ(res[3], 1); // ID Bound
|
EXPECT_EQ(res[3], 5); // ID Bound
|
||||||
EXPECT_EQ(res[4], 0); // Reserved
|
EXPECT_EQ(res[4], 0); // Reserved
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +44,12 @@ TEST_F(BinaryWriterTest, Float) {
|
|||||||
Builder b;
|
Builder b;
|
||||||
b.push_preamble(spv::Op::OpNop, {Operand::Float(2.4f)});
|
b.push_preamble(spv::Op::OpNop, {Operand::Float(2.4f)});
|
||||||
BinaryWriter bw;
|
BinaryWriter bw;
|
||||||
ASSERT_TRUE(bw.Write(b));
|
bw.WriteBuilder(b);
|
||||||
|
|
||||||
auto res = bw.result();
|
auto res = bw.result();
|
||||||
ASSERT_EQ(res.size(), 7);
|
ASSERT_EQ(res.size(), 2);
|
||||||
float f;
|
float f;
|
||||||
memcpy(&f, res.data() + 6, 4);
|
memcpy(&f, res.data() + 1, 4);
|
||||||
EXPECT_EQ(f, 2.4f);
|
EXPECT_EQ(f, 2.4f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,23 +57,23 @@ TEST_F(BinaryWriterTest, Int) {
|
|||||||
Builder b;
|
Builder b;
|
||||||
b.push_preamble(spv::Op::OpNop, {Operand::Int(2)});
|
b.push_preamble(spv::Op::OpNop, {Operand::Int(2)});
|
||||||
BinaryWriter bw;
|
BinaryWriter bw;
|
||||||
ASSERT_TRUE(bw.Write(b));
|
bw.WriteBuilder(b);
|
||||||
|
|
||||||
auto res = bw.result();
|
auto res = bw.result();
|
||||||
ASSERT_EQ(res.size(), 7);
|
ASSERT_EQ(res.size(), 2);
|
||||||
EXPECT_EQ(res[6], 2);
|
EXPECT_EQ(res[1], 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BinaryWriterTest, String) {
|
TEST_F(BinaryWriterTest, String) {
|
||||||
Builder b;
|
Builder b;
|
||||||
b.push_preamble(spv::Op::OpNop, {Operand::String("my_string")});
|
b.push_preamble(spv::Op::OpNop, {Operand::String("my_string")});
|
||||||
BinaryWriter bw;
|
BinaryWriter bw;
|
||||||
ASSERT_TRUE(bw.Write(b));
|
bw.WriteBuilder(b);
|
||||||
|
|
||||||
auto res = bw.result();
|
auto res = bw.result();
|
||||||
ASSERT_EQ(res.size(), 9);
|
ASSERT_EQ(res.size(), 4);
|
||||||
|
|
||||||
uint8_t* v = reinterpret_cast<uint8_t*>(res.data()) + (6 * 4);
|
uint8_t* v = reinterpret_cast<uint8_t*>(res.data() + 1);
|
||||||
EXPECT_EQ(v[0], 'm');
|
EXPECT_EQ(v[0], 'm');
|
||||||
EXPECT_EQ(v[1], 'y');
|
EXPECT_EQ(v[1], 'y');
|
||||||
EXPECT_EQ(v[2], '_');
|
EXPECT_EQ(v[2], '_');
|
||||||
@ -92,12 +92,12 @@ TEST_F(BinaryWriterTest, String_Multiple4Length) {
|
|||||||
Builder b;
|
Builder b;
|
||||||
b.push_preamble(spv::Op::OpNop, {Operand::String("mystring")});
|
b.push_preamble(spv::Op::OpNop, {Operand::String("mystring")});
|
||||||
BinaryWriter bw;
|
BinaryWriter bw;
|
||||||
ASSERT_TRUE(bw.Write(b));
|
bw.WriteBuilder(b);
|
||||||
|
|
||||||
auto res = bw.result();
|
auto res = bw.result();
|
||||||
ASSERT_EQ(res.size(), 9);
|
ASSERT_EQ(res.size(), 4);
|
||||||
|
|
||||||
uint8_t* v = reinterpret_cast<uint8_t*>(res.data()) + (6 * 4);
|
uint8_t* v = reinterpret_cast<uint8_t*>(res.data() + 1);
|
||||||
EXPECT_EQ(v[0], 'm');
|
EXPECT_EQ(v[0], 'm');
|
||||||
EXPECT_EQ(v[1], 'y');
|
EXPECT_EQ(v[1], 'y');
|
||||||
EXPECT_EQ(v[2], 's');
|
EXPECT_EQ(v[2], 's');
|
||||||
@ -112,6 +112,20 @@ TEST_F(BinaryWriterTest, String_Multiple4Length) {
|
|||||||
EXPECT_EQ(v[11], '\0');
|
EXPECT_EQ(v[11], '\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryWriterTest, TestInstructionWriter) {
|
||||||
|
Instruction i1{spv::Op::OpNop, {Operand::Int(2)}};
|
||||||
|
Instruction i2{spv::Op::OpNop, {Operand::Int(4)}};
|
||||||
|
|
||||||
|
BinaryWriter bw;
|
||||||
|
bw.WriteInstruction(i1);
|
||||||
|
bw.WriteInstruction(i2);
|
||||||
|
|
||||||
|
auto res = bw.result();
|
||||||
|
ASSERT_EQ(res.size(), 4);
|
||||||
|
EXPECT_EQ(res[1], 2);
|
||||||
|
EXPECT_EQ(res[3], 4);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace writer
|
} // namespace writer
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "src/ast/entry_point.h"
|
#include "src/ast/entry_point.h"
|
||||||
#include "src/ast/pipeline_stage.h"
|
#include "src/ast/pipeline_stage.h"
|
||||||
#include "src/writer/spirv/builder.h"
|
#include "src/writer/spirv/builder.h"
|
||||||
|
#include "src/writer/spirv/spv_dump.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace writer {
|
namespace writer {
|
||||||
@ -36,12 +37,8 @@ TEST_F(BuilderTest, EntryPoint) {
|
|||||||
|
|
||||||
auto preamble = b.preamble();
|
auto preamble = b.preamble();
|
||||||
ASSERT_EQ(preamble.size(), 1);
|
ASSERT_EQ(preamble.size(), 1);
|
||||||
EXPECT_EQ(preamble[0].opcode(), spv::Op::OpEntryPoint);
|
EXPECT_EQ(DumpInstruction(preamble[0]), R"(OpEntryPoint Fragment %2 "main"
|
||||||
|
)");
|
||||||
ASSERT_TRUE(preamble[0].operands().size() >= 3);
|
|
||||||
EXPECT_EQ(preamble[0].operands()[0].to_i(), SpvExecutionModelFragment);
|
|
||||||
EXPECT_EQ(preamble[0].operands()[1].to_i(), 2);
|
|
||||||
EXPECT_EQ(preamble[0].operands()[2].to_s(), "main");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, EntryPoint_WithoutName) {
|
TEST_F(BuilderTest, EntryPoint_WithoutName) {
|
||||||
@ -53,12 +50,9 @@ TEST_F(BuilderTest, EntryPoint_WithoutName) {
|
|||||||
|
|
||||||
auto preamble = b.preamble();
|
auto preamble = b.preamble();
|
||||||
ASSERT_EQ(preamble.size(), 1);
|
ASSERT_EQ(preamble.size(), 1);
|
||||||
EXPECT_EQ(preamble[0].opcode(), spv::Op::OpEntryPoint);
|
EXPECT_EQ(DumpInstruction(preamble[0]),
|
||||||
|
R"(OpEntryPoint GLCompute %3 "compute_main"
|
||||||
ASSERT_TRUE(preamble[0].operands().size() >= 3);
|
)");
|
||||||
EXPECT_EQ(preamble[0].operands()[0].to_i(), SpvExecutionModelGLCompute);
|
|
||||||
EXPECT_EQ(preamble[0].operands()[1].to_i(), 3);
|
|
||||||
EXPECT_EQ(preamble[0].operands()[2].to_s(), "compute_main");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, EntryPoint_BadFunction) {
|
TEST_F(BuilderTest, EntryPoint_BadFunction) {
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "spirv/unified1/spirv.hpp11"
|
#include "spirv/unified1/spirv.hpp11"
|
||||||
#include "src/ast/import.h"
|
#include "src/ast/import.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
#include "src/writer/spirv/spv_dump.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace writer {
|
namespace writer {
|
||||||
@ -36,28 +37,21 @@ TEST_F(BuilderTest, InsertsPreambleWithImport) {
|
|||||||
ASSERT_TRUE(b.Build(m));
|
ASSERT_TRUE(b.Build(m));
|
||||||
ASSERT_EQ(b.preamble().size(), 4);
|
ASSERT_EQ(b.preamble().size(), 4);
|
||||||
|
|
||||||
auto pre = b.preamble();
|
EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
|
||||||
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
OpCapability VulkanMemoryModel
|
||||||
EXPECT_EQ(pre[0].operands()[0].to_i(), SpvCapabilityShader);
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
EXPECT_EQ(pre[1].opcode(), spv::Op::OpCapability);
|
OpMemoryModel Logical Vulkan
|
||||||
EXPECT_EQ(pre[1].operands()[0].to_i(), SpvCapabilityVulkanMemoryModel);
|
)");
|
||||||
EXPECT_EQ(pre[2].opcode(), spv::Op::OpExtInstImport);
|
|
||||||
EXPECT_EQ(pre[2].operands()[1].to_s(), "GLSL.std.450");
|
|
||||||
EXPECT_EQ(pre[3].opcode(), spv::Op::OpMemoryModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, InsertsPreambleWithoutImport) {
|
TEST_F(BuilderTest, InsertsPreambleWithoutImport) {
|
||||||
ast::Module m;
|
ast::Module m;
|
||||||
Builder b;
|
Builder b;
|
||||||
ASSERT_TRUE(b.Build(m));
|
ASSERT_TRUE(b.Build(m));
|
||||||
ASSERT_EQ(b.preamble().size(), 3);
|
EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
|
||||||
|
OpCapability VulkanMemoryModel
|
||||||
auto pre = b.preamble();
|
OpMemoryModel Logical Vulkan
|
||||||
EXPECT_EQ(pre[0].opcode(), spv::Op::OpCapability);
|
)");
|
||||||
EXPECT_EQ(pre[0].operands()[0].to_i(), SpvCapabilityShader);
|
|
||||||
EXPECT_EQ(pre[1].opcode(), spv::Op::OpCapability);
|
|
||||||
EXPECT_EQ(pre[1].operands()[0].to_i(), SpvCapabilityVulkanMemoryModel);
|
|
||||||
EXPECT_EQ(pre[2].opcode(), spv::Op::OpMemoryModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, TracksIdBounds) {
|
TEST_F(BuilderTest, TracksIdBounds) {
|
||||||
|
@ -30,7 +30,9 @@ bool Generator::Generate() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return writer_.Write(builder_);
|
writer_.WriteHeader(builder_.id_bound());
|
||||||
|
writer_.WriteBuilder(builder_);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
|
82
src/writer/spirv/spv_dump.cc
Normal file
82
src/writer/spirv/spv_dump.cc
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 2020 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/writer/spirv/spv_dump.h"
|
||||||
|
|
||||||
|
#include "spirv-tools/libspirv.hpp"
|
||||||
|
#include "src/writer/spirv/binary_writer.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string Disassemble(const std::vector<uint32_t>& data) {
|
||||||
|
std::string spv_errors;
|
||||||
|
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_0;
|
||||||
|
|
||||||
|
auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
|
||||||
|
const spv_position_t& position,
|
||||||
|
const char* message) {
|
||||||
|
switch (level) {
|
||||||
|
case SPV_MSG_FATAL:
|
||||||
|
case SPV_MSG_INTERNAL_ERROR:
|
||||||
|
case SPV_MSG_ERROR:
|
||||||
|
spv_errors += "error: line " + std::to_string(position.index) + ": " +
|
||||||
|
message + "\n";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_WARNING:
|
||||||
|
spv_errors += "warning: line " + std::to_string(position.index) + ": " +
|
||||||
|
message + "\n";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_INFO:
|
||||||
|
spv_errors += "info: line " + std::to_string(position.index) + ": " +
|
||||||
|
message + "\n";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_DEBUG:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
spvtools::SpirvTools tools(target_env);
|
||||||
|
tools.SetMessageConsumer(msg_consumer);
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
if (!tools.Disassemble(data, &result,
|
||||||
|
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES |
|
||||||
|
SPV_BINARY_TO_TEXT_OPTION_NO_HEADER)) {
|
||||||
|
printf("%s\n", spv_errors.c_str());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::string DumpBuilder(const Builder& builder) {
|
||||||
|
BinaryWriter writer;
|
||||||
|
writer.WriteHeader(builder.id_bound());
|
||||||
|
writer.WriteBuilder(builder);
|
||||||
|
return Disassemble(writer.result());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DumpInstruction(const Instruction& inst) {
|
||||||
|
BinaryWriter writer;
|
||||||
|
writer.WriteHeader(kDefaultMaxIdBound);
|
||||||
|
writer.WriteInstruction(inst);
|
||||||
|
return Disassemble(writer.result());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
41
src/writer/spirv/spv_dump.h
Normal file
41
src/writer/spirv/spv_dump.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
#ifndef SRC_WRITER_SPIRV_SPV_DUMP_H_
|
||||||
|
#define SRC_WRITER_SPIRV_SPV_DUMP_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/writer/spirv/builder.h"
|
||||||
|
#include "src/writer/spirv/instruction.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace writer {
|
||||||
|
namespace spirv {
|
||||||
|
|
||||||
|
/// Dumps the given builder to a SPIR-V disassembly string
|
||||||
|
/// @param builder the builder to convert
|
||||||
|
/// @returns the builder as a SPIR-V disassembly string
|
||||||
|
std::string DumpBuilder(const Builder& builder);
|
||||||
|
|
||||||
|
/// Dumps the given instruction to a SPIR-V disassembly string
|
||||||
|
/// @param inst the instruction to dump
|
||||||
|
/// @returns the instruction as a SPIR-V disassembly string
|
||||||
|
std::string DumpInstruction(const Instruction& inst);
|
||||||
|
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace writer
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // SRC_WRITER_SPIRV_SPV_DUMP_H_
|
Loading…
x
Reference in New Issue
Block a user