Commit cc6f55dd by Geoff Lang

Split Buffer::map into map and mapRange to match the API.

BUG=angleproject:681 Change-Id: Ia4bf2b81134a922265ca762f33ac85d9ddbf1a7c Reviewed-on: https://chromium-review.googlesource.com/261890Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 8a6f19d7
...@@ -21,6 +21,7 @@ Buffer::Buffer(rx::BufferImpl *impl, GLuint id) ...@@ -21,6 +21,7 @@ Buffer::Buffer(rx::BufferImpl *impl, GLuint id)
mUsage(GL_DYNAMIC_DRAW), mUsage(GL_DYNAMIC_DRAW),
mSize(0), mSize(0),
mAccessFlags(0), mAccessFlags(0),
mAccess(GL_WRITE_ONLY_OES),
mMapped(GL_FALSE), mMapped(GL_FALSE),
mMapPointer(NULL), mMapPointer(NULL),
mMapOffset(0), mMapOffset(0),
...@@ -74,12 +75,36 @@ Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr ...@@ -74,12 +75,36 @@ Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr
return error; return error;
} }
Error Buffer::map(GLenum access)
{
ASSERT(!mMapped);
Error error = mBuffer->map(access, &mMapPointer);
if (error.isError())
{
mMapPointer = NULL;
return error;
}
ASSERT(access == GL_WRITE_ONLY_OES);
mMapped = GL_TRUE;
mMapOffset = 0;
mMapLength = mSize;
mAccess = access;
mAccessFlags = GL_MAP_WRITE_BIT;
mIndexRangeCache.invalidateRange(0, mMapLength);
return error;
}
Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
{ {
ASSERT(!mMapped); ASSERT(!mMapped);
ASSERT(offset + length <= mSize); ASSERT(offset + length <= mSize);
Error error = mBuffer->map(offset, length, access, &mMapPointer); Error error = mBuffer->mapRange(offset, length, access, &mMapPointer);
if (error.isError()) if (error.isError())
{ {
mMapPointer = NULL; mMapPointer = NULL;
...@@ -89,7 +114,13 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) ...@@ -89,7 +114,13 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
mMapped = GL_TRUE; mMapped = GL_TRUE;
mMapOffset = static_cast<GLint64>(offset); mMapOffset = static_cast<GLint64>(offset);
mMapLength = static_cast<GLint64>(length); mMapLength = static_cast<GLint64>(length);
mAccessFlags = static_cast<GLint>(access); mAccess = GL_WRITE_ONLY_OES;
mAccessFlags = access;
// The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid
// value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is
// no update for ES3 and the GL_READ_ONLY and GL_READ_WRITE enums don't exist for ES,
// we cannot properly set GL_BUFFER_ACCESS_OES when glMapBufferRange is called.
if ((access & GL_MAP_WRITE_BIT) > 0) if ((access & GL_MAP_WRITE_BIT) > 0)
{ {
...@@ -99,13 +130,14 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) ...@@ -99,13 +130,14 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
return error; return error;
} }
Error Buffer::unmap() Error Buffer::unmap(GLboolean *result)
{ {
ASSERT(mMapped); ASSERT(mMapped);
Error error = mBuffer->unmap(); Error error = mBuffer->unmap(result);
if (error.isError()) if (error.isError())
{ {
*result = GL_FALSE;
return error; return error;
} }
...@@ -113,6 +145,7 @@ Error Buffer::unmap() ...@@ -113,6 +145,7 @@ Error Buffer::unmap()
mMapPointer = NULL; mMapPointer = NULL;
mMapOffset = 0; mMapOffset = 0;
mMapLength = 0; mMapLength = 0;
mAccess = GL_WRITE_ONLY_OES;
mAccessFlags = 0; mAccessFlags = 0;
return error; return error;
......
...@@ -35,11 +35,13 @@ class Buffer : public RefCountObject ...@@ -35,11 +35,13 @@ class Buffer : public RefCountObject
Error bufferData(const void *data, GLsizeiptr size, GLenum usage); Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
Error map(GLenum access);
Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
Error unmap(); Error unmap(GLboolean *result);
GLenum getUsage() const { return mUsage; } GLenum getUsage() const { return mUsage; }
GLint getAccessFlags() const { return mAccessFlags; } GLbitfield getAccessFlags() const { return mAccessFlags; }
GLenum getAccess() const { return mAccess; }
GLboolean isMapped() const { return mMapped; } GLboolean isMapped() const { return mMapped; }
GLvoid *getMapPointer() const { return mMapPointer; } GLvoid *getMapPointer() const { return mMapPointer; }
GLint64 getMapOffset() const { return mMapOffset; } GLint64 getMapOffset() const { return mMapOffset; }
...@@ -56,7 +58,8 @@ class Buffer : public RefCountObject ...@@ -56,7 +58,8 @@ class Buffer : public RefCountObject
GLenum mUsage; GLenum mUsage;
GLint64 mSize; GLint64 mSize;
GLint mAccessFlags; GLbitfield mAccessFlags;
GLenum mAccess;
GLboolean mMapped; GLboolean mMapped;
GLvoid *mMapPointer; GLvoid *mMapPointer;
GLint64 mMapOffset; GLint64 mMapOffset;
......
...@@ -25,8 +25,9 @@ class BufferImpl : angle::NonCopyable ...@@ -25,8 +25,9 @@ class BufferImpl : angle::NonCopyable
virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 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 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 map(GLenum access, GLvoid **mapPtr) = 0;
virtual gl::Error unmap() = 0; virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
virtual gl::Error unmap(GLboolean *result) = 0;
// This method may not have a corresponding GL-backed function. It is necessary // This method may not have a corresponding GL-backed function. It is necessary
// for validation, for certain indexed draw calls. // for validation, for certain indexed draw calls.
......
...@@ -356,7 +356,15 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint ...@@ -356,7 +356,15 @@ gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) gl::Error Buffer11::map(GLenum access, GLvoid **mapPtr)
{
// GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield
// and call mapRange.
ASSERT(access == GL_WRITE_ONLY_OES);
return mapRange(0, mSize, GL_MAP_WRITE_BIT, mapPtr);
}
gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{ {
ASSERT(!mMappedStorage); ASSERT(!mMappedStorage);
...@@ -396,11 +404,15 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid ...@@ -396,11 +404,15 @@ gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Buffer11::unmap() gl::Error Buffer11::unmap(GLboolean *result)
{ {
ASSERT(mMappedStorage); ASSERT(mMappedStorage);
mMappedStorage->unmap(); mMappedStorage->unmap();
mMappedStorage = NULL; mMappedStorage = NULL;
// TODO: detect if we had corruption. if so, return false.
*result = GL_TRUE;
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -64,8 +64,9 @@ class Buffer11 : public BufferD3D ...@@ -64,8 +64,9 @@ class Buffer11 : public BufferD3D
gl::Error getData(const uint8_t **outData) override; gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset); 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 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 map(GLenum access, GLvoid **mapPtr);
virtual gl::Error unmap(); virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage(); virtual void markTransformFeedbackUsage();
private: private:
......
...@@ -90,13 +90,19 @@ gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintp ...@@ -90,13 +90,19 @@ gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintp
} }
// We do not support buffer mapping in D3D9 // We do not support buffer mapping in D3D9
gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) gl::Error Buffer9::map(GLenum access, GLvoid **mapPtr)
{ {
UNREACHABLE(); UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
gl::Error Buffer9::unmap() gl::Error Buffer9::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
gl::Error Buffer9::unmap(GLboolean *result)
{ {
UNREACHABLE(); UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
......
...@@ -32,8 +32,9 @@ class Buffer9 : public BufferD3D ...@@ -32,8 +32,9 @@ class Buffer9 : public BufferD3D
gl::Error getData(const uint8_t **outData) override; gl::Error getData(const uint8_t **outData) override;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset); 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 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 map(GLenum access, GLvoid **mapPtr);
virtual gl::Error unmap(); virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage(); virtual void markTransformFeedbackUsage();
private: private:
......
...@@ -73,20 +73,26 @@ gl::Error BufferGL::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint ...@@ -73,20 +73,26 @@ gl::Error BufferGL::copySubData(BufferImpl* source, GLintptr sourceOffset, GLint
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error BufferGL::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) gl::Error BufferGL::map(GLenum access, GLvoid **mapPtr)
{ {
// TODO: look into splitting this into two functions, glMapBuffer is available in 1.5, but mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
// glMapBufferRange requires 3.0 *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access);
return gl::Error(GL_NO_ERROR);
}
gl::Error BufferGL::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access); *mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error BufferGL::unmap() gl::Error BufferGL::unmap(GLboolean *result)
{ {
ASSERT(*result);
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
mFunctions->unmapBuffer(DestBufferOperationTarget); *result = mFunctions->unmapBuffer(DestBufferOperationTarget);
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -26,8 +26,9 @@ class BufferGL : public BufferImpl ...@@ -26,8 +26,9 @@ class BufferGL : public BufferImpl
gl::Error setData(const void* data, size_t size, GLenum usage) override; gl::Error setData(const void* data, size_t size, GLenum usage) override;
gl::Error setSubData(const void* data, size_t size, size_t offset) override; gl::Error setSubData(const void* data, size_t size, size_t offset) override;
gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) override; gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) override;
gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; gl::Error map(GLenum access, GLvoid **mapPtr) override;
gl::Error unmap() override; gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
gl::Error unmap(GLboolean *result) override;
// This method may not have a corresponding GL-backed function. It is necessary // This method may not have a corresponding GL-backed function. It is necessary
// for validation, for certain indexed draw calls. // for validation, for certain indexed draw calls.
......
...@@ -129,19 +129,27 @@ bool ValidBufferTarget(const Context *context, GLenum target) ...@@ -129,19 +129,27 @@ bool ValidBufferTarget(const Context *context, GLenum target)
bool ValidBufferParameter(const Context *context, GLenum pname) bool ValidBufferParameter(const Context *context, GLenum pname)
{ {
const Extensions &extensions = context->getExtensions();
switch (pname) switch (pname)
{ {
case GL_BUFFER_USAGE: case GL_BUFFER_USAGE:
case GL_BUFFER_SIZE: case GL_BUFFER_SIZE:
return true; return true;
case GL_BUFFER_ACCESS_OES:
return extensions.mapBuffer;
case GL_BUFFER_MAPPED:
static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
return (context->getClientVersion() >= 3) || extensions.mapBuffer || extensions.mapBufferRange;
// GL_BUFFER_MAP_POINTER is a special case, and may only be // GL_BUFFER_MAP_POINTER is a special case, and may only be
// queried with GetBufferPointerv // queried with GetBufferPointerv
case GL_BUFFER_ACCESS_FLAGS: case GL_BUFFER_ACCESS_FLAGS:
case GL_BUFFER_MAPPED:
case GL_BUFFER_MAP_OFFSET: case GL_BUFFER_MAP_OFFSET:
case GL_BUFFER_MAP_LENGTH: case GL_BUFFER_MAP_LENGTH:
return (context->getClientVersion() >= 3); return (context->getClientVersion() >= 3) || extensions.mapBufferRange;
default: default:
return false; return false;
......
...@@ -1784,7 +1784,11 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params ...@@ -1784,7 +1784,11 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params
case GL_BUFFER_ACCESS_FLAGS: case GL_BUFFER_ACCESS_FLAGS:
*params = buffer->getAccessFlags(); *params = buffer->getAccessFlags();
break; break;
case GL_BUFFER_ACCESS_OES:
*params = buffer->getAccess();
break;
case GL_BUFFER_MAPPED: case GL_BUFFER_MAPPED:
static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
*params = static_cast<GLint>(buffer->isMapped()); *params = static_cast<GLint>(buffer->isMapped());
break; break;
case GL_BUFFER_MAP_OFFSET: case GL_BUFFER_MAP_OFFSET:
......
...@@ -863,7 +863,7 @@ void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access) ...@@ -863,7 +863,7 @@ void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access)
return NULL; return NULL;
} }
Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT); Error error = buffer->map(access);
if (error.isError()) if (error.isError())
{ {
context->recordError(error); context->recordError(error);
...@@ -897,16 +897,15 @@ GLboolean GL_APIENTRY UnmapBufferOES(GLenum target) ...@@ -897,16 +897,15 @@ GLboolean GL_APIENTRY UnmapBufferOES(GLenum target)
return GL_FALSE; return GL_FALSE;
} }
// TODO: detect if we had corruption. if so, throw an error and return false. GLboolean result;
Error error = buffer->unmap(&result);
Error error = buffer->unmap();
if (error.isError()) if (error.isError())
{ {
context->recordError(error); context->recordError(error);
return GL_FALSE; return GL_FALSE;
} }
return GL_TRUE; return result;
} }
return GL_FALSE; return GL_FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment