mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
d3d12: cache PSO State too
This commit is contained in:
parent
da5b047c58
commit
75219be066
@ -457,7 +457,10 @@ bool D3D12GSRender::LoadProgram()
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,9 @@ bool PipelineStateObjectCache::SearchVp(const RSXVertexProgram& rsx_vp, Shader&
|
||||
return false;
|
||||
}
|
||||
|
||||
ID3D12PipelineState *PipelineStateObjectCache::GetProg(u32 fp, u32 vp) const
|
||||
ID3D12PipelineState *PipelineStateObjectCache::GetProg(const PSOKey &key) const
|
||||
{
|
||||
u64 vpLong = vp;
|
||||
u64 key = vpLong << 32 | fp;
|
||||
std::unordered_map<u64, ID3D12PipelineState *>::const_iterator It = m_cachePSO.find(key);
|
||||
std::unordered_map<PSOKey, ID3D12PipelineState *, PSOKeyHash, PSOKeyCompare>::const_iterator It = m_cachePSO.find(key);
|
||||
if (It == m_cachePSO.end())
|
||||
return nullptr;
|
||||
return It->second;
|
||||
@ -86,14 +84,18 @@ void PipelineStateObjectCache::AddFragmentProgram(Shader& fp, RSXFragmentProgram
|
||||
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;
|
||||
u64 key = vpLong << 32 | fp.Id;
|
||||
m_cachePSO.insert(std::make_pair(key, prog));
|
||||
m_cachePSO.insert(std::make_pair(PSOKey, 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;
|
||||
Shader m_vertex_prog, m_fragment_prog;
|
||||
@ -123,7 +125,9 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -221,7 +225,7 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||
graphicPipelineStateDesc.BlendState = CD3D12_BLEND_DESC;
|
||||
graphicPipelineStateDesc.DepthStencilState = CD3D12_DEPTH_STENCIL_DESC;
|
||||
graphicPipelineStateDesc.RasterizerState = CD3D12_RASTERIZER_DESC;
|
||||
graphicPipelineStateDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||
graphicPipelineStateDesc.PrimitiveTopologyType = pipelineProperties.Topology;
|
||||
|
||||
graphicPipelineStateDesc.NumRenderTargets = 1;
|
||||
graphicPipelineStateDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
@ -234,7 +238,7 @@ ID3D12PipelineState *PipelineStateObjectCache::getGraphicPipelineState(ID3D12Dev
|
||||
graphicPipelineStateDesc.NodeMask = 1;
|
||||
|
||||
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
|
||||
/*if (Ini.GSLogPrograms.GetValue())
|
||||
|
@ -13,6 +13,11 @@ enum class SHADER_TYPE
|
||||
SHADER_TYPE_FRAGMENT
|
||||
};
|
||||
|
||||
struct PipelineProperties
|
||||
{
|
||||
D3D12_PRIMITIVE_TOPOLOGY_TYPE Topology;
|
||||
};
|
||||
|
||||
/** Storage for a shader
|
||||
* 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, 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
|
||||
* 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;
|
||||
binary2VS m_cacheVS;
|
||||
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 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 AddFragmentProgram(Shader& fp, RSXFragmentProgram& rsx_fp);
|
||||
void Add(ID3D12PipelineState *prog, Shader& fp, Shader& vp);
|
||||
void Add(ID3D12PipelineState *prog, const PSOKey& PSOKey);
|
||||
public:
|
||||
PipelineStateObjectCache();
|
||||
~PipelineStateObjectCache();
|
||||
// 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…
x
Reference in New Issue
Block a user