OSDN Git Service

Buffer mapping state validation fixes
authorAlexis Hetu <sugoi@google.com>
Tue, 14 Nov 2017 20:27:00 +0000 (15:27 -0500)
committerAlexis Hétu <sugoi@google.com>
Tue, 14 Nov 2017 22:24:21 +0000 (22:24 +0000)
- Can't update an already mapped bufferData
- Can't unmap an unmapped buffer
- Disallowed illegal mapBufferRange flag combinations
- Can't flush buffer if not mapped

Change-Id: I7013f63e5db64c1016f9ce50a43d0629f0a2950e
Reviewed-on: https://swiftshader-review.googlesource.com/13788
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/OpenGL/libGLESv2/libGLESv2.cpp
src/OpenGL/libGLESv2/libGLESv3.cpp

index f486982..ffac13a 100644 (file)
@@ -649,6 +649,12 @@ void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid
                        return error(GL_INVALID_OPERATION);
                }
 
+               if(buffer->isMapped())
+               {
+                       // It is an invalid operation to update an already mapped buffer
+                       return error(GL_INVALID_OPERATION);
+               }
+
                if((size_t)size + offset > buffer->size())
                {
                        return error(GL_INVALID_VALUE);
index d268656..8b9116c 100644 (file)
@@ -560,7 +560,7 @@ GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)
                        GLuint index = (src - GL_COLOR_ATTACHMENT0);
                        if(index >= MAX_COLOR_ATTACHMENTS)
                        {
-                               return error(GL_INVALID_ENUM);
+                               return error(GL_INVALID_OPERATION);
                        }
                        if(readFramebufferName == 0)
                        {
@@ -570,7 +570,7 @@ GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)
                }
                        break;
                default:
-                       error(GL_INVALID_ENUM);
+                       return error(GL_INVALID_ENUM);
                }
        }
 }
@@ -1096,6 +1096,12 @@ GL_APICALL GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
                        return error(GL_INVALID_OPERATION, GL_TRUE);
                }
 
+               if(!buffer->isMapped())
+               {
+                       // Already unmapped
+                       return error(GL_INVALID_OPERATION, GL_TRUE);
+               }
+
                return buffer->unmap() ? GL_TRUE : GL_FALSE;
        }
 
@@ -1574,6 +1580,27 @@ GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GL
        TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = %X)",
              target, offset, length, access);
 
+       if((offset < 0) || (length < 0))
+       {
+               return error(GL_INVALID_VALUE, nullptr);
+       }
+
+       if(!(access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)))
+       {
+               // Must be able to read or write the buffer
+               return error(GL_INVALID_OPERATION, nullptr);
+       }
+       else if((access & GL_MAP_READ_BIT) && (access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT)))
+       {
+               // GL_MAP_INVALIDATE_RANGE_BIT, GL_MAP_INVALIDATE_BUFFER_BIT and GL_MAP_UNSYNCHRONIZED_BIT can't be used with GL_MAP_READ_BIT
+               return error(GL_INVALID_OPERATION, nullptr);
+       }
+       else if((!(access & GL_MAP_WRITE_BIT)) && (access & GL_MAP_FLUSH_EXPLICIT_BIT))
+       {
+               // GL_MAP_FLUSH_EXPLICIT_BIT can't be used without GL_MAP_WRITE_BIT
+               return error(GL_INVALID_OPERATION, nullptr);
+       }
+
        es2::Context *context = es2::getContext();
 
        if(context)
@@ -1597,9 +1624,9 @@ GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GL
                }
 
                GLsizeiptr bufferSize = buffer->size();
-               if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+               if((offset + length) > bufferSize)
                {
-                       error(GL_INVALID_VALUE);
+                       return error(GL_INVALID_VALUE, nullptr);
                }
 
                if((access & ~(GL_MAP_READ_BIT |
@@ -1609,7 +1636,7 @@ GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GL
                               GL_MAP_FLUSH_EXPLICIT_BIT |
                               GL_MAP_UNSYNCHRONIZED_BIT)) != 0)
                {
-                       error(GL_INVALID_VALUE);
+                       return error(GL_INVALID_VALUE, nullptr);
                }
 
                return buffer->mapRange(offset, length, access);
@@ -1623,6 +1650,11 @@ GL_APICALL void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr off
        TRACE("(GLenum target = 0x%X,  GLintptr offset = %d, GLsizeiptr length = %d)",
              target, offset, length);
 
+       if((offset < 0) || (length < 0))
+       {
+               return error(GL_INVALID_VALUE);
+       }
+
        es2::Context *context = es2::getContext();
 
        if(context)
@@ -1639,10 +1671,22 @@ GL_APICALL void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr off
                        return error(GL_INVALID_OPERATION);
                }
 
-               GLsizeiptr bufferSize = buffer->size();
-               if((offset < 0) || (length < 0) || ((offset + length) > bufferSize))
+               if(!buffer->isMapped())
+               {
+                       // Buffer must be mapped
+                       return error(GL_INVALID_OPERATION);
+               }
+
+               GLsizeiptr bufferSize = buffer->length();
+               if((offset + length) > bufferSize)
+               {
+                       return error(GL_INVALID_VALUE);
+               }
+
+               if(!(buffer->usage() & GL_MAP_FLUSH_EXPLICIT_BIT))
                {
-                       error(GL_INVALID_VALUE);
+                       // Flush must be explicitly allowed
+                       return error(GL_INVALID_OPERATION);
                }
 
                buffer->flushMappedRange(offset, length);
@@ -3014,7 +3058,7 @@ GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GL
 
        if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
        {
-               error(GL_INVALID_VALUE);
+               return error(GL_INVALID_VALUE, GL_FALSE);
        }
 
        es2::Context *context = es2::getContext();