summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-12-15 22:30:43 -0800
committerGravatar Yuri Kunde Schlesner2016-12-15 23:08:05 -0800
commitd27cb1dedca7ff5e977668160bf3e24b75beb092 (patch)
tree985bf71a0d2996872f52837e5cb48b93d94ae162 /src
parentMerge pull request #2260 from Subv/scheduling (diff)
downloadyuzu-d27cb1dedca7ff5e977668160bf3e24b75beb092.tar.gz
yuzu-d27cb1dedca7ff5e977668160bf3e24b75beb092.tar.xz
yuzu-d27cb1dedca7ff5e977668160bf3e24b75beb092.zip
VideoCore/Shader: Move DebugData to a separate file
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/shader/debug_data.h186
-rw-r--r--src/video_core/shader/shader.h173
-rw-r--r--src/video_core/shader/shader_interpreter.cpp1
4 files changed, 189 insertions, 172 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 9aa446a8f..6ca319b59 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -39,6 +39,7 @@ set(HEADERS
39 rasterizer.h 39 rasterizer.h
40 rasterizer_interface.h 40 rasterizer_interface.h
41 renderer_base.h 41 renderer_base.h
42 shader/debug_data.h
42 shader/shader.h 43 shader/shader.h
43 shader/shader_interpreter.h 44 shader/shader_interpreter.h
44 swrasterizer.h 45 swrasterizer.h
diff --git a/src/video_core/shader/debug_data.h b/src/video_core/shader/debug_data.h
new file mode 100644
index 000000000..b0ccf437d
--- /dev/null
+++ b/src/video_core/shader/debug_data.h
@@ -0,0 +1,186 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <vector>
8#include "common/common_types.h"
9#include "common/vector_math.h"
10#include "video_core/pica_types.h"
11
12namespace Pica {
13namespace Shader {
14
15/// Helper structure used to keep track of data useful for inspection of shader emulation
16template <bool full_debugging>
17struct DebugData;
18
19template <>
20struct DebugData<false> {
21 // TODO: Hide these behind and interface and move them to DebugData<true>
22 u32 max_offset; ///< maximum program counter ever reached
23 u32 max_opdesc_id; ///< maximum swizzle pattern index ever used
24};
25
26template <>
27struct DebugData<true> {
28 /// Records store the input and output operands of a particular instruction.
29 struct Record {
30 enum Type {
31 // Floating point arithmetic operands
32 SRC1 = 0x1,
33 SRC2 = 0x2,
34 SRC3 = 0x4,
35
36 // Initial and final output operand value
37 DEST_IN = 0x8,
38 DEST_OUT = 0x10,
39
40 // Current and next instruction offset (in words)
41 CUR_INSTR = 0x20,
42 NEXT_INSTR = 0x40,
43
44 // Output address register value
45 ADDR_REG_OUT = 0x80,
46
47 // Result of a comparison instruction
48 CMP_RESULT = 0x100,
49
50 // Input values for conditional flow control instructions
51 COND_BOOL_IN = 0x200,
52 COND_CMP_IN = 0x400,
53
54 // Input values for a loop
55 LOOP_INT_IN = 0x800,
56 };
57
58 Math::Vec4<float24> src1;
59 Math::Vec4<float24> src2;
60 Math::Vec4<float24> src3;
61
62 Math::Vec4<float24> dest_in;
63 Math::Vec4<float24> dest_out;
64
65 s32 address_registers[2];
66 bool conditional_code[2];
67 bool cond_bool;
68 bool cond_cmp[2];
69 Math::Vec4<u8> loop_int;
70
71 u32 instruction_offset;
72 u32 next_instruction;
73
74 /// set of enabled fields (as a combination of Type flags)
75 unsigned mask = 0;
76 };
77
78 u32 max_offset; ///< maximum program counter ever reached
79 u32 max_opdesc_id; ///< maximum swizzle pattern index ever used
80
81 /// List of records for each executed shader instruction
82 std::vector<DebugData<true>::Record> records;
83};
84
85/// Type alias for better readability
86using DebugDataRecord = DebugData<true>::Record;
87
88/// Helper function to set a DebugData<true>::Record field based on the template enum parameter.
89template <DebugDataRecord::Type type, typename ValueType>
90inline void SetField(DebugDataRecord& record, ValueType value);
91
92template <>
93inline void SetField<DebugDataRecord::SRC1>(DebugDataRecord& record, float24* value) {
94 record.src1.x = value[0];
95 record.src1.y = value[1];
96 record.src1.z = value[2];
97 record.src1.w = value[3];
98}
99
100template <>
101inline void SetField<DebugDataRecord::SRC2>(DebugDataRecord& record, float24* value) {
102 record.src2.x = value[0];
103 record.src2.y = value[1];
104 record.src2.z = value[2];
105 record.src2.w = value[3];
106}
107
108template <>
109inline void SetField<DebugDataRecord::SRC3>(DebugDataRecord& record, float24* value) {
110 record.src3.x = value[0];
111 record.src3.y = value[1];
112 record.src3.z = value[2];
113 record.src3.w = value[3];
114}
115
116template <>
117inline void SetField<DebugDataRecord::DEST_IN>(DebugDataRecord& record, float24* value) {
118 record.dest_in.x = value[0];
119 record.dest_in.y = value[1];
120 record.dest_in.z = value[2];
121 record.dest_in.w = value[3];
122}
123
124template <>
125inline void SetField<DebugDataRecord::DEST_OUT>(DebugDataRecord& record, float24* value) {
126 record.dest_out.x = value[0];
127 record.dest_out.y = value[1];
128 record.dest_out.z = value[2];
129 record.dest_out.w = value[3];
130}
131
132template <>
133inline void SetField<DebugDataRecord::ADDR_REG_OUT>(DebugDataRecord& record, s32* value) {
134 record.address_registers[0] = value[0];
135 record.address_registers[1] = value[1];
136}
137
138template <>
139inline void SetField<DebugDataRecord::CMP_RESULT>(DebugDataRecord& record, bool* value) {
140 record.conditional_code[0] = value[0];
141 record.conditional_code[1] = value[1];
142}
143
144template <>
145inline void SetField<DebugDataRecord::COND_BOOL_IN>(DebugDataRecord& record, bool value) {
146 record.cond_bool = value;
147}
148
149template <>
150inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool* value) {
151 record.cond_cmp[0] = value[0];
152 record.cond_cmp[1] = value[1];
153}
154
155template <>
156inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) {
157 record.loop_int = value;
158}
159
160template <>
161inline void SetField<DebugDataRecord::CUR_INSTR>(DebugDataRecord& record, u32 value) {
162 record.instruction_offset = value;
163}
164
165template <>
166inline void SetField<DebugDataRecord::NEXT_INSTR>(DebugDataRecord& record, u32 value) {
167 record.next_instruction = value;
168}
169
170/// Helper function to set debug information on the current shader iteration.
171template <DebugDataRecord::Type type, typename ValueType>
172inline void Record(DebugData<false>& debug_data, u32 offset, ValueType value) {
173 // Debugging disabled => nothing to do
174}
175
176template <DebugDataRecord::Type type, typename ValueType>
177inline void Record(DebugData<true>& debug_data, u32 offset, ValueType value) {
178 if (offset >= debug_data.records.size())
179 debug_data.records.resize(offset + 1);
180
181 SetField<type, ValueType>(debug_data.records[offset], value);
182 debug_data.records[offset].mask |= type;
183}
184
185} // namespace Shader
186} // namespace Pica
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h
index 0111d8c0f..87c4e0b6f 100644
--- a/src/video_core/shader/shader.h
+++ b/src/video_core/shader/shader.h
@@ -8,8 +8,6 @@
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <type_traits> 10#include <type_traits>
11#include <vector>
12#include <boost/container/static_vector.hpp>
13#include <nihstro/shader_bytecode.h> 11#include <nihstro/shader_bytecode.h>
14#include "common/assert.h" 12#include "common/assert.h"
15#include "common/common_funcs.h" 13#include "common/common_funcs.h"
@@ -17,6 +15,7 @@
17#include "common/vector_math.h" 15#include "common/vector_math.h"
18#include "video_core/pica.h" 16#include "video_core/pica.h"
19#include "video_core/pica_types.h" 17#include "video_core/pica_types.h"
18#include "video_core/shader/debug_data.h"
20 19
21using nihstro::RegisterType; 20using nihstro::RegisterType;
22using nihstro::SourceRegister; 21using nihstro::SourceRegister;
@@ -89,176 +88,6 @@ struct OutputRegisters {
89}; 88};
90static_assert(std::is_pod<OutputRegisters>::value, "Structure is not POD"); 89static_assert(std::is_pod<OutputRegisters>::value, "Structure is not POD");
91 90
92// Helper structure used to keep track of data useful for inspection of shader emulation
93template <bool full_debugging>
94struct DebugData;
95
96template <>
97struct DebugData<false> {
98 // TODO: Hide these behind and interface and move them to DebugData<true>
99 u32 max_offset; // maximum program counter ever reached
100 u32 max_opdesc_id; // maximum swizzle pattern index ever used
101};
102
103template <>
104struct DebugData<true> {
105 // Records store the input and output operands of a particular instruction.
106 struct Record {
107 enum Type {
108 // Floating point arithmetic operands
109 SRC1 = 0x1,
110 SRC2 = 0x2,
111 SRC3 = 0x4,
112
113 // Initial and final output operand value
114 DEST_IN = 0x8,
115 DEST_OUT = 0x10,
116
117 // Current and next instruction offset (in words)
118 CUR_INSTR = 0x20,
119 NEXT_INSTR = 0x40,
120
121 // Output address register value
122 ADDR_REG_OUT = 0x80,
123
124 // Result of a comparison instruction
125 CMP_RESULT = 0x100,
126
127 // Input values for conditional flow control instructions
128 COND_BOOL_IN = 0x200,
129 COND_CMP_IN = 0x400,
130
131 // Input values for a loop
132 LOOP_INT_IN = 0x800,
133 };
134
135 Math::Vec4<float24> src1;
136 Math::Vec4<float24> src2;
137 Math::Vec4<float24> src3;
138
139 Math::Vec4<float24> dest_in;
140 Math::Vec4<float24> dest_out;
141
142 s32 address_registers[2];
143 bool conditional_code[2];
144 bool cond_bool;
145 bool cond_cmp[2];
146 Math::Vec4<u8> loop_int;
147
148 u32 instruction_offset;
149 u32 next_instruction;
150
151 // set of enabled fields (as a combination of Type flags)
152 unsigned mask = 0;
153 };
154
155 u32 max_offset; // maximum program counter ever reached
156 u32 max_opdesc_id; // maximum swizzle pattern index ever used
157
158 // List of records for each executed shader instruction
159 std::vector<DebugData<true>::Record> records;
160};
161
162// Type alias for better readability
163using DebugDataRecord = DebugData<true>::Record;
164
165// Helper function to set a DebugData<true>::Record field based on the template enum parameter.
166template <DebugDataRecord::Type type, typename ValueType>
167inline void SetField(DebugDataRecord& record, ValueType value);
168
169template <>
170inline void SetField<DebugDataRecord::SRC1>(DebugDataRecord& record, float24* value) {
171 record.src1.x = value[0];
172 record.src1.y = value[1];
173 record.src1.z = value[2];
174 record.src1.w = value[3];
175}
176
177template <>
178inline void SetField<DebugDataRecord::SRC2>(DebugDataRecord& record, float24* value) {
179 record.src2.x = value[0];
180 record.src2.y = value[1];
181 record.src2.z = value[2];
182 record.src2.w = value[3];
183}
184
185template <>
186inline void SetField<DebugDataRecord::SRC3>(DebugDataRecord& record, float24* value) {
187 record.src3.x = value[0];
188 record.src3.y = value[1];
189 record.src3.z = value[2];
190 record.src3.w = value[3];
191}
192
193template <>
194inline void SetField<DebugDataRecord::DEST_IN>(DebugDataRecord& record, float24* value) {
195 record.dest_in.x = value[0];
196 record.dest_in.y = value[1];
197 record.dest_in.z = value[2];
198 record.dest_in.w = value[3];
199}
200
201template <>
202inline void SetField<DebugDataRecord::DEST_OUT>(DebugDataRecord& record, float24* value) {
203 record.dest_out.x = value[0];
204 record.dest_out.y = value[1];
205 record.dest_out.z = value[2];
206 record.dest_out.w = value[3];
207}
208
209template <>
210inline void SetField<DebugDataRecord::ADDR_REG_OUT>(DebugDataRecord& record, s32* value) {
211 record.address_registers[0] = value[0];
212 record.address_registers[1] = value[1];
213}
214
215template <>
216inline void SetField<DebugDataRecord::CMP_RESULT>(DebugDataRecord& record, bool* value) {
217 record.conditional_code[0] = value[0];
218 record.conditional_code[1] = value[1];
219}
220
221template <>
222inline void SetField<DebugDataRecord::COND_BOOL_IN>(DebugDataRecord& record, bool value) {
223 record.cond_bool = value;
224}
225
226template <>
227inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool* value) {
228 record.cond_cmp[0] = value[0];
229 record.cond_cmp[1] = value[1];
230}
231
232template <>
233inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) {
234 record.loop_int = value;
235}
236
237template <>
238inline void SetField<DebugDataRecord::CUR_INSTR>(DebugDataRecord& record, u32 value) {
239 record.instruction_offset = value;
240}
241
242template <>
243inline void SetField<DebugDataRecord::NEXT_INSTR>(DebugDataRecord& record, u32 value) {
244 record.next_instruction = value;
245}
246
247// Helper function to set debug information on the current shader iteration.
248template <DebugDataRecord::Type type, typename ValueType>
249inline void Record(DebugData<false>& debug_data, u32 offset, ValueType value) {
250 // Debugging disabled => nothing to do
251}
252
253template <DebugDataRecord::Type type, typename ValueType>
254inline void Record(DebugData<true>& debug_data, u32 offset, ValueType value) {
255 if (offset >= debug_data.records.size())
256 debug_data.records.resize(offset + 1);
257
258 SetField<type, ValueType>(debug_data.records[offset], value);
259 debug_data.records[offset].mask |= type;
260}
261
262/** 91/**
263 * This structure contains the state information that needs to be unique for a shader unit. The 3DS 92 * This structure contains the state information that needs to be unique for a shader unit. The 3DS
264 * has four shader units that process shaders in parallel. At the present, Citra only implements a 93 * has four shader units that process shaders in parallel. At the present, Citra only implements a
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 6abb6761f..167f9edc3 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -6,6 +6,7 @@
6#include <array> 6#include <array>
7#include <cmath> 7#include <cmath>
8#include <numeric> 8#include <numeric>
9#include <boost/container/static_vector.hpp>
9#include <nihstro/shader_bytecode.h> 10#include <nihstro/shader_bytecode.h>
10#include "common/assert.h" 11#include "common/assert.h"
11#include "common/common_types.h" 12#include "common/common_types.h"