From 174fb97172c3ad63e682d5ea25fefea6d079d39d Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 27 Nov 2015 23:23:00 +0100 Subject: [PATCH 1/5] d3d12: Fix for case where fragment shaders samples textures starting from non first unit. --- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index e496501984..ecfe56aa92 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -157,7 +157,8 @@ struct D3D12Traits { if (PT.type == "sampler2D") { - fragmentProgramData.m_textureCount++; + size_t texture_unit = atoi(PI.name.c_str() + 3); + fragmentProgramData.m_textureCount = std::max(texture_unit + 1, fragmentProgramData.m_textureCount); continue; } size_t offset = atoi(PI.name.c_str() + 2); From f4091b1027eecea1afd48ed632e196af25fda9e2 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 28 Nov 2015 01:43:19 +0100 Subject: [PATCH 2/5] d3d12: Fix fragment shader accessing to gl_Position --- rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 1cb5348612..98eb6c2cc3 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -121,6 +121,8 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS) for (ParamItem PI : PT.items) OS << " " << PT.type << " " << PI.name << " = In." << PI.name << ";" << std::endl; } + // A bit unclean, but works. + OS << " " << "float4 gl_Position = In.Position;" << std::endl; // Declare output for (ParamType PT : m_parr.params[PF_PARAM_NONE]) { From c9c436e6fcb3c79ad7f1d336bbe79208975ccb16 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sat, 28 Nov 2015 01:43:39 +0100 Subject: [PATCH 3/5] d3d12: In case of non supported rtt fallback to R8G8B8A8 format. --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 932c0ca136..708ca2028d 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -331,6 +331,7 @@ DXGI_FORMAT get_color_surface_format(u8 format) noexcept { switch (format) { + case CELL_GCM_SURFACE_R5G6B5: return DXGI_FORMAT_R8G8B8A8_UNORM; case CELL_GCM_SURFACE_A8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; case CELL_GCM_SURFACE_F_W16Z16Y16X16: return DXGI_FORMAT_R16G16B16A16_FLOAT; case CELL_GCM_SURFACE_F_X32: return DXGI_FORMAT_R32_FLOAT; From 88d7feda5c1d29a994c8acc46811154693b2cff3 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 30 Nov 2015 16:57:41 +0100 Subject: [PATCH 4/5] d3d12: Support unormalized texture coordinates --- rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 11 +++++++ rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp | 2 +- .../D3D12/D3D12FragmentProgramDecompiler.cpp | 32 ++++++++++++++++++- .../D3D12/D3D12VertexProgramDecompiler.cpp | 16 ++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 41407a7d03..52da134c03 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -154,6 +154,17 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) float alpha_ref = (float&)rsx::method_registers[NV4097_SET_ALPHA_REF]; memcpy((char*)mapped_buffer + heap_offset + 16 * sizeof(float), &is_alpha_tested, sizeof(int)); memcpy((char*)mapped_buffer + heap_offset + 17 * sizeof(float), &alpha_ref, sizeof(float)); + + size_t tex_idx = 0; + for (u32 i = 0; i < rsx::limits::textures_count; ++i) + { + if (!textures[i].enabled()) continue; + size_t w = textures[i].width(), h = textures[i].height(); + if (!w || !h) continue; + + int is_unorm = (textures[i].format() & CELL_GCM_TEXTURE_UN); + memcpy((char*)mapped_buffer + heap_offset + (18 + tex_idx++) * sizeof(int), &is_unorm, sizeof(int)); + } m_constants_data.m_heap->Unmap(0, &CD3DX12_RANGE(heap_offset, heap_offset + 256)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp index 688470a491..cbf1224c83 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp @@ -42,7 +42,7 @@ std::string getFunctionImp(FUNCTION f) case FUNCTION::FUNCTION_FRACT: return "frac($0)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE: - return "$t.Sample($tsampler, $0.xy)"; + return "$t.Sample($tsampler, $0.xy * $t_scale)"; case FUNCTION::FUNCTION_DFDX: return "ddx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 98eb6c2cc3..776b3aa385 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -39,6 +39,22 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS) OS << " float4x4 scaleOffsetMat;" << std::endl; OS << " int isAlphaTested;" << std::endl; OS << " float alphaRef;" << std::endl; + OS << " int tex0_is_unorm;" << std::endl; + OS << " int tex1_is_unorm;" << std::endl; + OS << " int tex2_is_unorm;" << std::endl; + OS << " int tex3_is_unorm;" << std::endl; + OS << " int tex4_is_unorm;" << std::endl; + OS << " int tex5_is_unorm;" << std::endl; + OS << " int tex6_is_unorm;" << std::endl; + OS << " int tex7_is_unorm;" << std::endl; + OS << " int tex8_is_unorm;" << std::endl; + OS << " int tex9_is_unorm;" << std::endl; + OS << " int tex10_is_unorm;" << std::endl; + OS << " int tex11_is_unorm;" << std::endl; + OS << " int tex12_is_unorm;" << std::endl; + OS << " int tex13_is_unorm;" << std::endl; + OS << " int tex14_is_unorm;" << std::endl; + OS << " int tex15_is_unorm;" << std::endl; OS << "};" << std::endl; } @@ -107,7 +123,6 @@ void D3D12FragmentDecompiler::insertConstants(std::stringstream & OS) size_t textureIndex = atoi(PI.name.data() + 3); OS << "Texture2D " << PI.name << " : register(t" << textureIndex << ");" << std::endl; OS << "sampler " << PI.name << "sampler : register(s" << textureIndex << ");" << std::endl; - textureIndex++; } } } @@ -129,6 +144,21 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS) for (ParamItem PI : PT.items) OS << " " << PT.type << " " << PI.name << " = float4(0., 0., 0., 0.);" << std::endl; } + + // Declare texture coordinate scaling component (to handle unormalized texture coordinates) + + for (ParamType PT : m_parr.params[PF_PARAM_UNIFORM]) + { + if (PT.type != "sampler2D") + continue; + for (const ParamItem& PI : PT.items) + { + size_t textureIndex = atoi(PI.name.data() + 3); + OS << " float2 " << PI.name << "_dim;" << std::endl; + OS << " " << PI.name << ".GetDimensions(" << PI.name << "_dim.x, " << PI.name << "_dim.y);" << std::endl; + OS << " float2 " << PI.name << "_scale = (!!" << PI.name << "_is_unorm) ? float2(1., 1.) / " << PI.name << "_dim : float2(1., 1.);" << std::endl; + } + } } void D3D12FragmentDecompiler::insertMainEnd(std::stringstream & OS) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp index 3a27b004fd..d603cc9c72 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp @@ -33,6 +33,22 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS) OS << " float4x4 scaleOffsetMat;" << std::endl; OS << " int isAlphaTested;" << std::endl; OS << " float alphaRef;" << std::endl; + OS << " int tex0_is_unorm;" << std::endl; + OS << " int tex1_is_unorm;" << std::endl; + OS << " int tex2_is_unorm;" << std::endl; + OS << " int tex3_is_unorm;" << std::endl; + OS << " int tex4_is_unorm;" << std::endl; + OS << " int tex5_is_unorm;" << std::endl; + OS << " int tex6_is_unorm;" << std::endl; + OS << " int tex7_is_unorm;" << std::endl; + OS << " int tex8_is_unorm;" << std::endl; + OS << " int tex9_is_unorm;" << std::endl; + OS << " int tex10_is_unorm;" << std::endl; + OS << " int tex11_is_unorm;" << std::endl; + OS << " int tex12_is_unorm;" << std::endl; + OS << " int tex13_is_unorm;" << std::endl; + OS << " int tex14_is_unorm;" << std::endl; + OS << " int tex15_is_unorm;" << std::endl; OS << "};" << std::endl; } From 450c8245ed22a4f53b399e11dd7c9dd992d514d0 Mon Sep 17 00:00:00 2001 From: Zangetsu38 Date: Tue, 1 Dec 2015 04:15:55 +0100 Subject: [PATCH 5/5] Fix Jet Set Radio --- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 708ca2028d..22996bdafc 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -108,13 +108,13 @@ D3D12_STENCIL_OP get_stencil_op(u32 op) noexcept 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_INVERT: return D3D12_STENCIL_OP_INVERT; case CELL_GCM_INCR_WRAP: case CELL_GCM_DECR_WRAP: - unreachable("Unsupported Stencil Op %d"); + LOG_WARNING(RSX, "Unsupported stencil op used %x, please report this to a developer.", op); } - // Jet Set Radio uses an unknow op but INCR seems to be the intended one - LOG_WARNING(RSX, "Unknow stencil op %x, fallback to INCR", op); - return D3D12_STENCIL_OP_INCR; + LOG_ERROR(RSX, "Unknow stencil op used %x, please report this to a developer.", op); + unreachable("Wrong Stencil op"); } D3D12_COMPARISON_FUNC get_compare_func(u32 op) noexcept