Browse Source

Don't use persistently mapped buffers on Intel Ivy Bridge GPUs on Windows. glClientWaitSync can hang with those drivers, apparently.

Alex Szpakowski 7 years ago
parent
commit
3857d09132

+ 9 - 0
src/modules/graphics/opengl/OpenGL.cpp

@@ -147,6 +147,15 @@ bool OpenGL::initContext()
 	}
 #endif
 
+#ifdef LOVE_WINDOWS
+	if (getVendor() == VENDOR_INTEL && gl.isCoreProfile())
+	{
+		const char *device = (const char *) glGetString(GL_RENDERER);
+		if (strstr(device, "HD Graphics 4000") || strstr(device, "HD Graphics 2500"))
+			bugs.clientWaitSyncStalls = true;
+	}
+#endif
+
 	contextInitialized = true;
 
 	return true;

+ 7 - 0
src/modules/graphics/opengl/OpenGL.h

@@ -152,6 +152,13 @@ public:
 		 **/
 		bool generateMipmapsRequiresTexture2DEnable;
 
+		/**
+		 * Report: Intel HD 4000 on Windows hangs during glClientWaitSync.
+		 * I found this when googling the issue:
+		 * https://github.com/mjn33/planetgen/commit/235e23873a22e219fffdd9ede706c1051aa0f107
+		 **/
+		bool clientWaitSyncStalls;
+
 		/**
 		 * Other bugs which have workarounds that don't use conditional code at
 		 * the moment:

+ 11 - 8
src/modules/graphics/opengl/StreamBuffer.cpp

@@ -538,14 +538,17 @@ love::graphics::StreamBuffer *CreateStreamBuffer(BufferType mode, size_t size)
 {
 	if (gl.isCoreProfile())
 	{
-		// AMD's pinned memory seems to be faster than persistent mapping, on
-		// AMD GPUs.
-		if (GLAD_AMD_pinned_memory)
-			return new StreamBufferPinnedMemory(mode, size);
-		else if (GLAD_VERSION_4_4 || GLAD_ARB_buffer_storage)
-			return new StreamBufferPersistentMapSync(mode, size);
-		else
-			return new StreamBufferSubDataOrphan(mode, size);
+		if (!gl.bugs.clientWaitSyncStalls)
+		{
+			// AMD's pinned memory seems to be faster than persistent mapping,
+			// on AMD GPUs.
+			if (GLAD_AMD_pinned_memory)
+				return new StreamBufferPinnedMemory(mode, size);
+			else if (GLAD_VERSION_4_4 || GLAD_ARB_buffer_storage)
+				return new StreamBufferPersistentMapSync(mode, size);
+		}
+
+		return new StreamBufferSubDataOrphan(mode, size);
 	}
 	else
 		return new StreamBufferClientMemory(mode, size);