diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp index 25f468614b..551c1257d8 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp @@ -399,17 +399,17 @@ std::string FragmentProgramDecompiler::GetRawCond() } if (src0.exec_if_gr && src0.exec_if_eq) - cond = compareFunction(COMPARE::FUNCTION_SGE, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SGE, AddCond() + swizzle, zero); else if (src0.exec_if_lt && src0.exec_if_eq) - cond = compareFunction(COMPARE::FUNCTION_SLE, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SLE, AddCond() + swizzle, zero); else if (src0.exec_if_gr && src0.exec_if_lt) - cond = compareFunction(COMPARE::FUNCTION_SNE, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SNE, AddCond() + swizzle, zero); else if (src0.exec_if_gr) - cond = compareFunction(COMPARE::FUNCTION_SGT, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SGT, AddCond() + swizzle, zero); else if (src0.exec_if_lt) - cond = compareFunction(COMPARE::FUNCTION_SLT, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SLT, AddCond() + swizzle, zero); else //if(src0.exec_if_eq) - cond = compareFunction(COMPARE::FUNCTION_SEQ, AddCond() + swizzle, zero); + cond = compareFunction(COMPARE::SEQ, AddCond() + swizzle, zero); return cond; } @@ -1018,10 +1018,10 @@ bool FragmentProgramDecompiler::handle_sct_scb(u32 opcode) SetDst("_builtin_divsq($0, $1.x)"); properties.has_divsq = true; return true; - case RSX_FP_OPCODE_DP2: SetDst(getFunction(FUNCTION::FUNCTION_DP2), OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_DP3: SetDst(getFunction(FUNCTION::FUNCTION_DP3), OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_DP4: SetDst(getFunction(FUNCTION::FUNCTION_DP4), OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_DP2A: SetDst(getFunction(FUNCTION::FUNCTION_DP2A), OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_DP2: SetDst(getFunction(FUNCTION::DP2), OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_DP3: SetDst(getFunction(FUNCTION::DP3), OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_DP4: SetDst(getFunction(FUNCTION::DP4), OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_DP2A: SetDst(getFunction(FUNCTION::DP2A), OPFLAGS::op_extern); return true; case RSX_FP_OPCODE_MAD: SetDst("fma($0, $1, $2)", OPFLAGS::src_cast_f32); return true; case RSX_FP_OPCODE_MAX: SetDst("max($0, $1)", OPFLAGS::src_cast_f32); return true; case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)", OPFLAGS::src_cast_f32); return true; @@ -1029,22 +1029,22 @@ bool FragmentProgramDecompiler::handle_sct_scb(u32 opcode) case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); return true; case RSX_FP_OPCODE_RCP: SetDst("_builtin_rcp($0.x).xxxx"); return true; case RSX_FP_OPCODE_RSQ: SetDst("_builtin_rsq($0.x).xxxx"); return true; - case RSX_FP_OPCODE_SEQ: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_SFL: SetDst(getFunction(FUNCTION::FUNCTION_SFL), OPFLAGS::skip_type_cast); return true; - case RSX_FP_OPCODE_SGE: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SGE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_SGT: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SGT, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_SLE: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SLE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_SLT: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SLT, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_SNE: SetDst("$Ty(" + compareFunction(COMPARE::FUNCTION_SNE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_STR: SetDst(getFunction(FUNCTION::FUNCTION_STR), OPFLAGS::skip_type_cast); return true; + case RSX_FP_OPCODE_SEQ: SetDst("$Ty(" + compareFunction(COMPARE::SEQ, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_SFL: SetDst(getFunction(FUNCTION::SFL), OPFLAGS::skip_type_cast); return true; + case RSX_FP_OPCODE_SGE: SetDst("$Ty(" + compareFunction(COMPARE::SGE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_SGT: SetDst("$Ty(" + compareFunction(COMPARE::SGT, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_SLE: SetDst("$Ty(" + compareFunction(COMPARE::SLE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_SLT: SetDst("$Ty(" + compareFunction(COMPARE::SLT, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_SNE: SetDst("$Ty(" + compareFunction(COMPARE::SNE, "$0", "$1") + ")", OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_STR: SetDst(getFunction(FUNCTION::STR), OPFLAGS::skip_type_cast); return true; // SCB-only ops case RSX_FP_OPCODE_COS: SetDst("cos($0.xxxx)"); return true; case RSX_FP_OPCODE_DST: SetDst("$Ty(1.0, $0.y * $1.y, $0.z, $1.w)", OPFLAGS::op_extern); return true; - case RSX_FP_OPCODE_REFL: SetDst(getFunction(FUNCTION::FUNCTION_REFL), OPFLAGS::op_extern); return true; + case RSX_FP_OPCODE_REFL: SetDst(getFunction(FUNCTION::REFL), OPFLAGS::op_extern); return true; case RSX_FP_OPCODE_EX2: SetDst("exp2($0.xxxx)"); return true; case RSX_FP_OPCODE_FLR: SetDst("_builtin_floor($0)"); return true; - case RSX_FP_OPCODE_FRC: SetDst(getFunction(FUNCTION::FUNCTION_FRACT)); return true; + case RSX_FP_OPCODE_FRC: SetDst(getFunction(FUNCTION::FRACT)); return true; case RSX_FP_OPCODE_LIT: SetDst("_builtin_lit($0)"); properties.has_lit_op = true; @@ -1074,48 +1074,51 @@ bool FragmentProgramDecompiler::handle_sct_scb(u32 opcode) bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) { - auto insert_texture_fetch = [this](const std::array& functions) + auto insert_texture_fetch = [this](FUNCTION base_func) { const auto type = m_prog.get_texture_dimension(dst.tex_num); const auto ref_mask = (1 << dst.tex_num); std::string swz_mask = ""; - auto select = static_cast(type); - if (type != rsx::texture_dimension_extended::texture_dimension_3d) + auto func_id = base_func; + + if (m_prog.texture_state.shadow_textures & ref_mask) { - if (m_prog.texture_state.shadow_textures & ref_mask) + properties.shadow_sampler_mask |= ref_mask; + swz_mask = ".xxxx"; + + func_id = (base_func == FUNCTION::TEXTURE_SAMPLE_PROJ_BASE) ? FUNCTION::TEXTURE_SAMPLE_SHADOW_PROJ_BASE : FUNCTION::TEXTURE_SAMPLE_SHADOW_BASE; + } + else + { + properties.common_access_sampler_mask |= ref_mask; + if (m_prog.texture_state.redirected_textures & ref_mask) { - properties.shadow_sampler_mask |= ref_mask; - select = 4; - swz_mask = ".xxxx"; - } - else - { - properties.common_access_sampler_mask |= ref_mask; - if (m_prog.texture_state.redirected_textures & ref_mask) - { - properties.redirected_sampler_mask |= ref_mask; - select = 5; - } + properties.redirected_sampler_mask |= ref_mask; + func_id = (base_func == FUNCTION::TEXTURE_SAMPLE_PROJ_BASE) ? FUNCTION::TEXTURE_SAMPLE_DEPTH_RGBA_PROJ_BASE : FUNCTION::TEXTURE_SAMPLE_DEPTH_RGBA_BASE; } } + // Sanity checks + if (func_id != base_func && base_func != FUNCTION::TEXTURE_SAMPLE_BASE) + { + // A lot of redundant special-access modes would be needed to cater for all the variations, ignore special modifiers for now, but log an error + rsx_log.error("[Unimplemented warning] Conflicting texture decode options in the shaders detected. Base option=%d, selected=%d", static_cast(base_func), static_cast(func_id)); + } + + ensure(func_id <= FUNCTION::TEXTURE_SAMPLE_MAX_BASE_ENUM && func_id >= FUNCTION::TEXTURE_SAMPLE_BASE); + + // Clamp type to 3 types (1d, 2d, cube+3d) and offset into sampling redirection table + const auto type_offset = (std::min(static_cast(type), 2) + 1) * static_cast(FUNCTION::TEXTURE_SAMPLE_BASE_ENUM_COUNT); + func_id = static_cast(static_cast(func_id) + type_offset); + if (dst.exp_tex) { properties.has_exp_tex_op = true; AddCode("_enable_texture_expand();"); } - auto function = functions[select]; - - if (function == FUNCTION::FUNCTION_TEXTURE_SHADOW2D && - type == rsx::texture_dimension_extended::texture_dimension_cubemap) - { - // Cubemap shadow override - function = FUNCTION::FUNCTION_TEXTURE_SHADOWCUBE; - } - - SetDst(getFunction(function) + swz_mask); + SetDst(getFunction(func_id) + swz_mask); if (dst.exp_tex) { @@ -1126,8 +1129,8 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) switch (opcode) { - case RSX_FP_OPCODE_DDX: SetDst(getFunction(FUNCTION::FUNCTION_DFDX)); return true; - case RSX_FP_OPCODE_DDY: SetDst(getFunction(FUNCTION::FUNCTION_DFDY)); return true; + case RSX_FP_OPCODE_DDX: SetDst(getFunction(FUNCTION::DFDX)); return true; + case RSX_FP_OPCODE_DDY: SetDst(getFunction(FUNCTION::DFDY)); return true; case RSX_FP_OPCODE_NRM: SetDst("_builtin_normalize($0.xyz).xyzz", OPFLAGS::src_cast_f32); return true; case RSX_FP_OPCODE_BEM: SetDst("$0.xyxy + $1.xxxx * $2.xzxz + $1.yyyy * $2.ywyw"); return true; case RSX_FP_OPCODE_TEXBEM: @@ -1140,15 +1143,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) case RSX_FP_OPCODE_TEX: { AddTex(); - insert_texture_fetch({ - FUNCTION::FUNCTION_TEXTURE_SAMPLE1D, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D, - FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE, - FUNCTION::FUNCTION_TEXTURE_SAMPLE3D, - FUNCTION::FUNCTION_TEXTURE_SHADOW2D, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA - }); - + insert_texture_fetch(FUNCTION::TEXTURE_SAMPLE_BASE); return true; } case RSX_FP_OPCODE_TXPBEM: @@ -1161,65 +1156,25 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) case RSX_FP_OPCODE_TXP: { AddTex(); - insert_texture_fetch({ - FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ, - FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ, - FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ, - FUNCTION::FUNCTION_TEXTURE_SHADOW2D_PROJ, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA_PROJ - }); - + insert_texture_fetch(FUNCTION::TEXTURE_SAMPLE_PROJ_BASE); return true; } case RSX_FP_OPCODE_TXD: { AddTex(); - - if (m_prog.texture_state.redirected_textures & (1 << dst.tex_num) || - m_prog.texture_state.shadow_textures & (1 << dst.tex_num)) - { - // Doesn't make sense to sample with derivates for these types - rsx_log.error("[Unimplemented warning] TXD operation performed on shadow/redirected texture!"); - } - - insert_texture_fetch({ - FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD, - FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD - }); - + insert_texture_fetch(FUNCTION::TEXTURE_SAMPLE_GRAD_BASE); return true; } case RSX_FP_OPCODE_TXB: { AddTex(); - insert_texture_fetch({ - FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_BIAS, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_BIAS, - FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_BIAS, - FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_BIAS, - FUNCTION::FUNCTION_TEXTURE_SHADOW2D, // Shadow and depth_rgba variants are generated for framebuffers where only LOD0 exists - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA - }); - + insert_texture_fetch(FUNCTION::TEXTURE_SAMPLE_BIAS_BASE); return true; } case RSX_FP_OPCODE_TXL: { AddTex(); - insert_texture_fetch({ - FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD, - FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD, - FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD, - FUNCTION::FUNCTION_TEXTURE_SHADOW2D, // Shadow and depth_rgba variants are generated for framebuffers where only LOD0 exists - FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA - }); - + insert_texture_fetch(FUNCTION::TEXTURE_SAMPLE_LOD_BASE); return true; } // Unpack operations. See https://www.khronos.org/registry/OpenGL/extensions/NV/NV_fragment_program.txt diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index f2f627ad34..f83a5db0eb 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -172,17 +172,17 @@ namespace glsl { switch (f) { - case COMPARE::FUNCTION_SEQ: + case COMPARE::SEQ: return Op0 + " == " + Op1; - case COMPARE::FUNCTION_SGE: + case COMPARE::SGE: return Op0 + " >= " + Op1; - case COMPARE::FUNCTION_SGT: + case COMPARE::SGT: return Op0 + " > " + Op1; - case COMPARE::FUNCTION_SLE: + case COMPARE::SLE: return Op0 + " <= " + Op1; - case COMPARE::FUNCTION_SLT: + case COMPARE::SLT: return Op0 + " < " + Op1; - case COMPARE::FUNCTION_SNE: + case COMPARE::SNE: return Op0 + " != " + Op1; } } @@ -190,17 +190,17 @@ namespace glsl { switch (f) { - case COMPARE::FUNCTION_SEQ: + case COMPARE::SEQ: return "equal(" + Op0 + ", " + Op1 + ")"; - case COMPARE::FUNCTION_SGE: + case COMPARE::SGE: return "greaterThanEqual(" + Op0 + ", " + Op1 + ")"; - case COMPARE::FUNCTION_SGT: + case COMPARE::SGT: return "greaterThan(" + Op0 + ", " + Op1 + ")"; - case COMPARE::FUNCTION_SLE: + case COMPARE::SLE: return "lessThanEqual(" + Op0 + ", " + Op1 + ")"; - case COMPARE::FUNCTION_SLT: + case COMPARE::SLT: return "lessThan(" + Op0 + ", " + Op1 + ")"; - case COMPARE::FUNCTION_SNE: + case COMPARE::SNE: return "notEqual(" + Op0 + ", " + Op1 + ")"; } } @@ -747,10 +747,10 @@ namespace glsl " return _select(result, vec4(remap_select), choice);\n" "}\n\n" - "vec4 texture2DReconstruct(sampler2D tex, usampler2D stencil_tex, const in vec2 coord, const in uint remap, const in uint flags)\n" + "vec4 convert_z24x8_to_rgba8(const in vec2 depth_stencil, const in uint remap, const in uint flags)\n" "{\n" - " vec4 result = decode_depth24(texture(tex, coord.xy).r, _test_bit(flags, DEPTH_FLOAT));\n" - " result.z = float(texture(stencil_tex, coord.xy).x) / 255.f;\n\n" + " vec4 result = decode_depth24(depth_stencil.x, _test_bit(flags, DEPTH_FLOAT));\n" + " result.z = depth_stencil.y / 255.;\n\n" " if (remap == 0xAAE4)\n" " return result;\n\n" @@ -855,15 +855,13 @@ namespace glsl "#define TEX1D_BIAS(index, coord1, bias) process_texel(texture(TEX_NAME(index), COORD_SCALE1(index, coord1), bias), TEX_FLAGS(index))\n" "#define TEX1D_LOD(index, coord1, lod) process_texel(textureLod(TEX_NAME(index), COORD_SCALE1(index, coord1), lod), TEX_FLAGS(index))\n" "#define TEX1D_GRAD(index, coord1, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), COORD_SCALE1(index, coord1), dpdx, dpdy), TEX_FLAGS(index))\n" - "#define TEX1D_PROJ(index, coord2) process_texel(textureProj(TEX_NAME(index), vec2(COORD_SCALE1(index, coord2.x), coord2.y)), TEX_FLAGS(index))\n" + "#define TEX1D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), vec2(COORD_SCALE1(index, coord2.x), coord2.w)), TEX_FLAGS(index))\n" "#define TEX2D(index, coord2) process_texel(texture(TEX_NAME(index), COORD_SCALE2(index, coord2)), TEX_FLAGS(index))\n" "#define TEX2D_BIAS(index, coord2, bias) process_texel(texture(TEX_NAME(index), COORD_SCALE2(index, coord2), bias), TEX_FLAGS(index))\n" "#define TEX2D_LOD(index, coord2, lod) process_texel(textureLod(TEX_NAME(index), COORD_SCALE2(index, coord2), lod), TEX_FLAGS(index))\n" "#define TEX2D_GRAD(index, coord2, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), COORD_SCALE2(index, coord2), dpdx, dpdy), TEX_FLAGS(index))\n" - "#define TEX2D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), vec4(COORD_SCALE2(index, coord4.xy), coord4.z, coord4.w)), TEX_FLAGS(index))\n" - - "#define TEX2D_DEPTH_RGBA8(index, coord2) process_texel(texture2DReconstruct(TEX_NAME(index), TEX_NAME_STENCIL(index), COORD_SCALE2(index, coord2), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index))\n"; + "#define TEX2D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), vec4(COORD_SCALE2(index, coord4.xy), coord4.z, coord4.w)), TEX_FLAGS(index))\n\n"; if (props.emulate_shadow_compare) { @@ -873,14 +871,14 @@ namespace glsl "#define SHADOW_COORD_PROJ(index, coord4) vec4(COORD_SCALE2(index, coord4.xy), _test_bit(TEX_FLAGS(index), DEPTH_FLOAT)? coord4.z : min(coord4.z, coord4.w), coord4.w)\n\n" "#define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), SHADOW_COORD(index, coord3))\n" - "#define TEX2D_SHADOWCUBE(index, coord4) texture(TEX_NAME(index), SHADOW_COORD4(index, coord4))\n" + "#define TEX3D_SHADOW(index, coord4) texture(TEX_NAME(index), SHADOW_COORD4(index, coord4))\n" "#define TEX2D_SHADOWPROJ(index, coord4) textureProj(TEX_NAME(index), SHADOW_COORD_PROJ(index, coord4))\n"; } else { OS << "#define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), vec3(COORD_SCALE2(index, coord3.xy), coord3.z))\n" - "#define TEX2D_SHADOWCUBE(index, coord4) texture(TEX_NAME(index), vec4(COORD_SCALE3(index, coord4.xyz), coord4.w))\n" + "#define TEX3D_SHADOW(index, coord4) texture(TEX_NAME(index), vec4(COORD_SCALE3(index, coord4.xyz), coord4.w))\n" "#define TEX2D_SHADOWPROJ(index, coord4) textureProj(TEX_NAME(index), vec4(COORD_SCALE2(index, coord4.xy), coord4.zw))\n"; } @@ -890,6 +888,15 @@ namespace glsl "#define TEX3D_LOD(index, coord3, lod) process_texel(textureLod(TEX_NAME(index), COORD_SCALE3(index, coord3), lod), TEX_FLAGS(index))\n" "#define TEX3D_GRAD(index, coord3, dpdx, dpdy) process_texel(textureGrad(TEX_NAME(index), COORD_SCALE3(index, coord3), dpdx, dpdy), TEX_FLAGS(index))\n" "#define TEX3D_PROJ(index, coord4) process_texel(textureProj(TEX_NAME(index), vec4(COORD_SCALE3(index, coord4.xyz), coord4.w)), TEX_FLAGS(index))\n\n"; + + if (props.require_depth_conversion) + { + OS << + "#define ZS_READ(index, coord) vec2(texture(TEX_NAME(index), coord).r, float(texture(TEX_NAME_STENCIL(index), coord).x))\n" + "#define TEX1D_Z24X8_RGBA8(index, coord1) process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE1(index, coord1)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index))\n" + "#define TEX2D_Z24X8_RGBA8(index, coord2) process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE2(index, coord2)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index))\n" + "#define TEX3D_Z24X8_RGBA8(index, coord3) process_texel(convert_z24x8_to_rgba8(ZS_READ(index, COORD_SCALE3(index, coord3)), texture_parameters[index].remap, TEX_FLAGS(index)), TEX_FLAGS(index))\n\n"; + } } if (props.require_wpos) @@ -914,86 +921,94 @@ namespace glsl { default: abort(); - case FUNCTION::FUNCTION_DP2: + case FUNCTION::DP2: return "$Ty(dot($0.xy, $1.xy))"; - case FUNCTION::FUNCTION_DP2A: + case FUNCTION::DP2A: return "$Ty(dot($0.xy, $1.xy) + $2.x)"; - case FUNCTION::FUNCTION_DP3: + case FUNCTION::DP3: return "$Ty(dot($0.xyz, $1.xyz))"; - case FUNCTION::FUNCTION_DP4: + case FUNCTION::DP4: return "$Ty(dot($0, $1))"; - case FUNCTION::FUNCTION_DPH: + case FUNCTION::DPH: return "$Ty(dot(vec4($0.xyz, 1.0), $1))"; - case FUNCTION::FUNCTION_SFL: + case FUNCTION::SFL: return "$Ty(0.)"; - case FUNCTION::FUNCTION_STR: + case FUNCTION::STR: return "$Ty(1.)"; - case FUNCTION::FUNCTION_FRACT: + case FUNCTION::FRACT: return "fract($0)"; - case FUNCTION::FUNCTION_REFL: + case FUNCTION::REFL: return "reflect($0, $1)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D: + case FUNCTION::TEXTURE_SAMPLE1D: return "TEX1D($_i, $0.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_BIAS: + case FUNCTION::TEXTURE_SAMPLE1D_BIAS: return "TEX1D_BIAS($_i, $0.x, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ: - return "TEX1D_PROJ($_i, $0.xy)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD: + case FUNCTION::TEXTURE_SAMPLE1D_PROJ: + return "TEX1D_PROJ($_i, $0)"; + case FUNCTION::TEXTURE_SAMPLE1D_LOD: return "TEX1D_LOD($_i, $0.x, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD: + case FUNCTION::TEXTURE_SAMPLE1D_GRAD: return "TEX1D_GRAD($_i, $0.x, $1.x, $2.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D: + case FUNCTION::TEXTURE_SAMPLE1D_SHADOW: + case FUNCTION::TEXTURE_SAMPLE1D_SHADOW_PROJ: + // Unimplemented + break; + case FUNCTION::TEXTURE_SAMPLE1D_DEPTH_RGBA: + return "TEX1D_Z24X8_RGBA8($_i, $0.x)"; + case FUNCTION::TEXTURE_SAMPLE1D_DEPTH_RGBA_PROJ: + return "TEX1D_Z24X8_RGBA8($_i, ($0.x / $0.w))"; + case FUNCTION::TEXTURE_SAMPLE2D: return "TEX2D($_i, $0.xy)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_BIAS: + case FUNCTION::TEXTURE_SAMPLE2D_BIAS: return "TEX2D_BIAS($_i, $0.xy, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ: + case FUNCTION::TEXTURE_SAMPLE2D_PROJ: return "TEX2D_PROJ($_i, $0)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD: + case FUNCTION::TEXTURE_SAMPLE2D_LOD: return "TEX2D_LOD($_i, $0.xy, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD: + case FUNCTION::TEXTURE_SAMPLE2D_GRAD: return "TEX2D_GRAD($_i, $0.xy, $1.xy, $2.xy)"; - case FUNCTION::FUNCTION_TEXTURE_SHADOW2D: + case FUNCTION::TEXTURE_SAMPLE2D_SHADOW: return "TEX2D_SHADOW($_i, $0.xyz)"; - case FUNCTION::FUNCTION_TEXTURE_SHADOWCUBE: - return "TEX2D_SHADOWCUBE($_i, $0)"; - case FUNCTION::FUNCTION_TEXTURE_SHADOW2D_PROJ: + case FUNCTION::TEXTURE_SAMPLE2D_SHADOW_PROJ: return "TEX2D_SHADOWPROJ($_i, $0)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: + case FUNCTION::TEXTURE_SAMPLE2D_DEPTH_RGBA: + return "TEX2D_Z24X8_RGBA8($_i, $0.xy)"; + case FUNCTION::TEXTURE_SAMPLE2D_DEPTH_RGBA_PROJ: + return "TEX2D_Z24X8_RGBA8($_i, ($0.xy / $0.w))"; + case FUNCTION::TEXTURE_SAMPLE3D: return "TEX3D($_i, $0.xyz)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_BIAS: + case FUNCTION::TEXTURE_SAMPLE3D_BIAS: return "TEX3D_BIAS($_i, $0.xyz, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ: - return "TEX3D($_i, ($0.xyz / $0.w))"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD: - return "TEX3D_LOD($_i, $0.xyz, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD: - return "TEX3D_GRAD($_i, $0.xyz, $1.xyz, $2.xyz)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D: - return "TEX3D($_i, $0.xyz)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_BIAS: - return "TEX3D_BIAS($_i, $0.xyz, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ: + case FUNCTION::TEXTURE_SAMPLE3D_PROJ: return "TEX3D_PROJ($_i, $0)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD: + case FUNCTION::TEXTURE_SAMPLE3D_LOD: return "TEX3D_LOD($_i, $0.xyz, $1.x)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD: + case FUNCTION::TEXTURE_SAMPLE3D_GRAD: return "TEX3D_GRAD($_i, $0.xyz, $1.xyz, $2.xyz)"; - case FUNCTION::FUNCTION_DFDX: + case FUNCTION::TEXTURE_SAMPLE3D_SHADOW: + return "TEX3D_SHADOW($_i, $0)"; + case FUNCTION::TEXTURE_SAMPLE3D_SHADOW_PROJ: + // Impossible + break; + case FUNCTION::TEXTURE_SAMPLE3D_DEPTH_RGBA: + return "TEX3D_Z24X8_RGBA8($_i, $0.xyz)"; + case FUNCTION::TEXTURE_SAMPLE3D_DEPTH_RGBA_PROJ: + return "TEX3D_Z24X8_RGBA8($_i, ($0.xyz / $0.w))"; + case FUNCTION::DFDX: return "dFdx($0)"; - case FUNCTION::FUNCTION_DFDY: + case FUNCTION::DFDY: return "dFdy($0)"; - case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH1D: + case FUNCTION::VERTEX_TEXTURE_FETCH1D: return "textureLod($t, $0.x, 0)"; - case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D: + case FUNCTION::VERTEX_TEXTURE_FETCH2D: return "textureLod($t, $0.xy, 0)"; - case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH3D: - case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCHCUBE: + case FUNCTION::VERTEX_TEXTURE_FETCH3D: + case FUNCTION::VERTEX_TEXTURE_FETCHCUBE: return "textureLod($t, $0.xyz, 0)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA: - return "TEX2D_DEPTH_RGBA8($_i, $0.xy)"; - case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA_PROJ: - return "TEX2D_DEPTH_RGBA8($_i, ($0.xy / $0.w))"; } + + rsx_log.error("Unexpected function request: %d", static_cast(f)); + return "$Ty(0.)"; } void insert_subheader_block(std::ostream& OS) diff --git a/rpcs3/Emu/RSX/Program/ShaderParam.h b/rpcs3/Emu/RSX/Program/ShaderParam.h index 9814a11c50..4be8e15ca3 100644 --- a/rpcs3/Emu/RSX/Program/ShaderParam.h +++ b/rpcs3/Emu/RSX/Program/ShaderParam.h @@ -10,56 +10,78 @@ enum class FUNCTION { - FUNCTION_DP2, - FUNCTION_DP2A, - FUNCTION_DP3, - FUNCTION_DP4, - FUNCTION_DPH, - FUNCTION_SFL, // Set zero - FUNCTION_STR, // Set One - FUNCTION_FRACT, - FUNCTION_DFDX, - FUNCTION_DFDY, - FUNCTION_REFL, - FUNCTION_TEXTURE_SAMPLE1D, - FUNCTION_TEXTURE_SAMPLE1D_BIAS, - FUNCTION_TEXTURE_SAMPLE1D_PROJ, - FUNCTION_TEXTURE_SAMPLE1D_LOD, - FUNCTION_TEXTURE_SAMPLE1D_GRAD, - FUNCTION_TEXTURE_SAMPLE2D, - FUNCTION_TEXTURE_SAMPLE2D_BIAS, - FUNCTION_TEXTURE_SAMPLE2D_PROJ, - FUNCTION_TEXTURE_SAMPLE2D_LOD, - FUNCTION_TEXTURE_SAMPLE2D_GRAD, - FUNCTION_TEXTURE_SHADOW2D, - FUNCTION_TEXTURE_SHADOWCUBE, - FUNCTION_TEXTURE_SHADOW2D_PROJ, - FUNCTION_TEXTURE_SAMPLECUBE, - FUNCTION_TEXTURE_SAMPLECUBE_BIAS, - FUNCTION_TEXTURE_SAMPLECUBE_PROJ, - FUNCTION_TEXTURE_SAMPLECUBE_LOD, - FUNCTION_TEXTURE_SAMPLECUBE_GRAD, - FUNCTION_TEXTURE_SAMPLE3D, - FUNCTION_TEXTURE_SAMPLE3D_BIAS, - FUNCTION_TEXTURE_SAMPLE3D_PROJ, - FUNCTION_TEXTURE_SAMPLE3D_LOD, - FUNCTION_TEXTURE_SAMPLE3D_GRAD, - FUNCTION_VERTEX_TEXTURE_FETCH1D, - FUNCTION_VERTEX_TEXTURE_FETCH2D, - FUNCTION_VERTEX_TEXTURE_FETCH3D, - FUNCTION_VERTEX_TEXTURE_FETCHCUBE, - FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA, - FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA_PROJ + NOP, + DP2, + DP2A, + DP3, + DP4, + DPH, + SFL, // Set zero + STR, // Set One + FRACT, + DFDX, + DFDY, + REFL, + + // Samplers. Must be clustered in order 1D-2D-3D; CUBE maps as a 3D texture here + TEXTURE_SAMPLE_BASE, + TEXTURE_SAMPLE_BIAS_BASE, + TEXTURE_SAMPLE_PROJ_BASE, + TEXTURE_SAMPLE_LOD_BASE, + TEXTURE_SAMPLE_GRAD_BASE, + TEXTURE_SAMPLE_SHADOW_BASE, + TEXTURE_SAMPLE_SHADOW_PROJ_BASE, + TEXTURE_SAMPLE_DEPTH_RGBA_BASE, + TEXTURE_SAMPLE_DEPTH_RGBA_PROJ_BASE, + + TEXTURE_SAMPLE1D, + TEXTURE_SAMPLE1D_BIAS, + TEXTURE_SAMPLE1D_PROJ, + TEXTURE_SAMPLE1D_LOD, + TEXTURE_SAMPLE1D_GRAD, + TEXTURE_SAMPLE1D_SHADOW, + TEXTURE_SAMPLE1D_SHADOW_PROJ, + TEXTURE_SAMPLE1D_DEPTH_RGBA, + TEXTURE_SAMPLE1D_DEPTH_RGBA_PROJ, + + TEXTURE_SAMPLE2D, + TEXTURE_SAMPLE2D_BIAS, + TEXTURE_SAMPLE2D_PROJ, + TEXTURE_SAMPLE2D_LOD, + TEXTURE_SAMPLE2D_GRAD, + TEXTURE_SAMPLE2D_SHADOW, + TEXTURE_SAMPLE2D_SHADOW_PROJ, + TEXTURE_SAMPLE2D_DEPTH_RGBA, + TEXTURE_SAMPLE2D_DEPTH_RGBA_PROJ, + + TEXTURE_SAMPLE3D, + TEXTURE_SAMPLE3D_BIAS, + TEXTURE_SAMPLE3D_PROJ, + TEXTURE_SAMPLE3D_LOD, + TEXTURE_SAMPLE3D_GRAD, + TEXTURE_SAMPLE3D_SHADOW, + TEXTURE_SAMPLE3D_SHADOW_PROJ, + TEXTURE_SAMPLE3D_DEPTH_RGBA, + TEXTURE_SAMPLE3D_DEPTH_RGBA_PROJ, + + VERTEX_TEXTURE_FETCH1D, + VERTEX_TEXTURE_FETCH2D, + VERTEX_TEXTURE_FETCH3D, + VERTEX_TEXTURE_FETCHCUBE, + + // Meta + TEXTURE_SAMPLE_MAX_BASE_ENUM = TEXTURE_SAMPLE_DEPTH_RGBA_PROJ_BASE, // Update if more base enums are added + TEXTURE_SAMPLE_BASE_ENUM_COUNT = (TEXTURE_SAMPLE_MAX_BASE_ENUM - TEXTURE_SAMPLE_BASE + 1), }; enum class COMPARE { - FUNCTION_SEQ, - FUNCTION_SGE, - FUNCTION_SGT, - FUNCTION_SLE, - FUNCTION_SLT, - FUNCTION_SNE, + SEQ, + SGE, + SGT, + SLE, + SLT, + SNE, }; enum ParamFlag diff --git a/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.cpp index a716a66bf6..6dc3cb23e2 100644 --- a/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/VertexProgramDecompiler.cpp @@ -250,13 +250,13 @@ std::string VertexProgramDecompiler::GetRawCond() { static const COMPARE cond_string_table[(lt | gt | eq) + 1] = { - COMPARE::FUNCTION_SLT, // "error" - COMPARE::FUNCTION_SLT, - COMPARE::FUNCTION_SEQ, - COMPARE::FUNCTION_SLE, - COMPARE::FUNCTION_SGT, - COMPARE::FUNCTION_SNE, - COMPARE::FUNCTION_SGE, + COMPARE::SLT, // "error" + COMPARE::SLT, + COMPARE::SEQ, + COMPARE::SLE, + COMPARE::SGT, + COMPARE::SNE, + COMPARE::SGE, }; static const char f[4] = { 'x', 'y', 'z', 'w' }; @@ -572,23 +572,23 @@ std::string VertexProgramDecompiler::Decompile() case RSX_VEC_OPCODE_MUL: SetDSTVec("($0 * $1)"); break; case RSX_VEC_OPCODE_ADD: SetDSTVec("($0 + $2)"); break; case RSX_VEC_OPCODE_MAD: SetDSTVec("fma($0, $1, $2)"); break; - case RSX_VEC_OPCODE_DP3: SetDSTVec(getFunction(FUNCTION::FUNCTION_DP3)); break; - case RSX_VEC_OPCODE_DPH: SetDSTVec(getFunction(FUNCTION::FUNCTION_DPH)); break; - case RSX_VEC_OPCODE_DP4: SetDSTVec(getFunction(FUNCTION::FUNCTION_DP4)); break; + case RSX_VEC_OPCODE_DP3: SetDSTVec(getFunction(FUNCTION::DP3)); break; + case RSX_VEC_OPCODE_DPH: SetDSTVec(getFunction(FUNCTION::DPH)); break; + case RSX_VEC_OPCODE_DP4: SetDSTVec(getFunction(FUNCTION::DP4)); break; case RSX_VEC_OPCODE_DST: SetDSTVec("vec4(1.0, $0.y * $1.y, $0.z, $1.w)"); break; case RSX_VEC_OPCODE_MIN: SetDSTVec("min($0, $1)"); break; case RSX_VEC_OPCODE_MAX: SetDSTVec("max($0, $1)"); break; - case RSX_VEC_OPCODE_SLT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SLT, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_SGE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SGE, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_SLT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SLT, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_SGE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SGE, "$0", "$1") + ")"); break; case RSX_VEC_OPCODE_ARL: SetDSTVec(getIntTypeName(4) + "($0)"); break; - case RSX_VEC_OPCODE_FRC: SetDSTVec(getFunction(FUNCTION::FUNCTION_FRACT)); break; + case RSX_VEC_OPCODE_FRC: SetDSTVec(getFunction(FUNCTION::FRACT)); break; case RSX_VEC_OPCODE_FLR: SetDSTVec("floor($0)"); break; - case RSX_VEC_OPCODE_SEQ: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_SFL: SetDSTVec(getFunction(FUNCTION::FUNCTION_SFL)); break; - case RSX_VEC_OPCODE_SGT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SGT, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_SLE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SLE, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_SNE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SNE, "$0", "$1") + ")"); break; - case RSX_VEC_OPCODE_STR: SetDSTVec(getFunction(FUNCTION::FUNCTION_STR)); break; + case RSX_VEC_OPCODE_SEQ: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SEQ, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_SFL: SetDSTVec(getFunction(FUNCTION::SFL)); break; + case RSX_VEC_OPCODE_SGT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SGT, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_SLE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SLE, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_SNE: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::SNE, "$0", "$1") + ")"); break; + case RSX_VEC_OPCODE_STR: SetDSTVec(getFunction(FUNCTION::STR)); break; case RSX_VEC_OPCODE_SSG: SetDSTVec("sign($0)"); break; case RSX_VEC_OPCODE_TXL: { @@ -596,16 +596,16 @@ std::string VertexProgramDecompiler::Decompile() switch (m_prog.get_texture_dimension(d2.tex_num)) { case rsx::texture_dimension_extended::texture_dimension_1d: - SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH1D)); + SetDSTVec(getFunction(FUNCTION::VERTEX_TEXTURE_FETCH1D)); break; case rsx::texture_dimension_extended::texture_dimension_2d: - SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D)); + SetDSTVec(getFunction(FUNCTION::VERTEX_TEXTURE_FETCH2D)); break; case rsx::texture_dimension_extended::texture_dimension_3d: - SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH3D)); + SetDSTVec(getFunction(FUNCTION::VERTEX_TEXTURE_FETCH3D)); break; case rsx::texture_dimension_extended::texture_dimension_cubemap: - SetDSTVec(getFunction(FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCHCUBE)); + SetDSTVec(getFunction(FUNCTION::VERTEX_TEXTURE_FETCHCUBE)); break; }