Replace internal 'staging' buffer data type with new 'readback' type.

This commit is contained in:
Alex Szpakowski
2022-05-30 21:43:25 -03:00
parent 7b66e50cfc
commit a533982cb4
10 changed files with 97 additions and 46 deletions
+35 -8
View File
@@ -103,7 +103,7 @@ Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const st
if (!load(data))
{
unloadVolatile();
throw love::Exception("Could not create buffer (out of VRAM?)");
throw love::Exception("Could not create buffer with %d bytes (out of VRAM?)", size);
}
}
@@ -164,11 +164,17 @@ 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 || isImmutable())
if (size == 0)
return nullptr;
if (map == MAP_WRITE_INVALIDATE && (isImmutable() || dataUsage == BUFFERDATAUSAGE_READBACK))
return nullptr;
if (map == MAP_READ_ONLY && dataUsage != BUFFERDATAUSAGE_READBACK)
return nullptr;
Range r(offset, size);
if (!Range(0, getSize()).contains(r))
@@ -176,7 +182,16 @@ void *Buffer::map(MapType /*map*/, size_t offset, size_t size)
char *data = nullptr;
if (ownsMemoryMap)
if (map == MAP_READ_ONLY)
{
gl.bindBuffer(mapUsage, buffer);
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
else if (GLAD_VERSION_1_1)
data = (char *) glMapBuffer(target, GL_READ_ONLY) + offset;
}
else if (ownsMemoryMap)
{
if (memoryMap == nullptr)
memoryMap = (char *) malloc(getSize());
@@ -191,6 +206,7 @@ void *Buffer::map(MapType /*map*/, size_t offset, size_t size)
if (data != nullptr)
{
mapped = true;
mappedType = map;
mappedRange = r;
if (!ownsMemoryMap)
memoryMap = data;
@@ -208,6 +224,15 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
mapped = false;
if (mappedType == MAP_READ_ONLY)
{
gl.bindBuffer(mapUsage, buffer);
glUnmapBuffer(target);
if (!ownsMemoryMap)
memoryMap = nullptr;
return;
}
// Orphan optimization - see fill().
if (supportsOrphan() && mappedRange.first == 0 && mappedRange.getSize() == getSize())
{
@@ -227,15 +252,15 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize)
}
}
void Buffer::fill(size_t offset, size_t size, const void *data)
bool Buffer::fill(size_t offset, size_t size, const void *data)
{
if (size == 0 || isImmutable())
return;
if (size == 0 || isImmutable() || dataUsage == BUFFERDATAUSAGE_READBACK)
return false;
size_t buffersize = getSize();
if (!Range(0, buffersize).contains(Range(offset, size)))
return;
return false;
GLenum gldatausage = OpenGL::getGLBufferDataUsage(dataUsage);
@@ -259,6 +284,8 @@ void Buffer::fill(size_t offset, size_t size, const void *data)
{
glBufferSubData(target, (GLintptr) offset, (GLsizeiptr) size, data);
}
return true;
}
void Buffer::copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
+3 -1
View File
@@ -52,12 +52,14 @@ public:
void *map(MapType map, size_t offset, size_t size) override;
void unmap(size_t usedoffset, size_t usedsize) override;
void fill(size_t offset, size_t size, const void *data) override;
bool fill(size_t offset, size_t size, const void *data) override;
void copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size) override;
ptrdiff_t getHandle() const override { return buffer; };
ptrdiff_t getTexelBufferHandle() const override { return texture; };
BufferUsage getMapUsage() const { return mapUsage; }
private:
bool load(const void *initialdata);
+1 -1
View File
@@ -843,7 +843,7 @@ GLenum OpenGL::getGLBufferDataUsage(BufferDataUsage usage)
case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
case BUFFERDATAUSAGE_STAGING:
case BUFFERDATAUSAGE_READBACK:
return (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) ? GL_STREAM_READ : GL_STREAM_DRAW;
default: return 0;
}