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;
- }
-}