From ca68dc367533c80bb2859bf3a46720251092e099 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Sat, 26 Dec 2020 21:50:47 +0700 Subject: [PATCH] Do not fail if indices of barycoords attributes are greater or equal to max vertex attributes. --- .../GLSL/glsl_CombinerProgramBuilder.cpp | 4 ++-- .../OpenGLContext/GLSL/glsl_Utils.cpp | 10 +++++++-- .../OpenGLContext/opengl_Attributes.cpp | 8 +++---- .../OpenGLContext/opengl_BufferedDrawer.cpp | 9 +++++--- .../OpenGLContext/opengl_BufferedDrawer.h | 2 +- src/Graphics/OpenGLContext/opengl_GLInfo.cpp | 9 +++++++- src/Graphics/OpenGLContext/opengl_GLInfo.h | 1 + .../OpenGLContext/opengl_UnbufferedDrawer.cpp | 21 ++++++++++++------- .../OpenGLContext/opengl_UnbufferedDrawer.h | 1 + 9 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index bae7394f..62350b49 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -2604,7 +2604,7 @@ public: " for (int j=0; j<4; j++) { \n" " addend *= step(0.0, vBaryCoords[j] + dot(vec2(dBCdx[j], dBCdy[j]), bias[i])); \n" " } \n" - " cvg += addend; \n" + " cvg += addend; \n" "} \n" ; } @@ -3019,13 +3019,13 @@ CombinerProgramBuilder::CombinerProgramBuilder(const opengl::GLInfo & _glinfo, o , m_shaderCoverage(new ShaderCoverage()) , m_useProgram(_useProgram) , m_combinerOptionsBits(graphics::CombinerProgram::getShaderCombinerOptionsBits()) +, m_useCoverage(_glinfo.coverage && config.generalEmulation.enableCoverage != 0) { m_vertexShaderRect = _createVertexShader(m_vertexHeader.get(), m_vertexRect.get(), m_vertexEnd.get()); m_vertexShaderTriangle = _createVertexShader(m_vertexHeader.get(), m_vertexTriangle.get(), m_vertexEnd.get()); m_vertexShaderTexturedRect = _createVertexShader(m_vertexHeader.get(), m_vertexTexturedRect.get(), m_vertexEnd.get()); m_vertexShaderTexturedTriangle = _createVertexShader(m_vertexHeader.get(), m_vertexTexturedTriangle.get(), m_vertexEnd.get()); m_uniformFactory.reset(new CombinerProgramUniformFactory(_glinfo)); - m_useCoverage = (config.generalEmulation.enableCoverage != 0) && (_glinfo.dual_source_blending || _glinfo.ext_fetch || _glinfo.ext_fetch_arm); } CombinerProgramBuilder::~CombinerProgramBuilder() diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_Utils.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_Utils.cpp index 2dc3e0a1..125e898b 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_Utils.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_Utils.cpp @@ -7,9 +7,14 @@ using namespace glsl; void Utils::locateAttributes(GLuint _program, bool _rect, bool _textures) { + static GLint maxVertexAttribs = 0; + if (maxVertexAttribs == 0) + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + if (_rect) { glBindAttribLocation(_program, opengl::rectAttrib::position, "aRectPosition"); - glBindAttribLocation(_program, opengl::rectAttrib::barycoords, "aBaryCoords"); + if (opengl::rectAttrib::barycoords < static_cast(maxVertexAttribs)) + glBindAttribLocation(_program, opengl::rectAttrib::barycoords, "aBaryCoords"); if (_textures) { glBindAttribLocation(_program, opengl::rectAttrib::texcoord0, "aTexCoord0"); glBindAttribLocation(_program, opengl::rectAttrib::texcoord1, "aTexCoord1"); @@ -21,7 +26,8 @@ void Utils::locateAttributes(GLuint _program, bool _rect, bool _textures) glBindAttribLocation(_program, opengl::triangleAttrib::color, "aColor"); glBindAttribLocation(_program, opengl::triangleAttrib::numlights, "aNumLights"); glBindAttribLocation(_program, opengl::triangleAttrib::modify, "aModify"); - glBindAttribLocation(_program, opengl::triangleAttrib::barycoords, "aBaryCoords"); + if (opengl::triangleAttrib::barycoords < static_cast(maxVertexAttribs)) + glBindAttribLocation(_program, opengl::triangleAttrib::barycoords, "aBaryCoords"); if (_textures) glBindAttribLocation(_program, opengl::triangleAttrib::texcoord, "aTexCoord"); } diff --git a/src/Graphics/OpenGLContext/opengl_Attributes.cpp b/src/Graphics/OpenGLContext/opengl_Attributes.cpp index 71d8cb73..d209efd5 100644 --- a/src/Graphics/OpenGLContext/opengl_Attributes.cpp +++ b/src/Graphics/OpenGLContext/opengl_Attributes.cpp @@ -8,14 +8,14 @@ namespace opengl { const GLuint texcoord = 2U; const GLuint numlights = 3U; const GLuint modify = 4U; - const GLuint barycoords = 5U; + const GLuint barycoords = 8U; } // Rect attributes namespace rectAttrib { - const GLuint position = 6U; - const GLuint texcoord0 = 7U; - const GLuint texcoord1 = 8U; + const GLuint position = 5U; + const GLuint texcoord0 = 6U; + const GLuint texcoord1 = 7U; const GLuint barycoords = 9U; } } diff --git a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp index b6feb234..bf781a26 100644 --- a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp +++ b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp @@ -33,7 +33,8 @@ BufferedDrawer::BufferedDrawer(const GLInfo & _glinfo, CachedVertexAttribArray * glVertexAttribPointer(rectAttrib::position, 4, GL_FLOAT, GL_FALSE, sizeof(RectVertex), (const GLvoid *)(offsetof(RectVertex, x))); glVertexAttribPointer(rectAttrib::texcoord0, 2, GL_FLOAT, GL_FALSE, sizeof(RectVertex), (const GLvoid *)(offsetof(RectVertex, s0))); glVertexAttribPointer(rectAttrib::texcoord1, 2, GL_FLOAT, GL_FALSE, sizeof(RectVertex), (const GLvoid *)(offsetof(RectVertex, s1))); - glVertexAttribPointer(rectAttrib::barycoords, 2, GL_FLOAT, GL_FALSE, sizeof(RectVertex), (const GLvoid *)(offsetof(RectVertex, bc0))); + if (_glinfo.coverage) + glVertexAttribPointer(rectAttrib::barycoords, 2, GL_FLOAT, GL_FALSE, sizeof(RectVertex), (const GLvoid *)(offsetof(RectVertex, bc0))); /* Init buffers for triangles */ glGenVertexArrays(1, &m_trisBuffers.vao); @@ -45,12 +46,14 @@ BufferedDrawer::BufferedDrawer(const GLInfo & _glinfo, CachedVertexAttribArray * m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::texcoord, true); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::modify, true); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::numlights, false); - m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, true); glVertexAttribPointer(triangleAttrib::position, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)(offsetof(Vertex, x))); glVertexAttribPointer(triangleAttrib::color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)(offsetof(Vertex, r))); glVertexAttribPointer(triangleAttrib::texcoord, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)(offsetof(Vertex, s))); glVertexAttribPointer(triangleAttrib::modify, 4, GL_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid *)(offsetof(Vertex, modify))); - glVertexAttribPointer(triangleAttrib::barycoords, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, bc0))); + if (_glinfo.coverage) { + m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, true); + glVertexAttribPointer(triangleAttrib::barycoords, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(offsetof(Vertex, bc0))); + } } void BufferedDrawer::_initBuffer(Buffer & _buffer, GLuint _bufSize) diff --git a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.h b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.h index e3288676..0255325b 100644 --- a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.h +++ b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.h @@ -57,8 +57,8 @@ namespace opengl { f32 x, y, z, w; f32 r, g, b, a; f32 s, t; - u32 modify; f32 bc0, bc1; + u32 modify; }; void _initBuffer(Buffer & _buffer, GLuint _bufSize); diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp index 3d74c928..af9fa3dd 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp @@ -96,7 +96,7 @@ void GLInfo::init() { fragment_interlock = Utils::isExtensionSupported(*this, "GL_ARB_fragment_shader_interlock") && !hasBuggyFragmentShaderInterlock; fragment_interlockNV = Utils::isExtensionSupported(*this, "GL_NV_fragment_shader_interlock") && !fragment_interlock && !hasBuggyFragmentShaderInterlock; fragment_ordering = Utils::isExtensionSupported(*this, "GL_INTEL_fragment_shader_ordering") && !fragment_interlock && !fragment_interlockNV; - + const bool imageTexturesInterlock = imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering); if (isGLES2) { @@ -198,6 +198,13 @@ void GLInfo::init() { } } + coverage = dual_source_blending || ext_fetch || ext_fetch_arm; + if (coverage) { + GLint maxVertexAttribs = 0; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + coverage = maxVertexAttribs >= 10; + } + #ifdef EGL if (isGLESX) { diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.h b/src/Graphics/OpenGLContext/opengl_GLInfo.h index 535ce47d..03ac6b96 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.h +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.h @@ -38,6 +38,7 @@ struct GLInfo { bool eglImage = false; bool eglImageFramebuffer = false; bool dual_source_blending = false; + bool coverage = false; Renderer renderer = Renderer::Other; void init(); diff --git a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp index 708c4a81..3c546b32 100644 --- a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp +++ b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp @@ -9,18 +9,22 @@ using namespace opengl; UnbufferedDrawer::UnbufferedDrawer(const GLInfo & _glinfo, CachedVertexAttribArray * _cachedAttribArray) : m_glInfo(_glinfo) , m_cachedAttribArray(_cachedAttribArray) +, m_useCoverage(_glinfo.coverage) { m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::position, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::color, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::texcoord, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::numlights, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::modify, false); - m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::position, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord0, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord1, false); - m_cachedAttribArray->enableVertexAttribArray(rectAttrib::barycoords, false); + + if (m_useCoverage) { + m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); + m_cachedAttribArray->enableVertexAttribArray(rectAttrib::barycoords, false); + } m_attribsData.fill(nullptr); } @@ -71,7 +75,7 @@ void UnbufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParame glVertexAttribPointer(triangleAttrib::modify, 4, GL_BYTE, GL_FALSE, sizeof(SPVertex), ptr); } - { + if (m_useCoverage) { m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, true); const void * ptr = &_params.vertices->bc0; if (_updateAttribPointer(triangleAttrib::barycoords, ptr)) @@ -84,7 +88,8 @@ void UnbufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParame m_cachedAttribArray->enableVertexAttribArray(rectAttrib::position, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord0, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord1, false); - m_cachedAttribArray->enableVertexAttribArray(rectAttrib::barycoords, false); + if (m_useCoverage) + m_cachedAttribArray->enableVertexAttribArray(rectAttrib::barycoords, false); if (config.frameBufferEmulation.N64DepthCompare != Config::dcCompatible) { if (_params.elements == nullptr) { @@ -143,7 +148,7 @@ void UnbufferedDrawer::drawRects(const graphics::Context::DrawRectParameters & _ } else m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord1, false); - { + if (m_useCoverage) { m_cachedAttribArray->enableVertexAttribArray(rectAttrib::barycoords, true); const void * ptr = &_params.vertices->bc0; if (_updateAttribPointer(rectAttrib::barycoords, ptr)) @@ -154,7 +159,8 @@ void UnbufferedDrawer::drawRects(const graphics::Context::DrawRectParameters & _ m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::color, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::texcoord, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::modify, false); - m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); + if (m_useCoverage) + m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); glDrawArrays(GLenum(_params.mode), 0, _params.verticesCount); } @@ -177,7 +183,8 @@ void UnbufferedDrawer::drawLine(f32 _width, SPVertex * _vertices) m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::texcoord, false); m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::modify, false); - m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); + if (m_useCoverage) + m_cachedAttribArray->enableVertexAttribArray(triangleAttrib::barycoords, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::position, false); m_cachedAttribArray->enableVertexAttribArray(rectAttrib::texcoord0, false); diff --git a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.h b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.h index c2b7c2cc..547cb834 100644 --- a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.h +++ b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.h @@ -24,6 +24,7 @@ namespace opengl { const GLInfo & m_glInfo; CachedVertexAttribArray * m_cachedAttribArray; std::array m_attribsData; + bool m_useCoverage = false; }; }