blob: 66a7ca3026ba0abba104bbf854964ccd1200c4f1 [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
Nicolas Capens348ba202021-01-03 01:49:39 -050018#include "SpirvShader.hpp"
19
Ben Claytonfc951cd2019-05-15 17:16:56 +010020// 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
Ben Clayton0d6791c2020-04-22 21:55:27 +010025// 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
Ben Claytonfc951cd2019-05-15 17:16:56 +010032#if SPIRV_SHADER_ENABLE_DBG
33# define SPIRV_SHADER_DBG(fmt, ...) rr::Print(fmt "\n", ##__VA_ARGS__)
34# include "spirv-tools/libspirv.h"
35namespace spvtools {
36// Function implemented in third_party/SPIRV-Tools/source/disassemble.cpp
37// but with no public header.
38std::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
51namespace rr {
52template<>
Nicolas Capens71134742022-10-12 12:44:16 -040053struct PrintValue::Ty<sw::Spirv::Object::ID>
Ben Claytonfc951cd2019-05-15 17:16:56 +010054{
Nicolas Capens71134742022-10-12 12:44:16 -040055 static inline std::string fmt(sw::Spirv::Object::ID v) { return "Object<" + std::to_string(v.value()) + ">"; }
56 static inline std::vector<Value *> val(sw::Spirv::Object::ID v) { return {}; }
Ben Claytonfc951cd2019-05-15 17:16:56 +010057};
58template<>
Nicolas Capens71134742022-10-12 12:44:16 -040059struct PrintValue::Ty<sw::Spirv::Type::ID>
Ben Claytonfc951cd2019-05-15 17:16:56 +010060{
Nicolas Capens71134742022-10-12 12:44:16 -040061 static inline std::string fmt(sw::Spirv::Type::ID v) { return "Type<" + std::to_string(v.value()) + ">"; }
62 static inline std::vector<Value *> val(sw::Spirv::Type::ID v) { return {}; }
Ben Claytonfc951cd2019-05-15 17:16:56 +010063};
64template<>
Nicolas Capens71134742022-10-12 12:44:16 -040065struct PrintValue::Ty<sw::Spirv::Block::ID>
Ben Claytonfc951cd2019-05-15 17:16:56 +010066{
Nicolas Capens71134742022-10-12 12:44:16 -040067 static inline std::string fmt(sw::Spirv::Block::ID v) { return "Block<" + std::to_string(v.value()) + ">"; }
68 static inline std::vector<Value *> val(sw::Spirv::Block::ID v) { return {}; }
Ben Claytonfc951cd2019-05-15 17:16:56 +010069};
70
71template<>
72struct PrintValue::Ty<sw::Intermediate>
73{
74 static inline std::string fmt(const sw::Intermediate &v, uint32_t i)
75 {
76 switch(v.typeHint)
77 {
Nicolas Capens112faf42019-12-13 17:32:26 -050078 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));
Ben Claytonfc951cd2019-05-15 17:16:56 +010084 }
85 return "";
86 }
87
88 static inline std::vector<Value *> val(const sw::Intermediate &v, uint32_t i)
89 {
90 switch(v.typeHint)
91 {
Nicolas Capens112faf42019-12-13 17:32:26 -050092 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));
Ben Claytonfc951cd2019-05-15 17:16:56 +010098 }
99 return {};
100 }
101
102 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
119 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
131template<>
Nicolas Capens1ab775a2022-10-12 15:27:02 -0400132struct PrintValue::Ty<sw::SpirvEmitter::Operand>
Ben Claytonfc951cd2019-05-15 17:16:56 +0100133{
Nicolas Capens1ab775a2022-10-12 15:27:02 -0400134 static inline std::string fmt(const sw::SpirvEmitter::Operand &v)
Ben Claytonfc951cd2019-05-15 17:16:56 +0100135 {
136 return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::fmt(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(0));
137 }
138
Nicolas Capens1ab775a2022-10-12 15:27:02 -0400139 static inline std::vector<Value *> val(const sw::SpirvEmitter::Operand &v)
Ben Claytonfc951cd2019-05-15 17:16:56 +0100140 {
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