From 224503d2dc54f61d05acfcf2a94009a289aebef0 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 8 Jun 2015 16:52:13 +0200 Subject: [PATCH] d3d12: Move program related code out of D3D12GSRender and some get* format functions --- rpcs3/Emu/RSX/D3D12/D3D12.h | 181 +++++++++++ rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 362 --------------------- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 259 +++++++++++++++ rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 69 +--- 4 files changed, 442 insertions(+), 429 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12.h b/rpcs3/Emu/RSX/D3D12/D3D12.h index 71e94fa740..d1598b7502 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12.h @@ -3,6 +3,7 @@ #include #include +#include "utilities/Log.h" inline void check(HRESULT hr) @@ -106,4 +107,184 @@ D3D12_RESOURCE_BARRIER getResourceBarrierTransition(ID3D12Resource *res, D3D12_R return barrier; } +/** + * Convert GCM blend operator code to D3D12 one + */ +inline D3D12_BLEND_OP getBlendOp(u16 op) +{ + switch (op) + { + case CELL_GCM_FUNC_ADD: return D3D12_BLEND_OP_ADD; + case CELL_GCM_FUNC_SUBTRACT: return D3D12_BLEND_OP_SUBTRACT; + case CELL_GCM_FUNC_REVERSE_SUBTRACT: return D3D12_BLEND_OP_REV_SUBTRACT; + case CELL_GCM_MIN: return D3D12_BLEND_OP_MIN; + case CELL_GCM_MAX: return D3D12_BLEND_OP_MAX; + case CELL_GCM_FUNC_ADD_SIGNED: + case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: + case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: + LOG_WARNING(RSX, "Unsupported Blend Op %d", op); + return D3D12_BLEND_OP(); + } +} + +/** + * Convert GCM blend factor code to D3D12 one + */ +inline D3D12_BLEND getBlendFactor(u16 factor) +{ + switch (factor) + { + case CELL_GCM_ZERO: return D3D12_BLEND_ZERO; + case CELL_GCM_ONE: return D3D12_BLEND_ONE; + case CELL_GCM_SRC_COLOR: return D3D12_BLEND_SRC_COLOR; + case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_COLOR; + case CELL_GCM_SRC_ALPHA: return D3D12_BLEND_SRC_ALPHA; + case CELL_GCM_ONE_MINUS_SRC_ALPHA: return D3D12_BLEND_INV_SRC_ALPHA; + case CELL_GCM_DST_ALPHA: return D3D12_BLEND_DEST_ALPHA; + case CELL_GCM_ONE_MINUS_DST_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA; + case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_COLOR; + case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_COLOR; + case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT; + case CELL_GCM_CONSTANT_COLOR: + case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: + case CELL_GCM_CONSTANT_ALPHA: + case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: + LOG_WARNING(RSX, "Unsupported Blend Factor %d", factor); + return D3D12_BLEND(); + } +} + +/** + * Convert GCM logic op code to D3D12 one + */ +inline D3D12_LOGIC_OP getLogicOp(u32 op) +{ + switch (op) + { + default: + LOG_WARNING(RSX, "Unsupported Logic Op %d", op); + return D3D12_LOGIC_OP(); + case CELL_GCM_CLEAR: return D3D12_LOGIC_OP_CLEAR; + case CELL_GCM_AND: return D3D12_LOGIC_OP_AND; + case CELL_GCM_AND_REVERSE: return D3D12_LOGIC_OP_AND_REVERSE; + case CELL_GCM_COPY: return D3D12_LOGIC_OP_COPY; + case CELL_GCM_AND_INVERTED: return D3D12_LOGIC_OP_AND_INVERTED; + case CELL_GCM_NOOP: return D3D12_LOGIC_OP_NOOP; + case CELL_GCM_XOR: return D3D12_LOGIC_OP_XOR; + case CELL_GCM_OR: return D3D12_LOGIC_OP_OR; + case CELL_GCM_NOR: return D3D12_LOGIC_OP_NOR; + case CELL_GCM_EQUIV: return D3D12_LOGIC_OP_EQUIV; + case CELL_GCM_INVERT: return D3D12_LOGIC_OP_INVERT; + case CELL_GCM_OR_REVERSE: return D3D12_LOGIC_OP_OR_REVERSE; + case CELL_GCM_COPY_INVERTED: return D3D12_LOGIC_OP_COPY_INVERTED; + case CELL_GCM_OR_INVERTED: return D3D12_LOGIC_OP_OR_INVERTED; + case CELL_GCM_NAND: return D3D12_LOGIC_OP_NAND; + } +} + +/** + * Convert GCM stencil op code to D3D12 one + */ +inline D3D12_STENCIL_OP getStencilOp(u32 op) +{ + switch (op) + { + case CELL_GCM_KEEP: return D3D12_STENCIL_OP_KEEP; + case CELL_GCM_ZERO: return D3D12_STENCIL_OP_ZERO; + case CELL_GCM_REPLACE: return D3D12_STENCIL_OP_REPLACE; + case CELL_GCM_INCR: return D3D12_STENCIL_OP_INCR; + case CELL_GCM_DECR: return D3D12_STENCIL_OP_DECR; + case CELL_GCM_INCR_WRAP: + case CELL_GCM_DECR_WRAP: + LOG_WARNING(RSX, "Unsupported Stencil Op %d", op); + return D3D12_STENCIL_OP(); + } +} + +/** + * Convert GCM comparison function code to D3D12 one. + */ +inline D3D12_COMPARISON_FUNC getCompareFunc(u32 op) +{ + switch (op) + { + 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; + case CELL_GCM_LEQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case CELL_GCM_GREATER: return D3D12_COMPARISON_FUNC_GREATER; + case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL; + case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS; + } +} + +/** + * Convert GCM texture format to an equivalent one supported by D3D12. + * Destination format may require a byte swap or data conversion. + */ +inline DXGI_FORMAT getTextureDXGIFormat(int format) +{ + switch (format) + { + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + case CELL_GCM_TEXTURE_COMPRESSED_HILO8: + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: + case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + default: + LOG_ERROR(RSX, "Unimplemented Texture format : %x", format); + return DXGI_FORMAT(); + case CELL_GCM_TEXTURE_B8: + return DXGI_FORMAT_R8_UNORM; + case CELL_GCM_TEXTURE_A1R5G5B5: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case CELL_GCM_TEXTURE_A4R4G4B4: + return DXGI_FORMAT_B4G4R4A4_UNORM; + case CELL_GCM_TEXTURE_R5G6B5: + return DXGI_FORMAT_B5G6R5_UNORM; + case CELL_GCM_TEXTURE_A8R8G8B8: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + return DXGI_FORMAT_BC1_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + return DXGI_FORMAT_BC2_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + return DXGI_FORMAT_BC3_UNORM; + case CELL_GCM_TEXTURE_G8B8: + return DXGI_FORMAT_G8R8_G8B8_UNORM; + case CELL_GCM_TEXTURE_R6G5B5: + // Not native + return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_DEPTH24_D8: + return DXGI_FORMAT_R32_UINT; + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + return DXGI_FORMAT_R32_FLOAT; + case CELL_GCM_TEXTURE_DEPTH16: + return DXGI_FORMAT_R16_UNORM; + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: + return DXGI_FORMAT_R16_FLOAT; + case CELL_GCM_TEXTURE_X16: + return DXGI_FORMAT_R16_UNORM; + case CELL_GCM_TEXTURE_Y16_X16: + return DXGI_FORMAT_R16G16_UNORM; + case CELL_GCM_TEXTURE_R5G5B5A1: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case CELL_GCM_TEXTURE_X32_FLOAT: + return DXGI_FORMAT_R32_FLOAT; + case CELL_GCM_TEXTURE_D1R5G5B5: + return DXGI_FORMAT_B5G5R5A1_UNORM; + case CELL_GCM_TEXTURE_D8R8G8B8: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + return DXGI_FORMAT_G8R8_G8B8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + return DXGI_FORMAT_R8G8_B8G8_UNORM; + } +} + #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index bf8141e014..32b4f83d51 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -577,368 +577,6 @@ void D3D12GSRender::ExecCMD(u32 cmd) m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**) &commandList); } -static D3D12_BLEND_OP getBlendOp(u16 op) -{ - switch (op) - { - case CELL_GCM_FUNC_ADD: return D3D12_BLEND_OP_ADD; - case CELL_GCM_FUNC_SUBTRACT: return D3D12_BLEND_OP_SUBTRACT; - case CELL_GCM_FUNC_REVERSE_SUBTRACT: return D3D12_BLEND_OP_REV_SUBTRACT; - case CELL_GCM_MIN: return D3D12_BLEND_OP_MIN; - case CELL_GCM_MAX: return D3D12_BLEND_OP_MAX; - case CELL_GCM_FUNC_ADD_SIGNED: - case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: - case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: - LOG_WARNING(RSX, "Unsupported Blend Op %d", op); - } -} - -static D3D12_BLEND getBlendFactor(u16 factor) -{ - switch (factor) - { - case CELL_GCM_ZERO: return D3D12_BLEND_ZERO; - case CELL_GCM_ONE: return D3D12_BLEND_ONE; - case CELL_GCM_SRC_COLOR: return D3D12_BLEND_SRC_COLOR; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_COLOR; - case CELL_GCM_SRC_ALPHA: return D3D12_BLEND_SRC_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_ALPHA: return D3D12_BLEND_INV_SRC_ALPHA; - case CELL_GCM_DST_ALPHA: return D3D12_BLEND_DEST_ALPHA; - case CELL_GCM_ONE_MINUS_DST_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA; - case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_COLOR; - case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_COLOR; - case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT; - case CELL_GCM_CONSTANT_COLOR: - case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: - case CELL_GCM_CONSTANT_ALPHA: - case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: - LOG_WARNING(RSX, "Unsupported Blend Factor %d", factor); - } -} - -static D3D12_LOGIC_OP getLogicOp(u32 op) -{ - switch (op) - { - default: LOG_WARNING(RSX, "Unsupported Logic Op %d", op); - case CELL_GCM_CLEAR: return D3D12_LOGIC_OP_CLEAR; - case CELL_GCM_AND: return D3D12_LOGIC_OP_AND; - case CELL_GCM_AND_REVERSE: return D3D12_LOGIC_OP_AND_REVERSE; - case CELL_GCM_COPY: return D3D12_LOGIC_OP_COPY; - case CELL_GCM_AND_INVERTED: return D3D12_LOGIC_OP_AND_INVERTED; - case CELL_GCM_NOOP: return D3D12_LOGIC_OP_NOOP; - case CELL_GCM_XOR: return D3D12_LOGIC_OP_XOR; - case CELL_GCM_OR: return D3D12_LOGIC_OP_OR; - case CELL_GCM_NOR: return D3D12_LOGIC_OP_NOR; - case CELL_GCM_EQUIV: return D3D12_LOGIC_OP_EQUIV; - case CELL_GCM_INVERT: return D3D12_LOGIC_OP_INVERT; - case CELL_GCM_OR_REVERSE: return D3D12_LOGIC_OP_OR_REVERSE; - case CELL_GCM_COPY_INVERTED: return D3D12_LOGIC_OP_COPY_INVERTED; - case CELL_GCM_OR_INVERTED: return D3D12_LOGIC_OP_OR_INVERTED; - case CELL_GCM_NAND: return D3D12_LOGIC_OP_NAND; - } -} - -static D3D12_STENCIL_OP getStencilOp(u32 op) -{ - switch (op) - { - case CELL_GCM_KEEP: return D3D12_STENCIL_OP_KEEP; - case CELL_GCM_ZERO: return D3D12_STENCIL_OP_ZERO; - case CELL_GCM_REPLACE: return D3D12_STENCIL_OP_REPLACE; - case CELL_GCM_INCR: return D3D12_STENCIL_OP_INCR; - case CELL_GCM_DECR: return D3D12_STENCIL_OP_DECR; - case CELL_GCM_INCR_WRAP: - case CELL_GCM_DECR_WRAP: - LOG_WARNING(RSX, "Unsupported Stencil Op %d", op); - } -} - -static D3D12_COMPARISON_FUNC getStencilFunc(u32 op) -{ - switch (op) - { - 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; - case CELL_GCM_LEQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL; - case CELL_GCM_GREATER: return D3D12_COMPARISON_FUNC_GREATER; - case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL; - case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; - case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS; - } -} - -static D3D12_COMPARISON_FUNC getDepthFunc(u32 op) -{ - switch (op) - { - 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; - case CELL_GCM_LEQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL; - case CELL_GCM_GREATER: return D3D12_COMPARISON_FUNC_GREATER; - case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL; - case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; - case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS; - } -} - -bool D3D12GSRender::LoadProgram() -{ - if (!m_cur_fragment_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); - return false; - } - - m_cur_fragment_prog->ctrl = m_shader_ctrl; - - if (!m_cur_vertex_prog) - { - LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); - return false; - } - - D3D12PipelineProperties prop = {}; - switch (m_draw_mode - 1) - { - case GL_POINTS: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; - break; - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; - break; - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - break; - case GL_QUADS: - case GL_QUAD_STRIP: - case GL_POLYGON: - default: -// LOG_ERROR(RSX, "Unsupported primitive type"); - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - break; - } - - static D3D12_BLEND_DESC CD3D12_BLEND_DESC = - { - FALSE, - FALSE, - { - FALSE,FALSE, - D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, - D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, - D3D12_LOGIC_OP_NOOP, - D3D12_COLOR_WRITE_ENABLE_ALL, - } - }; - prop.Blend = CD3D12_BLEND_DESC; - - if (m_set_blend) - { - prop.Blend.RenderTarget[0].BlendEnable = true; - - if (m_set_blend_mrt1) - prop.Blend.RenderTarget[1].BlendEnable = true; - if (m_set_blend_mrt2) - prop.Blend.RenderTarget[2].BlendEnable = true; - if (m_set_blend_mrt3) - prop.Blend.RenderTarget[3].BlendEnable = true; - } - - if (m_set_blend_equation) - { - prop.Blend.RenderTarget[0].BlendOp = getBlendOp(m_blend_equation_rgb); - prop.Blend.RenderTarget[0].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); - - if (m_set_blend_mrt1) - { - prop.Blend.RenderTarget[1].BlendOp = getBlendOp(m_blend_equation_rgb); - prop.Blend.RenderTarget[1].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); - } - - if (m_set_blend_mrt2) - { - prop.Blend.RenderTarget[2].BlendOp = getBlendOp(m_blend_equation_rgb); - prop.Blend.RenderTarget[2].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); - } - - if (m_set_blend_mrt3) - { - prop.Blend.RenderTarget[3].BlendOp = getBlendOp(m_blend_equation_rgb); - prop.Blend.RenderTarget[3].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); - } - } - - if (m_set_blend_sfactor && m_set_blend_dfactor) - { - prop.Blend.RenderTarget[0].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); - prop.Blend.RenderTarget[0].DestBlend = getBlendFactor(m_blend_dfactor_rgb); - prop.Blend.RenderTarget[0].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); - prop.Blend.RenderTarget[0].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); - - if (m_set_blend_mrt1) - { - prop.Blend.RenderTarget[1].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); - prop.Blend.RenderTarget[1].DestBlend = getBlendFactor(m_blend_dfactor_rgb); - prop.Blend.RenderTarget[1].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); - prop.Blend.RenderTarget[1].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); - } - - if (m_set_blend_mrt2) - { - prop.Blend.RenderTarget[2].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); - prop.Blend.RenderTarget[2].DestBlend = getBlendFactor(m_blend_dfactor_rgb); - prop.Blend.RenderTarget[2].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); - prop.Blend.RenderTarget[2].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); - } - - if (m_set_blend_mrt3) - { - prop.Blend.RenderTarget[3].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); - prop.Blend.RenderTarget[3].DestBlend = getBlendFactor(m_blend_dfactor_rgb); - prop.Blend.RenderTarget[3].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); - prop.Blend.RenderTarget[3].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); - } - } - - if (m_set_logic_op) - { - prop.Blend.RenderTarget[0].LogicOpEnable = true; - prop.Blend.RenderTarget[0].LogicOp = getLogicOp(m_logic_op); - } - - if (m_set_blend_color) - { -// glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); -// checkForGlError("glBlendColor"); - } - - switch (m_surface_depth_format) - { - case 0: - break; - case CELL_GCM_SURFACE_Z16: - prop.DepthStencilFormat = DXGI_FORMAT_D16_UNORM; - break; - case CELL_GCM_SURFACE_Z24S8: - prop.DepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; - break; - default: - LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); - assert(0); - } - - switch (m_surface_color_format) - { - case CELL_GCM_SURFACE_A8R8G8B8: - prop.RenderTargetsFormat = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - prop.RenderTargetsFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; - break; - } - - switch (m_surface_color_target) - { - case CELL_GCM_SURFACE_TARGET_0: - case CELL_GCM_SURFACE_TARGET_1: - prop.numMRT = 1; - break; - case CELL_GCM_SURFACE_TARGET_MRT1: - prop.numMRT = 2; - break; - case CELL_GCM_SURFACE_TARGET_MRT2: - prop.numMRT = 3; - break; - case CELL_GCM_SURFACE_TARGET_MRT3: - prop.numMRT = 4; - break; - default: - LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); - } - - prop.DepthStencil.DepthEnable = m_set_depth_test; - prop.DepthStencil.DepthWriteMask = m_depth_mask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; - prop.DepthStencil.DepthFunc = getDepthFunc(m_depth_func); - prop.DepthStencil.StencilEnable = m_set_stencil_test; - prop.DepthStencil.StencilReadMask = m_stencil_func_mask; - prop.DepthStencil.StencilWriteMask = m_stencil_mask; - prop.DepthStencil.FrontFace.StencilPassOp = getStencilOp(m_stencil_zpass); - prop.DepthStencil.FrontFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail); - prop.DepthStencil.FrontFace.StencilFailOp = getStencilOp(m_stencil_fail); - prop.DepthStencil.FrontFace.StencilFunc = getStencilFunc(m_stencil_func); - - if (m_set_two_sided_stencil_test_enable) - { - prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_back_stencil_fail); - prop.DepthStencil.BackFace.StencilFunc = getStencilFunc(m_back_stencil_func); - prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_back_stencil_zpass); - prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_back_stencil_zfail); - } - else - { - prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_stencil_zpass); - prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail); - prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_stencil_fail); - prop.DepthStencil.BackFace.StencilFunc = getStencilFunc(m_stencil_func); - } - - // Sensible default value - static D3D12_RASTERIZER_DESC CD3D12_RASTERIZER_DESC = - { - D3D12_FILL_MODE_SOLID, - D3D12_CULL_MODE_NONE, - FALSE, - D3D12_DEFAULT_DEPTH_BIAS, - D3D12_DEFAULT_DEPTH_BIAS_CLAMP, - D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - TRUE, - FALSE, - FALSE, - 0, - D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF, - }; - prop.Rasterization = CD3D12_RASTERIZER_DESC; - switch (m_set_cull_face) - { - case CELL_GCM_FRONT: - prop.Rasterization.CullMode = D3D12_CULL_MODE_FRONT; - break; - case CELL_GCM_BACK: - prop.Rasterization.CullMode = D3D12_CULL_MODE_BACK; - break; - default: - prop.Rasterization.CullMode = D3D12_CULL_MODE_NONE; - break; - } - - switch (m_front_face) - { - case CELL_GCM_CW: - prop.Rasterization.FrontCounterClockwise = FALSE; - break; - case CELL_GCM_CCW: - prop.Rasterization.FrontCounterClockwise = TRUE; - break; - } - - if (m_set_color_mask) - prop.SampleMask = m_color_mask_r | (m_color_mask_g << 1) | (m_color_mask_b << 2) | (m_color_mask_a << 3); - else - prop.SampleMask = UINT_MAX; - - prop.IASet = m_IASet; - - m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device, m_rootSignatures)); - return m_PSO != nullptr; -} - void D3D12GSRender::ExecCMD() { InitDrawBuffers(); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index 56c8f6f4e9..f6e2446015 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -3,6 +3,7 @@ #include "D3D12PipelineState.h" #include +#include "D3D12GSRender.h" #pragma comment (lib, "d3dcompiler.lib") @@ -27,4 +28,262 @@ void Shader::Compile(const std::string &code, SHADER_TYPE st) } + + +bool D3D12GSRender::LoadProgram() +{ + if (!m_cur_fragment_prog) + { + LOG_WARNING(RSX, "LoadProgram: m_cur_shader_prog == NULL"); + return false; + } + + m_cur_fragment_prog->ctrl = m_shader_ctrl; + + if (!m_cur_vertex_prog) + { + LOG_WARNING(RSX, "LoadProgram: m_cur_vertex_prog == NULL"); + return false; + } + + D3D12PipelineProperties prop = {}; + switch (m_draw_mode - 1) + { + case GL_POINTS: + prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + break; + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + break; + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + break; + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + default: + // LOG_ERROR(RSX, "Unsupported primitive type"); + prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + break; + } + + static D3D12_BLEND_DESC CD3D12_BLEND_DESC = + { + FALSE, + FALSE, + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + } + }; + prop.Blend = CD3D12_BLEND_DESC; + + if (m_set_blend) + { + prop.Blend.RenderTarget[0].BlendEnable = true; + + if (m_set_blend_mrt1) + prop.Blend.RenderTarget[1].BlendEnable = true; + if (m_set_blend_mrt2) + prop.Blend.RenderTarget[2].BlendEnable = true; + if (m_set_blend_mrt3) + prop.Blend.RenderTarget[3].BlendEnable = true; + } + + if (m_set_blend_equation) + { + prop.Blend.RenderTarget[0].BlendOp = getBlendOp(m_blend_equation_rgb); + prop.Blend.RenderTarget[0].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); + + if (m_set_blend_mrt1) + { + prop.Blend.RenderTarget[1].BlendOp = getBlendOp(m_blend_equation_rgb); + prop.Blend.RenderTarget[1].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); + } + + if (m_set_blend_mrt2) + { + prop.Blend.RenderTarget[2].BlendOp = getBlendOp(m_blend_equation_rgb); + prop.Blend.RenderTarget[2].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); + } + + if (m_set_blend_mrt3) + { + prop.Blend.RenderTarget[3].BlendOp = getBlendOp(m_blend_equation_rgb); + prop.Blend.RenderTarget[3].BlendOpAlpha = getBlendOp(m_blend_equation_alpha); + } + } + + if (m_set_blend_sfactor && m_set_blend_dfactor) + { + prop.Blend.RenderTarget[0].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); + prop.Blend.RenderTarget[0].DestBlend = getBlendFactor(m_blend_dfactor_rgb); + prop.Blend.RenderTarget[0].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); + prop.Blend.RenderTarget[0].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); + + if (m_set_blend_mrt1) + { + prop.Blend.RenderTarget[1].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); + prop.Blend.RenderTarget[1].DestBlend = getBlendFactor(m_blend_dfactor_rgb); + prop.Blend.RenderTarget[1].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); + prop.Blend.RenderTarget[1].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); + } + + if (m_set_blend_mrt2) + { + prop.Blend.RenderTarget[2].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); + prop.Blend.RenderTarget[2].DestBlend = getBlendFactor(m_blend_dfactor_rgb); + prop.Blend.RenderTarget[2].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); + prop.Blend.RenderTarget[2].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); + } + + if (m_set_blend_mrt3) + { + prop.Blend.RenderTarget[3].SrcBlend = getBlendFactor(m_blend_sfactor_rgb); + prop.Blend.RenderTarget[3].DestBlend = getBlendFactor(m_blend_dfactor_rgb); + prop.Blend.RenderTarget[3].SrcBlendAlpha = getBlendFactor(m_blend_sfactor_alpha); + prop.Blend.RenderTarget[3].DestBlendAlpha = getBlendFactor(m_blend_dfactor_alpha); + } + } + + if (m_set_logic_op) + { + prop.Blend.RenderTarget[0].LogicOpEnable = true; + prop.Blend.RenderTarget[0].LogicOp = getLogicOp(m_logic_op); + } + + if (m_set_blend_color) + { + // glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); + // checkForGlError("glBlendColor"); + } + + switch (m_surface_depth_format) + { + case 0: + break; + case CELL_GCM_SURFACE_Z16: + prop.DepthStencilFormat = DXGI_FORMAT_D16_UNORM; + break; + case CELL_GCM_SURFACE_Z24S8: + prop.DepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; + break; + default: + LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface_depth_format); + assert(0); + } + + switch (m_surface_color_format) + { + case CELL_GCM_SURFACE_A8R8G8B8: + prop.RenderTargetsFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: + prop.RenderTargetsFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + break; + } + + switch (m_surface_color_target) + { + case CELL_GCM_SURFACE_TARGET_0: + case CELL_GCM_SURFACE_TARGET_1: + prop.numMRT = 1; + break; + case CELL_GCM_SURFACE_TARGET_MRT1: + prop.numMRT = 2; + break; + case CELL_GCM_SURFACE_TARGET_MRT2: + prop.numMRT = 3; + break; + case CELL_GCM_SURFACE_TARGET_MRT3: + prop.numMRT = 4; + break; + default: + LOG_ERROR(RSX, "Bad surface color target: %d", m_surface_color_target); + } + + prop.DepthStencil.DepthEnable = m_set_depth_test; + prop.DepthStencil.DepthWriteMask = m_depth_mask ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + prop.DepthStencil.DepthFunc = getDepthFunc(m_depth_func); + prop.DepthStencil.StencilEnable = m_set_stencil_test; + prop.DepthStencil.StencilReadMask = m_stencil_func_mask; + prop.DepthStencil.StencilWriteMask = m_stencil_mask; + prop.DepthStencil.FrontFace.StencilPassOp = getStencilOp(m_stencil_zpass); + prop.DepthStencil.FrontFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail); + prop.DepthStencil.FrontFace.StencilFailOp = getStencilOp(m_stencil_fail); + prop.DepthStencil.FrontFace.StencilFunc = getStencilFunc(m_stencil_func); + + if (m_set_two_sided_stencil_test_enable) + { + prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_back_stencil_fail); + prop.DepthStencil.BackFace.StencilFunc = getStencilFunc(m_back_stencil_func); + prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_back_stencil_zpass); + prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_back_stencil_zfail); + } + else + { + prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(m_stencil_zpass); + prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(m_stencil_zfail); + prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(m_stencil_fail); + prop.DepthStencil.BackFace.StencilFunc = getStencilFunc(m_stencil_func); + } + + // Sensible default value + static D3D12_RASTERIZER_DESC CD3D12_RASTERIZER_DESC = + { + D3D12_FILL_MODE_SOLID, + D3D12_CULL_MODE_NONE, + FALSE, + D3D12_DEFAULT_DEPTH_BIAS, + D3D12_DEFAULT_DEPTH_BIAS_CLAMP, + D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + TRUE, + FALSE, + FALSE, + 0, + D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF, + }; + prop.Rasterization = CD3D12_RASTERIZER_DESC; + switch (m_set_cull_face) + { + case CELL_GCM_FRONT: + prop.Rasterization.CullMode = D3D12_CULL_MODE_FRONT; + break; + case CELL_GCM_BACK: + prop.Rasterization.CullMode = D3D12_CULL_MODE_BACK; + break; + default: + prop.Rasterization.CullMode = D3D12_CULL_MODE_NONE; + break; + } + + switch (m_front_face) + { + case CELL_GCM_CW: + prop.Rasterization.FrontCounterClockwise = FALSE; + break; + case CELL_GCM_CCW: + prop.Rasterization.FrontCounterClockwise = TRUE; + break; + } + + if (m_set_color_mask) + prop.SampleMask = m_color_mask_r | (m_color_mask_g << 1) | (m_color_mask_b << 2) | (m_color_mask_a << 3); + else + prop.SampleMask = UINT_MAX; + + prop.IASet = m_IASet; + + m_PSO = m_cachePSO.getGraphicPipelineState(m_cur_vertex_prog, m_cur_fragment_prog, prop, std::make_pair(m_device, m_rootSignatures)); + return m_PSO != nullptr; +} + + #endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index b492551765..4f796a4f86 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -81,71 +81,6 @@ D3D12_TEXTURE_ADDRESS_MODE D3D12GSRender::GetWrap(size_t wrap) return D3D12_TEXTURE_ADDRESS_MODE_WRAP; } -static -DXGI_FORMAT getDXGIFormat(int format) -{ - switch (format) - { - - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - case CELL_GCM_TEXTURE_COMPRESSED_HILO8: - case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - default: - LOG_ERROR(RSX, "Unimplemented Texture format : %x", format); - return DXGI_FORMAT(); - case CELL_GCM_TEXTURE_B8: - return DXGI_FORMAT_R8_UNORM; - case CELL_GCM_TEXTURE_A1R5G5B5: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_A4R4G4B4: - return DXGI_FORMAT_B4G4R4A4_UNORM; - case CELL_GCM_TEXTURE_R5G6B5: - return DXGI_FORMAT_B5G6R5_UNORM; - case CELL_GCM_TEXTURE_A8R8G8B8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: - return DXGI_FORMAT_BC1_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: - return DXGI_FORMAT_BC2_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - return DXGI_FORMAT_BC3_UNORM; - case CELL_GCM_TEXTURE_G8B8: - return DXGI_FORMAT_G8R8_G8B8_UNORM; - case CELL_GCM_TEXTURE_R6G5B5: - // Not native - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_DEPTH24_D8: - return DXGI_FORMAT_R32_UINT; - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: - return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_TEXTURE_DEPTH16: - return DXGI_FORMAT_R16_UNORM; - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: - return DXGI_FORMAT_R16_FLOAT; - case CELL_GCM_TEXTURE_X16: - return DXGI_FORMAT_R16_UNORM; - case CELL_GCM_TEXTURE_Y16_X16: - return DXGI_FORMAT_R16G16_UNORM; - case CELL_GCM_TEXTURE_R5G5B5A1: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case CELL_GCM_TEXTURE_X32_FLOAT: - return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_TEXTURE_D1R5G5B5: - return DXGI_FORMAT_B5G5R5A1_UNORM; - case CELL_GCM_TEXTURE_D8R8G8B8: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - return DXGI_FORMAT_G8R8_G8B8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - return DXGI_FORMAT_R8G8_B8G8_UNORM; - } -} static D3D12_FILTER getSamplerFilter(u32 minFilter, u32 magFilter) { @@ -212,7 +147,7 @@ ID3D12Resource *uploadSingleTexture( size_t blockSizeInByte, blockWidthInPixel, blockHeightInPixel; int format = texture.GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - DXGI_FORMAT dxgiFormat = getDXGIFormat(format); + DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); const u32 texaddr = GetAddress(texture.GetOffset(), texture.GetLocation()); @@ -487,7 +422,7 @@ size_t D3D12GSRender::UploadTextures() const u32 texaddr = GetAddress(m_textures[i].GetOffset(), m_textures[i].GetLocation()); int format = m_textures[i].GetFormat() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - DXGI_FORMAT dxgiFormat = getDXGIFormat(format); + DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); bool is_swizzled = !(m_textures[i].GetFormat() & CELL_GCM_TEXTURE_LN); ID3D12Resource *vramTexture;