• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The SwiftShader Authors. All Rights Reserved.
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 #ifndef sw_SpirvShaderDebug_hpp
16 #define sw_SpirvShaderDebug_hpp
17 
18 #include "SpirvShader.hpp"
19 
20 // Enable this to print verbose debug messages as each SPIR-V instructon is
21 // executed. Very handy for performing text diffs when the thread count is
22 // reduced to 1 and execution is deterministic.
23 #define SPIRV_SHADER_ENABLE_DBG 0
24 
25 // Enable this to write a GraphViz dot file containing a graph of the shader's
26 // control flow to the given file path. Helpful for diagnosing control-flow
27 // related issues.
28 #if 0
29 #	define SPIRV_SHADER_CFG_GRAPHVIZ_DOT_FILEPATH "swiftshader_%d.dot"
30 #endif
31 
32 #if SPIRV_SHADER_ENABLE_DBG
33 #	define SPIRV_SHADER_DBG(fmt, ...) rr::Print(fmt "\n", ##__VA_ARGS__)
34 #	include "spirv-tools/libspirv.h"
35 namespace spvtools {
36 // Function implemented in third_party/SPIRV-Tools/source/disassemble.cpp
37 // but with no public header.
38 std::string spvInstructionBinaryToText(const spv_target_env env,
39                                        const uint32_t *inst_binary,
40                                        const size_t inst_word_count,
41                                        const uint32_t *binary,
42                                        const size_t word_count,
43                                        const uint32_t options);
44 
45 }  // namespace spvtools
46 #else
47 #	define SPIRV_SHADER_DBG(...)
48 #endif  // SPIRV_SHADER_ENABLE_DBG
49 
50 #ifdef ENABLE_RR_PRINT
51 namespace rr {
52 template<>
53 struct PrintValue::Ty<sw::SpirvShader::Object::ID>
54 {
fmtrr::PrintValue::Ty55 	static inline std::string fmt(sw::SpirvShader::Object::ID v) { return "Object<" + std::to_string(v.value()) + ">"; }
valrr::PrintValue::Ty56 	static inline std::vector<Value *> val(sw::SpirvShader::Object::ID v) { return {}; }
57 };
58 template<>
59 struct PrintValue::Ty<sw::SpirvShader::Type::ID>
60 {
fmtrr::PrintValue::Ty61 	static inline std::string fmt(sw::SpirvShader::Type::ID v) { return "Type<" + std::to_string(v.value()) + ">"; }
valrr::PrintValue::Ty62 	static inline std::vector<Value *> val(sw::SpirvShader::Type::ID v) { return {}; }
63 };
64 template<>
65 struct PrintValue::Ty<sw::SpirvShader::Block::ID>
66 {
fmtrr::PrintValue::Ty67 	static inline std::string fmt(sw::SpirvShader::Block::ID v) { return "Block<" + std::to_string(v.value()) + ">"; }
valrr::PrintValue::Ty68 	static inline std::vector<Value *> val(sw::SpirvShader::Block::ID v) { return {}; }
69 };
70 
71 template<>
72 struct PrintValue::Ty<sw::Intermediate>
73 {
fmtrr::PrintValue::Ty74 	static inline std::string fmt(const sw::Intermediate &v, uint32_t i)
75 	{
76 		switch(v.typeHint)
77 		{
78 			case sw::Intermediate::TypeHint::Float:
79 				return PrintValue::Ty<sw::SIMD::Float>::fmt(v.Float(i));
80 			case sw::Intermediate::TypeHint::Int:
81 				return PrintValue::Ty<sw::SIMD::Int>::fmt(v.Int(i));
82 			case sw::Intermediate::TypeHint::UInt:
83 				return PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(i));
84 		}
85 		return "";
86 	}
87 
valrr::PrintValue::Ty88 	static inline std::vector<Value *> val(const sw::Intermediate &v, uint32_t i)
89 	{
90 		switch(v.typeHint)
91 		{
92 			case sw::Intermediate::TypeHint::Float:
93 				return PrintValue::Ty<sw::SIMD::Float>::val(v.Float(i));
94 			case sw::Intermediate::TypeHint::Int:
95 				return PrintValue::Ty<sw::SIMD::Int>::val(v.Int(i));
96 			case sw::Intermediate::TypeHint::UInt:
97 				return PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(i));
98 		}
99 		return {};
100 	}
101 
fmtrr::PrintValue::Ty102 	static inline std::string fmt(const sw::Intermediate &v)
103 	{
104 		if(v.componentCount == 1)
105 		{
106 			return fmt(v, 0);
107 		}
108 
109 		std::string out = "[";
110 		for(uint32_t i = 0; i < v.componentCount; i++)
111 		{
112 			if(i > 0) { out += ", "; }
113 			out += std::to_string(i) + ": ";
114 			out += fmt(v, i);
115 		}
116 		return out + "]";
117 	}
118 
valrr::PrintValue::Ty119 	static inline std::vector<Value *> val(const sw::Intermediate &v)
120 	{
121 		std::vector<Value *> out;
122 		for(uint32_t i = 0; i < v.componentCount; i++)
123 		{
124 			auto vals = val(v, i);
125 			out.insert(out.end(), vals.begin(), vals.end());
126 		}
127 		return out;
128 	}
129 };
130 
131 template<>
132 struct PrintValue::Ty<sw::SpirvShader::Operand>
133 {
fmtrr::PrintValue::Ty134 	static inline std::string fmt(const sw::SpirvShader::Operand &v)
135 	{
136 		return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::fmt(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(0));
137 	}
138 
valrr::PrintValue::Ty139 	static inline std::vector<Value *> val(const sw::SpirvShader::Operand &v)
140 	{
141 		return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::val(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(0));
142 	}
143 };
144 }  // namespace rr
145 #endif  // ENABLE_RR_PRINT
146 
147 #endif  // sw_SpirvShaderDebug_hpp
148