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 ae7ebcf0b2..7e7aa9039b 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -44,6 +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_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 74a05a5a75..ebfe4a1944 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -176,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