diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 1bf8b8e10e..fc28a3118f 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -455,7 +455,7 @@ Renderer::Renderer() g_ogl_config.bSupportsGLSLCache = true; g_ogl_config.bSupportsGLSync = true; - if (strstr(g_ogl_config.glsl_version, "3.0") || DriverDetails::HasBug(DriverDetails::BUG_BROKENGLES31)) + if (strstr(g_ogl_config.glsl_version, "3.0")) { g_ogl_config.eSupportedGLSLVersion = GLSLES_300; g_ogl_config.bSupportsAEP = false; diff --git a/Source/Core/VideoBackends/OGL/StreamBuffer.cpp b/Source/Core/VideoBackends/OGL/StreamBuffer.cpp index 5268423d72..b616720ae2 100644 --- a/Source/Core/VideoBackends/OGL/StreamBuffer.cpp +++ b/Source/Core/VideoBackends/OGL/StreamBuffer.cpp @@ -210,7 +210,7 @@ public: class BufferStorage : public StreamBuffer { public: - BufferStorage(u32 type, u32 size) : StreamBuffer(type, size) + BufferStorage(u32 type, u32 size, bool _coherent = false) : StreamBuffer(type, size), coherent(_coherent) { CreateFences(); glBindBuffer(m_buffertype, m_buffer); @@ -219,9 +219,9 @@ public: // COHERENT_BIT is set so we don't have to use a MemoryBarrier on write // CLIENT_STORAGE_BIT is set since we access the buffer more frequently on the client side then server side glBufferStorage(m_buffertype, m_size, nullptr, - GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : 0)); m_pointer = (u8*)glMapBufferRange(m_buffertype, 0, m_size, - GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); + GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT)); } ~BufferStorage() @@ -239,11 +239,13 @@ public: void Unmap(u32 used_size) override { - glFlushMappedBufferRange(m_buffertype, m_iterator, used_size); + if (!coherent) + glFlushMappedBufferRange(m_buffertype, m_iterator, used_size); m_iterator += used_size; } u8* m_pointer; + const bool coherent; }; /* --- AMD only --- @@ -377,10 +379,11 @@ std::unique_ptr StreamBuffer::Create(u32 type, u32 size) return std::make_unique(type, size); // buffer storage works well in most situations + bool coherent = DriverDetails::HasBug(DriverDetails::BUG_BROKENEXPLICITFLUSH); if (g_ogl_config.bSupportsGLBufferStorage && !(DriverDetails::HasBug(DriverDetails::BUG_BROKENBUFFERSTORAGE) && type == GL_ARRAY_BUFFER) && !(DriverDetails::HasBug(DriverDetails::BUG_INTELBROKENBUFFERSTORAGE) && type == GL_ELEMENT_ARRAY_BUFFER)) - return std::make_unique(type, size); + return std::make_unique(type, size, coherent); // don't fall back to MapAnd* for Nvidia drivers if (DriverDetails::HasBug(DriverDetails::BUG_BROKENUNSYNCMAPPING)) diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 4a88180fe4..7e7aa9039b 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -44,8 +44,7 @@ namespace DriverDetails static BugInfo m_known_bugs[] = { {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0, true}, {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENNEGATEDBOOLEAN,-1.0, -1.0, true}, - {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENGLES31, -1.0, -1.0, true}, - {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENALPHATEST, -1.0, -1.0, true}, + {OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN, BUG_BROKENEXPLICITFLUSH, -1.0, -1.0, true}, {OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0, true}, {OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKENVSYNC, -1.0, -1.0, true}, {OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN, BUG_BROKENBUFFERSTREAM, -1.0, -1.0, true}, diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index 2d1a11e456..ebfe4a1944 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -158,14 +158,6 @@ namespace DriverDetails // Mesa meta misses to disable the scissor test. BUG_BROKENCOPYIMAGE, - // Bug: Qualcomm has broken OpenGL ES 3.1 support - // Affected devices: Adreno - // Started Version: -1 - // Ended Version: -1 - // This isn't fully researched, but at the very least Qualcomm doesn't implement Geometry shader features fully. - // Until each bug is fully investigated, just disable GLES 3.1 entirely on these devices. - BUG_BROKENGLES31, - // Bug: ARM Mali managed to break disabling vsync // Affected Devices: Mali // Started Version: r5p0-rev2 @@ -177,17 +169,6 @@ namespace DriverDetails // the GL_VERSION string, we will have to force vsync to be enabled at all times. BUG_BROKENVSYNC, - // Bug: Adreno has a broken alpha test - // Affected Devices: Adreno - // Started Version: v103 confirmed (v95 potentially as well?) - // Ended Version: -1 - // The Qualcomm video drivers have somehow managed to hit a situation where in a certain situation the alpha test - // always evaluates to false for some reason. - // This has yet to be tracked as to why they fail at such a simple check - // Example alpha test path - // if(( (prev.a > alphaRef.r) && (prev.a > alphaRef.g)) == false) { - BUG_BROKENALPHATEST, - // Bug: Broken lines in geometry shaders // Affected Devices: Mesa r600/radeonsi, Mesa Sandy Bridge // Started Version: -1 @@ -195,6 +176,14 @@ namespace DriverDetails // Mesa introduced geometry shader support for radeon and sandy bridge devices and failed to test it with us. // Causes misrenderings on a large amount of things that draw lines. BUG_BROKENGEOMETRYSHADERS, + + // Bug: Explicit flush is very slow on Qualcomm + // Started Version: -1 + // Ended Version: -1 + // Our ARB_buffer_storage code uses explicit flush to avoid coherent mapping. + // Qualcomm seems to have lots of overhead on exlicit flushing, but the coherent mapping path is fine. + // So let's use coherent mapping there. + BUG_BROKENEXPLICITFLUSH, }; // Initializes our internal vendor, device family, and driver version