Browse Source

Add 'staging' buffer data usage enum.

Alex Szpakowski 3 years ago
parent
commit
bfcf025ef7

+ 3 - 0
src/modules/graphics/Buffer.cpp

@@ -60,6 +60,9 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
 	if (storagebuffer && dataUsage == BUFFERDATAUSAGE_STREAM)
 	if (storagebuffer && dataUsage == BUFFERDATAUSAGE_STREAM)
 		throw love::Exception("Buffers created with 'stream' data usage cannot be used as a shader storage buffer.");
 		throw love::Exception("Buffers created with 'stream' data usage cannot be used as a shader storage buffer.");
 
 
+	if (dataUsage == BUFFERDATAUSAGE_STAGING && (indexbuffer || vertexbuffer || texelbuffer || storagebuffer))
+		throw love::Exception("Buffers created with 'staging' data usage cannot be index, vertex, texel, or shaderstorage buffer types.");
+
 	size_t offset = 0;
 	size_t offset = 0;
 	size_t stride = 0;
 	size_t stride = 0;
 	size_t structurealignment = 1;
 	size_t structurealignment = 1;

+ 8 - 4
src/modules/graphics/opengl/Buffer.cpp

@@ -157,6 +157,11 @@ bool Buffer::load(const void *initialdata)
 	return (glGetError() == GL_NO_ERROR);
 	return (glGetError() == GL_NO_ERROR);
 }
 }
 
 
+bool Buffer::supportsOrphan() const
+{
+	return dataUsage == BUFFERDATAUSAGE_STREAM || dataUsage == BUFFERDATAUSAGE_DYNAMIC;
+}
+
 void *Buffer::map(MapType /*map*/, size_t offset, size_t size)
 void *Buffer::map(MapType /*map*/, size_t offset, size_t size)
 {
 {
 	if (size == 0)
 	if (size == 0)
@@ -202,7 +207,7 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
 	mapped = false;
 	mapped = false;
 
 
 	// Orphan optimization - see fill().
 	// Orphan optimization - see fill().
-	if (dataUsage != BUFFERDATAUSAGE_STATIC && mappedRange.first == 0 && mappedRange.getSize() == getSize())
+	if (supportsOrphan() && mappedRange.first == 0 && mappedRange.getSize() == getSize())
 	{
 	{
 		usedoffset = 0;
 		usedoffset = 0;
 		usedsize = getSize();
 		usedsize = getSize();
@@ -234,15 +239,14 @@ void Buffer::fill(size_t offset, size_t size, const void *data)
 
 
 	gl.bindBuffer(mapUsage, buffer);
 	gl.bindBuffer(mapUsage, buffer);
 
 
-	if (dataUsage != BUFFERDATAUSAGE_STATIC && size == buffersize)
+	if (supportsOrphan() && size == buffersize)
 	{
 	{
 		// "orphan" current buffer to avoid implicit synchronisation on the GPU:
 		// "orphan" current buffer to avoid implicit synchronisation on the GPU:
 		// http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf
 		// http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf
-		gl.bindBuffer(mapUsage, buffer);
 		glBufferData(target, (GLsizeiptr) buffersize, nullptr, gldatausage);
 		glBufferData(target, (GLsizeiptr) buffersize, nullptr, gldatausage);
 
 
 #if LOVE_WINDOWS
 #if LOVE_WINDOWS
-		// TODO: Verify that this codepath is a useful optimization.
+		// TODO: Verify that this intel codepath is a useful optimization.
 		if (gl.getVendor() == OpenGL::VENDOR_INTEL)
 		if (gl.getVendor() == OpenGL::VENDOR_INTEL)
 			glBufferData(target, (GLsizeiptr) buffersize, data, gldatausage);
 			glBufferData(target, (GLsizeiptr) buffersize, data, gldatausage);
 		else
 		else

+ 1 - 3
src/modules/graphics/opengl/Buffer.h

@@ -61,9 +61,7 @@ public:
 private:
 private:
 
 
 	bool load(const void *initialdata);
 	bool load(const void *initialdata);
-
-	void unmapStatic(size_t offset, size_t size);
-	void unmapStream();
+	bool supportsOrphan() const;
 
 
 	BufferUsage mapUsage = BUFFERUSAGE_VERTEX;
 	BufferUsage mapUsage = BUFFERUSAGE_VERTEX;
 	GLenum target = 0;
 	GLenum target = 0;

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

@@ -842,6 +842,8 @@ GLenum OpenGL::getGLBufferDataUsage(BufferDataUsage usage)
 		case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
 		case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
 		case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
 		case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
 		case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
 		case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
+		case BUFFERDATAUSAGE_STAGING:
+			return (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) ? GL_STREAM_READ : GL_STREAM_DRAW;
 		default: return 0;
 		default: return 0;
 	}
 	}
 }
 }

+ 1 - 0
src/modules/graphics/vertex.cpp

@@ -358,6 +358,7 @@ STRINGMAP_BEGIN(BufferDataUsage, BUFFERDATAUSAGE_MAX_ENUM, bufferDataUsage)
 	{ "stream",  BUFFERDATAUSAGE_STREAM  },
 	{ "stream",  BUFFERDATAUSAGE_STREAM  },
 	{ "dynamic", BUFFERDATAUSAGE_DYNAMIC },
 	{ "dynamic", BUFFERDATAUSAGE_DYNAMIC },
 	{ "static",  BUFFERDATAUSAGE_STATIC  },
 	{ "static",  BUFFERDATAUSAGE_STATIC  },
+	{ "staging", BUFFERDATAUSAGE_STAGING },
 }
 }
 STRINGMAP_END(BufferDataUsage, BUFFERDATAUSAGE_MAX_ENUM, bufferDataUsage)
 STRINGMAP_END(BufferDataUsage, BUFFERDATAUSAGE_MAX_ENUM, bufferDataUsage)
 
 

+ 1 - 0
src/modules/graphics/vertex.h

@@ -110,6 +110,7 @@ enum BufferDataUsage
 	BUFFERDATAUSAGE_STREAM,
 	BUFFERDATAUSAGE_STREAM,
 	BUFFERDATAUSAGE_DYNAMIC,
 	BUFFERDATAUSAGE_DYNAMIC,
 	BUFFERDATAUSAGE_STATIC,
 	BUFFERDATAUSAGE_STATIC,
+	BUFFERDATAUSAGE_STAGING,
 	BUFFERDATAUSAGE_MAX_ENUM
 	BUFFERDATAUSAGE_MAX_ENUM
 };
 };