mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-09 09:39:44 +00:00
d3d12: cache PSO State too
This commit is contained in:
parent
da5b047c58
commit
75219be066
3 changed files with 62 additions and 18 deletions
|
@ -457,7 +457,10 @@ bool D3D12GSRender::LoadProgram()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PSO = m_cachePSO.getGraphicPipelineState(m_device, m_rootSignature, m_cur_vertex_prog, m_cur_fragment_prog, m_IASet);
|
PipelineProperties prop = {};
|
||||||
|
prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
|
|
||||||
|
m_PSO = m_cachePSO.getGraphicPipelineState(m_device, m_rootSignature, m_cur_vertex_prog, m_cur_fragment_prog, prop, m_IASet);
|
||||||
return m_PSO != nullptr;
|
return m_PSO != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,9 @@ bool PipelineStateObjectCache::SearchVp(const RSXVertexProgram& rsx_vp, Shader&
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12PipelineState *PipelineStateObjectCache::GetProg(u32 fp, u32 vp) const
|
ID3D12PipelineState *PipelineStateObjectCache::GetProg(const PSOKey &key) const
|
||||||
{
|
{
|
||||||
u64 vpLong = vp;
|
std::unordered_map<PSOKey, ID3D12PipelineState *, PSOKeyHash, PSOKeyCompare>::const_iterator It = m_cachePSO.find(key);
|
||||||
u64 key = vpLong << 32 | fp;
|
|
||||||
std::unordered_map<u64, ID3D12PipelineState *>::const_iterator It = m_cachePSO.find(key);
|
|
||||||
if (It == m_cachePSO.end())
|
if (It == m_cachePSO.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return It->second;
|
return It->second;
|
||||||
|
@ -86,14 +84,18 @@ void PipelineStateObjectCache::AddFragmentProgram(Shader& fp, RSXFragmentProgram
|
||||||
m_cacheFS.insert(std::make_pair(fpShadowCopy, fp));
|
m_cacheFS.insert(std::make_pair(fpShadowCopy, fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineStateObjectCache::Add(ID3D12PipelineState *prog, Shader& fp, Shader& vp)
|
void PipelineStateObjectCache::Add(ID3D12PipelineState *prog, const PSOKey& PSOKey)
|
||||||
{
|
{
|
||||||
u64 vpLong = vp.Id;
|
m_cachePSO.insert(std::make_pair(PSOKey, prog));
|
||||||
u64 key = vpLong << 32 | fp.Id;
|
|
||||||
m_cachePSO.insert(std::make_pair(key, prog));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Device *device, ID3D12RootSignature *rootSignature, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader, const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet)
|
ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(
|
||||||
|
ID3D12Device *device,
|
||||||
|
ID3D12RootSignature *rootSignature,
|
||||||
|
RSXVertexProgram *vertexShader,
|
||||||
|
RSXFragmentProgram *fragmentShader,
|
||||||
|
const PipelineProperties &pipelineProperties,
|
||||||
|
const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet)
|
||||||
{
|
{
|
||||||
ID3D12PipelineState *result = nullptr;
|
ID3D12PipelineState *result = nullptr;
|
||||||
Shader m_vertex_prog, m_fragment_prog;
|
Shader m_vertex_prog, m_fragment_prog;
|
||||||
|
@ -123,7 +125,9 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fp_buf_num && m_vp_buf_num)
|
if (m_fp_buf_num && m_vp_buf_num)
|
||||||
result = GetProg(m_fragment_prog.Id, m_vertex_prog.Id);
|
{
|
||||||
|
result = GetProg({ m_vertex_prog.Id, m_fragment_prog.Id, pipelineProperties });
|
||||||
|
}
|
||||||
|
|
||||||
if (result != nullptr)
|
if (result != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -221,7 +225,7 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||||
graphicPipelineStateDesc.BlendState = CD3D12_BLEND_DESC;
|
graphicPipelineStateDesc.BlendState = CD3D12_BLEND_DESC;
|
||||||
graphicPipelineStateDesc.DepthStencilState = CD3D12_DEPTH_STENCIL_DESC;
|
graphicPipelineStateDesc.DepthStencilState = CD3D12_DEPTH_STENCIL_DESC;
|
||||||
graphicPipelineStateDesc.RasterizerState = CD3D12_RASTERIZER_DESC;
|
graphicPipelineStateDesc.RasterizerState = CD3D12_RASTERIZER_DESC;
|
||||||
graphicPipelineStateDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
graphicPipelineStateDesc.PrimitiveTopologyType = pipelineProperties.Topology;
|
||||||
|
|
||||||
graphicPipelineStateDesc.NumRenderTargets = 1;
|
graphicPipelineStateDesc.NumRenderTargets = 1;
|
||||||
graphicPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
graphicPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
@ -234,7 +238,7 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||||
graphicPipelineStateDesc.NodeMask = 1;
|
graphicPipelineStateDesc.NodeMask = 1;
|
||||||
|
|
||||||
device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result));
|
device->CreateGraphicsPipelineState(&graphicPipelineStateDesc, IID_PPV_ARGS(&result));
|
||||||
Add(result, m_fragment_prog, m_vertex_prog);
|
Add(result, {m_vertex_prog.Id, m_fragment_prog.Id, pipelineProperties });
|
||||||
|
|
||||||
// RSX Debugger
|
// RSX Debugger
|
||||||
/*if (Ini.GSLogPrograms.GetValue())
|
/*if (Ini.GSLogPrograms.GetValue())
|
||||||
|
|
|
@ -13,6 +13,11 @@ enum class SHADER_TYPE
|
||||||
SHADER_TYPE_FRAGMENT
|
SHADER_TYPE_FRAGMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PipelineProperties
|
||||||
|
{
|
||||||
|
D3D12_PRIMITIVE_TOPOLOGY_TYPE Topology;
|
||||||
|
};
|
||||||
|
|
||||||
/** Storage for a shader
|
/** Storage for a shader
|
||||||
* Embeds the D3DBlob corresponding to
|
* Embeds the D3DBlob corresponding to
|
||||||
*/
|
*/
|
||||||
|
@ -139,6 +144,31 @@ 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;
|
||||||
|
|
||||||
|
struct PSOKey
|
||||||
|
{
|
||||||
|
u32 vpIdx;
|
||||||
|
u32 fpIdx;
|
||||||
|
PipelineProperties properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSOKeyHash
|
||||||
|
{
|
||||||
|
size_t operator()(const PSOKey &key) const
|
||||||
|
{
|
||||||
|
size_t hashValue = 0;
|
||||||
|
hashValue ^= std::hash<unsigned>()(key.vpIdx);
|
||||||
|
return hashValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PSOKeyCompare
|
||||||
|
{
|
||||||
|
size_t operator()(const PSOKey &key1, const PSOKey &key2) const
|
||||||
|
{
|
||||||
|
return (key1.vpIdx == key2.vpIdx) && (key1.fpIdx == key2.fpIdx) && (key1.properties.Topology == key2.properties.Topology);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache for shader blobs and Pipeline state object
|
* Cache for shader blobs and Pipeline state object
|
||||||
* The class is responsible for creating the object so the state only has to call getGraphicPipelineState
|
* The class is responsible for creating the object so the state only has to call getGraphicPipelineState
|
||||||
|
@ -149,20 +179,27 @@ private:
|
||||||
size_t m_currentShaderId;
|
size_t m_currentShaderId;
|
||||||
binary2VS m_cacheVS;
|
binary2VS m_cacheVS;
|
||||||
binary2FS m_cacheFS;
|
binary2FS m_cacheFS;
|
||||||
// Key is vertex << 32 | fragment ids
|
|
||||||
std::unordered_map<u64, ID3D12PipelineState *> m_cachePSO;
|
std::unordered_map<PSOKey, ID3D12PipelineState *, PSOKeyHash, PSOKeyCompare> m_cachePSO;
|
||||||
|
|
||||||
bool SearchFp(const RSXFragmentProgram& rsx_fp, Shader& shader);
|
bool SearchFp(const RSXFragmentProgram& rsx_fp, Shader& shader);
|
||||||
bool SearchVp(const RSXVertexProgram& rsx_vp, Shader& shader);
|
bool SearchVp(const RSXVertexProgram& rsx_vp, Shader& shader);
|
||||||
ID3D12PipelineState *GetProg(u32 fp, u32 vp) const;
|
ID3D12PipelineState *GetProg(const PSOKey &psoKey) const;
|
||||||
void AddVertexProgram(Shader& vp, RSXVertexProgram& rsx_vp);
|
void AddVertexProgram(Shader& vp, RSXVertexProgram& rsx_vp);
|
||||||
void AddFragmentProgram(Shader& fp, RSXFragmentProgram& rsx_fp);
|
void AddFragmentProgram(Shader& fp, RSXFragmentProgram& rsx_fp);
|
||||||
void Add(ID3D12PipelineState *prog, Shader& fp, Shader& vp);
|
void Add(ID3D12PipelineState *prog, const PSOKey& PSOKey);
|
||||||
public:
|
public:
|
||||||
PipelineStateObjectCache();
|
PipelineStateObjectCache();
|
||||||
~PipelineStateObjectCache();
|
~PipelineStateObjectCache();
|
||||||
// Note: the last param is not taken into account if the PSO is not regenerated
|
// Note: the last param is not taken into account if the PSO is not regenerated
|
||||||
ID3D12PipelineState *getGraphicPipelineState(ID3D12Device *device, ID3D12RootSignature *rootSignature, RSXVertexProgram *vertexShader, RSXFragmentProgram *fragmentShader, const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet);
|
ID3D12PipelineState *getGraphicPipelineState(
|
||||||
|
ID3D12Device *device,
|
||||||
|
ID3D12RootSignature *rootSignature,
|
||||||
|
RSXVertexProgram *vertexShader,
|
||||||
|
RSXFragmentProgram *fragmentShader,
|
||||||
|
const PipelineProperties &pipelineProperties,
|
||||||
|
const std::vector<D3D12_INPUT_ELEMENT_DESC> &IASet
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue