Skip to content

Commit

Permalink
Merge pull request RPCS3#1196 from vlj/d3d12
Browse files Browse the repository at this point in the history
D3d12/RSX: Some light improvement to program management.
  • Loading branch information
tambry committed Aug 26, 2015
2 parents 3468a7e + e0aa74d commit 99a9fd8
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 1 deletion.
2 changes: 2 additions & 0 deletions rpcs3/Emu/RSX/Common/ProgramStateCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ class ProgramStateCache
{
size_t hashValue = 0;
hashValue ^= std::hash<unsigned>()(key.vpIdx);
hashValue ^= std::hash<unsigned>()(key.fpIdx);
hashValue ^= std::hash<typename BackendTraits::PipelineProperties>()(key.properties);
return hashValue;
}
};
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/RSX/D3D12/D3D12.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ inline D3D12_COMPARISON_FUNC getCompareFunc(u32 op)
{
switch (op)
{
case CELL_GCM_ZERO:
case CELL_GCM_NEVER: return D3D12_COMPARISON_FUNC_NEVER;
case CELL_GCM_LESS: return D3D12_COMPARISON_FUNC_LESS;
case CELL_GCM_EQUAL: return D3D12_COMPARISON_FUNC_EQUAL;
Expand Down
4 changes: 4 additions & 0 deletions rpcs3/Emu/RSX/D3D12/D3D12GSRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,10 @@ class D3D12GSRender : public GSRender
virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override;
virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override;
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override;
virtual void notifyProgramChange() override;
virtual void notifyBlendStateChange() override;
virtual void notifyDepthStencilStateChange() override;
virtual void notifyRasterizerStateChange() override;

private:
void InitD2DStructures();
Expand Down
20 changes: 20 additions & 0 deletions rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,28 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st)
}
}

void D3D12GSRender::notifyProgramChange()
{
m_PSO = nullptr;
}
void D3D12GSRender::notifyBlendStateChange()
{
m_PSO = nullptr;
}
void D3D12GSRender::notifyDepthStencilStateChange()
{
m_PSO = nullptr;
}
void D3D12GSRender::notifyRasterizerStateChange()
{
m_PSO = nullptr;
}

bool D3D12GSRender::LoadProgram()
{
if (m_PSO != nullptr)
return true;

if (!m_cur_fragment_prog)
{
LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL");
Expand Down
27 changes: 27 additions & 0 deletions rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,33 @@ struct D3D12PipelineProperties
}
};

template<typename T>
size_t hashStructContent(const T& structure)
{
char *data = (char*)(&structure);
size_t result = 0;
for (unsigned i = 0; i < sizeof(T); i++)
result ^= std::hash<char>()(data[i]);
return result;
}

namespace std
{
template <>
struct hash<D3D12PipelineProperties> {
size_t operator()(const D3D12PipelineProperties &pipelineProperties) const {
size_t seed = hash<unsigned>()(pipelineProperties.DepthStencilFormat) ^
(hash<unsigned>()(pipelineProperties.RenderTargetsFormat) << 2) ^
(hash<unsigned>()(pipelineProperties.Topology) << 2) ^
(hash<unsigned>()(pipelineProperties.numMRT) << 4);
seed ^= hashStructContent(pipelineProperties.Blend);
seed ^= hashStructContent(pipelineProperties.DepthStencil);
seed ^= hashStructContent(pipelineProperties.Rasterization);
return hash<size_t>()(seed);
}
};
}

/** Storage for a shader
* Embeds the D3DBlob
*/
Expand Down
5 changes: 5 additions & 0 deletions rpcs3/Emu/RSX/GL/GLGSRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,9 @@ class GLGSRender final : public GSRender
virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override;
virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override;
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override;

virtual void notifyProgramChange() override {}
virtual void notifyBlendStateChange() override {}
virtual void notifyDepthStencilStateChange() override {}
virtual void notifyRasterizerStateChange() override {}
};
5 changes: 5 additions & 0 deletions rpcs3/Emu/RSX/Null/NullGSRender.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ class NullGSRender final : public GSRender
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override
{
}

virtual void notifyProgramChange() override {}
virtual void notifyBlendStateChange() override {}
virtual void notifyDepthStencilStateChange() override {}
virtual void notifyRasterizerStateChange() override {}
};
30 changes: 29 additions & 1 deletion rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_color_mask_r = a0 & 0x0010000 ? true : false;
m_color_mask_g = a0 & 0x0000100 ? true : false;
m_color_mask_b = a0 & 0x0000001 ? true : false;
notifyRasterizerStateChange();
break;
}

Expand Down Expand Up @@ -572,26 +573,30 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_SET_CULL_FACE_ENABLE:
{
m_set_cull_face = ARGS(0) ? true : false;
notifyRasterizerStateChange();
break;
}

case NV4097_SET_CULL_FACE:
{
m_cull_face = ARGS(0);
notifyRasterizerStateChange();
break;
}

// Front face
case NV4097_SET_FRONT_FACE:
{
m_front_face = ARGS(0);
notifyRasterizerStateChange();
break;
}

// Blending
case NV4097_SET_BLEND_ENABLE:
{
m_set_blend = ARGS(0) ? true : false;
notifyBlendStateChange();
break;
}

Expand All @@ -600,6 +605,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_set_blend_mrt1 = ARGS(0) & 0x02 ? true : false;
m_set_blend_mrt2 = ARGS(0) & 0x04 ? true : false;
m_set_blend_mrt3 = ARGS(0) & 0x08 ? true : false;
notifyBlendStateChange();
break;
}

Expand All @@ -615,6 +621,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_blend_dfactor_rgb = ARGS(1) & 0xffff;
m_blend_dfactor_alpha = ARGS(1) >> 16;
}
notifyBlendStateChange();
break;
}

Expand All @@ -623,6 +630,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_set_blend_dfactor = true;
m_blend_dfactor_rgb = ARGS(0) & 0xffff;
m_blend_dfactor_alpha = ARGS(0) >> 16;
notifyBlendStateChange();
break;
}

Expand All @@ -633,6 +641,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_blend_color_g = (ARGS(0) >> 8) & 0xff;
m_blend_color_b = (ARGS(0) >> 16) & 0xff;
m_blend_color_a = (ARGS(0) >> 24) & 0xff;
notifyBlendStateChange();
break;
}

Expand All @@ -650,6 +659,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_set_blend_equation = true;
m_blend_equation_rgb = ARGS(0) & 0xffff;
m_blend_equation_alpha = ARGS(0) >> 16;
notifyBlendStateChange();
break;
}

Expand Down Expand Up @@ -762,13 +772,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
m_set_depth_func = true;
m_depth_func = ARGS(0);
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_DEPTH_MASK:
{
m_set_depth_mask = true;
m_depth_mask = ARGS(0);
notifyDepthStencilStateChange();
break;
}

Expand Down Expand Up @@ -1052,6 +1064,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_cur_fragment_prog->offset = a0 & ~0x3;
m_cur_fragment_prog->addr = GetAddress(m_cur_fragment_prog->offset, (a0 & 0x3) - 1);
m_cur_fragment_prog->ctrl = 0x40;
notifyProgramChange();
break;
}

Expand Down Expand Up @@ -1101,6 +1114,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
LOG_WARNING(RSX, "NV4097_SET_TRANSFORM_PROGRAM_LOAD: start = %d", start);
}
}
notifyProgramChange();
break;
}

Expand Down Expand Up @@ -1128,6 +1142,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
m_cur_vertex_prog->data.push_back(ARGS(i));
}
notifyProgramChange();
break;
}

Expand Down Expand Up @@ -1220,12 +1235,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_SET_LOGIC_OP_ENABLE:
{
m_set_logic_op = ARGS(0) ? true : false;
notifyBlendStateChange();
break;
}

case NV4097_SET_LOGIC_OP:
{
m_logic_op = ARGS(0);
notifyBlendStateChange();
break;
}

Expand All @@ -1240,6 +1257,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
case NV4097_SET_STENCIL_TEST_ENABLE:
{
m_set_stencil_test = ARGS(0) ? true : false;
notifyDepthStencilStateChange();
break;
}

Expand All @@ -1259,6 +1277,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
{
m_set_stencil_mask = true;
m_stencil_mask = ARGS(0);
notifyDepthStencilStateChange();
break;
}

Expand All @@ -1278,20 +1297,23 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_stencil_func_mask = ARGS(2);
}
}
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_STENCIL_FUNC_REF:
{
m_set_stencil_func_ref = true;
m_stencil_func_ref = ARGS(0);
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_STENCIL_FUNC_MASK:
{
m_set_stencil_func_mask = true;
m_stencil_func_mask = ARGS(0);
notifyDepthStencilStateChange();
break;
}

Expand All @@ -1311,13 +1333,15 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_stencil_zpass = ARGS(2);
}
}
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_BACK_STENCIL_MASK:
{
m_set_back_stencil_mask = true;
m_back_stencil_mask = ARGS(0);
notifyDepthStencilStateChange();
break;
}

Expand All @@ -1337,20 +1361,23 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_back_stencil_func_mask = ARGS(2);
}
}
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_BACK_STENCIL_FUNC_REF:
{
m_set_back_stencil_func_ref = true;
m_back_stencil_func_ref = ARGS(0);
notifyDepthStencilStateChange();
break;
}

case NV4097_SET_BACK_STENCIL_FUNC_MASK:
{
m_set_back_stencil_func_mask = true;
m_back_stencil_func_mask = ARGS(0);
notifyDepthStencilStateChange();
break;
}

Expand All @@ -1370,6 +1397,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_back_stencil_zpass = ARGS(2);
}
}
notifyDepthStencilStateChange();
break;
}

Expand Down Expand Up @@ -1484,7 +1512,6 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const
m_height_scale = (float)res.height / m_height * 2.0f;
m_width = (u32)res.width;
m_height = (u32)res.height;

break;
}

Expand Down Expand Up @@ -1746,6 +1773,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const

m_set_depth_test = a0 & 0x1 ? true : false;
m_set_stencil_test = a0 & 0x2 ? true : false;
notifyDepthStencilStateChange();
break;
}

Expand Down
21 changes: 21 additions & 0 deletions rpcs3/Emu/RSX/RSXThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,27 @@ class RSXThread : protected named_thread_t
* waiting.
*/
virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0;
/**
* Called when vertex or fragment shader changes.
* Backend can reuse same program if no change has been notified.
*/
virtual void notifyProgramChange() = 0;
/**
* Called when blend state changes.
* Backend can reuse same program if no change has been notified.
*/
virtual void notifyBlendStateChange() = 0;
/**
* Called when depth stencil state changes.
* Backend can reuse same program if no change has been notified.
*/
virtual void notifyDepthStencilStateChange() = 0;
/**
* Called when rasterizer state changes.
* Rasterizer state includes culling, color masking
* Backend can reuse same program if no change has been notified.
*/
virtual void notifyRasterizerStateChange() = 0;

void LoadVertexData(u32 first, u32 count)
{
Expand Down

0 comments on commit 99a9fd8

Please sign in to comment.