gl: cleanup; fix program linkage on mesa using GL_ARB_explicit_uniform_location, also make use of ARB_multidraw

This commit is contained in:
kd-11 2017-09-09 00:22:51 +03:00
parent 061824a7ec
commit 07c83f6e44
6 changed files with 130 additions and 103 deletions

View File

@ -94,7 +94,7 @@ namespace rsx
using surface_type = typename Traits::surface_type; using surface_type = typename Traits::surface_type;
using command_list_type = typename Traits::command_list_type; using command_list_type = typename Traits::command_list_type;
using download_buffer_object = typename Traits::download_buffer_object; 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_render_targets_storage = {};
std::unordered_map<u32, surface_storage_type> m_depth_stencil_storage = {}; std::unordered_map<u32, surface_storage_type> m_depth_stencil_storage = {};

View File

@ -2,69 +2,104 @@
#include "GLCommonDecompiler.h" #include "GLCommonDecompiler.h"
std::string getFunctionImpl(FUNCTION f) namespace gl
{ {
switch (f) std::string getFunctionImpl(FUNCTION f)
{ {
default: switch (f)
abort(); {
case FUNCTION::FUNCTION_DP2: default:
return "vec4(dot($0.xy, $1.xy))"; abort();
case FUNCTION::FUNCTION_DP2A: case FUNCTION::FUNCTION_DP2:
return "vec4(dot($0.xy, $1.xy) + $2.x)"; return "vec4(dot($0.xy, $1.xy))";
case FUNCTION::FUNCTION_DP3: case FUNCTION::FUNCTION_DP2A:
return "vec4(dot($0.xyz, $1.xyz))"; return "vec4(dot($0.xy, $1.xy) + $2.x)";
case FUNCTION::FUNCTION_DP4: case FUNCTION::FUNCTION_DP3:
return "vec4(dot($0, $1))"; return "vec4(dot($0.xyz, $1.xyz))";
case FUNCTION::FUNCTION_DPH: case FUNCTION::FUNCTION_DP4:
return "vec4(dot(vec4($0.xyz, 1.0), $1))"; return "vec4(dot($0, $1))";
case FUNCTION::FUNCTION_SFL: case FUNCTION::FUNCTION_DPH:
return "vec4(0., 0., 0., 0.)"; return "vec4(dot(vec4($0.xyz, 1.0), $1))";
case FUNCTION::FUNCTION_STR: case FUNCTION::FUNCTION_SFL:
return "vec4(1., 1., 1., 1.)"; return "vec4(0., 0., 0., 0.)";
case FUNCTION::FUNCTION_FRACT: case FUNCTION::FUNCTION_STR:
return "fract($0)"; return "vec4(1., 1., 1., 1.)";
case FUNCTION::FUNCTION_REFL: case FUNCTION::FUNCTION_FRACT:
return "vec4($0 - 2.0 * (dot($0, $1)) * $1)"; return "fract($0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D: case FUNCTION::FUNCTION_REFL:
return "texture($t, $0.x)"; return "vec4($0 - 2.0 * (dot($0, $1)) * $1)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ: case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D:
return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias return "texture($t, $0.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_PROJ:
return "textureLod($t, $0.x, $1.x)"; return "textureProj($t, $0.x, $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_LOD:
return "textureGrad($t, $0.x, $1.x, $2.x)"; return "textureLod($t, $0.x, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D: case FUNCTION::FUNCTION_TEXTURE_SAMPLE1D_GRAD:
return "texture($t, $0.xy * $t_coord_scale)"; return "textureGrad($t, $0.x, $1.x, $2.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ: case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D:
return "textureProj($t, $0 , $1.x)"; // Note: $1.x is bias return "texture($t, $0.xy * $t_coord_scale)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ:
return "textureLod($t, $0.xy * $t_coord_scale, $1.x)"; return "textureProj($t, $0 , $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD:
return "textureGrad($t, $0.xy * $t_coord_scale , $1.xy, $2.xy)"; return "textureLod($t, $0.xy * $t_coord_scale, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD:
return "texture($t, $0.xyz)"; return "textureGrad($t, $0.xy * $t_coord_scale , $1.xy, $2.xy)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ: case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE:
return "texture($t, ($0.xyz / $0.w))"; return "texture($t, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD: case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ:
return "textureLod($t, $0.xyz, $1.x)"; return "texture($t, ($0.xyz / $0.w))";
case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD: case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD:
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)"; return "textureLod($t, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D: case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD:
return "texture($t, $0.xyz)"; return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ: case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D:
return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias return "texture($t, $0.xyz)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_PROJ:
return "textureLod($t, $0.xyz, $1.x)"; return "textureProj($t, $0.xyzw, $1.x)"; // Note: $1.x is bias
case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD: case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_LOD:
return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)"; return "textureLod($t, $0.xyz, $1.x)";
case FUNCTION::FUNCTION_DFDX: case FUNCTION::FUNCTION_TEXTURE_SAMPLE3D_GRAD:
return "dFdx($0)"; return "textureGrad($t, $0.xyz, $1.xyz, $2.xyz)";
case FUNCTION::FUNCTION_DFDY: case FUNCTION::FUNCTION_DFDX:
return "dFdy($0)"; return "dFdx($0)";
case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D: case FUNCTION::FUNCTION_DFDY:
return "textureLod($t, $0.xy, 0)"; return "dFdy($0)";
case FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA: case FUNCTION::FUNCTION_VERTEX_TEXTURE_FETCH2D:
return "texture2DReconstruct($t, $0.xy * $t_coord_scale)"; 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());
} }
} }

View File

@ -4,4 +4,8 @@
#include "../Common/GLSLCommon.h" #include "../Common/GLSLCommon.h"
#include <ostream> #include <ostream>
std::string getFunctionImpl(FUNCTION f); namespace gl
{
std::string getFunctionImpl(FUNCTION f);
int get_varying_register_location(const std::string &var_name);
}

View File

@ -7,6 +7,7 @@
#include "GLCommonDecompiler.h" #include "GLCommonDecompiler.h"
#include "../GCM.h" #include "../GCM.h"
std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount) std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount)
{ {
return glsl::getFloatTypeNameImpl(elementCount); return glsl::getFloatTypeNameImpl(elementCount);
@ -14,7 +15,7 @@ std::string GLFragmentDecompilerThread::getFloatTypeName(size_t elementCount)
std::string GLFragmentDecompilerThread::getFunction(FUNCTION f) std::string GLFragmentDecompilerThread::getFunction(FUNCTION f)
{ {
return getFunctionImpl(f); return gl::getFunctionImpl(f);
} }
std::string GLFragmentDecompilerThread::saturate(const std::string & code) std::string GLFragmentDecompilerThread::saturate(const std::string & code)
@ -35,6 +36,7 @@ void GLFragmentDecompilerThread::insertHeader(std::stringstream & OS)
void GLFragmentDecompilerThread::insertIntputs(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); 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]) for (const ParamType& PT : m_parr.params[PF_PARAM_IN])
{ {
@ -57,7 +59,7 @@ void GLFragmentDecompilerThread::insertIntputs(std::stringstream & OS)
if (var_name == "fogc") if (var_name == "fogc")
var_name = "fog_c"; 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) 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) 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) 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 << "void fs_main(" << parameters << ")\n";
OS << "{\n"; OS << "{\n";

View File

@ -550,13 +550,7 @@ void GLGSRender::end()
index_ptr += (index_size << type_scale); index_ptr += (index_size << type_scale);
} }
for (int i = 0; i < draw_count; ++i) glMultiDrawElements(draw_mode, counts.data(), index_type, offsets.data(), (GLsizei)draw_count);
{
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);
} }
} }
else else
@ -581,15 +575,7 @@ void GLGSRender::end()
counts.push_back(range.second); counts.push_back(range.second);
} }
///* glMultiDrawArrays(draw_mode, firsts.data(), counts.data(), (GLsizei)draw_count);
// 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);
} }
} }

View File

@ -21,7 +21,7 @@ std::string GLVertexDecompilerThread::getIntTypeName(size_t elementCount)
std::string GLVertexDecompilerThread::getFunction(FUNCTION f) 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) 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) 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 << "layout(std140, binding = 0) uniform VertexContextBuffer\n";
OS << "{\n"; OS << "{\n";
OS << " mat4 scale_offset_mat;\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_diffuse = (insert_back_diffuse && insert_front_diffuse);
bool front_back_specular = (insert_back_specular && insert_front_specular); bool front_back_specular = (insert_back_specular && insert_front_specular);
std::vector<std::string> outputs_to_declare;
for (auto &i : reg_table) 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") if (i.name == "front_diff_color")
insert_front_diffuse = false; insert_front_diffuse = false;
@ -130,24 +130,20 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::
if (front_back_specular && name == "spec_color") if (front_back_specular && name == "spec_color")
name = "back_spec_color"; name = "back_spec_color";
OS << "out vec4 " << name << ";\n"; outputs_to_declare.push_back(name);
}
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";
}
} }
} }
if (insert_back_diffuse && insert_front_diffuse) 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) 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) void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS)