mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 08:21:29 +12:00
rsx: Implement interpolation using barycentrics
This commit is contained in:
parent
1fd265d316
commit
a0ef1a672c
13 changed files with 199 additions and 90 deletions
|
@ -1,7 +1,9 @@
|
|||
#include "stdafx.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "../Common/simple_array.hpp"
|
||||
|
||||
#include "GLSLCommon.h"
|
||||
#include "RSXFragmentProgram.h"
|
||||
|
||||
namespace program_common
|
||||
{
|
||||
|
@ -1140,4 +1142,103 @@ namespace glsl
|
|||
" uint flags;\n"
|
||||
"};\n\n";
|
||||
}
|
||||
|
||||
void insert_fragment_shader_inputs_block(
|
||||
std::stringstream& OS,
|
||||
const RSXFragmentProgram& prog,
|
||||
const std::vector<ParamType>& params,
|
||||
const two_sided_lighting_config& _2sided_lighting,
|
||||
std::function<int(std::string_view)> varying_location)
|
||||
{
|
||||
struct _varying_register_config
|
||||
{
|
||||
int location;
|
||||
std::string name;
|
||||
std::string type;
|
||||
};
|
||||
|
||||
rsx::simple_array<_varying_register_config> varying_list;
|
||||
|
||||
for (const ParamType& PT : params)
|
||||
{
|
||||
for (const ParamItem& PI : PT.items)
|
||||
{
|
||||
// ssa is defined in the program body and is not a varying type
|
||||
if (PI.name == "ssa") continue;
|
||||
|
||||
const auto reg_location = varying_location(PI.name);
|
||||
std::string var_name = PI.name;
|
||||
|
||||
if (var_name == "fogc")
|
||||
{
|
||||
var_name = "fog_c";
|
||||
}
|
||||
else if (prog.two_sided_lighting)
|
||||
{
|
||||
if (var_name == "diff_color")
|
||||
{
|
||||
var_name = "diff_color0";
|
||||
}
|
||||
else if (var_name == "spec_color")
|
||||
{
|
||||
var_name = "spec_color0";
|
||||
}
|
||||
}
|
||||
|
||||
varying_list.push_back({ reg_location, var_name, PT.type });
|
||||
}
|
||||
}
|
||||
|
||||
if (prog.two_sided_lighting)
|
||||
{
|
||||
if (_2sided_lighting.two_sided_color)
|
||||
{
|
||||
varying_list.push_back({ varying_location("diff_color1"), "diff_color1", "vec4" });
|
||||
}
|
||||
|
||||
if (_2sided_lighting.two_sided_specular)
|
||||
{
|
||||
varying_list.push_back({ varying_location("spec_color1"), "spec_color1", "vec4" });
|
||||
}
|
||||
}
|
||||
|
||||
if (varying_list.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make the output a little nicer
|
||||
varying_list.sort(FN(x.location < y.location));
|
||||
|
||||
if (!(prog.ctrl & RSX_SHADER_CONTROL_ATTRIBUTE_INTERPOLATION))
|
||||
{
|
||||
for (const auto& reg : varying_list)
|
||||
{
|
||||
OS << "layout(location=" << reg.location << ") in " << reg.type << " " << reg.name << ";\n";
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& reg : varying_list)
|
||||
{
|
||||
OS << "layout(location=" << reg.location << ") pervertexNV in " << reg.type << " " << reg.name << "_raw[3];\n";
|
||||
}
|
||||
|
||||
// Interpolate the input attributes manually.
|
||||
// Matches AMD behavior where gl_BaryCoordSmoothAMD only provides x and y with z being autogenerated.
|
||||
OS <<
|
||||
"vec4 _interpolate_varying3(const in vec4[3] v)\n"
|
||||
"{\n"
|
||||
" const BaryCoord_z = 1.0 - (gl_BaryCoordNV.x + gl_BaryCoordNV.y);\n"
|
||||
" return gl_BaryCoordNV.x * v[0] + gl_BaryCoordNV.y * v[1] + BaryCoord_z * v[2];\n"
|
||||
"}\n\n";
|
||||
|
||||
for (const auto& reg : varying_list)
|
||||
{
|
||||
OS << "vec4 " << reg.name << " = _interpolate_varying3(" << reg.name << "_raw);\n";
|
||||
}
|
||||
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue