1 // Copyright 2020 The Tint Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "src/writer/spirv/spv_dump.h" 16 17 #include "spirv-tools/libspirv.hpp" 18 #include "src/writer/spirv/binary_writer.h" 19 20 namespace tint { 21 namespace writer { 22 namespace spirv { 23 namespace { 24 Disassemble(const std::vector<uint32_t> & data)25std::string Disassemble(const std::vector<uint32_t>& data) { 26 std::string spv_errors; 27 spv_target_env target_env = SPV_ENV_UNIVERSAL_1_0; 28 29 auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*, 30 const spv_position_t& position, 31 const char* message) { 32 switch (level) { 33 case SPV_MSG_FATAL: 34 case SPV_MSG_INTERNAL_ERROR: 35 case SPV_MSG_ERROR: 36 spv_errors += "error: line " + std::to_string(position.index) + ": " + 37 message + "\n"; 38 break; 39 case SPV_MSG_WARNING: 40 spv_errors += "warning: line " + std::to_string(position.index) + ": " + 41 message + "\n"; 42 break; 43 case SPV_MSG_INFO: 44 spv_errors += "info: line " + std::to_string(position.index) + ": " + 45 message + "\n"; 46 break; 47 case SPV_MSG_DEBUG: 48 break; 49 } 50 }; 51 52 spvtools::SpirvTools tools(target_env); 53 tools.SetMessageConsumer(msg_consumer); 54 55 std::string result; 56 if (!tools.Disassemble(data, &result, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER)) { 57 return "*** Invalid SPIR-V ***\n" + spv_errors; 58 } 59 return result; 60 } 61 62 } // namespace 63 DumpBuilder(Builder & builder)64std::string DumpBuilder(Builder& builder) { 65 BinaryWriter writer; 66 writer.WriteHeader(builder.id_bound()); 67 writer.WriteBuilder(&builder); 68 return Disassemble(writer.result()); 69 } 70 DumpInstruction(const Instruction & inst)71std::string DumpInstruction(const Instruction& inst) { 72 BinaryWriter writer; 73 writer.WriteHeader(kDefaultMaxIdBound); 74 writer.WriteInstruction(inst); 75 return Disassemble(writer.result()); 76 } 77 DumpInstructions(const InstructionList & insts)78std::string DumpInstructions(const InstructionList& insts) { 79 BinaryWriter writer; 80 writer.WriteHeader(kDefaultMaxIdBound); 81 for (const auto& inst : insts) { 82 writer.WriteInstruction(inst); 83 } 84 return Disassemble(writer.result()); 85 } 86 87 } // namespace spirv 88 } // namespace writer 89 } // namespace tint 90