mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 15:31:26 +12:00
d3d12: PSO caching works
This commit is contained in:
parent
0ebc221011
commit
e58292bb11
4 changed files with 42 additions and 80 deletions
|
@ -211,7 +211,7 @@ bool D3D12GSRender::LoadProgram()
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ void D3D12GSRender::ExecCMD()
|
||||||
|
|
||||||
InitDrawBuffers();
|
InitDrawBuffers();
|
||||||
|
|
||||||
ID3D12CommandList *commandList;
|
// ID3D12CommandList *commandList;
|
||||||
// m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList));
|
// m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocator, nullptr, IID_PPV_ARGS(&commandList));
|
||||||
|
|
||||||
/* if (m_set_color_mask)
|
/* if (m_set_color_mask)
|
||||||
|
|
|
@ -47,7 +47,7 @@ private:
|
||||||
// std::vector<u8> m_vdata;
|
// std::vector<u8> m_vdata;
|
||||||
// std::vector<PostDrawObj> m_post_draw_objs;
|
// std::vector<PostDrawObj> m_post_draw_objs;
|
||||||
|
|
||||||
D3D12PipelineState *m_PSO;
|
ID3D12PipelineState *m_PSO;
|
||||||
int m_fp_buf_num;
|
int m_fp_buf_num;
|
||||||
int m_vp_buf_num;
|
int m_vp_buf_num;
|
||||||
// GLProgramBuffer m_prog_buffer;
|
// GLProgramBuffer m_prog_buffer;
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
Shader() : bytecode(nullptr) {}
|
Shader() : bytecode(nullptr) {}
|
||||||
~Shader() {}
|
~Shader() {}
|
||||||
|
|
||||||
|
u32 Id;
|
||||||
Microsoft::WRL::ComPtr<ID3DBlob> bytecode;
|
Microsoft::WRL::ComPtr<ID3DBlob> bytecode;
|
||||||
std::vector<u8> RSXBinary;
|
std::vector<u8> RSXBinary;
|
||||||
|
|
||||||
|
@ -198,13 +199,21 @@ struct FragmentProgramCompare
|
||||||
|
|
||||||
typedef std::unordered_map<void *, Shader, HashVertexProgram, VertexProgramCompare> binary2VS;
|
typedef std::unordered_map<void *, Shader, HashVertexProgram, VertexProgramCompare> binary2VS;
|
||||||
typedef std::unordered_map<void *, Shader, HashFragmentProgram, FragmentProgramCompare> binary2FS;
|
typedef std::unordered_map<void *, Shader, HashFragmentProgram, FragmentProgramCompare> binary2FS;
|
||||||
static int tmp = 0;
|
|
||||||
class ProgramBuffer
|
class ProgramBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
binary2VS cacheVS;
|
binary2VS cacheVS;
|
||||||
binary2FS cacheFS;
|
binary2FS cacheFS;
|
||||||
|
|
||||||
|
// Key is vertex << 32 | fragment ids
|
||||||
|
std::unordered_map<u64, ID3D12PipelineState *> cachePSO;
|
||||||
|
|
||||||
|
size_t currentShaderId;
|
||||||
|
|
||||||
|
ProgramBuffer() : currentShaderId(0)
|
||||||
|
{}
|
||||||
|
|
||||||
bool SearchFp(const RSXFragmentProgram& rsx_fp, Shader& shader)
|
bool SearchFp(const RSXFragmentProgram& rsx_fp, Shader& shader)
|
||||||
{
|
{
|
||||||
binary2FS::const_iterator It = cacheFS.find(vm::get_ptr<void>(rsx_fp.addr));
|
binary2FS::const_iterator It = cacheFS.find(vm::get_ptr<void>(rsx_fp.addr));
|
||||||
|
@ -227,78 +236,45 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID3D12PipelineState *GetProg(u32 fp, u32 vp) const
|
ID3D12PipelineState *GetProg(u32 fp, u32 vp) const
|
||||||
{
|
{
|
||||||
if (fp == vp)
|
u64 key = vp << 32 | fp;
|
||||||
{*/
|
std::unordered_map<u64, ID3D12PipelineState *>::const_iterator It = cachePSO.find(key);
|
||||||
/*
|
if (It == cachePSO.end())
|
||||||
LOG_NOTICE(RSX, "Get program (%d):", fp);
|
return nullptr;
|
||||||
LOG_NOTICE(RSX, "*** prog id = %d", m_buf[fp].prog_id);
|
return It->second;
|
||||||
LOG_NOTICE(RSX, "*** vp id = %d", m_buf[fp].vp_id);
|
|
||||||
LOG_NOTICE(RSX, "*** fp id = %d", m_buf[fp].fp_id);
|
|
||||||
|
|
||||||
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<m_buf.size(); ++i)
|
void AddVertexProgram(Shader& vp, RSXVertexProgram& rsx_vp)
|
||||||
{
|
|
||||||
if (i == fp || i == vp) continue;*/
|
|
||||||
|
|
||||||
// if (CmpVP(vp, i) && CmpFP(fp, i))
|
|
||||||
// {
|
|
||||||
/*
|
|
||||||
LOG_NOTICE(RSX, "Get program (%d):", i);
|
|
||||||
LOG_NOTICE(RSX, "*** prog id = %d", m_buf[i].prog_id);
|
|
||||||
LOG_NOTICE(RSX, "*** vp id = %d", m_buf[i].vp_id);
|
|
||||||
LOG_NOTICE(RSX, "*** fp id = %d", m_buf[i].fp_id);
|
|
||||||
|
|
||||||
LOG_NOTICE(RSX, "*** vp shader = \n%s", m_buf[i].vp_shader.wx_str());
|
|
||||||
LOG_NOTICE(RSX, "*** fp shader = \n%s", m_buf[i].fp_shader.wx_str());
|
|
||||||
*/
|
|
||||||
/* return m_buf[i].prog_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void AddVertexProgram(const Shader& vp, RSXVertexProgram& rsx_vp)
|
|
||||||
{
|
{
|
||||||
size_t actualVPSize = rsx_vp.data.size() * 4;
|
size_t actualVPSize = rsx_vp.data.size() * 4;
|
||||||
void *fpShadowCopy = malloc(actualVPSize);
|
void *fpShadowCopy = malloc(actualVPSize);
|
||||||
memcpy(fpShadowCopy, rsx_vp.data.data(), actualVPSize);
|
memcpy(fpShadowCopy, rsx_vp.data.data(), actualVPSize);
|
||||||
|
vp.Id = currentShaderId++;
|
||||||
cacheVS.insert(std::make_pair(fpShadowCopy, vp));
|
cacheVS.insert(std::make_pair(fpShadowCopy, vp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddFragmentProgram(const Shader& fp, RSXFragmentProgram& rsx_fp)
|
void AddFragmentProgram(Shader& fp, RSXFragmentProgram& rsx_fp)
|
||||||
{
|
{
|
||||||
size_t actualFPSize = getFPBinarySize(vm::get_ptr<u8>(rsx_fp.addr));
|
size_t actualFPSize = getFPBinarySize(vm::get_ptr<u8>(rsx_fp.addr));
|
||||||
void *fpShadowCopy = malloc(actualFPSize);
|
void *fpShadowCopy = malloc(actualFPSize);
|
||||||
memcpy(fpShadowCopy, vm::get_ptr<u8>(rsx_fp.addr), actualFPSize);
|
memcpy(fpShadowCopy, vm::get_ptr<u8>(rsx_fp.addr), actualFPSize);
|
||||||
|
fp.Id = currentShaderId++;
|
||||||
cacheFS.insert(std::make_pair(fpShadowCopy, fp));
|
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());
|
u64 key = vp.Id << 32 | fp.Id;
|
||||||
LOG_NOTICE(RSX, "*** prog id = %x", prog);
|
cachePSO.insert(std::make_pair(key, 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());*/
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static ProgramBuffer g_cachedProgram;
|
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;
|
Shader m_vertex_prog, m_fragment_prog;
|
||||||
bool m_fp_buf_num = g_cachedProgram.SearchFp(*fragmentShader, 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);
|
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());
|
// 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)
|
if (m_fp_buf_num && m_vp_buf_num)
|
||||||
{
|
result = g_cachedProgram.GetProg(m_fragment_prog.Id, m_vertex_prog.Id);
|
||||||
// m_program.id = m_prog_buffer.GetProg(m_fp_buf_num, m_vp_buf_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false)//m_program.id)
|
if (result != nullptr)
|
||||||
{
|
{
|
||||||
|
return result;
|
||||||
/* // RSX Debugger: Check if this program was modified and update it
|
/* // RSX Debugger: Check if this program was modified and update it
|
||||||
if (Ini.GSLogPrograms.GetValue())
|
if (Ini.GSLogPrograms.GetValue())
|
||||||
{
|
{
|
||||||
|
@ -364,22 +339,21 @@ D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *v
|
||||||
}
|
}
|
||||||
else
|
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 = {};
|
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.VS.pShaderBytecode = m_vertex_prog.bytecode->GetBufferPointer();
|
||||||
graphicPipelineStateDesc.PS.BytecodeLength = m_fragment_prog.bytecode->GetBufferSize();
|
graphicPipelineStateDesc.PS.BytecodeLength = m_fragment_prog.bytecode->GetBufferSize();
|
||||||
graphicPipelineStateDesc.PS.pShaderBytecode = m_fragment_prog.bytecode->GetBufferPointer();
|
graphicPipelineStateDesc.PS.pShaderBytecode = m_fragment_prog.bytecode->GetBufferPointer();
|
||||||
device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&m_pipelineStateObject));*/
|
device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result));
|
||||||
g_cachedProgram.Add(m_pipelineStateObject, m_fragment_prog, *fragmentShader, m_vertex_prog, *vertexShader);
|
g_cachedProgram.Add(result, m_fragment_prog, m_vertex_prog);
|
||||||
/*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();
|
|
||||||
|
|
||||||
// RSX Debugger
|
// RSX Debugger
|
||||||
if (Ini.GSLogPrograms.GetValue())
|
/*if (Ini.GSLogPrograms.GetValue())
|
||||||
{
|
{
|
||||||
RSXDebuggerProgram program;
|
RSXDebuggerProgram program;
|
||||||
program.id = m_program.id;
|
program.id = m_program.id;
|
||||||
|
@ -392,10 +366,5 @@ D3D12PipelineState::D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12PipelineState::~D3D12PipelineState()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -5,13 +5,6 @@
|
||||||
#include "Emu/RSX/RSXFragmentProgram.h"
|
#include "Emu/RSX/RSXFragmentProgram.h"
|
||||||
#include "Emu/RSX/RSXVertexProgram.h"
|
#include "Emu/RSX/RSXVertexProgram.h"
|
||||||
|
|
||||||
class D3D12PipelineState
|
ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader);
|
||||||
{
|
|
||||||
ID3D12PipelineState *m_pipelineStateObject;
|
|
||||||
ID3D12RootSignature *m_rootSignature;
|
|
||||||
public:
|
|
||||||
D3D12PipelineState(ID3D12Device *device, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader);
|
|
||||||
~D3D12PipelineState();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue