mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
rsx/decompiler: Restructure program register behavior
- Fix reading of varying registers in FP Different registers have different behavior - Always write to varying registers. If a register is not written to, it is initialized to (0, 0, 0, 1) - Reimplements two-sided lighting correctly without hacks - Also bumps shader cache version
This commit is contained in:
parent
fe6ff8622a
commit
3e28e4b1e0
17 changed files with 318 additions and 426 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/System.h"
|
||||
#include "../rsx_methods.h"
|
||||
|
||||
#include "FragmentProgramDecompiler.h"
|
||||
|
||||
|
@ -520,27 +521,81 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
|
|||
"ssa"
|
||||
};
|
||||
|
||||
//TODO: Investigate effect of input modifier on this type
|
||||
// NOTE: Hw testing showed the following:
|
||||
// 1. Reading from registers 1 and 2 (COL0 and COL1) is clamped to (0, 1)
|
||||
// 2. Reading from registers 4-12 (inclusive) is not clamped, but..
|
||||
// 3. If the texcoord control mask is enabled, the last 2 values are always 0 and 1!
|
||||
const std::string reg_var = (dst.src_attr_reg_num < std::size(reg_table))? reg_table[dst.src_attr_reg_num] : "unk";
|
||||
bool insert = true;
|
||||
|
||||
switch (dst.src_attr_reg_num)
|
||||
{
|
||||
case 0x00:
|
||||
{
|
||||
// WPOS
|
||||
ret += reg_table[0];
|
||||
properties.has_wpos_input = true;
|
||||
insert = false;
|
||||
break;
|
||||
default:
|
||||
if (dst.src_attr_reg_num < std::size(reg_table))
|
||||
}
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
{
|
||||
// COL0, COL1
|
||||
ret += "_saturate(" + reg_var + ")";
|
||||
apply_precision_modifier = false;
|
||||
break;
|
||||
}
|
||||
case 0x03:
|
||||
{
|
||||
// FOGC
|
||||
// TODO: Confirm if precision modifiers affect this one
|
||||
ret += reg_var;
|
||||
break;
|
||||
}
|
||||
case 0x4:
|
||||
case 0x5:
|
||||
case 0x6:
|
||||
case 0x7:
|
||||
case 0x8:
|
||||
case 0x9:
|
||||
case 0xA:
|
||||
case 0xB:
|
||||
case 0xC:
|
||||
case 0xD:
|
||||
{
|
||||
// TEX0 - TEX9
|
||||
// Texcoord mask seems to reset the last 2 arguments to 0 and 1 if set
|
||||
if (m_prog.texcoord_is_2d(dst.src_attr_reg_num - 4))
|
||||
{
|
||||
ret += m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_table[dst.src_attr_reg_num]);
|
||||
ret += getFloatTypeName(4) + "(" + reg_var + ".x, " + reg_var + ".y, 0., 1.)";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(RSX, "Bad src reg num: %d", u32{ dst.src_attr_reg_num });
|
||||
ret += m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), "unk");
|
||||
Emu.Pause();
|
||||
ret += reg_var;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// SSA (winding direction register)
|
||||
// UNK
|
||||
if (reg_var == "unk")
|
||||
{
|
||||
LOG_ERROR(RSX, "Bad src reg num: %d", u32{ dst.src_attr_reg_num });
|
||||
}
|
||||
|
||||
ret += reg_var;
|
||||
apply_precision_modifier = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (insert)
|
||||
{
|
||||
m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_var);
|
||||
}
|
||||
|
||||
properties.in_register_mask |= (1 << dst.src_attr_reg_num);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -252,11 +252,30 @@ protected:
|
|||
virtual void insertMainEnd(std::stringstream &OS) = 0;
|
||||
|
||||
public:
|
||||
enum : u16
|
||||
{
|
||||
in_wpos = (1 << 0),
|
||||
in_diff_color = (1 << 1),
|
||||
in_spec_color = (1 << 2),
|
||||
in_fogc = (1 << 3),
|
||||
in_tc0 = (1 << 4),
|
||||
in_tc1 = (1 << 5),
|
||||
in_tc2 = (1 << 6),
|
||||
in_tc3 = (1 << 7),
|
||||
in_tc4 = (1 << 8),
|
||||
in_tc5 = (1 << 9),
|
||||
in_tc6 = (1 << 10),
|
||||
in_tc7 = (1 << 11),
|
||||
in_tc8 = (1 << 12),
|
||||
in_tc9 = (1 << 13),
|
||||
in_ssa = (1 << 14)
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
u16 in_register_mask = 0;
|
||||
bool has_lit_op = false;
|
||||
bool has_gather_op = false;
|
||||
bool has_wpos_input = false;
|
||||
bool has_no_output = false;
|
||||
bool has_discard_op = false;
|
||||
bool has_tex_op = false;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "ProgramStateCache.h"
|
||||
#include "Emu/System.h"
|
||||
|
||||
|
@ -424,9 +424,7 @@ size_t fragment_program_storage_hash::operator()(const RSXFragmentProgram& progr
|
|||
hash ^= program.ctrl;
|
||||
hash ^= program.texture_dimensions;
|
||||
hash ^= program.unnormalized_coords;
|
||||
hash ^= program.back_color_diffuse_output;
|
||||
hash ^= program.back_color_specular_output;
|
||||
hash ^= program.front_back_color_enabled;
|
||||
hash ^= program.two_sided_lighting;
|
||||
hash ^= program.shadow_textures;
|
||||
hash ^= program.redirected_textures;
|
||||
|
||||
|
@ -436,8 +434,7 @@ size_t fragment_program_storage_hash::operator()(const RSXFragmentProgram& progr
|
|||
bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, const RSXFragmentProgram& binary2) const
|
||||
{
|
||||
if (binary1.ctrl != binary2.ctrl || binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
|
||||
binary1.back_color_diffuse_output != binary2.back_color_diffuse_output || binary1.back_color_specular_output != binary2.back_color_specular_output ||
|
||||
binary1.front_back_color_enabled != binary2.front_back_color_enabled ||
|
||||
binary1.two_sided_lighting != binary2.two_sided_lighting ||
|
||||
binary1.shadow_textures != binary2.shadow_textures || binary1.redirected_textures != binary2.redirected_textures)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -325,14 +325,50 @@ public:
|
|||
|
||||
struct vertex_reg_info
|
||||
{
|
||||
std::string name; //output name
|
||||
bool need_declare; //needs explicit declaration as output (not language in-built)
|
||||
std::string src_reg; //reg to get data from
|
||||
std::string src_reg_mask; //input swizzle mask
|
||||
bool need_cast; //needs casting
|
||||
std::string cond; //update on condition
|
||||
std::string default_val; //fallback value on cond fail
|
||||
std::string dst_alias; //output name override
|
||||
bool check_mask; //check program output control mask for this output
|
||||
u32 check_mask_value; //program output control mask for testing
|
||||
enum mask_test_type : u8
|
||||
{
|
||||
any = 0, // Any bit set
|
||||
none = 1, // No bits set
|
||||
all = 2, // All bits set
|
||||
xall = 3 // Some bits set
|
||||
};
|
||||
|
||||
std::string name; // output name
|
||||
bool need_declare; // needs explicit declaration as output (not language in-built)
|
||||
std::string src_reg; // reg to get data from
|
||||
std::string src_reg_mask; // input swizzle mask
|
||||
bool need_cast; // needs casting
|
||||
std::string cond; // update on condition
|
||||
std::string default_val; // fallback value on cond fail
|
||||
std::string dst_alias; // output name override
|
||||
bool check_mask; // check program output control mask for this output
|
||||
u32 check_mask_value; // program output control mask for testing
|
||||
|
||||
mask_test_type check_flags; // whole mask must match
|
||||
|
||||
bool test(u32 mask) const
|
||||
{
|
||||
if (!check_mask)
|
||||
return true;
|
||||
|
||||
const u32 val = (mask & check_mask_value);
|
||||
switch (check_flags)
|
||||
{
|
||||
case none:
|
||||
return (val == 0);
|
||||
case any:
|
||||
return (val != 0);
|
||||
case all:
|
||||
return (val == check_mask_value);
|
||||
case xall:
|
||||
return (val && val != check_mask_value);
|
||||
default:
|
||||
fmt::throw_exception("Unreachable" HERE);
|
||||
}
|
||||
}
|
||||
|
||||
bool declare(u32 mask) const
|
||||
{
|
||||
return test(mask);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifdef _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
#include "stdafx.h"
|
||||
#include "stdafx_d3d12.h"
|
||||
#include "D3D12FragmentProgramDecompiler.h"
|
||||
|
@ -206,19 +206,6 @@ void D3D12FragmentDecompiler::insertMainStart(std::stringstream & OS)
|
|||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
if (m_prog.front_back_color_enabled)
|
||||
{
|
||||
if (PI.name == "spec_color" && m_prog.back_color_specular_output)
|
||||
{
|
||||
OS << " float4 spec_color = is_front_face ? In.dst_reg4 : In.spec_color;\n";
|
||||
continue;
|
||||
}
|
||||
if (PI.name == "diff_color" && m_prog.back_color_diffuse_output)
|
||||
{
|
||||
OS << " float4 diff_color = is_front_face ? In.dst_reg3 : In.diff_color;\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
OS << " float4 fogc = fetch_fog_value(fog_mode, In.fogc);\n";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "GLCommonDecompiler.h"
|
||||
|
||||
namespace gl
|
||||
|
@ -7,10 +7,9 @@ namespace gl
|
|||
{{
|
||||
{"diff_color", 1},
|
||||
{"spec_color", 2},
|
||||
{"back_diff_color", 1},
|
||||
{"back_spec_color", 2},
|
||||
{"front_diff_color", 3},
|
||||
{"front_spec_color", 4},
|
||||
{"diff_color1", 3},
|
||||
{"spec_color1", 4},
|
||||
{"fogc", 5},
|
||||
{"fog_c", 5},
|
||||
{"tc0", 6},
|
||||
{"tc1", 7},
|
||||
|
|
|
@ -48,7 +48,6 @@ void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
|||
|
||||
void GLFragmentDecompilerThread::insertInputs(std::stringstream & OS)
|
||||
{
|
||||
bool two_sided_enabled = m_prog.front_back_color_enabled && (m_prog.back_color_diffuse_output || m_prog.back_color_specular_output);
|
||||
std::vector<std::string> inputs_to_declare;
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
|
@ -58,41 +57,28 @@ void GLFragmentDecompilerThread::insertInputs(std::stringstream & OS)
|
|||
//ssa is defined in the program body and is not a varying type
|
||||
if (PI.name == "ssa") continue;
|
||||
|
||||
const auto reg_location = gl::get_varying_register_location(PI.name);
|
||||
std::string var_name = PI.name;
|
||||
|
||||
if (two_sided_enabled)
|
||||
if (var_name == "fogc")
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && var_name == "diff_color")
|
||||
var_name = "back_diff_color";
|
||||
|
||||
if (m_prog.back_color_specular_output && var_name == "spec_color")
|
||||
var_name = "back_spec_color";
|
||||
var_name = "fog_c";
|
||||
}
|
||||
else if (m_prog.two_sided_lighting)
|
||||
{
|
||||
if (var_name == "diff_color")
|
||||
{
|
||||
var_name = "diff_color0";
|
||||
}
|
||||
else if (var_name == "spec_color")
|
||||
{
|
||||
var_name = "spec_color0";
|
||||
}
|
||||
}
|
||||
|
||||
if (var_name == "fogc")
|
||||
var_name = "fog_c";
|
||||
|
||||
inputs_to_declare.push_back(var_name);
|
||||
OS << "layout(location=" << reg_location << ") in vec4 " << var_name << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (two_sided_enabled)
|
||||
{
|
||||
if (m_prog.front_color_diffuse_output && m_prog.back_color_diffuse_output)
|
||||
{
|
||||
inputs_to_declare.emplace_back("front_diff_color");
|
||||
}
|
||||
|
||||
if (m_prog.front_color_specular_output && m_prog.back_color_specular_output)
|
||||
{
|
||||
inputs_to_declare.emplace_back("front_spec_color");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &name: inputs_to_declare)
|
||||
{
|
||||
OS << "layout(location=" << gl::get_varying_register_location(name) << ") in vec4 " << name << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
void GLFragmentDecompilerThread::insertOutputs(std::stringstream & OS)
|
||||
|
@ -201,7 +187,7 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
|
|||
properties2.require_lit_emulation = properties.has_lit_op;
|
||||
properties2.fp32_outputs = !!(m_prog.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS);
|
||||
properties2.require_depth_conversion = m_prog.redirected_textures != 0;
|
||||
properties2.require_wpos = properties.has_wpos_input;
|
||||
properties2.require_wpos = !!(properties.in_register_mask & in_wpos);
|
||||
properties2.require_texture_ops = properties.has_tex_op;
|
||||
properties2.require_shadow_ops = m_prog.shadow_textures != 0;
|
||||
properties2.emulate_coverage_tests = g_cfg.video.antialiasing_level == msaa_level::none;
|
||||
|
@ -213,18 +199,8 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
|
|||
|
||||
void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
//TODO: Generate input mask during parse stage to avoid this
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
glsl::insert_fog_declaration(OS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_fogc)
|
||||
glsl::insert_fog_declaration(OS);
|
||||
|
||||
const std::set<std::string> output_values =
|
||||
{
|
||||
|
@ -267,58 +243,25 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
if (m_parr.HasParam(PF_PARAM_IN, "vec4", "ssa"))
|
||||
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
|
||||
|
||||
if (properties.has_wpos_input)
|
||||
if (properties.in_register_mask & in_wpos)
|
||||
OS << " vec4 wpos = get_wpos();\n";
|
||||
|
||||
bool two_sided_enabled = m_prog.front_back_color_enabled && (m_prog.back_color_diffuse_output || m_prog.back_color_specular_output);
|
||||
if (properties.in_register_mask & in_ssa)
|
||||
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
if (properties.in_register_mask & in_wpos)
|
||||
OS << " vec4 wpos = get_wpos();\n";
|
||||
|
||||
if (properties.in_register_mask & in_fogc)
|
||||
OS << " vec4 fogc = fetch_fog_value(fog_mode);\n";
|
||||
|
||||
if (m_prog.two_sided_lighting)
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (two_sided_enabled)
|
||||
{
|
||||
if (PI.name == "spec_color")
|
||||
{
|
||||
if (m_prog.back_color_specular_output)
|
||||
{
|
||||
if (m_prog.back_color_specular_output && m_prog.front_color_specular_output)
|
||||
{
|
||||
OS << " vec4 spec_color = gl_FrontFacing ? front_spec_color : back_spec_color;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
OS << " vec4 spec_color = back_spec_color;\n";
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_diff_color)
|
||||
OS << " vec4 diff_color = gl_FrontFacing ? diff_color1 : diff_color0;\n";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (PI.name == "diff_color")
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output)
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && m_prog.front_color_diffuse_output)
|
||||
{
|
||||
OS << " vec4 diff_color = gl_FrontFacing ? front_diff_color : back_diff_color;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
OS << " vec4 diff_color = back_diff_color;\n";
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
OS << " vec4 fogc = fetch_fog_value(fog_mode);\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_spec_color)
|
||||
OS << " vec4 spec_color = gl_FrontFacing ? spec_color1 : spec_color0;\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ u64 GLGSRender::get_cycles()
|
|||
|
||||
GLGSRender::GLGSRender() : GSRender()
|
||||
{
|
||||
m_shaders_cache = std::make_unique<gl::shader_cache>(m_prog_buffer, "opengl", "v1.6");
|
||||
m_shaders_cache = std::make_unique<gl::shader_cache>(m_prog_buffer, "opengl", "v1.91");
|
||||
|
||||
if (g_cfg.video.disable_vertex_cache || g_cfg.video.multithreaded_rsx)
|
||||
m_vertex_cache = std::make_unique<gl::null_vertex_cache>();
|
||||
|
|
|
@ -79,78 +79,43 @@ void GLVertexDecompilerThread::insertConstants(std::stringstream & OS, const std
|
|||
static const vertex_reg_info reg_table[] =
|
||||
{
|
||||
{ "gl_Position", false, "dst_reg0", "", false },
|
||||
{ "diff_color", true, "dst_reg1", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE },
|
||||
{ "spec_color", true, "dst_reg2", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR },
|
||||
{ "diff_color", true, "dst_reg1", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE },
|
||||
{ "spec_color", true, "dst_reg2", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR },
|
||||
//These are only present when back variants are specified, otherwise the default diff/spec color vars are for both front and back
|
||||
{ "front_diff_color", true, "dst_reg3", "", false },
|
||||
{ "front_spec_color", true, "dst_reg4", "", false },
|
||||
{ "diff_color1", true, "dst_reg3", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE },
|
||||
{ "spec_color1", true, "dst_reg4", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR },
|
||||
//Fog output shares a data source register with clip planes 0-2 so only declare when specified
|
||||
{ "fog_c", true, "dst_reg5", ".xxxx", true, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FOG },
|
||||
//Warning: Always define all 3 clip plane groups together to avoid flickering with openGL
|
||||
{ "gl_ClipDistance[0]", false, "dst_reg5", ".y * user_clip_factor[0].x", false, "user_clip_enabled[0].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 },
|
||||
{ "gl_ClipDistance[1]", false, "dst_reg5", ".z * user_clip_factor[0].y", false, "user_clip_enabled[0].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 },
|
||||
{ "gl_ClipDistance[2]", false, "dst_reg5", ".w * user_clip_factor[0].z", false, "user_clip_enabled[0].z > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 },
|
||||
{ "gl_PointSize", false, "dst_reg6", ".x", false },
|
||||
{ "gl_PointSize", false, "dst_reg6", ".x", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_POINTSIZE },
|
||||
{ "gl_ClipDistance[3]", false, "dst_reg6", ".y * user_clip_factor[0].w", false, "user_clip_enabled[0].w > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 },
|
||||
{ "gl_ClipDistance[4]", false, "dst_reg6", ".z * user_clip_factor[1].x", false, "user_clip_enabled[1].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 },
|
||||
{ "gl_ClipDistance[5]", false, "dst_reg6", ".w * user_clip_factor[1].y", false, "user_clip_enabled[1].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 },
|
||||
{ "tc0", true, "dst_reg7", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 },
|
||||
{ "tc1", true, "dst_reg8", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 },
|
||||
{ "tc2", true, "dst_reg9", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 },
|
||||
{ "tc3", true, "dst_reg10", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 },
|
||||
{ "tc4", true, "dst_reg11", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 },
|
||||
{ "tc5", true, "dst_reg12", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 },
|
||||
{ "tc6", true, "dst_reg13", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 },
|
||||
{ "tc7", true, "dst_reg14", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 },
|
||||
{ "tc8", true, "dst_reg15", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 },
|
||||
{ "tc0", true, "dst_reg7", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 },
|
||||
{ "tc1", true, "dst_reg8", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 },
|
||||
{ "tc2", true, "dst_reg9", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 },
|
||||
{ "tc3", true, "dst_reg10", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 },
|
||||
{ "tc4", true, "dst_reg11", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 },
|
||||
{ "tc5", true, "dst_reg12", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 },
|
||||
{ "tc6", true, "dst_reg13", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 },
|
||||
{ "tc7", true, "dst_reg14", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 },
|
||||
{ "tc8", true, "dst_reg15", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 },
|
||||
{ "tc9", true, "dst_reg6", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15.
|
||||
};
|
||||
|
||||
void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector<ParamType> & outputs)
|
||||
{
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE) != 0;
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE) != 0;
|
||||
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR) != 0;
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR) != 0;
|
||||
|
||||
bool front_back_diffuse = (insert_back_diffuse && insert_front_diffuse);
|
||||
bool front_back_specular = (insert_back_specular && insert_front_specular);
|
||||
|
||||
std::vector<std::string> outputs_to_declare;
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (i.need_declare)
|
||||
{
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
std::string name = i.name;
|
||||
|
||||
if (front_back_diffuse && name == "diff_color")
|
||||
name = "back_diff_color";
|
||||
|
||||
if (front_back_specular && name == "spec_color")
|
||||
name = "back_spec_color";
|
||||
|
||||
outputs_to_declare.push_back(name);
|
||||
// All outputs must be declared always to allow setting default values
|
||||
OS << "layout(location=" << gl::get_varying_register_location(i.name) << ") out vec4 " << i.name << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
outputs_to_declare.emplace_back("front_diff_color");
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
outputs_to_declare.emplace_back("front_spec_color");
|
||||
|
||||
for (auto &name: outputs_to_declare)
|
||||
{
|
||||
OS << "layout(location=" << gl::get_varying_register_location(name) << ") out vec4 " << name << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
|
@ -240,65 +205,43 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
|
||||
OS << "\n" << " vs_main(" << parameters << ");\n\n";
|
||||
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE) != 0;
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR) != 0;
|
||||
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE) != 0;
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR) != 0;
|
||||
|
||||
bool front_back_diffuse = (insert_back_diffuse && insert_front_diffuse);
|
||||
bool front_back_specular = (insert_back_specular && insert_front_specular);
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
std::string name = i.name;
|
||||
|
||||
if (front_back_diffuse && name == "diff_color")
|
||||
name = "back_diff_color";
|
||||
|
||||
if (front_back_specular && name == "spec_color")
|
||||
name = "back_spec_color";
|
||||
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg))
|
||||
if (!i.check_mask || i.test(rsx_vertex_program.output_mask))
|
||||
{
|
||||
if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg))
|
||||
{
|
||||
std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : "";
|
||||
|
||||
if (condition.empty() || i.default_val.empty())
|
||||
{
|
||||
if (!condition.empty()) condition = "if " + condition;
|
||||
OS << " " << condition << i.name << " = " << i.src_reg << i.src_reg_mask << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Insert if-else condition
|
||||
OS << " " << i.name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";\n";
|
||||
}
|
||||
|
||||
// Register was marked for output and a properly initialized source register exists
|
||||
// Nothing more to do
|
||||
continue;
|
||||
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : "";
|
||||
if (condition.empty() || i.default_val.empty())
|
||||
{
|
||||
if (!condition.empty()) condition = "if " + condition;
|
||||
OS << " " << condition << name << " = " << i.src_reg << i.src_reg_mask << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Insert if-else condition
|
||||
OS << " " << name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";\n";
|
||||
}
|
||||
}
|
||||
else if (i.need_declare && (rsx_vertex_program.output_mask & i.check_mask_value) > 0)
|
||||
|
||||
if (i.need_declare)
|
||||
{
|
||||
//An output was declared but nothing was written to it
|
||||
//Set it to all ones (Atelier Escha)
|
||||
OS << " " << name << " = vec4(1.);\n";
|
||||
OS << " " << i.name << " = vec4(0., 0., 0., 1.);\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg1"))
|
||||
OS << " front_diff_color = dst_reg1;\n";
|
||||
// Default point size if none was generated by the program
|
||||
if ((rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE) == 0)
|
||||
{
|
||||
OS << " gl_PointSize = point_size;\n";
|
||||
}
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg2"))
|
||||
OS << " front_spec_color = dst_reg2;\n";
|
||||
|
||||
OS << " gl_PointSize = point_size;\n";
|
||||
OS << " gl_Position = gl_Position * scale_offset_mat;\n";
|
||||
OS << " gl_Position = apply_zclip_xform(gl_Position, z_near, z_far);\n";
|
||||
|
||||
|
|
|
@ -234,12 +234,9 @@ struct RSXFragmentProgram
|
|||
u16 unnormalized_coords;
|
||||
u16 redirected_textures;
|
||||
u16 shadow_textures;
|
||||
bool front_back_color_enabled : 1;
|
||||
bool back_color_diffuse_output : 1;
|
||||
bool back_color_specular_output : 1;
|
||||
bool front_color_diffuse_output : 1;
|
||||
bool front_color_specular_output : 1;
|
||||
bool two_sided_lighting;
|
||||
u32 texture_dimensions;
|
||||
u32 texcoord_control_mask;
|
||||
|
||||
float texture_scale[16][4];
|
||||
u8 textures_alpha_kill[16];
|
||||
|
@ -252,6 +249,11 @@ struct RSXFragmentProgram
|
|||
return (rsx::texture_dimension_extended)((texture_dimensions >> (id * 2)) & 0x3);
|
||||
}
|
||||
|
||||
bool texcoord_is_2d(u8 index) const
|
||||
{
|
||||
return !!(texcoord_control_mask & (1u << index));
|
||||
}
|
||||
|
||||
RSXFragmentProgram()
|
||||
{
|
||||
memset(this, 0, sizeof(RSXFragmentProgram));
|
||||
|
|
|
@ -1618,12 +1618,9 @@ namespace rsx
|
|||
result.ucode_length = current_fp_metadata.program_ucode_length;
|
||||
result.valid = true;
|
||||
result.ctrl = rsx::method_registers.shader_control() & (CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS | CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT);
|
||||
result.texcoord_control_mask = rsx::method_registers.texcoord_control_mask();
|
||||
result.unnormalized_coords = 0;
|
||||
result.front_back_color_enabled = !rsx::method_registers.two_side_light_en();
|
||||
result.back_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
|
||||
result.back_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
|
||||
result.front_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE);
|
||||
result.front_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR);
|
||||
result.two_sided_lighting = rsx::method_registers.two_side_light_en();
|
||||
result.redirected_textures = 0;
|
||||
result.shadow_textures = 0;
|
||||
|
||||
|
@ -1754,11 +1751,7 @@ namespace rsx
|
|||
result.valid = true;
|
||||
result.ctrl = rsx::method_registers.shader_control() & (CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS | CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT);
|
||||
result.unnormalized_coords = 0;
|
||||
result.front_back_color_enabled = !rsx::method_registers.two_side_light_en();
|
||||
result.back_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE);
|
||||
result.back_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR);
|
||||
result.front_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE);
|
||||
result.front_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR);
|
||||
result.two_sided_lighting = rsx::method_registers.two_side_light_en();
|
||||
result.redirected_textures = 0;
|
||||
result.shadow_textures = 0;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "VKCommonDecompiler.h"
|
||||
#include "restore_new.h"
|
||||
#include "SPIRV/GlslangToSpv.h"
|
||||
|
@ -118,11 +118,9 @@ namespace vk
|
|||
{ "tc8", 8 },
|
||||
{ "tc9", 9 },
|
||||
{ "diff_color", 10 },
|
||||
{ "back_diff_color", 10 },
|
||||
{ "front_diff_color", 11 },
|
||||
{ "diff_color1", 11 },
|
||||
{ "spec_color", 12 },
|
||||
{ "back_spec_color", 12 },
|
||||
{ "front_spec_color", 13 },
|
||||
{ "spec_color1", 13 },
|
||||
{ "fog_c", 14 },
|
||||
{ "fogc", 14 }
|
||||
}};
|
||||
|
|
|
@ -44,9 +44,6 @@ void VKFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
|||
|
||||
void VKFragmentDecompilerThread::insertInputs(std::stringstream & OS)
|
||||
{
|
||||
//It is possible for the two_sided_enabled flag to be set without actual 2-sided outputs
|
||||
bool two_sided_enabled = m_prog.front_back_color_enabled && (m_prog.back_color_diffuse_output || m_prog.back_color_specular_output);
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
|
@ -57,33 +54,36 @@ void VKFragmentDecompilerThread::insertInputs(std::stringstream & OS)
|
|||
const auto reg_location = vk::get_varying_register_location(PI.name);
|
||||
std::string var_name = PI.name;
|
||||
|
||||
if (two_sided_enabled)
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && var_name == "diff_color")
|
||||
var_name = "back_diff_color";
|
||||
|
||||
if (m_prog.back_color_specular_output && var_name == "spec_color")
|
||||
var_name = "back_spec_color";
|
||||
}
|
||||
|
||||
if (var_name == "fogc")
|
||||
{
|
||||
var_name = "fog_c";
|
||||
}
|
||||
else if (m_prog.two_sided_lighting)
|
||||
{
|
||||
if (var_name == "diff_color")
|
||||
{
|
||||
var_name = "diff_color0";
|
||||
}
|
||||
else if (var_name == "spec_color")
|
||||
{
|
||||
var_name = "spec_color0";
|
||||
}
|
||||
}
|
||||
|
||||
OS << "layout(location=" << reg_location << ") in " << PT.type << " " << var_name << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (two_sided_enabled)
|
||||
if (m_prog.two_sided_lighting)
|
||||
{
|
||||
//Only include the front counterparts if the default output is for back only and exists.
|
||||
if (m_prog.front_color_diffuse_output && m_prog.back_color_diffuse_output)
|
||||
if (properties.in_register_mask & in_diff_color)
|
||||
{
|
||||
OS << "layout(location=" << vk::get_varying_register_location("front_diff_color") << ") in vec4 front_diff_color;\n";
|
||||
OS << "layout(location=" << vk::get_varying_register_location("diff_color1") << ") in vec4 diff_color1;\n";
|
||||
}
|
||||
|
||||
if (m_prog.front_color_specular_output && m_prog.back_color_specular_output)
|
||||
if (properties.in_register_mask & in_spec_color)
|
||||
{
|
||||
OS << "layout(location=" << vk::get_varying_register_location("front_spec_color") << ") in vec4 front_spec_color;\n";
|
||||
OS << "layout(location=" << vk::get_varying_register_location("spec_color1") << ") in vec4 spec_color1;\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
|
|||
properties2.require_lit_emulation = properties.has_lit_op;
|
||||
properties2.fp32_outputs = !!(m_prog.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS);
|
||||
properties2.require_depth_conversion = m_prog.redirected_textures != 0;
|
||||
properties2.require_wpos = properties.has_wpos_input;
|
||||
properties2.require_wpos = !!(properties.in_register_mask & in_wpos);
|
||||
properties2.require_texture_ops = properties.has_tex_op;
|
||||
properties2.require_shadow_ops = m_prog.shadow_textures != 0;
|
||||
properties2.emulate_coverage_tests = g_cfg.video.antialiasing_level == msaa_level::none;
|
||||
|
@ -243,18 +243,8 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
|
|||
|
||||
void VKFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
{
|
||||
//TODO: Generate input mask during parse stage to avoid this
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
glsl::insert_fog_declaration(OS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_fogc)
|
||||
glsl::insert_fog_declaration(OS);
|
||||
|
||||
const std::set<std::string> output_values =
|
||||
{
|
||||
|
@ -294,64 +284,22 @@ void VKFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_parr.HasParam(PF_PARAM_IN, "vec4", "ssa"))
|
||||
if (properties.in_register_mask & in_ssa)
|
||||
OS << " vec4 ssa = gl_FrontFacing ? vec4(1.) : vec4(-1.);\n";
|
||||
|
||||
if (properties.has_wpos_input)
|
||||
if (properties.in_register_mask & in_wpos)
|
||||
OS << " vec4 wpos = get_wpos();\n";
|
||||
|
||||
bool two_sided_enabled = m_prog.front_back_color_enabled && (m_prog.back_color_diffuse_output || m_prog.back_color_specular_output);
|
||||
if (properties.in_register_mask & in_fogc)
|
||||
OS << " vec4 fogc = fetch_fog_value(fog_mode);\n";
|
||||
|
||||
//Some registers require redirection
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
if (m_prog.two_sided_lighting)
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (two_sided_enabled)
|
||||
{
|
||||
if (PI.name == "spec_color")
|
||||
{
|
||||
//Only redirect/rename variables if the back_color exists
|
||||
if (m_prog.back_color_specular_output)
|
||||
{
|
||||
if (m_prog.back_color_specular_output && m_prog.front_color_specular_output)
|
||||
{
|
||||
OS << " vec4 spec_color = gl_FrontFacing ? front_spec_color : back_spec_color;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
OS << " vec4 spec_color = back_spec_color;\n";
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_diff_color)
|
||||
OS << " vec4 diff_color = gl_FrontFacing ? diff_color1 : diff_color0;\n";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (PI.name == "diff_color")
|
||||
{
|
||||
//Only redirect/rename variables if the back_color exists
|
||||
if (m_prog.back_color_diffuse_output)
|
||||
{
|
||||
if (m_prog.back_color_diffuse_output && m_prog.front_color_diffuse_output)
|
||||
{
|
||||
OS << " vec4 diff_color = gl_FrontFacing ? front_diff_color : back_diff_color;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
OS << " vec4 diff_color = back_diff_color;\n";
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (PI.name == "fogc")
|
||||
{
|
||||
OS << " vec4 fogc = fetch_fog_value(fog_mode);\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (properties.in_register_mask & in_spec_color)
|
||||
OS << " vec4 spec_color = gl_FrontFacing ? spec_color1 : spec_color0;\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -503,7 +503,7 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
else
|
||||
m_vertex_cache = std::make_unique<vk::weak_vertex_cache>();
|
||||
|
||||
m_shaders_cache = std::make_unique<vk::shader_cache>(*m_prog_buffer, "vulkan", "v1.8");
|
||||
m_shaders_cache = std::make_unique<vk::shader_cache>(*m_prog_buffer, "vulkan", "v1.91");
|
||||
|
||||
open_command_buffer();
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "VKHelpers.h"
|
||||
#include "../Common/GLSLCommon.h"
|
||||
|
||||
#pragma optimize("", off)
|
||||
|
||||
std::string VKVertexDecompilerThread::getFloatTypeName(size_t elementCount)
|
||||
{
|
||||
return glsl::getFloatTypeNameImpl(elementCount);
|
||||
|
@ -129,70 +131,41 @@ static const vertex_reg_info reg_table[] =
|
|||
{
|
||||
{ "gl_Position", false, "dst_reg0", "", false },
|
||||
//Technically these two are for both back and front
|
||||
{ "back_diff_color", true, "dst_reg1", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE },
|
||||
{ "back_spec_color", true, "dst_reg2", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR },
|
||||
{ "front_diff_color", true, "dst_reg3", "", false },
|
||||
{ "front_spec_color", true, "dst_reg4", "", false },
|
||||
{ "diff_color", true, "dst_reg1", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE },
|
||||
{ "spec_color", true, "dst_reg2", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR },
|
||||
{ "diff_color1", true, "dst_reg3", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE },
|
||||
{ "spec_color1", true, "dst_reg4", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR | CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR },
|
||||
{ "fog_c", true, "dst_reg5", ".xxxx", true, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FOG },
|
||||
//Warning: With spir-v if you declare clip distance var, you must assign a value even when its disabled! Runtime does not assign a default value
|
||||
{ "gl_ClipDistance[0]", false, "dst_reg5", ".y * user_clip_factor[0].x", false, "user_clip_enabled[0].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 },
|
||||
{ "gl_ClipDistance[1]", false, "dst_reg5", ".z * user_clip_factor[0].y", false, "user_clip_enabled[0].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 },
|
||||
{ "gl_ClipDistance[2]", false, "dst_reg5", ".w * user_clip_factor[0].z", false, "user_clip_enabled[0].z > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 },
|
||||
{ "gl_PointSize", false, "dst_reg6", ".x", false },
|
||||
{ "gl_PointSize", false, "dst_reg6", ".x", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE },
|
||||
{ "gl_ClipDistance[3]", false, "dst_reg6", ".y * user_clip_factor[0].w", false, "user_clip_enabled[0].w > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 },
|
||||
{ "gl_ClipDistance[4]", false, "dst_reg6", ".z * user_clip_factor[1].x", false, "user_clip_enabled[1].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 },
|
||||
{ "gl_ClipDistance[5]", false, "dst_reg6", ".w * user_clip_factor[1].y", false, "user_clip_enabled[1].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 },
|
||||
{ "tc0", true, "dst_reg7", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 },
|
||||
{ "tc1", true, "dst_reg8", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 },
|
||||
{ "tc2", true, "dst_reg9", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 },
|
||||
{ "tc3", true, "dst_reg10", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 },
|
||||
{ "tc4", true, "dst_reg11", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 },
|
||||
{ "tc5", true, "dst_reg12", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 },
|
||||
{ "tc6", true, "dst_reg13", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 },
|
||||
{ "tc7", true, "dst_reg14", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 },
|
||||
{ "tc8", true, "dst_reg15", "", false, "", "", "", false, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 },
|
||||
{ "tc0", true, "dst_reg7", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX0 },
|
||||
{ "tc1", true, "dst_reg8", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX1 },
|
||||
{ "tc2", true, "dst_reg9", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX2 },
|
||||
{ "tc3", true, "dst_reg10", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX3 },
|
||||
{ "tc4", true, "dst_reg11", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX4 },
|
||||
{ "tc5", true, "dst_reg12", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX5 },
|
||||
{ "tc6", true, "dst_reg13", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 },
|
||||
{ "tc7", true, "dst_reg14", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 },
|
||||
{ "tc8", true, "dst_reg15", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX8 },
|
||||
{ "tc9", true, "dst_reg6", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15.
|
||||
};
|
||||
|
||||
void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector<ParamType> & outputs)
|
||||
{
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE) != 0;
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE) != 0;
|
||||
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR) != 0;
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR) != 0;
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg) && i.need_declare)
|
||||
if (i.need_declare)
|
||||
{
|
||||
if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0)
|
||||
continue;
|
||||
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
// All outputs must be declared always to allow setting default values
|
||||
OS << "layout(location=" << vk::get_varying_register_location(i.name) << ") out vec4 " << i.name << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Force some outputs to be declared even if unused so we can set default values
|
||||
//NOTE: Registers that can be skept will not have their check_mask_value set
|
||||
if (i.need_declare && (rsx_vertex_program.output_mask & i.check_mask_value) > 0)
|
||||
{
|
||||
OS << "layout(location=" << vk::get_varying_register_location(i.name) << ") out vec4 " << i.name << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
OS << "layout(location=" << vk::get_varying_register_location("front_diff_color") << ") out vec4 front_diff_color;\n";
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
OS << "layout(location=" << vk::get_varying_register_location("front_spec_color") << ") out vec4 front_spec_color;\n";
|
||||
}
|
||||
|
||||
void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
||||
|
@ -280,55 +253,43 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
|
||||
OS << "\n" << " vs_main(" << parameters << ");\n\n";
|
||||
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTDIFFUSE) != 0;
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_FRONTSPECULAR) != 0;
|
||||
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE) != 0;
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR) != 0;
|
||||
|
||||
for (auto &i : reg_table)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg))
|
||||
if (!i.check_mask || i.test(rsx_vertex_program.output_mask))
|
||||
{
|
||||
if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg))
|
||||
{
|
||||
std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : "";
|
||||
|
||||
if (condition.empty() || i.default_val.empty())
|
||||
{
|
||||
if (!condition.empty()) condition = "if " + condition;
|
||||
OS << " " << condition << i.name << " = " << i.src_reg << i.src_reg_mask << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Insert if-else condition
|
||||
OS << " " << i.name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";\n";
|
||||
}
|
||||
|
||||
// Register was marked for output and a properly initialized source register exists
|
||||
// Nothing more to do
|
||||
continue;
|
||||
|
||||
if (i.name == "front_diff_color")
|
||||
insert_front_diffuse = false;
|
||||
|
||||
if (i.name == "front_spec_color")
|
||||
insert_front_specular = false;
|
||||
|
||||
std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : "";
|
||||
|
||||
if (condition.empty() || i.default_val.empty())
|
||||
{
|
||||
if (!condition.empty()) condition = "if " + condition;
|
||||
OS << " " << condition << i.name << " = " << i.src_reg << i.src_reg_mask << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Insert if-else condition
|
||||
OS << " " << i.name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";\n";
|
||||
}
|
||||
}
|
||||
else if (i.need_declare && (rsx_vertex_program.output_mask & i.check_mask_value) > 0)
|
||||
|
||||
if (i.need_declare)
|
||||
{
|
||||
//An output was declared but nothing was written to it
|
||||
//Set it to all ones (Atelier Escha)
|
||||
OS << " " << i.name << " = vec4(1.);\n";
|
||||
OS << " " << i.name << " = vec4(0., 0., 0., 1.);\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg1"))
|
||||
OS << " front_diff_color = dst_reg1;\n";
|
||||
// Default point size if none was generated by the program
|
||||
if ((rsx_vertex_program.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_POINTSIZE) == 0)
|
||||
{
|
||||
OS << " gl_PointSize = point_size;\n";
|
||||
}
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg2"))
|
||||
OS << " front_spec_color = dst_reg2;\n";
|
||||
|
||||
OS << " gl_PointSize = point_size;\n";
|
||||
OS << " gl_Position = gl_Position * scale_offset_mat;\n";
|
||||
OS << " gl_Position = apply_zclip_xform(gl_Position, z_near, z_far);\n";
|
||||
OS << "}\n";
|
||||
|
|
|
@ -401,6 +401,7 @@ namespace rsx
|
|||
|
||||
u32 fp_ctrl;
|
||||
u32 fp_texture_dimensions;
|
||||
u32 fp_texcoord_control;
|
||||
u16 fp_unnormalized_coords;
|
||||
u16 fp_height;
|
||||
u16 fp_pixel_layout;
|
||||
|
@ -738,6 +739,7 @@ namespace rsx
|
|||
state_hash ^= rpcs3::hash_base<u32>(data.fp_ctrl);
|
||||
state_hash ^= rpcs3::hash_base<u32>(data.vp_texture_dimensions);
|
||||
state_hash ^= rpcs3::hash_base<u32>(data.fp_texture_dimensions);
|
||||
state_hash ^= rpcs3::hash_base<u32>(data.fp_texcoord_control);
|
||||
state_hash ^= rpcs3::hash_base<u16>(data.fp_unnormalized_coords);
|
||||
state_hash ^= rpcs3::hash_base<u16>(data.fp_height);
|
||||
state_hash ^= rpcs3::hash_base<u16>(data.fp_pixel_layout);
|
||||
|
@ -810,12 +812,9 @@ namespace rsx
|
|||
|
||||
fp.ctrl = data.fp_ctrl;
|
||||
fp.texture_dimensions = data.fp_texture_dimensions;
|
||||
fp.texcoord_control_mask = data.fp_texcoord_control;
|
||||
fp.unnormalized_coords = data.fp_unnormalized_coords;
|
||||
fp.front_back_color_enabled = (data.fp_lighting_flags & 0x1) != 0;
|
||||
fp.back_color_diffuse_output = ((data.fp_lighting_flags >> 1) & 0x1) != 0;
|
||||
fp.back_color_specular_output = ((data.fp_lighting_flags >> 2) & 0x1) != 0;
|
||||
fp.front_color_diffuse_output = ((data.fp_lighting_flags >> 3) & 0x1) != 0;
|
||||
fp.front_color_specular_output = ((data.fp_lighting_flags >> 4) & 0x1) != 0;
|
||||
fp.two_sided_lighting = !!(data.fp_lighting_flags & 0x1);
|
||||
fp.shadow_textures = data.fp_shadow_textures;
|
||||
fp.redirected_textures = data.fp_redirected_textures;
|
||||
|
||||
|
@ -863,9 +862,9 @@ namespace rsx
|
|||
|
||||
data_block.fp_ctrl = fp.ctrl;
|
||||
data_block.fp_texture_dimensions = fp.texture_dimensions;
|
||||
data_block.fp_texcoord_control = fp.texcoord_control_mask;
|
||||
data_block.fp_unnormalized_coords = fp.unnormalized_coords;
|
||||
data_block.fp_lighting_flags = (u16)fp.front_back_color_enabled | (u16)fp.back_color_diffuse_output << 1 |
|
||||
(u16)fp.back_color_specular_output << 2 | (u16)fp.front_color_diffuse_output << 3 | (u16)fp.front_color_specular_output << 4;
|
||||
data_block.fp_lighting_flags = u16(fp.two_sided_lighting);
|
||||
data_block.fp_shadow_textures = fp.shadow_textures;
|
||||
data_block.fp_redirected_textures = fp.redirected_textures;
|
||||
|
||||
|
|
|
@ -1624,6 +1624,18 @@ namespace rsx
|
|||
{
|
||||
return decode<NV4097_SET_CONTROL0>().depth_float();
|
||||
}
|
||||
|
||||
u32 texcoord_control_mask()
|
||||
{
|
||||
// Only 10 texture coords exist [0-9]
|
||||
u32 control_mask = 0;
|
||||
for (u8 index = 0; index < 10; ++index)
|
||||
{
|
||||
control_mask |= ((registers[NV4097_SET_TEX_COORD_CONTROL + index] & 1) << index);
|
||||
}
|
||||
|
||||
return control_mask;
|
||||
}
|
||||
};
|
||||
|
||||
extern rsx_state method_registers;
|
||||
|
|
Loading…
Add table
Reference in a new issue