diff options
| author | 2015-08-16 13:18:56 +0200 | |
|---|---|---|
| committer | 2015-08-16 13:18:56 +0200 | |
| commit | 7312894a6a1a1600629f2eaec8843508a2fd3578 (patch) | |
| tree | 4f67fb221da50ada7a62efc45788d16950ef16f6 /src/video_core/debug_utils | |
| parent | Merge pull request #1033 from bbarenblat/master (diff) | |
| parent | citra-qt/VertexShader: Minor UI improvements. (diff) | |
| download | yuzu-7312894a6a1a1600629f2eaec8843508a2fd3578.tar.gz yuzu-7312894a6a1a1600629f2eaec8843508a2fd3578.tar.xz yuzu-7312894a6a1a1600629f2eaec8843508a2fd3578.zip | |
Merge pull request #933 from neobrain/shader_debugger
Shader debugger improvements
Diffstat (limited to 'src/video_core/debug_utils')
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 81 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 5 |
2 files changed, 68 insertions, 18 deletions
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 572b4fd62..ac071790a 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <png.h> | 14 | #include <png.h> |
| 15 | #endif | 15 | #endif |
| 16 | 16 | ||
| 17 | #include <nihstro/float24.h> | ||
| 17 | #include <nihstro/shader_binary.h> | 18 | #include <nihstro/shader_binary.h> |
| 18 | 19 | ||
| 19 | #include "common/assert.h" | 20 | #include "common/assert.h" |
| @@ -110,8 +111,7 @@ void GeometryDumper::Dump() { | |||
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | 113 | ||
| 113 | void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, | 114 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes) |
| 114 | u32 main_offset, const Regs::VSOutputAttributes* output_attributes) | ||
| 115 | { | 115 | { |
| 116 | struct StuffToWrite { | 116 | struct StuffToWrite { |
| 117 | u8* pointer; | 117 | u8* pointer; |
| @@ -131,11 +131,14 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data | |||
| 131 | // into shbin format (separate type and component mask). | 131 | // into shbin format (separate type and component mask). |
| 132 | union OutputRegisterInfo { | 132 | union OutputRegisterInfo { |
| 133 | enum Type : u64 { | 133 | enum Type : u64 { |
| 134 | POSITION = 0, | 134 | POSITION = 0, |
| 135 | COLOR = 2, | 135 | QUATERNION = 1, |
| 136 | TEXCOORD0 = 3, | 136 | COLOR = 2, |
| 137 | TEXCOORD1 = 5, | 137 | TEXCOORD0 = 3, |
| 138 | TEXCOORD2 = 6, | 138 | TEXCOORD1 = 5, |
| 139 | TEXCOORD2 = 6, | ||
| 140 | |||
| 141 | VIEW = 8, | ||
| 139 | }; | 142 | }; |
| 140 | 143 | ||
| 141 | BitField< 0, 64, u64> hex; | 144 | BitField< 0, 64, u64> hex; |
| @@ -157,6 +160,10 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data | |||
| 157 | { OutputAttributes::POSITION_Y, { OutputRegisterInfo::POSITION, 2} }, | 160 | { OutputAttributes::POSITION_Y, { OutputRegisterInfo::POSITION, 2} }, |
| 158 | { OutputAttributes::POSITION_Z, { OutputRegisterInfo::POSITION, 4} }, | 161 | { OutputAttributes::POSITION_Z, { OutputRegisterInfo::POSITION, 4} }, |
| 159 | { OutputAttributes::POSITION_W, { OutputRegisterInfo::POSITION, 8} }, | 162 | { OutputAttributes::POSITION_W, { OutputRegisterInfo::POSITION, 8} }, |
| 163 | { OutputAttributes::QUATERNION_X, { OutputRegisterInfo::QUATERNION, 1} }, | ||
| 164 | { OutputAttributes::QUATERNION_Y, { OutputRegisterInfo::QUATERNION, 2} }, | ||
| 165 | { OutputAttributes::QUATERNION_Z, { OutputRegisterInfo::QUATERNION, 4} }, | ||
| 166 | { OutputAttributes::QUATERNION_W, { OutputRegisterInfo::QUATERNION, 8} }, | ||
| 160 | { OutputAttributes::COLOR_R, { OutputRegisterInfo::COLOR, 1} }, | 167 | { OutputAttributes::COLOR_R, { OutputRegisterInfo::COLOR, 1} }, |
| 161 | { OutputAttributes::COLOR_G, { OutputRegisterInfo::COLOR, 2} }, | 168 | { OutputAttributes::COLOR_G, { OutputRegisterInfo::COLOR, 2} }, |
| 162 | { OutputAttributes::COLOR_B, { OutputRegisterInfo::COLOR, 4} }, | 169 | { OutputAttributes::COLOR_B, { OutputRegisterInfo::COLOR, 4} }, |
| @@ -166,7 +173,10 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data | |||
| 166 | { OutputAttributes::TEXCOORD1_U, { OutputRegisterInfo::TEXCOORD1, 1} }, | 173 | { OutputAttributes::TEXCOORD1_U, { OutputRegisterInfo::TEXCOORD1, 1} }, |
| 167 | { OutputAttributes::TEXCOORD1_V, { OutputRegisterInfo::TEXCOORD1, 2} }, | 174 | { OutputAttributes::TEXCOORD1_V, { OutputRegisterInfo::TEXCOORD1, 2} }, |
| 168 | { OutputAttributes::TEXCOORD2_U, { OutputRegisterInfo::TEXCOORD2, 1} }, | 175 | { OutputAttributes::TEXCOORD2_U, { OutputRegisterInfo::TEXCOORD2, 1} }, |
| 169 | { OutputAttributes::TEXCOORD2_V, { OutputRegisterInfo::TEXCOORD2, 2} } | 176 | { OutputAttributes::TEXCOORD2_V, { OutputRegisterInfo::TEXCOORD2, 2} }, |
| 177 | { OutputAttributes::VIEW_X, { OutputRegisterInfo::VIEW, 1} }, | ||
| 178 | { OutputAttributes::VIEW_Y, { OutputRegisterInfo::VIEW, 2} }, | ||
| 179 | { OutputAttributes::VIEW_Z, { OutputRegisterInfo::VIEW, 4} } | ||
| 170 | }; | 180 | }; |
| 171 | 181 | ||
| 172 | for (const auto& semantic : std::vector<OutputAttributes::Semantic>{ | 182 | for (const auto& semantic : std::vector<OutputAttributes::Semantic>{ |
| @@ -221,28 +231,69 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data | |||
| 221 | 231 | ||
| 222 | // TODO: Reduce the amount of binary code written to relevant portions | 232 | // TODO: Reduce the amount of binary code written to relevant portions |
| 223 | dvlp.binary_offset = write_offset - dvlp_offset; | 233 | dvlp.binary_offset = write_offset - dvlp_offset; |
| 224 | dvlp.binary_size_words = binary_size; | 234 | dvlp.binary_size_words = setup.program_code.size(); |
| 225 | QueueForWriting((u8*)binary_data, binary_size * sizeof(u32)); | 235 | QueueForWriting((u8*)setup.program_code.data(), setup.program_code.size() * sizeof(u32)); |
| 226 | 236 | ||
| 227 | dvlp.swizzle_info_offset = write_offset - dvlp_offset; | 237 | dvlp.swizzle_info_offset = write_offset - dvlp_offset; |
| 228 | dvlp.swizzle_info_num_entries = swizzle_size; | 238 | dvlp.swizzle_info_num_entries = setup.swizzle_data.size(); |
| 229 | u32 dummy = 0; | 239 | u32 dummy = 0; |
| 230 | for (unsigned int i = 0; i < swizzle_size; ++i) { | 240 | for (unsigned int i = 0; i < setup.swizzle_data.size(); ++i) { |
| 231 | QueueForWriting((u8*)&swizzle_data[i], sizeof(swizzle_data[i])); | 241 | QueueForWriting((u8*)&setup.swizzle_data[i], sizeof(setup.swizzle_data[i])); |
| 232 | QueueForWriting((u8*)&dummy, sizeof(dummy)); | 242 | QueueForWriting((u8*)&dummy, sizeof(dummy)); |
| 233 | } | 243 | } |
| 234 | 244 | ||
| 235 | dvle.main_offset_words = main_offset; | 245 | dvle.main_offset_words = config.main_offset; |
| 236 | dvle.output_register_table_offset = write_offset - dvlb.dvle_offset; | 246 | dvle.output_register_table_offset = write_offset - dvlb.dvle_offset; |
| 237 | dvle.output_register_table_size = static_cast<u32>(output_info_table.size()); | 247 | dvle.output_register_table_size = static_cast<u32>(output_info_table.size()); |
| 238 | QueueForWriting((u8*)output_info_table.data(), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo))); | 248 | QueueForWriting((u8*)output_info_table.data(), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo))); |
| 239 | 249 | ||
| 240 | // TODO: Create a label table for "main" | 250 | // TODO: Create a label table for "main" |
| 241 | 251 | ||
| 252 | std::vector<nihstro::ConstantInfo> constant_table; | ||
| 253 | for (unsigned i = 0; i < setup.uniforms.b.size(); ++i) { | ||
| 254 | nihstro::ConstantInfo constant; | ||
| 255 | memset(&constant, 0, sizeof(constant)); | ||
| 256 | constant.type = nihstro::ConstantInfo::Bool; | ||
| 257 | constant.regid = i; | ||
| 258 | constant.b = setup.uniforms.b[i]; | ||
| 259 | constant_table.emplace_back(constant); | ||
| 260 | } | ||
| 261 | for (unsigned i = 0; i < setup.uniforms.i.size(); ++i) { | ||
| 262 | nihstro::ConstantInfo constant; | ||
| 263 | memset(&constant, 0, sizeof(constant)); | ||
| 264 | constant.type = nihstro::ConstantInfo::Int; | ||
| 265 | constant.regid = i; | ||
| 266 | constant.i.x = setup.uniforms.i[i].x; | ||
| 267 | constant.i.y = setup.uniforms.i[i].y; | ||
| 268 | constant.i.z = setup.uniforms.i[i].z; | ||
| 269 | constant.i.w = setup.uniforms.i[i].w; | ||
| 270 | constant_table.emplace_back(constant); | ||
| 271 | } | ||
| 272 | for (unsigned i = 0; i < sizeof(setup.uniforms.f) / sizeof(setup.uniforms.f[0]); ++i) { | ||
| 273 | nihstro::ConstantInfo constant; | ||
| 274 | memset(&constant, 0, sizeof(constant)); | ||
| 275 | constant.type = nihstro::ConstantInfo::Float; | ||
| 276 | constant.regid = i; | ||
| 277 | constant.f.x = nihstro::to_float24(setup.uniforms.f[i].x.ToFloat32()); | ||
| 278 | constant.f.y = nihstro::to_float24(setup.uniforms.f[i].y.ToFloat32()); | ||
| 279 | constant.f.z = nihstro::to_float24(setup.uniforms.f[i].z.ToFloat32()); | ||
| 280 | constant.f.w = nihstro::to_float24(setup.uniforms.f[i].w.ToFloat32()); | ||
| 281 | |||
| 282 | // Store constant if it's different from zero.. | ||
| 283 | if (setup.uniforms.f[i].x.ToFloat32() != 0.0 || | ||
| 284 | setup.uniforms.f[i].y.ToFloat32() != 0.0 || | ||
| 285 | setup.uniforms.f[i].z.ToFloat32() != 0.0 || | ||
| 286 | setup.uniforms.f[i].w.ToFloat32() != 0.0) | ||
| 287 | constant_table.emplace_back(constant); | ||
| 288 | } | ||
| 289 | dvle.constant_table_offset = write_offset - dvlb.dvle_offset; | ||
| 290 | dvle.constant_table_size = constant_table.size(); | ||
| 291 | for (const auto& constant : constant_table) { | ||
| 292 | QueueForWriting((uint8_t*)&constant, sizeof(constant)); | ||
| 293 | } | ||
| 242 | 294 | ||
| 243 | // Write data to file | 295 | // Write data to file |
| 244 | static int dump_index = 0; | 296 | static int dump_index = 0; |
| 245 | std::string filename = std::string("shader_dump") + std::to_string(++dump_index) + std::string(".shbin"); | ||
| 246 | std::ofstream file(filename, std::ios_base::out | std::ios_base::binary); | 297 | std::ofstream file(filename, std::ios_base::out | std::ios_base::binary); |
| 247 | 298 | ||
| 248 | for (auto& chunk : writing_queue) { | 299 | for (auto& chunk : writing_queue) { |
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 81eea30a9..0b30d7ffa 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h | |||
| @@ -158,7 +158,6 @@ extern std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this g | |||
| 158 | namespace DebugUtils { | 158 | namespace DebugUtils { |
| 159 | 159 | ||
| 160 | #define PICA_DUMP_GEOMETRY 0 | 160 | #define PICA_DUMP_GEOMETRY 0 |
| 161 | #define PICA_DUMP_SHADERS 0 | ||
| 162 | #define PICA_DUMP_TEXTURES 0 | 161 | #define PICA_DUMP_TEXTURES 0 |
| 163 | #define PICA_LOG_TEV 0 | 162 | #define PICA_LOG_TEV 0 |
| 164 | 163 | ||
| @@ -182,8 +181,8 @@ private: | |||
| 182 | std::vector<Face> faces; | 181 | std::vector<Face> faces; |
| 183 | }; | 182 | }; |
| 184 | 183 | ||
| 185 | void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, | 184 | void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, |
| 186 | u32 main_offset, const Regs::VSOutputAttributes* output_attributes); | 185 | const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes); |
| 187 | 186 | ||
| 188 | 187 | ||
| 189 | // Utility class to log Pica commands. | 188 | // Utility class to log Pica commands. |