From fc1408e64300db53c329a8b216ec549d982ca493 Mon Sep 17 00:00:00 2001 From: raven02 Date: Sun, 29 May 2016 23:33:41 +0800 Subject: [PATCH] FP: Implement texture lookup with explicit gradients (#1706) --- .../RSX/Common/FragmentProgramDecompiler.cpp | 18 +++++++++++++++++- rpcs3/Emu/RSX/Common/ShaderParam.h | 4 ++++ rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp | 8 ++++++++ rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp | 8 ++++++++ rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp | 6 ++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 1c905301e6..c50c708249 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -477,7 +477,23 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) } return false; case RSX_FP_OPCODE_TXPBEM: SetDst("textureProj($t, $0.xyz, $1.x)"); return true; - case RSX_FP_OPCODE_TXD: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: TXD"); return true; + case RSX_FP_OPCODE_TXD: + switch (m_prog.get_texture_dimension(dst.tex_num)) + { + case rsx::texture_dimension_extended::texture_dimension_1d: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD)); + return true; + case rsx::texture_dimension_extended::texture_dimension_2d: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD)); + return true; + case rsx::texture_dimension_extended::texture_dimension_cubemap: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD)); + return true; + case rsx::texture_dimension_extended::texture_dimension_3d: + SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD)); + return true; + } + return false; case RSX_FP_OPCODE_TXB: SetDst("texture($t, $0.xy, $1.x)"); return true; case RSX_FP_OPCODE_TXL: switch (m_prog.get_texture_dimension(dst.tex_num)) diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index d667369565..d5cb7513b6 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -19,15 +19,19 @@ enum class FUNCTION { FUNCTION_TEXTURE_SAMPLE1D, FUNCTION_TEXTURE_SAMPLE1D_PROJ, FUNCTION_TEXTURE_SAMPLE1D_LOD, + FUNCTION_TEXTURE_SAMPLE1D_GRAD, FUNCTION_TEXTURE_SAMPLE2D, FUNCTION_TEXTURE_SAMPLE2D_PROJ, FUNCTION_TEXTURE_SAMPLE2D_LOD, + FUNCTION_TEXTURE_SAMPLE2D_GRAD, FUNCTION_TEXTURE_SAMPLECUBE, FUNCTION_TEXTURE_SAMPLECUBE_PROJ, FUNCTION_TEXTURE_SAMPLECUBE_LOD, + FUNCTION_TEXTURE_SAMPLECUBE_GRAD, FUNCTION_TEXTURE_SAMPLE3D, FUNCTION_TEXTURE_SAMPLE3D_PROJ, FUNCTION_TEXTURE_SAMPLE3D_LOD, + FUNCTION_TEXTURE_SAMPLE3D_GRAD, }; enum class COMPARE { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp index 29a7ddfc79..1280bab1b0 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12CommonDecompiler.cpp @@ -48,24 +48,32 @@ std::string getFunctionImp(FUNCTION f) return "$t.Sample($tsampler, ($0.x / $0.w))"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD: return "$t.SampleLevel($tsampler, $0.x, $1)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD: + return "$t.SampleGrad($tsampler, $0.x, $1, $2)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D: return "$t.Sample($tsampler, $0.xy * $t_scale)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ: return "$t.Sample($tsampler, ($0.xy / $0.w) * $t_scale)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD: return "$t.SampleLevel($tsampler, $0.xy * $t_scale, $1)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD: + return "$t.SampleGrad($tsampler, $0.xy, $1, $2)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: return "$t.Sample($tsampler, $0.xyz)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ: return "$t.Sample($tsampler, ($0.xyz / $0.w))"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD: return "$t.SampleLevel($tsampler, $0.xyz, $1)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD: + return "$t.SampleGrad($tsampler, $0.xyz, $1, $2)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D: return "$t.Sample($tsampler, $0.xyz)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ: return "$t.Sample($tsampler, ($0.xyz / $0.w))"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD: return "$t.SampleLevel($tsampler, $0.xyz, $1)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD: + return "$t.SampleGrad($tsampler, $0.xyz, $1, $2)"; case FUNCTION::FUNCTION_DFDX: return "ddx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp index aa01e6bc06..5662618c88 100644 --- a/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/GL/GLCommonDecompiler.cpp @@ -46,24 +46,32 @@ std::string getFunctionImpl(FUNCTION f) return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD: return "textureLod($t, $0.x, $1)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD: + return "textureGrad($t, $0.x, $1.x, $2.y)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D: return "texture($t, $0.xy * $t_coord_scale)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ: return "textureProj($t, $0.xyz * vec3($t_coord_scale, 1.) , $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD: return "textureLod($t, $0.xy * $t_coord_scale, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD: + return "textureGrad($t, $0.xyz * vec3($t_coord_scale, 1.) , $1.x, $2.y)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: return "texture($t, $0.xyz)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ: return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD: return "textureLod($t, $0.xyz, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD: + return "textureGrad($t, $0.xyzw, $1.x, $2.y)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D: return "texture($t, $0.xyz)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ: return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD: return "textureLod($t, $0.xyz, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD: + return "textureGrad($t, $0.xyzw, $1.x, $2.y)"; case FUNCTION::FUNCTION_DFDX: return "dFdx($0)"; case FUNCTION::FUNCTION_DFDY: diff --git a/rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp b/rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp index 137efbd300..e4fd45cba8 100644 --- a/rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp +++ b/rpcs3/Emu/RSX/VK/VKCommonDecompiler.cpp @@ -49,18 +49,24 @@ namespace vk return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD: return "textureLod($t, $0.x, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD: + return "textureGrad($t, $0.x, $1.x, $2.y)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D: return "texture($t, $0.xy)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ: return "textureProj($t, $0.xyz, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD: return "textureLod($t, $0.xy, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD: + return "textureGrad($t, $0.xyz, $1.x, $2.y)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: return "texture($t, $0.xyz)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ: return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD: return "textureLod($t, $0.xyz, $1.x)"; + case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD: + return "textureGrad($t, $0.xyzw, $1.x, $2.y)"; case FUNCTION::FUNCTION_DFDX: return "dFdx($0)"; case FUNCTION::FUNCTION_DFDY: