d3d12: Move enum conversion to a separate files.

* Add noexcept
* Use unreachable
* Use a_b_c style
This commit is contained in:
Vincent Lejeune 2015-10-26 23:26:35 +01:00
parent 5c42a3cbc4
commit 119126c60c
10 changed files with 641 additions and 588 deletions

View file

@ -81,6 +81,7 @@
<ClInclude Include="Emu\RSX\D3D12\D3D12Utils.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12Buffer.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12CommonDecompiler.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12GSRender.h" />
<ClInclude Include="Emu\RSX\D3D12\D3D12PipelineState.h" />
@ -93,6 +94,7 @@
<ItemGroup>
<ClCompile Include="Emu\RSX\D3D12\D3D12Buffer.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12CommonDecompiler.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12Formats.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12FragmentProgramDecompiler.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12GSRender.cpp" />
<ClCompile Include="Emu\RSX\D3D12\D3D12Overlay.cpp" />

View file

@ -41,6 +41,9 @@
<ClInclude Include="Emu\RSX\D3D12\D3D12Utils.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\D3D12\D3D12Formats.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Emu\RSX\D3D12\D3D12Buffer.cpp">
@ -76,5 +79,8 @@
<ClCompile Include="stdafx_d3d12.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Emu\RSX\D3D12\D3D12Formats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -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::vector<std::pair<u32, u3
IAElement.SemanticName = "TEXCOORD";
IAElement.SemanticIndex = (UINT)index;
IAElement.InputSlot = (UINT)inputSlot++;
IAElement.Format = getFormat(info.type - 1, info.size);
IAElement.Format = get_vertex_attribute_format(info.type, info.size);
IAElement.AlignedByteOffset = 0;
IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
IAElement.InstanceDataStepRate = 0;
@ -208,7 +127,7 @@ void D3D12GSRender::upload_vertex_attributes(const std::vector<std::pair<u32, u3
IAElement.SemanticName = "TEXCOORD";
IAElement.SemanticIndex = (UINT)index;
IAElement.InputSlot = (UINT)inputSlot++;
IAElement.Format = getFormat(info.type - 1, info.size);
IAElement.Format = get_vertex_attribute_format(info.type, info.size);
IAElement.AlignedByteOffset = 0;
IAElement.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
IAElement.InstanceDataStepRate = 1;
@ -429,7 +348,7 @@ void D3D12GSRender::upload_vertex_index_data(ID3D12GraphicsCommandList *cmdlist)
D3D12_INDEX_BUFFER_VIEW indexBufferView = {
m_vertexIndexData.m_heap->GetGPUVirtualAddress() + 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);

View file

@ -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

View file

@ -0,0 +1,99 @@
#pragma once
#include <d3d12.h>
/**
* 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;

View file

@ -9,6 +9,7 @@
#include "d3dx12.h"
#include <d3d11on12.h>
#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;

View file

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

View file

@ -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),

View file

@ -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<ID3D12Resource> 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;

View file

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