diff options
Diffstat (limited to 'src/libGLESv2')
-rw-r--r-- | src/libGLESv2/Buffer.cpp | 55 | ||||
-rw-r--r-- | src/libGLESv2/Buffer.h | 14 | ||||
-rw-r--r-- | src/libGLESv2/libGLESv2.cpp | 46 | ||||
-rw-r--r-- | src/libGLESv2/renderer/BufferImpl.h | 10 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp | 157 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d11/Buffer11.h | 10 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp | 32 | ||||
-rw-r--r-- | src/libGLESv2/renderer/d3d/d3d9/Buffer9.h | 10 |
8 files changed, 214 insertions, 120 deletions
diff --git a/src/libGLESv2/Buffer.cpp b/src/libGLESv2/Buffer.cpp index c4fbe2b3..3b2a1a91 100644 --- a/src/libGLESv2/Buffer.cpp +++ b/src/libGLESv2/Buffer.cpp @@ -33,35 +33,60 @@ Buffer::~Buffer() SafeDelete(mBuffer); } -void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) +Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) { + gl::Error error = mBuffer->setData(data, size, usage); + if (error.isError()) + { + return error; + } + mIndexRangeCache.clear(); mUsage = usage; mSize = size; - mBuffer->setData(data, size, usage); + + return error; } -void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) +Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) { + gl::Error error = mBuffer->setSubData(data, size, offset); + if (error.isError()) + { + return error; + } + mIndexRangeCache.invalidateRange(offset, size); - mBuffer->setSubData(data, size, offset); + + return error; } -void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { + gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size); + if (error.isError()) + { + return error; + } + mIndexRangeCache.invalidateRange(destOffset, size); - mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size); + + return error; } -GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) +Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) { ASSERT(!mMapped); ASSERT(offset + length <= mSize); - void *dataPointer = mBuffer->map(offset, length, access); + Error error = mBuffer->map(offset, length, access, &mMapPointer); + if (error.isError()) + { + mMapPointer = NULL; + return error; + } mMapped = GL_TRUE; - mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer)); mMapOffset = static_cast<GLint64>(offset); mMapLength = static_cast<GLint64>(length); mAccessFlags = static_cast<GLint>(access); @@ -71,20 +96,26 @@ GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) mIndexRangeCache.invalidateRange(offset, length); } - return mMapPointer; + return error; } -void Buffer::unmap() +Error Buffer::unmap() { ASSERT(mMapped); - mBuffer->unmap(); + Error error = mBuffer->unmap(); + if (error.isError()) + { + return error; + } mMapped = GL_FALSE; mMapPointer = NULL; mMapOffset = 0; mMapLength = 0; mAccessFlags = 0; + + return error; } void Buffer::markTransformFeedbackUsage() diff --git a/src/libGLESv2/Buffer.h b/src/libGLESv2/Buffer.h index c39d7d7b..35a67675 100644 --- a/src/libGLESv2/Buffer.h +++ b/src/libGLESv2/Buffer.h @@ -11,6 +11,8 @@ #ifndef LIBGLESV2_BUFFER_H_ #define LIBGLESV2_BUFFER_H_ +#include "libGLESv2/Error.h" + #include "common/angleutils.h" #include "common/RefCountObject.h" #include "libGLESv2/renderer/IndexRangeCache.h" @@ -31,13 +33,13 @@ class Buffer : public RefCountObject virtual ~Buffer(); - void bufferData(const void *data, GLsizeiptr size, GLenum usage); - void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); - void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); - void unmap(); + Error bufferData(const void *data, GLsizeiptr size, GLenum usage); + Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); + Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); + Error unmap(); - GLenum getUsage() const { return mUsage; } + GLenum getUsage() const { return mUsage; } GLint getAccessFlags() const { return mAccessFlags; } GLboolean isMapped() const { return mMapped; } GLvoid *getMapPointer() const { return mMapPointer; } diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp index 62f98d8a..e0443da7 100644 --- a/src/libGLESv2/libGLESv2.cpp +++ b/src/libGLESv2/libGLESv2.cpp @@ -542,7 +542,12 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, return; } - buffer->bufferData(data, size, usage); + gl::Error error = buffer->bufferData(data, size, usage); + if (error.isError()) + { + context->recordError(error); + return; + } } } @@ -598,7 +603,12 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, return; } - buffer->bufferSubData(data, size, offset); + gl::Error error = buffer->bufferSubData(data, size, offset); + if (error.isError()) + { + context->recordError(error); + return; + } } } @@ -6780,7 +6790,12 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp // if size is zero, the copy is a successful no-op if (size > 0) { - writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size); + gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size); + if (error.isError()) + { + context->recordError(error); + return; + } } } } @@ -8379,7 +8394,14 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access) return NULL; } - return buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT); + gl::Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT); + if (error.isError()) + { + context->recordError(error); + return NULL; + } + + return buffer->getMapPointer(); } return NULL; @@ -8408,7 +8430,12 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target) // TODO: detect if we had corruption. if so, throw an error and return false. - buffer->unmap(); + gl::Error error = buffer->unmap(); + if (error.isError()) + { + context->recordError(error); + return GL_FALSE; + } return GL_TRUE; } @@ -8498,7 +8525,14 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr return NULL; } - return buffer->mapRange(offset, length, access); + gl::Error error = buffer->mapRange(offset, length, access); + if (error.isError()) + { + context->recordError(error); + return NULL; + } + + return buffer->getMapPointer(); } return NULL; diff --git a/src/libGLESv2/renderer/BufferImpl.h b/src/libGLESv2/renderer/BufferImpl.h index bea689b9..f0b5f022 100644 --- a/src/libGLESv2/renderer/BufferImpl.h +++ b/src/libGLESv2/renderer/BufferImpl.h @@ -20,12 +20,12 @@ class BufferImpl public: virtual ~BufferImpl() { } - virtual void setData(const void* data, size_t size, GLenum usage) = 0; + virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; virtual void *getData() = 0; - virtual void setSubData(const void* data, size_t size, size_t offset) = 0; - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access) = 0; - virtual void unmap() = 0; + virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0; + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; + virtual gl::Error unmap() = 0; virtual void markTransformFeedbackUsage() = 0; }; diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp index b84e77c3..08e9c338 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.cpp @@ -181,7 +181,7 @@ Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer) return static_cast<Buffer11*>(buffer); } -void Buffer11::setData(const void *data, size_t size, GLenum usage) +gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) { mDynamicUsage = (usage == GL_DYNAMIC_DRAW); @@ -189,16 +189,22 @@ void Buffer11::setData(const void *data, size_t size, GLenum usage) { if (!mDynamicData.resize(size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY); } } - setSubData(data, size, 0); + gl::Error error = setSubData(data, size, 0); + if (error.isError()) + { + return error; + } if (usage == GL_STATIC_DRAW) { initializeStaticData(); } + + return error; } void *Buffer11::getData() @@ -242,12 +248,9 @@ void *Buffer11::getData() return mResolvedData.data(); } -void Buffer11::setSubData(const void *data, size_t size, size_t offset) +gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) { size_t requiredSize = size + offset; - mSize = std::max(mSize, requiredSize); - - invalidateStaticData(); if (data && size > 0) { @@ -256,85 +259,96 @@ void Buffer11::setSubData(const void *data, size_t size, size_t offset) mDynamicDirtyRange.start = std::min(mDynamicDirtyRange.start, offset); mDynamicDirtyRange.end = std::max(mDynamicDirtyRange.end, size + offset); memcpy(mDynamicData.data() + offset, data, size); - return; } + else + { + NativeBuffer11 *stagingBuffer = getStagingBuffer(); - NativeBuffer11 *stagingBuffer = getStagingBuffer(); + if (!stagingBuffer) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); + } - if (!stagingBuffer) - { - // Out-of-memory - return; - } + // Explicitly resize the staging buffer, preserving data if the new data will not + // completely fill the buffer + if (stagingBuffer->getSize() < requiredSize) + { + bool preserveData = (offset > 0); + if (!stagingBuffer->resize(requiredSize, preserveData)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer."); + } + } - // Explicitly resize the staging buffer, preserving data if the new data will not - // completely fill the buffer - if (stagingBuffer->getSize() < requiredSize) - { - bool preserveData = (offset > 0); - if (!stagingBuffer->resize(requiredSize, preserveData)) + if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset)) { - // Out-of-memory - return; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer."); } - } - stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset); - stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); + stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1); + } } + + mSize = std::max(mSize, requiredSize); + invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { Buffer11 *sourceBuffer = makeBuffer11(source); - if (sourceBuffer) + ASSERT(sourceBuffer != NULL); + + BufferStorage11 *copyDest = getLatestBufferStorage(); + if (!copyDest) { - BufferStorage11 *dest = getLatestBufferStorage(); - if (!dest) - { - dest = getStagingBuffer(); - } + copyDest = getStagingBuffer(); + } - BufferStorage11 *source = sourceBuffer->getLatestBufferStorage(); - if (source && dest) - { - // If copying to/from a pixel pack buffer, we must have a staging or - // pack buffer partner, because other native buffers can't be mapped - if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable()) - { - source = sourceBuffer->getStagingBuffer(); - } - else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable()) - { - dest = getStagingBuffer(); - } + BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage(); - // D3D11 does not allow overlapped copies until 11.1, and only if the - // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap - // Get around this via a different source buffer - if (source == dest) - { - if (source->getUsage() == BUFFER_USAGE_STAGING) - { - source = getBufferStorage(BUFFER_USAGE_VERTEX); - } - else - { - source = getStagingBuffer(); - } - } + if (!copySource || !copyDest) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); + } - dest->copyFromStorage(source, sourceOffset, size, destOffset); - dest->setDataRevision(dest->getDataRevision() + 1); - } + // If copying to/from a pixel pack buffer, we must have a staging or + // pack buffer partner, because other native buffers can't be mapped + if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) + { + copySource = sourceBuffer->getStagingBuffer(); + } + else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) + { + copyDest = getStagingBuffer(); + } - mSize = std::max<size_t>(mSize, destOffset + size); + // D3D11 does not allow overlapped copies until 11.1, and only if the + // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap + // Get around this via a different source buffer + if (copySource == copyDest) + { + if (copySource->getUsage() == BUFFER_USAGE_STAGING) + { + copySource = getBufferStorage(BUFFER_USAGE_VERTEX); + } + else + { + copySource = getStagingBuffer(); + } } + copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); + copyDest->setDataRevision(copyDest->getDataRevision() + 1); + + mSize = std::max<size_t>(mSize, destOffset + size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { ASSERT(!mMappedStorage); @@ -355,8 +369,7 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) if (!mMappedStorage) { - // Out-of-memory - return NULL; + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer."); } if ((access & GL_MAP_WRITE_BIT) > 0) @@ -365,14 +378,22 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access) mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); } - return mMappedStorage->map(offset, length, access); + void *mappedBuffer = mMappedStorage->map(offset, length, access); + if (!mappedBuffer) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); + } + + *mapPtr = mappedBuffer; + return gl::Error(GL_NO_ERROR); } -void Buffer11::unmap() +gl::Error Buffer11::unmap() { ASSERT(mMappedStorage); mMappedStorage->unmap(); mMappedStorage = NULL; + return gl::Error(GL_NO_ERROR); } void Buffer11::markTransformFeedbackUsage() diff --git a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h index 41ab780d..68126333 100644 --- a/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h +++ b/src/libGLESv2/renderer/d3d/d3d11/Buffer11.h @@ -68,12 +68,12 @@ class Buffer11 : public BufferD3D virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + virtual gl::Error setSubData(const void* data, size_t size, size_t offset); + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(); virtual void markTransformFeedbackUsage(); private: diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp index 3b584eee..c02db515 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.cpp @@ -30,13 +30,13 @@ Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer) return static_cast<Buffer9*>(buffer); } -void Buffer9::setData(const void* data, size_t size, GLenum usage) +gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) { if (size > mMemory.size()) { if (!mMemory.resize(size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -52,6 +52,8 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage) { initializeStaticData(); } + + return gl::Error(GL_NO_ERROR); } void *Buffer9::getData() @@ -59,13 +61,13 @@ void *Buffer9::getData() return mMemory.data(); } -void Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) { if (offset + size > mMemory.size()) { if (!mMemory.resize(offset + size)) { - return gl::error(GL_OUT_OF_MEMORY); + return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); } } @@ -76,30 +78,34 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset) } invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { // Note: this method is currently unreachable Buffer9* sourceBuffer = makeBuffer9(source); - if (sourceBuffer) - { - memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - } + ASSERT(sourceBuffer); + + memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); invalidateStaticData(); + + return gl::Error(GL_NO_ERROR); } -// We do not suppot buffer mapping in D3D9 -GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access) +// We do not support buffer mapping in D3D9 +gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) { UNREACHABLE(); - return NULL; + return gl::Error(GL_INVALID_OPERATION); } -void Buffer9::unmap() +gl::Error Buffer9::unmap() { UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION); } void Buffer9::markTransformFeedbackUsage() diff --git a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h index f12ee000..e78182f9 100644 --- a/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h +++ b/src/libGLESv2/renderer/d3d/d3d9/Buffer9.h @@ -31,12 +31,12 @@ class Buffer9 : public BufferD3D virtual Renderer* getRenderer(); // BufferImpl implementation - virtual void setData(const void* data, size_t size, GLenum usage); + virtual gl::Error setData(const void* data, size_t size, GLenum usage); virtual void *getData(); - virtual void setSubData(const void* data, size_t size, size_t offset); - virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual GLvoid* map(size_t offset, size_t length, GLbitfield access); - virtual void unmap(); + virtual gl::Error setSubData(const void* data, size_t size, size_t offset); + virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); + virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); + virtual gl::Error unmap(); virtual void markTransformFeedbackUsage(); private: |