1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2020 The SwiftShader Authors. All Rights Reserved. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef sw_SpirvShaderDebug_hpp 16*03ce13f7SAndroid Build Coastguard Worker #define sw_SpirvShaderDebug_hpp 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "SpirvShader.hpp" 19*03ce13f7SAndroid Build Coastguard Worker 20*03ce13f7SAndroid Build Coastguard Worker // Enable this to print verbose debug messages as each SPIR-V instruction is 21*03ce13f7SAndroid Build Coastguard Worker // executed. Very handy for performing text diffs when the thread count is 22*03ce13f7SAndroid Build Coastguard Worker // reduced to 1 and execution is deterministic. 23*03ce13f7SAndroid Build Coastguard Worker #define SPIRV_SHADER_ENABLE_DBG 0 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker // Enable this to write a GraphViz dot file containing a graph of the shader's 26*03ce13f7SAndroid Build Coastguard Worker // control flow to the given file path. Helpful for diagnosing control-flow 27*03ce13f7SAndroid Build Coastguard Worker // related issues. 28*03ce13f7SAndroid Build Coastguard Worker #if 0 29*03ce13f7SAndroid Build Coastguard Worker # define SPIRV_SHADER_CFG_GRAPHVIZ_DOT_FILEPATH "swiftshader_%d.dot" 30*03ce13f7SAndroid Build Coastguard Worker #endif 31*03ce13f7SAndroid Build Coastguard Worker 32*03ce13f7SAndroid Build Coastguard Worker #if SPIRV_SHADER_ENABLE_DBG 33*03ce13f7SAndroid Build Coastguard Worker # define SPIRV_SHADER_DBG(fmt, ...) rr::Print(fmt "\n", ##__VA_ARGS__) 34*03ce13f7SAndroid Build Coastguard Worker # include "spirv-tools/libspirv.h" 35*03ce13f7SAndroid Build Coastguard Worker namespace spvtools { 36*03ce13f7SAndroid Build Coastguard Worker // Function implemented in third_party/SPIRV-Tools/source/disassemble.cpp 37*03ce13f7SAndroid Build Coastguard Worker // but with no public header. 38*03ce13f7SAndroid Build Coastguard Worker std::string spvInstructionBinaryToText(const spv_target_env env, 39*03ce13f7SAndroid Build Coastguard Worker const uint32_t *inst_binary, 40*03ce13f7SAndroid Build Coastguard Worker const size_t inst_word_count, 41*03ce13f7SAndroid Build Coastguard Worker const uint32_t *binary, 42*03ce13f7SAndroid Build Coastguard Worker const size_t word_count, 43*03ce13f7SAndroid Build Coastguard Worker const uint32_t options); 44*03ce13f7SAndroid Build Coastguard Worker 45*03ce13f7SAndroid Build Coastguard Worker } // namespace spvtools 46*03ce13f7SAndroid Build Coastguard Worker #else 47*03ce13f7SAndroid Build Coastguard Worker # define SPIRV_SHADER_DBG(...) 48*03ce13f7SAndroid Build Coastguard Worker #endif // SPIRV_SHADER_ENABLE_DBG 49*03ce13f7SAndroid Build Coastguard Worker 50*03ce13f7SAndroid Build Coastguard Worker #ifdef ENABLE_RR_PRINT 51*03ce13f7SAndroid Build Coastguard Worker namespace rr { 52*03ce13f7SAndroid Build Coastguard Worker template<> 53*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<sw::Spirv::Object::ID> 54*03ce13f7SAndroid Build Coastguard Worker { fmtrr::PrintValue::Ty55*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(sw::Spirv::Object::ID v) { return "Object<" + std::to_string(v.value()) + ">"; } valrr::PrintValue::Ty56*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(sw::Spirv::Object::ID v) { return {}; } 57*03ce13f7SAndroid Build Coastguard Worker }; 58*03ce13f7SAndroid Build Coastguard Worker template<> 59*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<sw::Spirv::Type::ID> 60*03ce13f7SAndroid Build Coastguard Worker { fmtrr::PrintValue::Ty61*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(sw::Spirv::Type::ID v) { return "Type<" + std::to_string(v.value()) + ">"; } valrr::PrintValue::Ty62*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(sw::Spirv::Type::ID v) { return {}; } 63*03ce13f7SAndroid Build Coastguard Worker }; 64*03ce13f7SAndroid Build Coastguard Worker template<> 65*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<sw::Spirv::Block::ID> 66*03ce13f7SAndroid Build Coastguard Worker { fmtrr::PrintValue::Ty67*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(sw::Spirv::Block::ID v) { return "Block<" + std::to_string(v.value()) + ">"; } valrr::PrintValue::Ty68*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(sw::Spirv::Block::ID v) { return {}; } 69*03ce13f7SAndroid Build Coastguard Worker }; 70*03ce13f7SAndroid Build Coastguard Worker 71*03ce13f7SAndroid Build Coastguard Worker template<> 72*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<sw::Intermediate> 73*03ce13f7SAndroid Build Coastguard Worker { fmtrr::PrintValue::Ty74*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(const sw::Intermediate &v, uint32_t i) 75*03ce13f7SAndroid Build Coastguard Worker { 76*03ce13f7SAndroid Build Coastguard Worker switch(v.typeHint) 77*03ce13f7SAndroid Build Coastguard Worker { 78*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::Float: 79*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::Float>::fmt(v.Float(i)); 80*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::Int: 81*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::Int>::fmt(v.Int(i)); 82*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::UInt: 83*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(i)); 84*03ce13f7SAndroid Build Coastguard Worker } 85*03ce13f7SAndroid Build Coastguard Worker return ""; 86*03ce13f7SAndroid Build Coastguard Worker } 87*03ce13f7SAndroid Build Coastguard Worker valrr::PrintValue::Ty88*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(const sw::Intermediate &v, uint32_t i) 89*03ce13f7SAndroid Build Coastguard Worker { 90*03ce13f7SAndroid Build Coastguard Worker switch(v.typeHint) 91*03ce13f7SAndroid Build Coastguard Worker { 92*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::Float: 93*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::Float>::val(v.Float(i)); 94*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::Int: 95*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::Int>::val(v.Int(i)); 96*03ce13f7SAndroid Build Coastguard Worker case sw::Intermediate::TypeHint::UInt: 97*03ce13f7SAndroid Build Coastguard Worker return PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(i)); 98*03ce13f7SAndroid Build Coastguard Worker } 99*03ce13f7SAndroid Build Coastguard Worker return {}; 100*03ce13f7SAndroid Build Coastguard Worker } 101*03ce13f7SAndroid Build Coastguard Worker fmtrr::PrintValue::Ty102*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(const sw::Intermediate &v) 103*03ce13f7SAndroid Build Coastguard Worker { 104*03ce13f7SAndroid Build Coastguard Worker if(v.componentCount == 1) 105*03ce13f7SAndroid Build Coastguard Worker { 106*03ce13f7SAndroid Build Coastguard Worker return fmt(v, 0); 107*03ce13f7SAndroid Build Coastguard Worker } 108*03ce13f7SAndroid Build Coastguard Worker 109*03ce13f7SAndroid Build Coastguard Worker std::string out = "["; 110*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < v.componentCount; i++) 111*03ce13f7SAndroid Build Coastguard Worker { 112*03ce13f7SAndroid Build Coastguard Worker if(i > 0) { out += ", "; } 113*03ce13f7SAndroid Build Coastguard Worker out += std::to_string(i) + ": "; 114*03ce13f7SAndroid Build Coastguard Worker out += fmt(v, i); 115*03ce13f7SAndroid Build Coastguard Worker } 116*03ce13f7SAndroid Build Coastguard Worker return out + "]"; 117*03ce13f7SAndroid Build Coastguard Worker } 118*03ce13f7SAndroid Build Coastguard Worker valrr::PrintValue::Ty119*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(const sw::Intermediate &v) 120*03ce13f7SAndroid Build Coastguard Worker { 121*03ce13f7SAndroid Build Coastguard Worker std::vector<Value *> out; 122*03ce13f7SAndroid Build Coastguard Worker for(uint32_t i = 0; i < v.componentCount; i++) 123*03ce13f7SAndroid Build Coastguard Worker { 124*03ce13f7SAndroid Build Coastguard Worker auto vals = val(v, i); 125*03ce13f7SAndroid Build Coastguard Worker out.insert(out.end(), vals.begin(), vals.end()); 126*03ce13f7SAndroid Build Coastguard Worker } 127*03ce13f7SAndroid Build Coastguard Worker return out; 128*03ce13f7SAndroid Build Coastguard Worker } 129*03ce13f7SAndroid Build Coastguard Worker }; 130*03ce13f7SAndroid Build Coastguard Worker 131*03ce13f7SAndroid Build Coastguard Worker template<> 132*03ce13f7SAndroid Build Coastguard Worker struct PrintValue::Ty<sw::SpirvEmitter::Operand> 133*03ce13f7SAndroid Build Coastguard Worker { fmtrr::PrintValue::Ty134*03ce13f7SAndroid Build Coastguard Worker static inline std::string fmt(const sw::SpirvEmitter::Operand &v) 135*03ce13f7SAndroid Build Coastguard Worker { 136*03ce13f7SAndroid Build Coastguard Worker return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::fmt(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(0)); 137*03ce13f7SAndroid Build Coastguard Worker } 138*03ce13f7SAndroid Build Coastguard Worker valrr::PrintValue::Ty139*03ce13f7SAndroid Build Coastguard Worker static inline std::vector<Value *> val(const sw::SpirvEmitter::Operand &v) 140*03ce13f7SAndroid Build Coastguard Worker { 141*03ce13f7SAndroid Build Coastguard Worker return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::val(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(0)); 142*03ce13f7SAndroid Build Coastguard Worker } 143*03ce13f7SAndroid Build Coastguard Worker }; 144*03ce13f7SAndroid Build Coastguard Worker } // namespace rr 145*03ce13f7SAndroid Build Coastguard Worker #endif // ENABLE_RR_PRINT 146*03ce13f7SAndroid Build Coastguard Worker 147*03ce13f7SAndroid Build Coastguard Worker #endif // sw_SpirvShaderDebug_hpp 148