diff options
Diffstat (limited to 'src/video_core/debug_utils')
-rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 99 | ||||
-rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 19 |
2 files changed, 82 insertions, 36 deletions
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 6d6b65286..8ad77f0c8 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -4,9 +4,10 @@ #include <algorithm> #include <condition_variable> +#include <cstring> +#include <fstream> #include <list> #include <map> -#include <fstream> #include <mutex> #include <string> @@ -14,6 +15,7 @@ #include <png.h> #endif +#include <nihstro/float24.h> #include <nihstro/shader_binary.h> #include "common/assert.h" @@ -63,7 +65,7 @@ void DebugContext::OnEvent(Event event, void* data) { void DebugContext::Resume() { { - std::unique_lock<std::mutex> lock(breakpoint_mutex); + std::lock_guard<std::mutex> lock(breakpoint_mutex); // Tell all observers that we are about to resume for (auto& breakpoint_observer : breakpoint_observers) { @@ -110,8 +112,7 @@ void GeometryDumper::Dump() { } -void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, - u32 main_offset, const Regs::VSOutputAttributes* output_attributes) +void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes) { struct StuffToWrite { u8* pointer; @@ -131,11 +132,14 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data // into shbin format (separate type and component mask). union OutputRegisterInfo { enum Type : u64 { - POSITION = 0, - COLOR = 2, - TEXCOORD0 = 3, - TEXCOORD1 = 5, - TEXCOORD2 = 6, + POSITION = 0, + QUATERNION = 1, + COLOR = 2, + TEXCOORD0 = 3, + TEXCOORD1 = 5, + TEXCOORD2 = 6, + + VIEW = 8, }; BitField< 0, 64, u64> hex; @@ -157,6 +161,10 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data { OutputAttributes::POSITION_Y, { OutputRegisterInfo::POSITION, 2} }, { OutputAttributes::POSITION_Z, { OutputRegisterInfo::POSITION, 4} }, { OutputAttributes::POSITION_W, { OutputRegisterInfo::POSITION, 8} }, + { OutputAttributes::QUATERNION_X, { OutputRegisterInfo::QUATERNION, 1} }, + { OutputAttributes::QUATERNION_Y, { OutputRegisterInfo::QUATERNION, 2} }, + { OutputAttributes::QUATERNION_Z, { OutputRegisterInfo::QUATERNION, 4} }, + { OutputAttributes::QUATERNION_W, { OutputRegisterInfo::QUATERNION, 8} }, { OutputAttributes::COLOR_R, { OutputRegisterInfo::COLOR, 1} }, { OutputAttributes::COLOR_G, { OutputRegisterInfo::COLOR, 2} }, { OutputAttributes::COLOR_B, { OutputRegisterInfo::COLOR, 4} }, @@ -166,7 +174,10 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data { OutputAttributes::TEXCOORD1_U, { OutputRegisterInfo::TEXCOORD1, 1} }, { OutputAttributes::TEXCOORD1_V, { OutputRegisterInfo::TEXCOORD1, 2} }, { OutputAttributes::TEXCOORD2_U, { OutputRegisterInfo::TEXCOORD2, 1} }, - { OutputAttributes::TEXCOORD2_V, { OutputRegisterInfo::TEXCOORD2, 2} } + { OutputAttributes::TEXCOORD2_V, { OutputRegisterInfo::TEXCOORD2, 2} }, + { OutputAttributes::VIEW_X, { OutputRegisterInfo::VIEW, 1} }, + { OutputAttributes::VIEW_Y, { OutputRegisterInfo::VIEW, 2} }, + { OutputAttributes::VIEW_Z, { OutputRegisterInfo::VIEW, 4} } }; for (const auto& semantic : std::vector<OutputAttributes::Semantic>{ @@ -221,28 +232,69 @@ void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data // TODO: Reduce the amount of binary code written to relevant portions dvlp.binary_offset = write_offset - dvlp_offset; - dvlp.binary_size_words = binary_size; - QueueForWriting((u8*)binary_data, binary_size * sizeof(u32)); + dvlp.binary_size_words = setup.program_code.size(); + QueueForWriting((u8*)setup.program_code.data(), setup.program_code.size() * sizeof(u32)); dvlp.swizzle_info_offset = write_offset - dvlp_offset; - dvlp.swizzle_info_num_entries = swizzle_size; + dvlp.swizzle_info_num_entries = setup.swizzle_data.size(); u32 dummy = 0; - for (unsigned int i = 0; i < swizzle_size; ++i) { - QueueForWriting((u8*)&swizzle_data[i], sizeof(swizzle_data[i])); + for (unsigned int i = 0; i < setup.swizzle_data.size(); ++i) { + QueueForWriting((u8*)&setup.swizzle_data[i], sizeof(setup.swizzle_data[i])); QueueForWriting((u8*)&dummy, sizeof(dummy)); } - dvle.main_offset_words = main_offset; + dvle.main_offset_words = config.main_offset; dvle.output_register_table_offset = write_offset - dvlb.dvle_offset; dvle.output_register_table_size = static_cast<u32>(output_info_table.size()); QueueForWriting((u8*)output_info_table.data(), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo))); // TODO: Create a label table for "main" + std::vector<nihstro::ConstantInfo> constant_table; + for (unsigned i = 0; i < setup.uniforms.b.size(); ++i) { + nihstro::ConstantInfo constant; + memset(&constant, 0, sizeof(constant)); + constant.type = nihstro::ConstantInfo::Bool; + constant.regid = i; + constant.b = setup.uniforms.b[i]; + constant_table.emplace_back(constant); + } + for (unsigned i = 0; i < setup.uniforms.i.size(); ++i) { + nihstro::ConstantInfo constant; + memset(&constant, 0, sizeof(constant)); + constant.type = nihstro::ConstantInfo::Int; + constant.regid = i; + constant.i.x = setup.uniforms.i[i].x; + constant.i.y = setup.uniforms.i[i].y; + constant.i.z = setup.uniforms.i[i].z; + constant.i.w = setup.uniforms.i[i].w; + constant_table.emplace_back(constant); + } + for (unsigned i = 0; i < sizeof(setup.uniforms.f) / sizeof(setup.uniforms.f[0]); ++i) { + nihstro::ConstantInfo constant; + memset(&constant, 0, sizeof(constant)); + constant.type = nihstro::ConstantInfo::Float; + constant.regid = i; + constant.f.x = nihstro::to_float24(setup.uniforms.f[i].x.ToFloat32()); + constant.f.y = nihstro::to_float24(setup.uniforms.f[i].y.ToFloat32()); + constant.f.z = nihstro::to_float24(setup.uniforms.f[i].z.ToFloat32()); + constant.f.w = nihstro::to_float24(setup.uniforms.f[i].w.ToFloat32()); + + // Store constant if it's different from zero.. + if (setup.uniforms.f[i].x.ToFloat32() != 0.0 || + setup.uniforms.f[i].y.ToFloat32() != 0.0 || + setup.uniforms.f[i].z.ToFloat32() != 0.0 || + setup.uniforms.f[i].w.ToFloat32() != 0.0) + constant_table.emplace_back(constant); + } + dvle.constant_table_offset = write_offset - dvlb.dvle_offset; + dvle.constant_table_size = constant_table.size(); + for (const auto& constant : constant_table) { + QueueForWriting((uint8_t*)&constant, sizeof(constant)); + } // Write data to file static int dump_index = 0; - std::string filename = std::string("shader_dump") + std::to_string(++dump_index) + std::string(".shbin"); std::ofstream file(filename, std::ios_base::out | std::ios_base::binary); for (auto& chunk : writing_queue) { @@ -261,11 +313,10 @@ void StartPicaTracing() return; } - pica_trace_mutex.lock(); + std::lock_guard<std::mutex> lock(pica_trace_mutex); pica_trace = std::unique_ptr<PicaTrace>(new PicaTrace); is_pica_tracing = true; - pica_trace_mutex.unlock(); } bool IsPicaTracing() @@ -273,18 +324,18 @@ bool IsPicaTracing() return is_pica_tracing != 0; } -void OnPicaRegWrite(u32 id, u32 value) +void OnPicaRegWrite(PicaTrace::Write write) { // Double check for is_pica_tracing to avoid pointless locking overhead if (!is_pica_tracing) return; - std::unique_lock<std::mutex> lock(pica_trace_mutex); + std::lock_guard<std::mutex> lock(pica_trace_mutex); if (!is_pica_tracing) return; - pica_trace->writes.emplace_back(id, value); + pica_trace->writes.push_back(write); } std::unique_ptr<PicaTrace> FinishPicaTracing() @@ -298,9 +349,9 @@ std::unique_ptr<PicaTrace> FinishPicaTracing() is_pica_tracing = false; // Wait until running tracing is finished - pica_trace_mutex.lock(); + std::lock_guard<std::mutex> lock(pica_trace_mutex); std::unique_ptr<PicaTrace> ret(std::move(pica_trace)); - pica_trace_mutex.unlock(); + return std::move(ret); } diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 81eea30a9..85762f5b4 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 namespace DebugUtils { #define PICA_DUMP_GEOMETRY 0 -#define PICA_DUMP_SHADERS 0 #define PICA_DUMP_TEXTURES 0 #define PICA_LOG_TEV 0 @@ -182,27 +181,23 @@ private: std::vector<Face> faces; }; -void DumpShader(const u32* binary_data, u32 binary_size, const u32* swizzle_data, u32 swizzle_size, - u32 main_offset, const Regs::VSOutputAttributes* output_attributes); +void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, + const State::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes); // Utility class to log Pica commands. struct PicaTrace { - struct Write : public std::pair<u32,u32> { - Write(u32 id, u32 value) : std::pair<u32,u32>(id, value) {} - - u32& Id() { return first; } - const u32& Id() const { return first; } - - u32& Value() { return second; } - const u32& Value() const { return second; } + struct Write { + u16 cmd_id; + u16 mask; + u32 value; }; std::vector<Write> writes; }; void StartPicaTracing(); bool IsPicaTracing(); -void OnPicaRegWrite(u32 id, u32 value); +void OnPicaRegWrite(PicaTrace::Write write); std::unique_ptr<PicaTrace> FinishPicaTracing(); struct TextureInfo { |