mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 15:01:28 +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);
|
||||
}
|
||||
|
|
|
@ -477,31 +477,17 @@ void GLGSRender::end()
|
|||
|
||||
void GLGSRender::set_viewport()
|
||||
{
|
||||
u16 viewport_x = rsx::method_registers.viewport_origin_x();
|
||||
u16 viewport_y = rsx::method_registers.viewport_origin_y();
|
||||
u16 viewport_w = rsx::method_registers.viewport_width();
|
||||
u16 viewport_h = rsx::method_registers.viewport_height();
|
||||
//NOTE: scale offset matrix already contains the viewport transformation
|
||||
glViewport(0, 0, rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height());
|
||||
|
||||
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
||||
u16 scissor_w = rsx::method_registers.scissor_width();
|
||||
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
||||
u16 scissor_h = rsx::method_registers.scissor_height();
|
||||
|
||||
rsx::window_origin shader_window_origin = rsx::method_registers.shader_window_origin();
|
||||
|
||||
if (shader_window_origin == rsx::window_origin::bottom)
|
||||
{
|
||||
__glcheck glViewport(viewport_x, viewport_y, viewport_w, viewport_h);
|
||||
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 shader_window_height = rsx::method_registers.shader_window_height();
|
||||
|
||||
__glcheck glViewport(viewport_x, shader_window_height - viewport_y - viewport_h + 1, viewport_w, viewport_h);
|
||||
__glcheck glScissor(scissor_x, shader_window_height - scissor_y - scissor_h + 1, scissor_w, scissor_h);
|
||||
}
|
||||
|
||||
//NOTE: window origin does not affect scissor region (probably only affects viewport matrix; already applied)
|
||||
//See LIMBO [NPUB-30373] which uses shader window origin = top
|
||||
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ struct gl_render_target_traits
|
|||
.type(format.type)
|
||||
.format(format.format)
|
||||
.internal_format(format.internal_format)
|
||||
.swizzle(gl::texture::channel::r, gl::texture::channel::r, gl::texture::channel::r, gl::texture::channel::r)
|
||||
.wrap(gl::texture::wrap::clamp_to_border, gl::texture::wrap::clamp_to_border, gl::texture::wrap::clamp_to_border)
|
||||
.apply();
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ namespace
|
|||
case CELL_GCM_TEXTURE_R5G5B5A1:
|
||||
case CELL_GCM_TEXTURE_R6G5B5:
|
||||
case CELL_GCM_TEXTURE_R5G6B5:
|
||||
//case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
case CELL_GCM_TEXTURE_A8R8G8B8: // TODO
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8:
|
||||
case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT:
|
||||
|
@ -140,24 +141,20 @@ namespace
|
|||
case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:
|
||||
return { GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE };
|
||||
|
||||
case CELL_GCM_TEXTURE_B8:
|
||||
return { GL_RED, GL_RED, GL_RED, GL_RED };
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
return{ GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
|
||||
case CELL_GCM_TEXTURE_A4R4G4B4:
|
||||
return { GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN };
|
||||
case CELL_GCM_TEXTURE_B8:
|
||||
case CELL_GCM_TEXTURE_X16:
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT:
|
||||
return { GL_RED, GL_RED, GL_RED, GL_RED };
|
||||
|
||||
case CELL_GCM_TEXTURE_G8B8:
|
||||
return { GL_GREEN, GL_RED, GL_GREEN, GL_RED};
|
||||
|
||||
case CELL_GCM_TEXTURE_X16:
|
||||
return { GL_RED, GL_RED, GL_RED, GL_RED };
|
||||
|
||||
case CELL_GCM_TEXTURE_Y16_X16:
|
||||
return { GL_RED, GL_GREEN, GL_RED, GL_GREEN};
|
||||
|
||||
case CELL_GCM_TEXTURE_X32_FLOAT:
|
||||
return { GL_RED, GL_RED, GL_RED, GL_RED };
|
||||
|
||||
case CELL_GCM_TEXTURE_Y16_X16_FLOAT:
|
||||
return { GL_GREEN, GL_RED, GL_GREEN, GL_RED };
|
||||
|
||||
|
@ -492,25 +489,15 @@ namespace rsx
|
|||
|
||||
glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, tex.get_exact_mipmap_count() - 1);
|
||||
|
||||
if (format != CELL_GCM_TEXTURE_B8 && format != CELL_GCM_TEXTURE_X16 && format != CELL_GCM_TEXTURE_X32_FLOAT)
|
||||
{
|
||||
u8 remap_a = tex.remap() & 0x3;
|
||||
u8 remap_r = (tex.remap() >> 2) & 0x3;
|
||||
u8 remap_g = (tex.remap() >> 4) & 0x3;
|
||||
u8 remap_b = (tex.remap() >> 6) & 0x3;
|
||||
u8 remap_a = tex.remap() & 0x3;
|
||||
u8 remap_r = (tex.remap() >> 2) & 0x3;
|
||||
u8 remap_g = (tex.remap() >> 4) & 0x3;
|
||||
u8 remap_b = (tex.remap() >> 6) & 0x3;
|
||||
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
|
||||
}
|
||||
else
|
||||
{
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[0]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[1]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[2]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[3]);
|
||||
}
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_A, glRemap[remap_a]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_R, glRemap[remap_r]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_G, glRemap[remap_g]);
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_SWIZZLE_B, glRemap[remap_b]);
|
||||
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_S, gl_wrap(tex.wrap_s()));
|
||||
__glcheck glTexParameteri(m_target, GL_TEXTURE_WRAP_T, gl_wrap(tex.wrap_t()));
|
||||
|
|
|
@ -351,7 +351,6 @@ namespace
|
|||
const rsx::draw_indexed_array_command& command)
|
||||
{
|
||||
u32 min_index = 0, max_index = 0;
|
||||
u32 max_vertex_attrib_size = 0;
|
||||
|
||||
rsx::index_array_type type = rsx::method_registers.index_type();
|
||||
u32 type_size = ::narrow<u32>(get_index_type_size(type));
|
||||
|
|
|
@ -198,13 +198,42 @@ static const reg_info reg_table[] =
|
|||
|
||||
void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector<ParamType> & outputs)
|
||||
{
|
||||
for (const auto &i : reg_table)
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & 4);
|
||||
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & 8);
|
||||
|
||||
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)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare)
|
||||
{
|
||||
OS << "out vec4 " << i.name << ";" << std::endl;
|
||||
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";
|
||||
|
||||
OS << "out vec4 " << name << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
OS << "out vec4 front_diff_color;" << std::endl;
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
OS << "out vec4 front_spec_color;" << std::endl;
|
||||
}
|
||||
|
||||
void add_input(std::stringstream & OS, const ParamItem &PI, const std::vector<rsx_vertex_input> &inputs)
|
||||
|
@ -247,17 +276,34 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
{
|
||||
insert_glsl_legacy_function(OS);
|
||||
|
||||
OS << "void main()" << std::endl;
|
||||
std::string parameters = "";
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
std::string reg_name = "dst_reg" + std::to_string(i);
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name))
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += "inout vec4 " + reg_name;
|
||||
}
|
||||
}
|
||||
|
||||
OS << "void vs_main(" << parameters << ")" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
// Declare inside main function
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_NONE])
|
||||
//Declare temporary registers, ignoring those mapped to outputs
|
||||
for (const ParamType PT : m_parr.params[PF_PARAM_NONE])
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
if (PI.name.substr(0, 7) == "dst_reg")
|
||||
continue;
|
||||
|
||||
OS << " " << PT.type << " " << PI.name;
|
||||
if (!PI.value.empty())
|
||||
OS << " = " << PI.value;
|
||||
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -282,10 +328,68 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
|
||||
void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
for (const auto &i : reg_table)
|
||||
OS << "}" << std::endl << std::endl;
|
||||
|
||||
OS << "void main ()" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
std::string parameters = "";
|
||||
|
||||
if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_NONE, "vec4"))
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
std::string reg_name = "dst_reg" + std::to_string(i);
|
||||
for (auto &PI : vec4Types->items)
|
||||
{
|
||||
if (reg_name == PI.name)
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += reg_name;
|
||||
OS << " vec4 " << reg_name;
|
||||
|
||||
if (!PI.value.empty())
|
||||
OS << "= " << PI.value;
|
||||
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OS << std::endl << " vs_main(" << parameters << ");" << std::endl << std::endl;
|
||||
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
|
||||
bool insert_back_diffuse = (rsx_vertex_program.output_mask & 4);
|
||||
bool insert_back_specular = (rsx_vertex_program.output_mask & 8);
|
||||
|
||||
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)
|
||||
{
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg))
|
||||
OS << " " << i.name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl;
|
||||
{
|
||||
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";
|
||||
|
||||
OS << " " << name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& uc : get_user_clip_planes(rsx_vertex_program))
|
||||
|
@ -293,6 +397,14 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
OS << uc.second;
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg1"))
|
||||
OS << " front_diff_color = dst_reg1;\n";
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg2"))
|
||||
OS << " front_spec_color = dst_reg2;\n";
|
||||
|
||||
OS << " gl_Position = gl_Position * scaleOffsetMat;" << std::endl;
|
||||
OS << "}" << std::endl;
|
||||
}
|
||||
|
|
|
@ -231,16 +231,38 @@ void VKFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
{
|
||||
vk::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;
|
||||
}
|
||||
}
|
||||
|
@ -312,25 +334,21 @@ void VKFragmentDecompilerThread::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,6 +386,41 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS)
|
|||
OS << make_comparison_test(m_prog.alpha_func, "bool(alpha_test) && ", 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;
|
||||
}
|
||||
|
||||
|
@ -396,8 +449,12 @@ void VKFragmentProgram::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);
|
||||
}
|
||||
|
|
|
@ -792,24 +792,17 @@ void VKGSRender::end()
|
|||
|
||||
void VKGSRender::set_viewport()
|
||||
{
|
||||
u16 viewport_x = rsx::method_registers.viewport_origin_x();
|
||||
u16 viewport_y = rsx::method_registers.viewport_origin_y();
|
||||
u16 viewport_w = rsx::method_registers.viewport_width();
|
||||
u16 viewport_h = rsx::method_registers.viewport_height();
|
||||
|
||||
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
||||
u16 scissor_w = rsx::method_registers.scissor_width();
|
||||
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
||||
u16 scissor_h = rsx::method_registers.scissor_height();
|
||||
|
||||
// u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW];
|
||||
// rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf);
|
||||
|
||||
//NOTE: The scale_offset matrix already has viewport matrix factored in
|
||||
VkViewport viewport = {};
|
||||
viewport.x = viewport_x;
|
||||
viewport.y = viewport_y;
|
||||
viewport.width = viewport_w;
|
||||
viewport.height = viewport_h;
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.width = rsx::method_registers.surface_clip_width();
|
||||
viewport.height = rsx::method_registers.surface_clip_height();
|
||||
viewport.minDepth = 0.f;
|
||||
viewport.maxDepth = 1.f;
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace rsx
|
|||
VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0));
|
||||
|
||||
ds->native_layout = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R };
|
||||
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, range);
|
||||
|
||||
//Clear new surface..
|
||||
|
|
|
@ -191,7 +191,7 @@ namespace vk
|
|||
if (rtt_texture = m_rtts.get_texture_from_depth_stencil_if_applicable(texaddr))
|
||||
{
|
||||
m_temporary_image_view.push_back(std::make_unique<vk::image_view>(*vk::get_current_renderer(), rtt_texture->value, VK_IMAGE_VIEW_TYPE_2D, rtt_texture->info.format,
|
||||
vk::default_component_map(),
|
||||
rtt_texture->native_layout,
|
||||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT)));
|
||||
return m_temporary_image_view.back().get();
|
||||
}
|
||||
|
|
|
@ -253,17 +253,34 @@ void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
{
|
||||
vk::insert_glsl_legacy_function(OS);
|
||||
|
||||
OS << "void main()" << std::endl;
|
||||
std::string parameters = "";
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
std::string reg_name = "dst_reg" + std::to_string(i);
|
||||
if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name))
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += "inout vec4 " + reg_name;
|
||||
}
|
||||
}
|
||||
|
||||
OS << "void vs_main(" << parameters << ")" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
// Declare inside main function
|
||||
//Declare temporary registers, ignoring those mapped to outputs
|
||||
for (const ParamType PT : m_parr.params[PF_PARAM_NONE])
|
||||
{
|
||||
for (const ParamItem &PI : PT.items)
|
||||
{
|
||||
if (PI.name.substr(0, 7) == "dst_reg")
|
||||
continue;
|
||||
|
||||
OS << " " << PT.type << " " << PI.name;
|
||||
if (!PI.value.empty())
|
||||
OS << " = " << PI.value;
|
||||
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -277,6 +294,39 @@ void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
|
||||
void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||
{
|
||||
OS << "}" << std::endl << std::endl;
|
||||
|
||||
OS << "void main ()" << std::endl;
|
||||
OS << "{" << std::endl;
|
||||
|
||||
std::string parameters = "";
|
||||
|
||||
if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_NONE, "vec4"))
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
std::string reg_name = "dst_reg" + std::to_string(i);
|
||||
for (auto &PI : vec4Types->items)
|
||||
{
|
||||
if (reg_name == PI.name)
|
||||
{
|
||||
if (parameters.length())
|
||||
parameters += ", ";
|
||||
|
||||
parameters += reg_name;
|
||||
OS << " vec4 " << reg_name;
|
||||
|
||||
if (!PI.value.empty())
|
||||
OS << "= " << PI.value;
|
||||
|
||||
OS << ";" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OS << std::endl << " vs_main(" << parameters << ");" << std::endl << std::endl;
|
||||
|
||||
bool insert_front_diffuse = (rsx_vertex_program.output_mask & 1);
|
||||
bool insert_front_specular = (rsx_vertex_program.output_mask & 2);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue