From 119126c60c8046d03116704d415f710fc1676c5e Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 26 Oct 2015 23:26:35 +0100 Subject: [PATCH] d3d12: Move enum conversion to a separate files. * Add noexcept * Use unreachable * Use a_b_c style --- rpcs3/D3D12GSRender.vcxproj | 2 + rpcs3/D3D12GSRender.vcxproj.filters | 6 + rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 89 +--- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 468 ++++++++++++++++++ rpcs3/Emu/RSX/D3D12/D3D12Formats.h | 99 ++++ rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 52 +- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 138 ++---- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 57 +-- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 102 +--- rpcs3/Emu/RSX/D3D12/D3D12Utils.h | 216 -------- 10 files changed, 641 insertions(+), 588 deletions(-) create mode 100644 rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp create mode 100644 rpcs3/Emu/RSX/D3D12/D3D12Formats.h diff --git a/rpcs3/D3D12GSRender.vcxproj b/rpcs3/D3D12GSRender.vcxproj index 33e6f48c37..62f6c8b182 100644 --- a/rpcs3/D3D12GSRender.vcxproj +++ b/rpcs3/D3D12GSRender.vcxproj @@ -81,6 +81,7 @@ + @@ -93,6 +94,7 @@ + diff --git a/rpcs3/D3D12GSRender.vcxproj.filters b/rpcs3/D3D12GSRender.vcxproj.filters index 80a9451c8e..81dbb92bb2 100644 --- a/rpcs3/D3D12GSRender.vcxproj.filters +++ b/rpcs3/D3D12GSRender.vcxproj.filters @@ -41,6 +41,9 @@ Source Files + + Source Files + @@ -76,5 +79,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 78c66bc379..7d6888a7ec 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -6,94 +6,13 @@ #include "D3D12GSRender.h" #include "d3dx12.h" #include "../Common/BufferUtils.h" +#include "D3D12Formats.h" const int g_vertexCount = 32; -// Where are these type defined ??? -static -DXGI_FORMAT getFormat(u8 type, u8 size) -{ - /*static const u32 gl_types[] = - { - GL_SHORT, - GL_FLOAT, - GL_HALF_FLOAT, - GL_UNSIGNED_BYTE, - GL_SHORT, - GL_FLOAT, // Needs conversion - GL_UNSIGNED_BYTE, - }; - - static const bool gl_normalized[] = - { - GL_TRUE, - GL_FALSE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - GL_TRUE, - GL_FALSE, - };*/ - static const DXGI_FORMAT typeX1[] = - { - DXGI_FORMAT_R16_SNORM, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R8_UINT - }; - static const DXGI_FORMAT typeX2[] = - { - DXGI_FORMAT_R16G16_SNORM, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R8G8_UINT - }; - static const DXGI_FORMAT typeX3[] = - { - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_R32G32B32_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R32G32B32_FLOAT, - DXGI_FORMAT_R8G8B8A8_UINT - }; - static const DXGI_FORMAT typeX4[] = - { - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R8G8B8A8_UINT - }; - - switch (size) - { - case 1: - return typeX1[type]; - case 2: - return typeX2[type]; - case 3: - return typeX3[type]; - case 4: - return typeX4[type]; - default: - LOG_ERROR(RSX, "Wrong size for vertex attrib : %d", size); - return DXGI_FORMAT(); - } -} // D3D12GS member handling buffers - /** * */ @@ -166,7 +85,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vectorGetGPUVirtualAddress() + heapOffset, (UINT)subBufferSize, - (indexed_type == CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT + get_index_type(indexed_type) }; m_timers.m_bufferUploadSize += subBufferSize; cmdlist->IASetIndexBuffer(&indexBufferView); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp new file mode 100644 index 0000000000..01dc44db03 --- /dev/null +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -0,0 +1,468 @@ +#include "stdafx_d3d12.h" +#ifdef _WIN32 +#include "D3D12Formats.h" +#include "D3D12Utils.h" +#include "Emu/RSX/GCM.h" + + +D3D12_BLEND_OP get_blend_op(u16 op) noexcept +{ + 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: + unreachable("Unsupported blend op"); + } + unreachable("Wrong blend op"); +} + +D3D12_BLEND get_blend_factor(u16 factor) noexcept +{ + 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: + unreachable("Unsupported blend color factor"); + } + unreachable("Wrong blend color factor"); +} + +D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept +{ + 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_ALPHA; + case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_ALPHA; + 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_ALPHA; + case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_COLOR; + case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_INV_DEST_ALPHA; + case CELL_GCM_CONSTANT_COLOR: + case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: + case CELL_GCM_CONSTANT_ALPHA: + case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: + unreachable("Unsupported blend alpha factor"); + } + unreachable("Wrong blend alpha factor"); +} + +/** +* Convert GCM logic op code to D3D12 one +*/ +D3D12_LOGIC_OP get_logic_op(u32 op) noexcept +{ + switch (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; + } + unreachable("Wrong logic op"); +} + +/** +* Convert GCM stencil op code to D3D12 one +*/ +D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept +{ + 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: + unreachable("Unsupported Stencil Op %d"); + } + unreachable("Wrong Stencil Op %d"); +} + +D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept +{ + 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; + 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; + } + unreachable("Wrong compare function"); +} + +DXGI_FORMAT get_texture_format(int format) noexcept +{ + switch (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; + 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: + unreachable( "Unimplemented Texture format"); + } + unreachable("Wrong Texture format"); +} + +UINT get_texture_max_aniso(u8 aniso) noexcept +{ + switch (aniso) + { + case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1; + case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2; + case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4; + case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6; + case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8; + case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10; + case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12; + case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16; + } + unreachable("Wrong Texture max aniso"); +} + +D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept +{ + switch (wrap) + { + case CELL_GCM_TEXTURE_WRAP: return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + case CELL_GCM_TEXTURE_MIRROR: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + case CELL_GCM_TEXTURE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_BORDER; + case CELL_GCM_TEXTURE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + } + unreachable("Wrong texture wrap mode"); +} + +namespace +{ + void get_min_filter(u8 min_filter, D3D12_FILTER_TYPE &min, D3D12_FILTER_TYPE &mip) noexcept + { + switch (min_filter) + { + case CELL_GCM_TEXTURE_NEAREST: + min = D3D12_FILTER_TYPE_POINT; + mip = D3D12_FILTER_TYPE_POINT; + return;; + case CELL_GCM_TEXTURE_LINEAR: + min = D3D12_FILTER_TYPE_LINEAR; + mip = D3D12_FILTER_TYPE_POINT; + return; + case CELL_GCM_TEXTURE_NEAREST_NEAREST: + min = D3D12_FILTER_TYPE_POINT; + mip = D3D12_FILTER_TYPE_POINT; + return; + case CELL_GCM_TEXTURE_LINEAR_NEAREST: + min = D3D12_FILTER_TYPE_LINEAR; + mip = D3D12_FILTER_TYPE_POINT; + return; + case CELL_GCM_TEXTURE_NEAREST_LINEAR: + min = D3D12_FILTER_TYPE_POINT; + mip = D3D12_FILTER_TYPE_LINEAR; + return; + case CELL_GCM_TEXTURE_LINEAR_LINEAR: + min = D3D12_FILTER_TYPE_LINEAR; + mip = D3D12_FILTER_TYPE_LINEAR; + return; + case CELL_GCM_TEXTURE_CONVOLUTION_MIN: + unreachable("Unsupported min filter"); + } + unreachable("Wrong min filter"); + } + + D3D12_FILTER_TYPE get_mag_filter(u8 mag_filter) noexcept + { + switch (mag_filter) + { + case CELL_GCM_TEXTURE_NEAREST: return D3D12_FILTER_TYPE_POINT; + case CELL_GCM_TEXTURE_LINEAR: return D3D12_FILTER_TYPE_LINEAR; + } + unreachable("Wrong mag filter"); + } +} + +D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) noexcept +{ + D3D12_FILTER_TYPE min, mip; + get_min_filter(min_filter, min, mip); + D3D12_FILTER_TYPE mag = get_mag_filter(mag_filter); + return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD); +} + +D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept +{ + switch (draw_mode) + { + case CELL_GCM_PRIMITIVE_POINTS: return D3D_PRIMITIVE_TOPOLOGY_POINTLIST; + case CELL_GCM_PRIMITIVE_LINES: return D3D_PRIMITIVE_TOPOLOGY_LINELIST; + case CELL_GCM_PRIMITIVE_LINE_LOOP: return D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + case CELL_GCM_PRIMITIVE_TRIANGLES: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + // Emulated + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: + case CELL_GCM_PRIMITIVE_QUADS: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + case CELL_GCM_PRIMITIVE_QUAD_STRIP: + case CELL_GCM_PRIMITIVE_POLYGON: return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + } + unreachable("Wrong draw mode"); +} +D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept +{ + switch (draw_mode) + { + case CELL_GCM_PRIMITIVE_POINTS: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; + case CELL_GCM_PRIMITIVE_LINES: + case CELL_GCM_PRIMITIVE_LINE_LOOP: + case CELL_GCM_PRIMITIVE_LINE_STRIP: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; + case CELL_GCM_PRIMITIVE_TRIANGLES: + case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: + case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + case CELL_GCM_PRIMITIVE_QUADS: + // unsupported + case CELL_GCM_PRIMITIVE_QUAD_STRIP: + case CELL_GCM_PRIMITIVE_POLYGON: return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + } + unreachable("Wrong draw mode"); +} + +DXGI_FORMAT get_color_surface_format(u8 format) noexcept +{ + switch (format) + { + case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT; + } + unreachable("Wrong color surface format"); +} + +DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept +{ + switch (format) + { + case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; + case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; + } + unreachable("Wrong depth stencil surface format"); +} + +DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept +{ + switch (format) + { + case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_D16_UNORM; + case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; + } + unreachable("Wrong depth stencil surface format"); +} + +DXGI_FORMAT get_depth_typeless_surface_format(u8 format) noexcept +{ + switch (format) + { + case CELL_GCM_SURFACE_Z16: return DXGI_FORMAT_R16_TYPELESS; + case CELL_GCM_SURFACE_Z24S8: return DXGI_FORMAT_R24G8_TYPELESS; + } + unreachable("Wrong depth stencil surface format"); +} + +BOOL get_front_face_ccw(u32 set_front_face_value) noexcept +{ + switch (set_front_face_value) + { + case CELL_GCM_CW: return FALSE; + default: // Disgaea 3 pass some garbage value at startup, this is needed to survive. + case CELL_GCM_CCW: return TRUE; + } + unreachable("Wrong front face value"); +} + +DXGI_FORMAT get_index_type(u8 index_type) noexcept +{ + switch (index_type) + { + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16: return DXGI_FORMAT_R16_UINT; + case CELL_GCM_DRAW_INDEX_ARRAY_TYPE_32: return DXGI_FORMAT_R32_UINT; + } + unreachable("Wrong index type"); +} + +DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept +{ + switch (type) + { + case CELL_GCM_VERTEX_S1: + { + switch (size) + { + case 1: return DXGI_FORMAT_R16_SNORM; + case 2: return DXGI_FORMAT_R16G16_SNORM; + case 3: return DXGI_FORMAT_R16G16B16A16_SNORM; // No 3 channel type + case 4: return DXGI_FORMAT_R16G16B16A16_SNORM; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_F: + { + switch (size) + { + case 1: return DXGI_FORMAT_R32_FLOAT; + case 2: return DXGI_FORMAT_R32G32_FLOAT; + case 3: return DXGI_FORMAT_R32G32B32_FLOAT; + case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_SF: + { + switch (size) + { + case 1: return DXGI_FORMAT_R16_FLOAT; + case 2: return DXGI_FORMAT_R16G16_FLOAT; + case 3: return DXGI_FORMAT_R16G16B16A16_FLOAT; // No 3 channel type + case 4: return DXGI_FORMAT_R16G16B16A16_FLOAT; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_UB: + { + switch (size) + { + case 1: return DXGI_FORMAT_R8_UNORM; + case 2: return DXGI_FORMAT_R8G8_UNORM; + case 3: return DXGI_FORMAT_R8G8B8A8_UNORM; // No 3 channel type + case 4: return DXGI_FORMAT_R8G8B8A8_UNORM; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_S32K: + { + switch (size) + { + case 1: return DXGI_FORMAT_R16_SINT; + case 2: return DXGI_FORMAT_R16G16_SINT; + case 3: return DXGI_FORMAT_R16G16B16A16_SINT; // No 3 channel type + case 4: return DXGI_FORMAT_R16G16B16A16_SINT; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_CMP: + { + switch (size) + { + case 1: return DXGI_FORMAT_R32_FLOAT; + case 2: return DXGI_FORMAT_R32G32_FLOAT; + case 3: return DXGI_FORMAT_R32G32B32_FLOAT; + case 4: return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + unreachable("Wrong type size"); + } + case CELL_GCM_VERTEX_UB256: + { + switch (size) + { + case 1: return DXGI_FORMAT_R8_UINT; + case 2: return DXGI_FORMAT_R8G8_UINT; + case 3: return DXGI_FORMAT_R8G8B8A8_UINT; // No 3 channel type + case 4: return DXGI_FORMAT_R8G8B8A8_UINT; + } + unreachable("Wrong type size"); + } + } + unreachable("Wrong type"); +} +#endif \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h new file mode 100644 index 0000000000..2171fad99f --- /dev/null +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h @@ -0,0 +1,99 @@ +#pragma once + +#include + +/** + * Convert GCM blend operator code to D3D12 one + */ +D3D12_BLEND_OP get_blend_op(u16 op) noexcept; + +/** + * Convert GCM blend factor code to D3D12 one + */ +D3D12_BLEND get_blend_factor(u16 factor) noexcept; + +/** + * Convert GCM blend factor code to D3D12 one for alpha component + */ +D3D12_BLEND get_blend_factor_alpha(u16 factor) noexcept; + +/** +* Convert GCM logic op code to D3D12 one +*/ +D3D12_LOGIC_OP get_logic_op(u32 op) noexcept; + +/** + * Convert GCM stencil op code to D3D12 one + */ +D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept; + +/** + * Convert GCM comparison function code to D3D12 one. + */ +D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept; + +/** + * Convert GCM texture format to an equivalent one supported by D3D12. + * Destination format may require a byte swap or data conversion. + */ +DXGI_FORMAT get_texture_format(int format) noexcept; + +/** + * Convert texture aniso value to UINT. + */ +UINT get_texture_max_aniso(u8 aniso) noexcept; + +/** + * Convert texture wrap mode to D3D12_TEXTURE_ADDRESS_MODE + */ +D3D12_TEXTURE_ADDRESS_MODE get_texture_wrap_mode(u8 wrap) noexcept; + +/** + * Convert minify and magnify filter to D3D12_FILTER + */ +D3D12_FILTER get_texture_filter(u8 min_filter, u8 mag_filter) noexcept; + +/** + * Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY + */ +D3D12_PRIMITIVE_TOPOLOGY get_primitive_topology(u8 draw_mode) noexcept; + +/** +* Convert draw mode to D3D12_PRIMITIVE_TOPOLOGY_TYPE +*/ +D3D12_PRIMITIVE_TOPOLOGY_TYPE get_primitive_topology_type(u8 draw_mode) noexcept; + +/** + * Convert color surface format to DXGI_FORMAT + */ +DXGI_FORMAT get_color_surface_format(u8 format) noexcept; + +/** + * Convert depth stencil surface format to DXGI_FORMAT + */ +DXGI_FORMAT get_depth_stencil_surface_format(u8 format) noexcept; + +/** + *Convert depth stencil surface format to DXGI_FORMAT suited for clear value + */ +DXGI_FORMAT get_depth_stencil_surface_clear_format(u8 format) noexcept; + +/** + * Convert depth surface format to DXGI_FORMAT using typeless for stencil + */ +DXGI_FORMAT get_depth_typeless_surface_format(u8 format) noexcept; + +/** + * Convert front face value to bool value telling wheter front face is counterclockwise or not + */ +BOOL get_front_face_ccw(u32 set_front_face_value) noexcept; + +/** + * Convert index type to DXGI_FORMAT + */ +DXGI_FORMAT get_index_type(u8 index_type) noexcept; + +/** + * Convert vertex attribute format and size to DXGI_FORMAT + */ +DXGI_FORMAT get_vertex_attribute_format(u8 type, u8 size) noexcept; \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index f9c7cabd9a..97aebe8299 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -9,6 +9,7 @@ #include "d3dx12.h" #include #include "Emu/state.h" +#include "D3D12Formats.h" #pragma comment(lib, "d2d1") #pragma comment(lib, "DXGI") #pragma comment(lib, "Dwrite") @@ -556,37 +557,7 @@ void D3D12GSRender::end() }; getCurrentResourceStorage().m_commandList->RSSetScissorRects(1, &box); - switch (draw_mode) - { - case CELL_GCM_PRIMITIVE_POINTS: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_POINTLIST); - break; - case CELL_GCM_PRIMITIVE_LINES: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST); - break; - case CELL_GCM_PRIMITIVE_LINE_LOOP: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ); - break; - case CELL_GCM_PRIMITIVE_LINE_STRIP: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINESTRIP); - break; - case CELL_GCM_PRIMITIVE_TRIANGLES: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - break; - case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - break; - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - case CELL_GCM_PRIMITIVE_QUADS: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - break; - case CELL_GCM_PRIMITIVE_QUAD_STRIP: - case CELL_GCM_PRIMITIVE_POLYGON: - default: - getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - LOG_ERROR(RSX, "Unsupported primitive type"); - break; - } + getCurrentResourceStorage().m_commandList->IASetPrimitiveTopology(get_primitive_topology(draw_mode)); if (m_renderingInfo.m_indexed) getCurrentResourceStorage().m_commandList->DrawIndexedInstanced((UINT)m_renderingInfo.m_count, 1, 0, 0, 0); @@ -840,16 +811,14 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; ID3D12Resource *Result; size_t w = clip_w, h = clip_h; - DXGI_FORMAT dxgiFormat; + DXGI_FORMAT dxgiFormat = get_color_surface_format(m_surface.color_format); size_t rowPitch; switch (m_surface.color_format) { case CELL_GCM_SURFACE_A8R8G8B8: - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; rowPitch = align(w * 4, 256); break; case CELL_GCM_SURFACE_F_W16Z16Y16X16: - dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; rowPitch = align(w * 8, 256); break; } @@ -960,20 +929,7 @@ void D3D12GSRender::semaphore_PGRAPH_backend_release() m_device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(descriptorHeap.GetAddressOf())) ); D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - switch (m_surface.depth_format) - { - case 0: - break; - case CELL_GCM_SURFACE_Z16: - srvDesc.Format = DXGI_FORMAT_R16_UNORM; - break; - case CELL_GCM_SURFACE_Z24S8: - srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - break; - default: - LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface.depth_format); - assert(0); - } + m_surface.depth_format = get_depth_typeless_surface_format(m_surface.depth_format); srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MipLevels = 1; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index ca03098028..26b1f5559b 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -4,6 +4,7 @@ #include "D3D12PipelineState.h" #include "D3D12GSRender.h" #include "Emu/state.h" +#include "D3D12Formats.h" #pragma comment (lib, "d3dcompiler.lib") @@ -57,29 +58,7 @@ bool D3D12GSRender::LoadProgram() fragment_program.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; D3D12PipelineProperties prop = {}; - switch (draw_mode) - { - case CELL_GCM_PRIMITIVE_POINTS: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; - break; - case CELL_GCM_PRIMITIVE_LINES: - case CELL_GCM_PRIMITIVE_LINE_LOOP: - case CELL_GCM_PRIMITIVE_LINE_STRIP: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; - break; - case CELL_GCM_PRIMITIVE_TRIANGLES: - case CELL_GCM_PRIMITIVE_TRIANGLE_STRIP: - case CELL_GCM_PRIMITIVE_TRIANGLE_FAN: - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - break; - case CELL_GCM_PRIMITIVE_QUADS: - case CELL_GCM_PRIMITIVE_QUAD_STRIP: - case CELL_GCM_PRIMITIVE_POLYGON: - default: - // LOG_ERROR(RSX, "Unsupported primitive type"); - prop.Topology = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - break; - } + prop.Topology = get_primitive_topology_type(draw_mode); static D3D12_BLEND_DESC CD3D12_BLEND_DESC = { @@ -106,61 +85,61 @@ bool D3D12GSRender::LoadProgram() if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) prop.Blend.RenderTarget[3].BlendEnable = true; - prop.Blend.RenderTarget[0].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[0].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[0].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); + prop.Blend.RenderTarget[0].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2) { - prop.Blend.RenderTarget[1].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[1].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[1].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); + prop.Blend.RenderTarget[1].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); } if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4) { - prop.Blend.RenderTarget[2].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[2].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[2].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); + prop.Blend.RenderTarget[2].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); } if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) { - prop.Blend.RenderTarget[3].BlendOp = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[3].BlendOpAlpha = getBlendOp(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[3].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); + prop.Blend.RenderTarget[3].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); } - prop.Blend.RenderTarget[0].SrcBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[0].DestBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[0].SrcBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[0].DestBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[0].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[0].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[0].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); + prop.Blend.RenderTarget[0].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2) { - prop.Blend.RenderTarget[1].SrcBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[1].DestBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[1].SrcBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[1].DestBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[1].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[1].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[1].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); + prop.Blend.RenderTarget[1].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); } if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4) { - prop.Blend.RenderTarget[2].SrcBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[2].DestBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[2].SrcBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[2].DestBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[2].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[2].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[2].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); + prop.Blend.RenderTarget[2].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); } if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) { - prop.Blend.RenderTarget[3].SrcBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[3].DestBlend = getBlendFactor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[3].SrcBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[3].DestBlendAlpha = getBlendFactorAlpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[3].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[3].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); + prop.Blend.RenderTarget[3].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); + prop.Blend.RenderTarget[3].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); } } if (rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE]) { prop.Blend.RenderTarget[0].LogicOpEnable = true; - prop.Blend.RenderTarget[0].LogicOp = getLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]); + prop.Blend.RenderTarget[0].LogicOp = get_logic_op(rsx::method_registers[NV4097_SET_LOGIC_OP]); } // if (m_set_blend_color) @@ -168,31 +147,8 @@ bool D3D12GSRender::LoadProgram() // 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; - } + prop.DepthStencilFormat = get_depth_stencil_surface_format(m_surface.depth_format); + prop.RenderTargetsFormat = get_color_surface_format(m_surface.color_format); switch (u32 color_target = rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]) { @@ -215,28 +171,28 @@ bool D3D12GSRender::LoadProgram() prop.DepthStencil.DepthEnable = !!(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE]); prop.DepthStencil.DepthWriteMask = !!(rsx::method_registers[NV4097_SET_DEPTH_MASK]) ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; - prop.DepthStencil.DepthFunc = getCompareFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + prop.DepthStencil.DepthFunc = get_compare_func(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); prop.DepthStencil.StencilEnable = !!(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE]); prop.DepthStencil.StencilReadMask = rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]; prop.DepthStencil.StencilWriteMask = rsx::method_registers[NV4097_SET_STENCIL_MASK]; - prop.DepthStencil.FrontFace.StencilPassOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - prop.DepthStencil.FrontFace.StencilDepthFailOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); - prop.DepthStencil.FrontFace.StencilFailOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); - prop.DepthStencil.FrontFace.StencilFunc = getCompareFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); + prop.DepthStencil.FrontFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); + prop.DepthStencil.FrontFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); + prop.DepthStencil.FrontFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); + prop.DepthStencil.FrontFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); if (rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE]) { - prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL]); - prop.DepthStencil.BackFace.StencilFunc = getCompareFunc(rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC]); - prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); - prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL]); + prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL]); + prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC]); + prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); + prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL]); } else { - prop.DepthStencil.BackFace.StencilPassOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - prop.DepthStencil.BackFace.StencilDepthFailOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); - prop.DepthStencil.BackFace.StencilFailOp = getStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); - prop.DepthStencil.BackFace.StencilFunc = getCompareFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); + prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); + prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); + prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); + prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); } // Sensible default value @@ -273,15 +229,7 @@ bool D3D12GSRender::LoadProgram() else prop.Rasterization.CullMode = D3D12_CULL_MODE_NONE; - switch (rsx::method_registers[NV4097_SET_FRONT_FACE]) - { - case CELL_GCM_CW: - prop.Rasterization.FrontCounterClockwise = FALSE; - break; - case CELL_GCM_CCW: - prop.Rasterization.FrontCounterClockwise = TRUE; - break; - } + prop.Rasterization.FrontCounterClockwise = get_front_face_ccw(rsx::method_registers[NV4097_SET_FRONT_FACE]); UINT8 mask = 0; mask |= (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 16) & 0xFF ? D3D12_COLOR_WRITE_ENABLE_RED : 0; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index 44a97ef872..0d980a5159 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -11,6 +11,7 @@ #include "D3D12.h" #include "D3D12GSRender.h" +#include "D3D12Formats.h" void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) { @@ -78,16 +79,7 @@ void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) D3D12_CPU_DESCRIPTOR_HANDLE Handle = m_rtts.m_renderTargetsDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); size_t g_RTTIncrement = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - DXGI_FORMAT dxgiFormat; - switch (m_surface.color_format) - { - case CELL_GCM_SURFACE_A8R8G8B8: - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; - break; - } + DXGI_FORMAT dxgiFormat = get_color_surface_format(m_surface.color_format); D3D12_RENDER_TARGET_VIEW_DESC rttViewDesc = {}; rttViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rttViewDesc.Format = dxgiFormat; @@ -171,20 +163,7 @@ void D3D12GSRender::PrepareRenderTargets(ID3D12GraphicsCommandList *copycmdlist) ID3D12Resource *ds = m_rtts.bindAddressAsDepthStencil(m_device.Get(), copycmdlist, address_z, clip_width, clip_height, m_surface.depth_format, 1., 0); D3D12_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc = {}; - switch (m_surface.depth_format) - { - case 0: - break; - case CELL_GCM_SURFACE_Z16: - depthStencilViewDesc.Format = DXGI_FORMAT_D16_UNORM; - break; - case CELL_GCM_SURFACE_Z24S8: - depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - break; - default: - LOG_ERROR(RSX, "Bad depth format! (%d)", m_surface.depth_format); - assert(0); - } + depthStencilViewDesc.Format = get_depth_stencil_surface_format(m_surface.depth_format); depthStencilViewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; m_device->CreateDepthStencilView(ds, &depthStencilViewDesc, m_rtts.m_depthStencilDescriptorHeap->GetCPUDescriptorHandleForHeapStart()); } @@ -203,16 +182,7 @@ ID3D12Resource *RenderTargets::bindAddressAsRenderTargets(ID3D12Device *device, else { LOG_WARNING(RSX, "Creating RTT"); - DXGI_FORMAT dxgiFormat; - switch (surfaceColorFormat) - { - case CELL_GCM_SURFACE_A8R8G8B8: - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case CELL_GCM_SURFACE_F_W16Z16Y16X16: - dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; - break; - } + DXGI_FORMAT dxgiFormat = get_color_surface_format(surfaceColorFormat); D3D12_CLEAR_VALUE clearColorValue = {}; clearColorValue.Format = dxgiFormat; clearColorValue.Color[0] = clearColor[0]; @@ -254,23 +224,8 @@ ID3D12Resource * RenderTargets::bindAddressAsDepthStencil(ID3D12Device * device, D3D12_HEAP_PROPERTIES heapProp = {}; heapProp.Type = D3D12_HEAP_TYPE_DEFAULT; - DXGI_FORMAT dxgiFormat; - switch (surfaceDepthFormat) - { - case 0: - break; - case CELL_GCM_SURFACE_Z16: - dxgiFormat = DXGI_FORMAT_R16_TYPELESS; - clearDepthValue.Format = DXGI_FORMAT_D16_UNORM; - break; - case CELL_GCM_SURFACE_Z24S8: - dxgiFormat = DXGI_FORMAT_R24G8_TYPELESS; - clearDepthValue.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - break; - default: - LOG_ERROR(RSX, "Bad depth format! (%d)", surfaceDepthFormat); - assert(0); - } + DXGI_FORMAT dxgiFormat = get_depth_typeless_surface_format(surfaceDepthFormat); + clearDepthValue.Format = get_depth_stencil_surface_clear_format(surfaceDepthFormat); device->CreateCommittedResource( &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 78b6df4c7b..d9d9a91e36 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -4,6 +4,7 @@ #include "d3dx12.h" #include "../Common/TextureUtils.h" // For clarity this code deals with texture but belongs to D3D12GSRender class +#include "D3D12Formats.h" static D3D12_COMPARISON_FUNC getSamplerCompFunc[] = @@ -18,101 +19,16 @@ D3D12_COMPARISON_FUNC getSamplerCompFunc[] = D3D12_COMPARISON_FUNC_ALWAYS }; -static -size_t getSamplerMaxAniso(size_t aniso) -{ - switch (aniso) - { - case CELL_GCM_TEXTURE_MAX_ANISO_1: return 1; - case CELL_GCM_TEXTURE_MAX_ANISO_2: return 2; - case CELL_GCM_TEXTURE_MAX_ANISO_4: return 4; - case CELL_GCM_TEXTURE_MAX_ANISO_6: return 6; - case CELL_GCM_TEXTURE_MAX_ANISO_8: return 8; - case CELL_GCM_TEXTURE_MAX_ANISO_10: return 10; - case CELL_GCM_TEXTURE_MAX_ANISO_12: return 12; - case CELL_GCM_TEXTURE_MAX_ANISO_16: return 16; - } - - return 1; -} - -static -D3D12_TEXTURE_ADDRESS_MODE getSamplerWrap(size_t wrap) -{ - switch (wrap) - { - case CELL_GCM_TEXTURE_WRAP: return D3D12_TEXTURE_ADDRESS_MODE_WRAP; - case CELL_GCM_TEXTURE_MIRROR: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; - case CELL_GCM_TEXTURE_CLAMP_TO_EDGE: return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - case CELL_GCM_TEXTURE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_BORDER; - case CELL_GCM_TEXTURE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; - case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; - case CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; - case CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP: return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; - } - return D3D12_TEXTURE_ADDRESS_MODE_WRAP; -} - -static -D3D12_FILTER getSamplerFilter(u32 minFilter, u32 magFilter) -{ - D3D12_FILTER_TYPE min, mag, mip; - switch (minFilter) - { - case CELL_GCM_TEXTURE_NEAREST: - min = D3D12_FILTER_TYPE_POINT; - mip = D3D12_FILTER_TYPE_POINT; - break; - case CELL_GCM_TEXTURE_LINEAR: - min = D3D12_FILTER_TYPE_LINEAR; - mip = D3D12_FILTER_TYPE_POINT; - break; - case CELL_GCM_TEXTURE_NEAREST_NEAREST: - min = D3D12_FILTER_TYPE_POINT; - mip = D3D12_FILTER_TYPE_POINT; - break; - case CELL_GCM_TEXTURE_LINEAR_NEAREST: - min = D3D12_FILTER_TYPE_LINEAR; - mip = D3D12_FILTER_TYPE_POINT; - break; - case CELL_GCM_TEXTURE_NEAREST_LINEAR: - min = D3D12_FILTER_TYPE_POINT; - mip = D3D12_FILTER_TYPE_LINEAR; - break; - case CELL_GCM_TEXTURE_LINEAR_LINEAR: - min = D3D12_FILTER_TYPE_LINEAR; - mip = D3D12_FILTER_TYPE_LINEAR; - break; - case CELL_GCM_TEXTURE_CONVOLUTION_MIN: - default: - LOG_ERROR(RSX, "Unknow min filter %x", minFilter); - } - - switch (magFilter) - { - case CELL_GCM_TEXTURE_NEAREST: - mag = D3D12_FILTER_TYPE_POINT; - break; - case CELL_GCM_TEXTURE_LINEAR: - mag = D3D12_FILTER_TYPE_LINEAR; - break; - default: - LOG_ERROR(RSX, "Unknow mag filter %x", magFilter); - } - - return D3D12_ENCODE_BASIC_FILTER(min, mag, mip, D3D12_FILTER_REDUCTION_TYPE_STANDARD); -} - static D3D12_SAMPLER_DESC getSamplerDesc(const rsx::texture &texture) { D3D12_SAMPLER_DESC samplerDesc = {}; - samplerDesc.Filter = getSamplerFilter(texture.min_filter(), texture.mag_filter()); - samplerDesc.AddressU = getSamplerWrap(texture.wrap_s()); - samplerDesc.AddressV = getSamplerWrap(texture.wrap_t()); - samplerDesc.AddressW = getSamplerWrap(texture.wrap_r()); + samplerDesc.Filter = get_texture_filter(texture.min_filter(), texture.mag_filter()); + samplerDesc.AddressU = get_texture_wrap_mode(texture.wrap_s()); + samplerDesc.AddressV = get_texture_wrap_mode(texture.wrap_t()); + samplerDesc.AddressW = get_texture_wrap_mode(texture.wrap_r()); samplerDesc.ComparisonFunc = getSamplerCompFunc[texture.zfunc()]; - samplerDesc.MaxAnisotropy = (UINT)getSamplerMaxAniso(texture.max_aniso()); + samplerDesc.MaxAnisotropy = get_texture_max_aniso(texture.max_aniso()); samplerDesc.MipLODBias = texture.bias(); samplerDesc.BorderColor[4] = (FLOAT)texture.border_color(); samplerDesc.MinLOD = (FLOAT)(texture.min_lod() >> 8); @@ -136,7 +52,7 @@ ComPtr uploadSingleTexture( size_t w = texture.width(), h = texture.height(); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); + DXGI_FORMAT dxgiFormat = get_texture_format(format); size_t textureSize = getPlacedTextureStorageSpace(texture, 256); assert(textureBuffersHeap.canAlloc(textureSize)); @@ -187,7 +103,7 @@ void updateExistingTexture( size_t w = texture.width(), h = texture.height(); int format = texture.format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); + DXGI_FORMAT dxgiFormat = get_texture_format(format); size_t textureSize = getPlacedTextureStorageSpace(texture, 256); assert(textureBuffersHeap.canAlloc(textureSize)); @@ -297,7 +213,7 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist, size_t const u32 texaddr = rsx::get_address(textures[i].offset(), textures[i].location()); int format = textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - DXGI_FORMAT dxgiFormat = getTextureDXGIFormat(format); + DXGI_FORMAT dxgiFormat = get_texture_format(format); bool is_swizzled = !(textures[i].format() & CELL_GCM_TEXTURE_LN); ID3D12Resource *vramTexture; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Utils.h b/rpcs3/Emu/RSX/D3D12/D3D12Utils.h index 85b2fa4ef5..a82186e9f3 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Utils.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Utils.h @@ -116,219 +116,3 @@ void streamBuffer(void* dst, void* src, size_t sizeInBytes) } memcpy((char*)dst + offset, (char*)src + offset, sizeInBytes - offset); } - -/** - * 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; - default: - 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; - default: - 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 blend factor code to D3D12 one for alpha component -*/ -inline D3D12_BLEND getBlendFactorAlpha(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_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_ALPHA; - 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_ALPHA; - case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_COLOR; - case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_INV_DEST_ALPHA; - default: - 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; - default: - 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_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; - 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; - default: - LOG_WARNING(RSX, "Unsupported Compare Function %d", op); - return D3D12_COMPARISON_FUNC(); - } -} - -/** - * 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; - } -}