GPU/OpenGL: Work around rasterization/interplation issue on V3D/Pi4

This commit is contained in:
Connor McLaughlin 2020-12-01 15:14:23 +10:00
parent a2666de7c8
commit 7e944103c2
2 changed files with 24 additions and 6 deletions

View File

@ -88,7 +88,20 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
WriteCommonFunctions(ss);
WriteBatchUniformBuffer(ss);
ss << "CONSTANT float EPSILON = 0.00001;\n";
ss << R"(
// OpenGL seems to be off by one pixel in the Y direction due to lower-left origin, but only on
// Intel and NVIDIA drivers. AMD is fine. V3D requires coordinates to be slightly offset even further.
#if API_OPENGL || API_OPENGL_ES
#ifdef DRIVER_V3D
CONSTANT float POS_EPSILON = 0.0001;
#else
CONSTANT float POS_EPSILON = 0.00001;
#endif
#endif
CONSTANT float TEX_EPSILON = 0.00001;
)";
if (textured)
{
@ -126,9 +139,7 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
float pos_w = a_pos.w;
#if API_OPENGL || API_OPENGL_ES
// OpenGL seems to be off by one pixel in the Y direction due to lower-left origin, but only on
// Intel and NVIDIA drivers. AMD is fine...
pos_y += EPSILON;
pos_y += POS_EPSILON;
// 0..1 to -1..1 depth range.
pos_z = (pos_z * 2.0) - 1.0;
@ -145,8 +156,8 @@ std::string GPU_HW_ShaderGen::GenerateBatchVertexShader(bool textured)
#if TEXTURED
// Fudge the texture coordinates by half a pixel in screen-space.
// This fixes the rounding/interpolation error on NVIDIA GPUs with shared edges between triangles.
v_tex0 = float2(float((a_texcoord & 0xFFFFu) * RESOLUTION_SCALE) + EPSILON,
float((a_texcoord >> 16) * RESOLUTION_SCALE) + EPSILON);
v_tex0 = float2(float((a_texcoord & 0xFFFFu) * RESOLUTION_SCALE) + TEX_EPSILON,
float((a_texcoord >> 16) * RESOLUTION_SCALE) + TEX_EPSILON);
// base_x,base_y,palette_x,palette_y
v_texpage.x = (a_texpage & 15u) * 64u * RESOLUTION_SCALE;

View File

@ -91,6 +91,13 @@ void ShaderGen::WriteHeader(std::stringstream& ss)
ss << "#extension GL_EXT_blend_func_extended : require\n";
if (GLAD_GL_ARB_blend_func_extended)
ss << "#extension GL_ARB_blend_func_extended : require\n";
// Test for V3D driver - we have to fudge coordinates slightly.
if (std::strstr(reinterpret_cast<const char*>(glGetString(GL_VENDOR)), "Broadcom") &&
std::strstr(reinterpret_cast<const char*>(glGetString(GL_RENDERER)), "V3D"))
{
ss << "#define DRIVER_V3D 1\n";
}
}
else if (m_render_api == HostDisplay::RenderAPI::OpenGL)
{