mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
gl: cleanup; fix program linkage on mesa using GL_ARB_explicit_uniform_location, also make use of ARB_multidraw
This commit is contained in:
parent
061824a7ec
commit
07c83f6e44
6 changed files with 130 additions and 103 deletions
|
@ -94,7 +94,7 @@ namespace rsx
|
|||
using surface_type = typename Traits::surface_type;
|
||||
using command_list_type = typename Traits::command_list_type;
|
||||
using download_buffer_object = typename Traits::download_buffer_object;
|
||||
using surface_subresource = typename surface_subresource_storage<surface_type>;
|
||||
using surface_subresource = surface_subresource_storage<surface_type>;
|
||||
|
||||
std::unordered_map<u32, surface_storage_type> m_render_targets_storage = {};
|
||||
std::unordered_map<u32, surface_storage_type> m_depth_stencil_storage = {};
|
||||
|
|
|
@ -2,69 +2,104 @@
|
|||
#include "GLCommonDecompiler.h"
|
||||
|
||||
|
||||
std::string getFunctionImpl(FUNCTION f)
|
||||
namespace gl
|
||||
{
|
||||
switch (f)
|
||||
std::string getFunctionImpl(FUNCTION f)
|
||||
{
|
||||
default:
|
||||
abort();
|
||||
case FUNCTION::FUNCTION_DP2:
|
||||
return "vec4(dot($0.xy, $1.xy))";
|
||||
case FUNCTION::FUNCTION_DP2A:
|
||||
return "vec4(dot($0.xy, $1.xy) + $2.x)";
|
||||
case FUNCTION::FUNCTION_DP3:
|
||||
return "vec4(dot($0.xyz, $1.xyz))";
|
||||
case FUNCTION::FUNCTION_DP4:
|
||||
return "vec4(dot($0, $1))";
|
||||
case FUNCTION::FUNCTION_DPH:
|
||||
return "vec4(dot(vec4($0.xyz, 1.0), $1))";
|
||||
case FUNCTION::FUNCTION_SFL:
|
||||
return "vec4(0., 0., 0., 0.)";
|
||||
case FUNCTION::FUNCTION_STR:
|
||||
return "vec4(1., 1., 1., 1.)";
|
||||
case FUNCTION::FUNCTION_FRACT:
|
||||
return "fract($0)";
|
||||
case FUNCTION::FUNCTION_REFL:
|
||||
return "vec4($0 - 2.0 * (dot($0, $1)) * $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
|
||||
return "texture($t, $0.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
|
||||
return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
|
||||
return "textureLod($t, $0.x, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD:
|
||||
return "textureGrad($t, $0.x, $1.x, $2.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
|
||||
return "texture($t, $0.xy * $t_coord_scale)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
|
||||
return "textureProj($t, $0 , $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
|
||||
return "textureLod($t, $0.xy * $t_coord_scale, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD:
|
||||
return "textureGrad($t, $0.xy * $t_coord_scale , $1.xy, $2.xy)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
|
||||
return "texture($t, ($0.xyz / $0.w))";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
|
||||
return "textureLod($t, $0.xyz, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD:
|
||||
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ:
|
||||
return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD:
|
||||
return "textureLod($t, $0.xyz, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD:
|
||||
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
|
||||
case FUNCTION::FUNCTION_DFDX:
|
||||
return "dFdx($0)";
|
||||
case FUNCTION::FUNCTION_DFDY:
|
||||
return "dFdy($0)";
|
||||
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
|
||||
return "textureLod($t, $0.xy, 0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t, $0.xy * $t_coord_scale)";
|
||||
switch (f)
|
||||
{
|
||||
default:
|
||||
abort();
|
||||
case FUNCTION::FUNCTION_DP2:
|
||||
return "vec4(dot($0.xy, $1.xy))";
|
||||
case FUNCTION::FUNCTION_DP2A:
|
||||
return "vec4(dot($0.xy, $1.xy) + $2.x)";
|
||||
case FUNCTION::FUNCTION_DP3:
|
||||
return "vec4(dot($0.xyz, $1.xyz))";
|
||||
case FUNCTION::FUNCTION_DP4:
|
||||
return "vec4(dot($0, $1))";
|
||||
case FUNCTION::FUNCTION_DPH:
|
||||
return "vec4(dot(vec4($0.xyz, 1.0), $1))";
|
||||
case FUNCTION::FUNCTION_SFL:
|
||||
return "vec4(0., 0., 0., 0.)";
|
||||
case FUNCTION::FUNCTION_STR:
|
||||
return "vec4(1., 1., 1., 1.)";
|
||||
case FUNCTION::FUNCTION_FRACT:
|
||||
return "fract($0)";
|
||||
case FUNCTION::FUNCTION_REFL:
|
||||
return "vec4($0 - 2.0 * (dot($0, $1)) * $1)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
|
||||
return "texture($t, $0.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
|
||||
return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
|
||||
return "textureLod($t, $0.x, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD:
|
||||
return "textureGrad($t, $0.x, $1.x, $2.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
|
||||
return "texture($t, $0.xy * $t_coord_scale)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
|
||||
return "textureProj($t, $0 , $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
|
||||
return "textureLod($t, $0.xy * $t_coord_scale, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD:
|
||||
return "textureGrad($t, $0.xy * $t_coord_scale , $1.xy, $2.xy)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
|
||||
return "texture($t, ($0.xyz / $0.w))";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
|
||||
return "textureLod($t, $0.xyz, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD:
|
||||
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
|
||||
return "texture($t, $0.xyz)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ:
|
||||
return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD:
|
||||
return "textureLod($t, $0.xyz, $1.x)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD:
|
||||
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
|
||||
case FUNCTION::FUNCTION_DFDX:
|
||||
return "dFdx($0)";
|
||||
case FUNCTION::FUNCTION_DFDY:
|
||||
return "dFdy($0)";
|
||||
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
|
||||
return "textureLod($t, $0.xy, 0)";
|
||||
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA:
|
||||
return "texture2DReconstruct($t, $0.xy * $t_coord_scale)";
|
||||
}
|
||||
}
|
||||
|
||||
int get_varying_register_location(const std::string &var_name)
|
||||
{
|
||||
static const std::pair<std::string, int> reg_table[] =
|
||||
{
|
||||
{ "diff_color", 1 },
|
||||
{ "spec_color", 2 },
|
||||
{ "back_diff_color", 1 },
|
||||
{ "back_spec_color", 2 },
|
||||
{ "front_diff_color", 3 },
|
||||
{ "front_spec_color", 4 },
|
||||
{ "fog_c", 5 },
|
||||
{ "tc0", 6 },
|
||||
{ "tc1", 7 },
|
||||
{ "tc2", 8 },
|
||||
{ "tc3", 9 },
|
||||
{ "tc4", 10 },
|
||||
{ "tc5", 11 },
|
||||
{ "tc6", 12 },
|
||||
{ "tc7", 13 },
|
||||
{ "tc8", 14 },
|
||||
{ "tc9", 15 }
|
||||
};
|
||||
|
||||
for (const auto& v: reg_table)
|
||||
{
|
||||
if (v.first == var_name)
|
||||
return v.second;
|
||||
}
|
||||
|
||||
fmt::throw_exception("register named %s should not be declared!", var_name.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,8 @@
|
|||
#include "../Common/GLSLCommon.h"
|
||||
#include <ostream>
|
||||
|
||||
std::string getFunctionImpl(FUNCTION f);
|
||||
namespace gl
|
||||
{
|
||||
std::string getFunctionImpl(FUNCTION f);
|
||||
int get_varying_register_location(const std::string &var_name);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "GLCommonDecompiler.h"
|
||||
#include "../GCM.h"
|
||||
|
||||
|
||||
std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount)
|
||||
{
|
||||
return glsl::getFloatTypeNameImpl(elementCount);
|
||||
|
@ -14,7 +15,7 @@ std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount)
|
|||
|
||||
std::string GLFragmentDecompilerThread::getFunction(FUNCTION f)
|
||||
{
|
||||
return getFunctionImpl(f);
|
||||
return gl::getFunctionImpl(f);
|
||||
}
|
||||
|
||||
std::string GLFragmentDecompilerThread::saturate(const std::string & code)
|
||||
|
@ -35,6 +36,7 @@ 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);
|
||||
std::vector<std::string> inputs_to_declare;
|
||||
|
||||
for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
|
||||
{
|
||||
|
@ -57,7 +59,7 @@ void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
|
|||
if (var_name == "fogc")
|
||||
var_name = "fog_c";
|
||||
|
||||
OS << "in " << PT.type << " " << var_name << ";\n";
|
||||
inputs_to_declare.push_back(var_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,14 +67,19 @@ void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
|
|||
{
|
||||
if (m_prog.front_color_diffuse_output && m_prog.back_color_diffuse_output)
|
||||
{
|
||||
OS << "in vec4 front_diff_color;\n";
|
||||
inputs_to_declare.push_back("front_diff_color");
|
||||
}
|
||||
|
||||
if (m_prog.front_color_specular_output && m_prog.back_color_specular_output)
|
||||
{
|
||||
OS << "in vec4 front_spec_color;\n";
|
||||
inputs_to_declare.push_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)
|
||||
|
@ -225,7 +232,6 @@ void GLFragmentDecompilerThread::insertMainStart(std::stringstream & OS)
|
|||
}
|
||||
}
|
||||
|
||||
OS << "//FP_HASH=" << fmt::format("%llX", program_hash_util::fragment_program_hash()(m_prog)) << "\n";
|
||||
OS << "void fs_main(" << parameters << ")\n";
|
||||
OS << "{\n";
|
||||
|
||||
|
|
|
@ -550,13 +550,7 @@ void GLGSRender::end()
|
|||
index_ptr += (index_size << type_scale);
|
||||
}
|
||||
|
||||
for (int i = 0; i < draw_count; ++i)
|
||||
{
|
||||
if (counts[i] > 0)
|
||||
glDrawElements(draw_mode, counts[i], index_type, offsets[i]);
|
||||
}
|
||||
|
||||
//glMultiDrawElements(draw_mode, counts.data(), index_type, offsets.data(), (GLsizei)draw_count);
|
||||
glMultiDrawElements(draw_mode, counts.data(), index_type, offsets.data(), (GLsizei)draw_count);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -581,15 +575,7 @@ void GLGSRender::end()
|
|||
counts.push_back(range.second);
|
||||
}
|
||||
|
||||
///*
|
||||
// TEST FOR DRIVER BUGS - AMD: SHAME, SHAME, SHAME
|
||||
for (int i = 0; i < draw_count; i++)
|
||||
{
|
||||
if (counts[i] > 0)
|
||||
glDrawArrays(draw_mode, firsts[i], counts[i]);
|
||||
}//*/
|
||||
|
||||
//glMultiDrawArrays(draw_mode, firsts.data(), counts.data(), (GLsizei)draw_count);
|
||||
glMultiDrawArrays(draw_mode, firsts.data(), counts.data(), (GLsizei)draw_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ std::string GLVertexDecompilerThread::getIntTypeName(size_t elementCount)
|
|||
|
||||
std::string GLVertexDecompilerThread::getFunction(FUNCTION f)
|
||||
{
|
||||
return getFunctionImpl(f);
|
||||
return gl::getFunctionImpl(f);
|
||||
}
|
||||
|
||||
std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::string &Op0, const std::string &Op1)
|
||||
|
@ -31,7 +31,8 @@ std::string GLVertexDecompilerThread::compareFunction(COMPARE f, const std::stri
|
|||
|
||||
void GLVertexDecompilerThread::insertHeader(std::stringstream &OS)
|
||||
{
|
||||
OS << "#version 430\n\n";
|
||||
OS << "#version 430\n";
|
||||
OS << "#extension GL_ARB_separate_program_objects: enable\n\n";
|
||||
OS << "layout(std140, binding = 0) uniform VertexContextBuffer\n";
|
||||
OS << "{\n";
|
||||
OS << " mat4 scale_offset_mat;\n";
|
||||
|
@ -109,13 +110,12 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
|
|||
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 (m_parr.HasParam(PF_PARAM_NONE, "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;
|
||||
|
||||
|
@ -130,24 +130,20 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
|
|||
if (front_back_specular && name == "spec_color")
|
||||
name = "back_spec_color";
|
||||
|
||||
OS << "out vec4 " << name << ";\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
//Mesa drivers are very strict on shader-stage matching
|
||||
//Force some outputs to be declared even if unused
|
||||
if (i.need_declare && (rsx_vertex_program.output_mask & i.check_mask_value) > 0)
|
||||
{
|
||||
OS << "out vec4 " << i.name << ";\n";
|
||||
}
|
||||
outputs_to_declare.push_back(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (insert_back_diffuse && insert_front_diffuse)
|
||||
OS << "out vec4 front_diff_color;\n";
|
||||
outputs_to_declare.push_back("front_diff_color");
|
||||
|
||||
if (insert_back_specular && insert_front_specular)
|
||||
OS << "out vec4 front_spec_color;\n";
|
||||
outputs_to_declare.push_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)
|
||||
|
|
Loading…
Add table
Reference in a new issue