mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 23:41:26 +12:00
gl/vk: Bug fixes and improvements (#2155)
* gl: Fix broken buffer reserve computation * gl: Texture format fixes * gl: Two sided lighting * gl: Always update glsl output registers * gl: Simplify vertex input declaration * vk: Always write output registers * vk/gl: swizzle component read on depth textures * gl/vk: Use proper MVP matrix gl: fix broken mvp when window_origin=top * vk/gl: Move fragment operations block into the proxy function
This commit is contained in:
parent
38f35df7b6
commit
7884356e90
11 changed files with 420 additions and 110 deletions
|
@ -1,4 +1,5 @@
|
|||
#include "stdafx.h"
|
||||
#include <set>
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "GLFragmentProgram.h"
|
||||
|
@ -42,15 +43,43 @@ void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
|
|||
|
||||
void GLFragmentDecompilerThread::insertIntputs(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);
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
//Rename fogc to fog_c to differentiate the input register from the variable
|
||||
if (PI.name == "fogc")
|
||||
OS << "in vec4 fog_c;" << std::endl;
|
||||
|
||||
OS << "in " << PT.type << " " << PI.name << ";" << std::endl;
|
||||
//ssa is defined in the program body and is not a varying type
|
||||
if (PI.name == "ssa") continue;
|
||||
|
||||
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";
|
||||
|
||||
OS << "in " << PT.type << " " << var_name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (two_sided_enabled)
|
||||
{
|
||||
if (m_prog.front_color_diffuse_output && m_prog.back_color_diffuse_output)
|
||||
{
|
||||
OS << "in vec4 front_diff_color;" << std::endl;
|
||||
}
|
||||
|
||||
if (m_prog.front_color_specular_output && m_prog.back_color_specular_output)
|
||||
{
|
||||
OS << "in vec4 front_spec_color;" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,16 +213,38 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
{
|
||||
insert_glsl_legacy_function(OS);
|
||||
|
||||
OS << "void main ()" << std::endl;
|
||||
const std::set<std::string> output_values =
|
||||
{
|
||||
"r0", "r1", "r2", "r3", "r4",
|
||||
"h0", "h2", "h4", "h6", "h8"
|
||||
};
|
||||
|
||||
std::string parameters = "";
|
||||
for (auto ®_name : output_values)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name))
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += "inout vec4 " + reg_name;
|
||||
}
|
||||
}
|
||||
|
||||
OS << "void fs_main(" << parameters << ")" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_NONE])
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (output_values.find(PI.name) != output_values.end())
|
||||
continue;
|
||||
|
||||
OS << " " << PT.type << " " << PI.name;
|
||||
if (!PI.value.empty())
|
||||
OS << " = " << PI.value;
|
||||
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -214,11 +265,49 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
}
|
||||
}
|
||||
|
||||
// search if there is fogc in inputs
|
||||
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)
|
||||
{
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
{
|
||||
insert_fog_declaration(OS, m_prog.fog_equation);
|
||||
|
@ -238,25 +327,21 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
{ "ocol3", m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS ? "r4" : "h8" },
|
||||
};
|
||||
|
||||
std::string first_output_name;
|
||||
const std::set<std::string> output_values =
|
||||
{
|
||||
"r0", "r1", "r2", "r3", "r4",
|
||||
"h0", "h2", "h4", "h6", "h8"
|
||||
};
|
||||
|
||||
std::string first_output_name = "";
|
||||
std::string color_output_block = "";
|
||||
|
||||
for (int i = 0; i < sizeof(table) / sizeof(*table); ++i)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", table[i].second))
|
||||
{
|
||||
OS << " " << table[i].first << " = " << table[i].second << ";" << std::endl;
|
||||
if (first_output_name.empty()) first_output_name = table[i].first;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)
|
||||
{
|
||||
{
|
||||
/** Note: Naruto Shippuden : Ultimate Ninja Storm 2 sets CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS in a shader
|
||||
* but it writes depth in r1.z and not h2.z.
|
||||
* Maybe there's a different flag for depth ?
|
||||
*/
|
||||
//OS << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n") << std::endl;
|
||||
OS << " gl_FragDepth = r1.z;\n";
|
||||
color_output_block += " " + table[i].first + " = " + table[i].second + ";\n";
|
||||
if (first_output_name.empty()) first_output_name = table[i].second;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,6 +379,41 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
OS << make_comparison_test(m_prog.alpha_func, "alpha_test != 0 && ", first_output_name + ".a", "alpha_ref");
|
||||
}
|
||||
|
||||
OS << "}" << std::endl << std::endl;
|
||||
|
||||
OS << "void main()" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
std::string parameters = "";
|
||||
for (auto ®_name : output_values)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name))
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += reg_name;
|
||||
OS << " vec4 " << reg_name << " = vec4(0.);" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
OS << std::endl << " fs_main(" + parameters + ");" << std::endl << std::endl;
|
||||
|
||||
//Append the color output assignments
|
||||
OS << color_output_block;
|
||||
|
||||
if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT)
|
||||
{
|
||||
{
|
||||
/** Note: Naruto Shippuden : Ultimate Ninja Storm 2 sets CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS in a shader
|
||||
* but it writes depth in r1.z and not h2.z.
|
||||
* Maybe there's a different flag for depth ?
|
||||
*/
|
||||
//OS << ((m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? "\tgl_FragDepth = r1.z;\n" : "\tgl_FragDepth = h0.z;\n") << std::endl;
|
||||
OS << " gl_FragDepth = r1.z;\n";
|
||||
}
|
||||
}
|
||||
|
||||
OS << "}" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -320,8 +440,12 @@ void GLFragmentProgram::Decompile(const RSXFragmentProgram& prog)
|
|||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
if (PT.type == "sampler2D")
|
||||
if (PT.type == "sampler1D" ||
|
||||
PT.type == "sampler2D" ||
|
||||
PT.type == "sampler3D" ||
|
||||
PT.type == "samplerCube")
|
||||
continue;
|
||||
|
||||
size_t offset = atoi(PI.name.c_str() + 2);
|
||||
FragmentConstantOffsetCache.push_back(offset);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue