diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index f9b456ea1d..106ff9143b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -211,7 +211,7 @@ bool D3D12GSRender::LoadProgram() return false; } - m_PSO = new D3D12PipelineState(m_device, m_cur_vertex_prog, m_cur_fragment_prog); + m_PSO = getGraphicPipelineState(m_device, m_cur_vertex_prog, m_cur_fragment_prog); return true; } @@ -226,7 +226,7 @@ void D3D12GSRender::ExecCMD() InitDrawBuffers(); - ID3D12CommandList *commandList; +// ID3D12CommandList *commandList; // m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList)); /* if (m_set_color_mask) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index bbc86c13be..c0a36a241d 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -47,7 +47,7 @@ private: // std::vector m_vdata; // std::vector m_post_draw_objs; - D3D12PipelineState *m_PSO; + ID3D12PipelineState *m_PSO; int m_fp_buf_num; int m_vp_buf_num; // GLProgramBuffer m_prog_buffer; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 173eb1066d..4e83f034ae 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -41,6 +41,7 @@ public: Shader() : bytecode(nullptr) {} ~Shader() {} + u32 Id; Microsoft::WRL::ComPtr bytecode; std::vector RSXBinary; @@ -198,13 +199,21 @@ struct FragmentProgramCompare typedef std::unordered_map binary2VS; typedef std::unordered_map binary2FS; -static int tmp = 0; + class ProgramBuffer { public: binary2VS cacheVS; binary2FS cacheFS; + // Key is vertex << 32 | fragment ids + std::unordered_map cachePSO; + + size_t currentShaderId; + + ProgramBuffer() : currentShaderId(0) + {} + bool SearchFp(const RSXFragmentProgram& rsx_fp, Shader& shader) { binary2FS::const_iterator It = cacheFS.find(vm::get_ptr(rsx_fp.addr)); @@ -227,78 +236,45 @@ public: return false; } -/* ID3D12PipelineState *GetProg(u32 fp, u32 vp) const + ID3D12PipelineState *GetProg(u32 fp, u32 vp) const { - if (fp == vp) - {*/ - /* - LOG_NOTICE(RSX, "Get program (%d):", fp); - LOG_NOTICE(RSX, "*** prog id = %d", m_buf[fp].prog_id); - LOG_NOTICE(RSX, "*** vp id = %d", m_buf[fp].vp_id); - LOG_NOTICE(RSX, "*** fp id = %d", m_buf[fp].fp_id); + u64 key = vp << 32 | fp; + std::unordered_map::const_iterator It = cachePSO.find(key); + if (It == cachePSO.end()) + return nullptr; + return It->second; + } - LOG_NOTICE(RSX, "*** vp shader = \n%s", m_buf[fp].vp_shader.wx_str()); - LOG_NOTICE(RSX, "*** fp shader = \n%s", m_buf[fp].fp_shader.wx_str()); - */ -/* return m_buf[fp].prog_id; - } - - for (u32 i = 0; i(rsx_fp.addr)); void *fpShadowCopy = malloc(actualFPSize); memcpy(fpShadowCopy, vm::get_ptr(rsx_fp.addr), actualFPSize); + fp.Id = currentShaderId++; cacheFS.insert(std::make_pair(fpShadowCopy, fp)); } - void Add(ID3D12PipelineState *prog, Shader& fp, RSXFragmentProgram& rsx_fp, Shader& vp, RSXVertexProgram& rsx_vp) + void Add(ID3D12PipelineState *prog, Shader& fp, Shader& vp) { -/* LOG_NOTICE(RSX, "Add program (%d):", m_buf.size()); - LOG_NOTICE(RSX, "*** prog id = %x", prog); - LOG_NOTICE(RSX, "*** vp id = %d", vp.id); - LOG_NOTICE(RSX, "*** fp id = %d", fp.id); - LOG_NOTICE(RSX, "*** vp data size = %d", rsx_vp.data.size() * 4); - LOG_NOTICE(RSX, "*** fp data size = %d", rsx_fp.size); - - LOG_NOTICE(RSX, "*** vp shader = \n%s", vp.shader.c_str()); - LOG_NOTICE(RSX, "*** fp shader = \n%s", fp.shader.c_str());*/ + u64 key = vp.Id << 32 | fp.Id; + cachePSO.insert(std::make_pair(key, prog)); } }; static ProgramBuffer g_cachedProgram; -D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader) +ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader) { + ID3D12PipelineState *result = nullptr; Shader m_vertex_prog, m_fragment_prog; bool m_fp_buf_num = g_cachedProgram.SearchFp(*fragmentShader, m_fragment_prog); bool m_vp_buf_num = g_cachedProgram.SearchVp(*vertexShader, m_vertex_prog); @@ -325,13 +301,12 @@ D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *v // fs::file("./VertexProgram.txt", o_write | o_create | o_trunc).write(m_vertex_prog.shader.c_str(), m_vertex_prog.shader.size()); } -// if (m_fp_buf_num != -1 && m_vp_buf_num != -1) - { -// m_program.id = m_prog_buffer.GetProg(m_fp_buf_num, m_vp_buf_num); - } + if (m_fp_buf_num && m_vp_buf_num) + result = g_cachedProgram.GetProg(m_fragment_prog.Id, m_vertex_prog.Id); - if (false)//m_program.id) + if (result != nullptr) { + return result; /* // RSX Debugger: Check if this program was modified and update it if (Ini.GSLogPrograms.GetValue()) { @@ -364,22 +339,21 @@ D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *v } else { + LOG_WARNING(RSX, "Add program :"); + LOG_WARNING(RSX, "*** vp id = %d", m_vertex_prog.Id); + LOG_WARNING(RSX, "*** fp id = %d", m_fragment_prog.Id); + D3D12_GRAPHICS_PIPELINE_STATE_DESC graphicPipelineStateDesc = {}; -/* graphicPipelineStateDesc.VS.BytecodeLength = m_vertex_prog.bytecode->GetBufferSize(); + graphicPipelineStateDesc.VS.BytecodeLength = m_vertex_prog.bytecode->GetBufferSize(); graphicPipelineStateDesc.VS.pShaderBytecode = m_vertex_prog.bytecode->GetBufferPointer(); graphicPipelineStateDesc.PS.BytecodeLength = m_fragment_prog.bytecode->GetBufferSize(); graphicPipelineStateDesc.PS.pShaderBytecode = m_fragment_prog.bytecode->GetBufferPointer(); - device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&m_pipelineStateObject));*/ - g_cachedProgram.Add(m_pipelineStateObject, m_fragment_prog, *fragmentShader, m_vertex_prog, *vertexShader); - /*m_program.Create(m_vertex_prog.id, m_fragment_prog.id); - checkForGlError("m_program.Create"); - m_prog_buffer.Add(m_program, m_fragment_prog, *m_cur_fragment_prog, m_vertex_prog, *m_cur_vertex_prog); - checkForGlError("m_prog_buffer.Add"); - m_program.Use(); + device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result)); + g_cachedProgram.Add(result, m_fragment_prog, m_vertex_prog); // RSX Debugger - if (Ini.GSLogPrograms.GetValue()) + /*if (Ini.GSLogPrograms.GetValue()) { RSXDebuggerProgram program; program.id = m_program.id; @@ -392,10 +366,5 @@ D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *v } } -D3D12PipelineState::~D3D12PipelineState() -{ - -} - #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 1916f1768c..f4b428f2a5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -5,13 +5,6 @@ #include "Emu/RSX/RSXFragmentProgram.h" #include "Emu/RSX/RSXVertexProgram.h" -class D3D12PipelineState -{ - ID3D12PipelineState *m_pipelineStateObject; - ID3D12RootSignature *m_rootSignature; -public: - D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader); - ~D3D12PipelineState(); -}; +ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader); #endif \ No newline at end of file