From b9d8d9383addaeced4047ce26c7c55200e4d32bc Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 10 Nov 2015 18:59:15 +0100 Subject: [PATCH] rsx/d3d12: dump program content when capturing frame --- rpcs3/Emu/RSX/Common/ProgramStateCache.h | 16 ++++++++++++++++ rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 2 ++ rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 7 ++++++- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 2 ++ rpcs3/Emu/RSX/RSXThread.cpp | 1 + rpcs3/Emu/RSX/RSXThread.h | 3 +++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index cfb07ff44d..af85971c80 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -294,6 +294,22 @@ public: clear(); } + const typename BackendTraits::VertexProgramData* get_transform_program(const RSXVertexProgram& rsx_vp) const noexcept + { + typename binary2VS::const_iterator It = m_cacheVS.find(rsx_vp.data); + if (It == m_cacheVS.end()) + return nullptr; + return &It->second; + } + + const typename BackendTraits::FragmentProgramData* get_shader_program(const RSXFragmentProgram& rsx_fp) const noexcept + { + typename binary2FS::const_iterator It = m_cacheFS.find(vm::base(rsx_fp.addr)); + if (It == m_cacheFS.end()) + return nullptr; + return &It->second; + } + void clear() { for (auto pair : m_cachePSO) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index d81af97d40..c306d9ee56 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -66,6 +66,7 @@ private: rsx::surface_info m_surface; + RSXVertexProgram vertex_program; RSXFragmentProgram fragment_program; PipelineStateObjectCache m_pso_cache; std::tuple, size_t> *m_current_pso; @@ -215,4 +216,5 @@ protected: virtual void copy_render_targets_to_memory(void *buffer, u8 rtt) override; virtual void copy_depth_buffer_to_memory(void *buffer) override; virtual void copy_stencil_buffer_to_memory(void *buffer) override; + virtual std::pair get_programs() const override; }; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 857433d895..360c8abba0 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -11,6 +11,7 @@ extern pD3DCompile wrapD3DCompile; void Shader::Compile(const std::string &code, SHADER_TYPE st) { + content = code; HRESULT hr; ComPtr errorBlob; UINT compileFlags; @@ -35,7 +36,6 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st) bool D3D12GSRender::load_program() { - RSXVertexProgram vertex_program; u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; vertex_program.data.reserve((512 - transform_program_start) * 4); @@ -246,4 +246,9 @@ bool D3D12GSRender::load_program() m_current_pso = m_pso_cache.getGraphicPipelineState(&vertex_program, &fragment_program, prop, std::make_pair(m_device.Get(), m_root_signatures)); return m_current_pso != nullptr; } + +std::pair D3D12GSRender::get_programs() const +{ + return std::make_pair(m_pso_cache.get_transform_program(vertex_program)->content, m_pso_cache.get_shader_program(fragment_program)->content); +} #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index f0766bfc4c..e496501984 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -91,6 +91,8 @@ public: u32 id; ComPtr bytecode; + // For debugging + std::string content; std::vector vertex_shader_inputs; std::vector FragmentConstantOffsetCache; size_t m_textureCount; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 4bec2f842d..60913cc382 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -939,6 +939,7 @@ namespace rsx draw_state.stencil.data.resize(clip_w * clip_h * 4); copy_stencil_buffer_to_memory(draw_state.stencil.data.data()); } + draw_state.programs = get_programs(); draw_state.name = name; frame_debug.draw_calls.push_back(draw_state); } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 33f57ba9ac..e7ecc9a970 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -24,6 +24,7 @@ struct frame_capture_data struct draw_state { std::string name; + std::pair programs; buffer color_buffer[4]; buffer depth; buffer stencil; @@ -284,6 +285,8 @@ namespace rsx * TODO: It's more efficient to combine multiple call of this function into one. */ virtual void copy_stencil_buffer_to_memory(void *buffer) {}; + + virtual std::pair get_programs() const { return std::make_pair("", ""); }; public: void reset(); void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);