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