diff --git a/src/Graphics/Context.h b/src/Graphics/Context.h index 13d124a3..ba1729f6 100644 --- a/src/Graphics/Context.h +++ b/src/Graphics/Context.h @@ -81,7 +81,6 @@ namespace graphics { struct InitTextureParams { ObjectHandle handle; - ImageUnitParam ImageUnit; TextureUnitParam textureUnitIndex{0}; u32 msaaLevel = 0; u32 width = 0; @@ -98,7 +97,6 @@ namespace graphics { struct UpdateTextureDataParams { ObjectHandle handle; - ImageUnitParam ImageUnit; TextureUnitParam textureUnitIndex{0}; u32 x = 0; u32 y = 0; diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp index 0ba8d2e6..6f2d1759 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp @@ -229,8 +229,10 @@ public: std::stringstream ss; ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 es " << std::endl; ss << "# define IN in" << std::endl << "# define OUT out" << std::endl; - if (_glinfo.noPerspective) - ss << "noperspective OUT highp float vZCoord;" << std::endl << "uniform lowp int uClampMode;" << std::endl; + if (_glinfo.noPerspective) { + ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl + << "noperspective OUT highp float vZCoord;" << std::endl << "uniform lowp int uClampMode;" << std::endl; + } m_part = ss.str(); } else { @@ -455,6 +457,13 @@ public: } else if (_glinfo.isGLESX) { std::stringstream ss; ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 es " << std::endl; + if (_glinfo.noPerspective) + ss << "#extension GL_NV_shader_noperspective_interpolation : enable" << std::endl; + if (config.frameBufferEmulation.N64DepthCompare != 0) { + if (_glinfo.fragment_interlockNV) + ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl + << "layout(pixel_interlock_ordered) in;" << std::endl; + } ss << "# define IN in" << std::endl << "# define OUT out" << std::endl << "# define texture2D texture" << std::endl; @@ -462,9 +471,19 @@ public: } else { std::stringstream ss; ss << "#version " << Utils::to_string(_glinfo.majorVersion) << Utils::to_string(_glinfo.minorVersion) << "0 core " << std::endl; - if (_glinfo.imageTextures && _glinfo.majorVersion * 10 + _glinfo.minorVersion < 42) { - ss << "#extension GL_ARB_shader_image_load_store : enable" << std::endl - << "#extension GL_ARB_shading_language_420pack : enable" << std::endl; + if (config.frameBufferEmulation.N64DepthCompare != 0) { + if (_glinfo.majorVersion * 10 + _glinfo.minorVersion < 42) { + ss << "#extension GL_ARB_shader_image_load_store : enable" << std::endl + << "#extension GL_ARB_shading_language_420pack : enable" << std::endl; + } + if (_glinfo.fragment_interlock) + ss << "#extension GL_ARB_fragment_shader_interlock : enable" << std::endl + << "layout(pixel_interlock_ordered) in;" << std::endl; + else if (_glinfo.fragment_interlockNV) + ss << "#extension GL_NV_fragment_shader_interlock : enable" << std::endl + << "layout(pixel_interlock_ordered) in;" << std::endl; + else if (_glinfo.fragment_ordering) + ss << "#extension GL_INTEL_fragment_shader_ordering : enable" << std::endl; } ss << "# define IN in" << std::endl << "# define OUT out" << std::endl @@ -938,8 +957,8 @@ public: if (config.frameBufferEmulation.N64DepthCompare != 0) { m_part += - "layout(binding = 2, r32f) highp uniform coherent image2D uDepthImageZ; \n" - "layout(binding = 3, r32f) highp uniform coherent image2D uDepthImageDeltaZ;\n" + "layout(binding = 2, r32f) highp uniform restrict image2D uDepthImageZ; \n" + "layout(binding = 3, r32f) highp uniform restrict image2D uDepthImageDeltaZ;\n" "bool depth_compare(highp float curZ);\n" "bool depth_render(highp float Z, highp float curZ);\n"; ; @@ -1312,10 +1331,27 @@ public: ShaderFragmentCallN64Depth(const opengl::GLInfo & _glinfo) { if (config.frameBufferEmulation.N64DepthCompare != 0) { - m_part = - " if (uRenderTarget != 0) { if (!depth_render(fragColor.r, fragDepth)) discard; } \n" - " else if (!depth_compare(fragDepth)) discard; \n" - ; + m_part = " bool should_discard = false; \n"; + + if (_glinfo.fragment_interlock) + m_part += " beginInvocationInterlockARB(); \n"; + else if (_glinfo.fragment_interlockNV) + m_part += " beginInvocationInterlockNV(); \n"; + else if (_glinfo.fragment_ordering) + m_part += " beginFragmentShaderOrderingINTEL(); \n"; + + m_part += + " if (uRenderTarget != 0) { if (!depth_render(fragColor.r, fragDepth)) should_discard = true; } \n" + " else if (!depth_compare(fragDepth)) should_discard = true; \n" + ; + + if (_glinfo.fragment_interlock) + m_part += " endInvocationInterlockARB(); \n"; + else if (_glinfo.fragment_interlockNV) + m_part += " endInvocationInterlockNV(); \n"; + + m_part += " if (should_discard) discard; \n"; + } } }; @@ -1919,14 +1955,11 @@ public: " imageStore(uDepthImageZ, coord, depthOutZ); \n" " imageStore(uDepthImageDeltaZ, coord, depthOutDeltaZ);\n" " } \n" - " memoryBarrierImage(); \n" " if (uEnableDepthCompare != 0) \n" " return bRes; \n" " return true; \n" "} \n" ; - if (!_glinfo.isGLESX && _glinfo.imageTextures && _glinfo.majorVersion * 10 + _glinfo.minorVersion < 43) - m_part = "#extension GL_ARB_compute_shader : enable \n" + m_part; } } }; @@ -1950,12 +1983,9 @@ public: " highp vec4 depthOutDeltaZ = vec4(0.0, 1.0, 1.0, 1.0);\n" " imageStore(uDepthImageZ,coord, depthOutZ); \n" " imageStore(uDepthImageDeltaZ,coord, depthOutDeltaZ); \n" - " memoryBarrierImage(); \n" " return true; \n" "} \n" ; - if (!_glinfo.isGLESX && _glinfo.imageTextures && _glinfo.majorVersion * 10 + _glinfo.minorVersion < 43) - m_part = "#extension GL_ARB_compute_shader : enable \n" + m_part; } } }; diff --git a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp index 7a0d1eee..5fbab9f0 100644 --- a/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp +++ b/src/Graphics/OpenGLContext/opengl_BufferedDrawer.cpp @@ -203,20 +203,8 @@ void BufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParamete return; } - if (config.frameBufferEmulation.N64DepthCompare == 0) { - glDrawRangeElementsBaseVertex(GLenum(_params.mode), 0, _params.verticesCount - 1, _params.elementsCount, GL_UNSIGNED_SHORT, - (u16*)nullptr + m_trisBuffers.ebo.pos - _params.elementsCount, m_trisBuffers.vbo.pos - _params.verticesCount); - return; - } - - // Draw polygons one by one - const GLint eboStartPos = m_trisBuffers.ebo.pos - _params.elementsCount; - const GLint vboStartPos = m_trisBuffers.vbo.pos - _params.verticesCount; - for (GLuint i = 0; i < _params.elementsCount; i += 3) { - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - glDrawRangeElementsBaseVertex(GLenum(_params.mode), 0, _params.verticesCount - 1, 3, GL_UNSIGNED_SHORT, - (u16*)nullptr + eboStartPos + i, vboStartPos); - } + glDrawRangeElementsBaseVertex(GLenum(_params.mode), 0, _params.verticesCount - 1, _params.elementsCount, GL_UNSIGNED_SHORT, + (u16*)nullptr + m_trisBuffers.ebo.pos - _params.elementsCount, m_trisBuffers.vbo.pos - _params.verticesCount); } void BufferedDrawer::drawLine(f32 _width, SPVertex * _vertices) diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp index 89baffb2..d171bc33 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp @@ -54,10 +54,18 @@ void GLInfo::init() { Utils::isExtensionSupported(*this, "GL_ARB_compute_shader"))) && IS_GL_FUNCTION_VALID(glBindImageTexture); msaa = true; } - if (!imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) { - config.frameBufferEmulation.N64DepthCompare = 0; - LOG(LOG_WARNING, "N64 depth compare will not work without Image Textures support provided in OpenGL >= 4.3 or GLES >= 3.1\n"); + + fragment_interlock = Utils::isExtensionSupported(*this, "GL_ARB_fragment_shader_interlock"); + fragment_interlockNV = Utils::isExtensionSupported(*this, "GL_NV_fragment_shader_interlock") && !fragment_interlock; + fragment_ordering = Utils::isExtensionSupported(*this, "GL_INTEL_fragment_shader_ordering") && !fragment_interlock && !fragment_interlockNV; + + if (config.frameBufferEmulation.N64DepthCompare != 0) { + if (!(imageTextures && (fragment_interlock || fragment_interlockNV || fragment_ordering))) { + config.frameBufferEmulation.N64DepthCompare = 0; + LOG(LOG_WARNING, "Your GPU does not support the extensions needed for N64 Depth Compare.\n"); + } } + if (isGLES2) config.generalEmulation.enableFragmentDepthWrite = 0; diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.h b/src/Graphics/OpenGLContext/opengl_GLInfo.h index df9ddb40..f47f1d04 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.h +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.h @@ -28,6 +28,9 @@ struct GLInfo { bool fetch_depth = false; bool texture_barrier = false; bool texture_barrierNV = false; + bool fragment_interlock = false; + bool fragment_interlockNV = false; + bool fragment_ordering = false; Renderer renderer = Renderer::Other; void init(); diff --git a/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp b/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp index 160cfb5e..7b51721b 100644 --- a/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp +++ b/src/Graphics/OpenGLContext/opengl_TextureManipulationObjectFactory.cpp @@ -98,9 +98,8 @@ namespace opengl { #endif } - Init2DTexStorage(CachedBindTexture* _bind, bool _imageTextures) - : m_bind(_bind) - , m_imageTextures(_imageTextures) {} + Init2DTexStorage(CachedBindTexture* _bind) + : m_bind(_bind) {} void init2DTexture(const graphics::Context::InitTextureParams & _params) override { @@ -125,10 +124,6 @@ namespace opengl { GLenum(_params.dataType), _params.data); } - - if (_params.ImageUnit.isValid() && m_imageTextures) - glBindImageTexture(GLuint(_params.ImageUnit), GLuint(_params.handle), - 0, GL_FALSE, GL_FALSE, GL_READ_ONLY, GLuint(_params.internalFormat)); } else { m_bind->bind(_params.textureUnitIndex, graphics::textureTarget::TEXTURE_2D_MULTISAMPLE, _params.handle); @@ -152,7 +147,6 @@ namespace opengl { private: CachedBindTexture* m_bind; - bool m_imageTextures; graphics::ObjectHandle m_handle; }; @@ -189,11 +183,6 @@ namespace opengl { GLenum(_params.dataType), _params.data); } - - if (_params.ImageUnit.isValid()) { - glBindImageTexture(GLuint(_params.ImageUnit), GLuint(_params.handle), - 0, GL_FALSE, GL_FALSE, GL_READ_ONLY, GLuint(_params.internalFormat)); - } } else { glTexStorage2DMultisample(GLuint(_params.handle), @@ -220,9 +209,8 @@ namespace opengl { class Update2DTexSubImage : public Update2DTexture { public: - Update2DTexSubImage(CachedBindTexture* _bind, bool _imageTextures) - : m_bind(_bind) - , m_imageTextures(_imageTextures) {} + Update2DTexSubImage(CachedBindTexture* _bind) + : m_bind(_bind) {} void update2DTexture(const graphics::Context::UpdateTextureDataParams & _params) override { @@ -237,15 +225,10 @@ namespace opengl { GLuint(_params.format), GLenum(_params.dataType), _params.data); - - if (_params.ImageUnit.isValid() && _params.internalFormat.isValid() && m_imageTextures) - glBindImageTexture(GLuint(_params.ImageUnit), GLuint(_params.handle), - 0, GL_FALSE, GL_FALSE, GL_READ_ONLY, GLuint(_params.internalFormat)); } private: CachedBindTexture* m_bind; - bool m_imageTextures; }; class Update2DTextureSubImage : public Update2DTexture @@ -270,11 +253,6 @@ namespace opengl { GLuint(_params.format), GLenum(_params.dataType), _params.data); - - if (_params.ImageUnit.isValid() && _params.internalFormat.isValid()) { - glBindImageTexture(GLuint(_params.ImageUnit), GLuint(_params.handle), - 0, GL_FALSE, GL_FALSE, GL_READ_ONLY, GLuint(_params.internalFormat)); - } } }; @@ -399,7 +377,7 @@ namespace opengl { return new Init2DTextureStorage; if (Init2DTexStorage::Check(m_glInfo)) - return new Init2DTexStorage(m_cachedFunctions.getCachedBindTexture(), m_glInfo.imageTextures); + return new Init2DTexStorage(m_cachedFunctions.getCachedBindTexture()); return new Init2DTexImage(m_cachedFunctions.getCachedBindTexture()); } @@ -409,7 +387,7 @@ namespace opengl { if (Update2DTextureSubImage::Check(m_glInfo)) return new Update2DTextureSubImage; - return new Update2DTexSubImage(m_cachedFunctions.getCachedBindTexture(), m_glInfo.imageTextures); + return new Update2DTexSubImage(m_cachedFunctions.getCachedBindTexture()); } Set2DTextureParameters * TextureManipulationObjectFactory::getSet2DTextureParameters() const diff --git a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp index 38764e30..2fae0ac1 100644 --- a/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp +++ b/src/Graphics/OpenGLContext/opengl_UnbufferedDrawer.cpp @@ -81,16 +81,7 @@ void UnbufferedDrawer::drawTriangles(const graphics::Context::DrawTriangleParame return; } - if (config.frameBufferEmulation.N64DepthCompare == 0) { - glDrawElements(GLenum(_params.mode), _params.elementsCount, GL_UNSIGNED_SHORT, _params.elements); - return; - } - - // Draw polygons one by one - for (GLuint i = 0; i < _params.elementsCount; i += 3) { - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); - glDrawElements(GLenum(_params.mode), 3, GL_UNSIGNED_SHORT, (u16*)_params.elements + i); - } + glDrawElements(GLenum(_params.mode), _params.elementsCount, GL_UNSIGNED_SHORT, _params.elements); } void UnbufferedDrawer::drawRects(const graphics::Context::DrawRectParameters & _params) diff --git a/src/Graphics/Parameters.h b/src/Graphics/Parameters.h index 3d070e6b..3410ed71 100644 --- a/src/Graphics/Parameters.h +++ b/src/Graphics/Parameters.h @@ -74,8 +74,6 @@ namespace graphics { } namespace textureImageUnits { - extern ImageUnitParam Zlut; - extern ImageUnitParam Tlut; extern ImageUnitParam DepthZ; extern ImageUnitParam DepthDeltaZ; }