From 7e944103c21d6754f0fa52b80510f63239658ac5 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 1 Dec 2020 15:14:23 +1000 Subject: [PATCH] GPU/OpenGL: Work around rasterization/interplation issue on V3D/Pi4 --- src/core/gpu_hw_shadergen.cpp | 23 +++++++++++++++++------ src/core/shadergen.cpp | 7 +++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/core/gpu_hw_shadergen.cpp b/src/core/gpu_hw_shadergen.cpp index 59c2414b6..4e3d677f9 100644 --- a/src/core/gpu_hw_shadergen.cpp +++ b/src/core/gpu_hw_shadergen.cpp @@ -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; diff --git a/src/core/shadergen.cpp b/src/core/shadergen.cpp index be6d7aa12..aa121869a 100644 --- a/src/core/shadergen.cpp +++ b/src/core/shadergen.cpp @@ -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(glGetString(GL_VENDOR)), "Broadcom") && + std::strstr(reinterpret_cast(glGetString(GL_RENDERER)), "V3D")) + { + ss << "#define DRIVER_V3D 1\n"; + } } else if (m_render_api == HostDisplay::RenderAPI::OpenGL) {