OSDN Git Service

Adding draw instanced functions
authorAlexis Hetu <sugoi@google.com>
Fri, 17 Apr 2015 20:58:45 +0000 (16:58 -0400)
committerAlexis Hétu <sugoi@google.com>
Thu, 23 Apr 2015 15:40:44 +0000 (15:40 +0000)
This cl adds the API function
implementations for both the
core OpenGL ES 3.0 functions:
- glDrawArraysInstanced
- glDrawElementsInstanced

and the OpenGL ES 2.0 extensions:
- GL_EXT_draw_instanced
- GL_EXT_instanced_arrays

which include these functions:
- glDrawArraysInstancedEXT
- glDrawElementsInstancedEXT
- glVertexAttribDivisorEXT

Change-Id: I71efdd48087f14fe5e8229c7f6a74e6525921fe3
Reviewed-on: https://swiftshader-review.googlesource.com/2893
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
src/OpenGL/libGLESv2/Context.cpp
src/OpenGL/libGLESv2/Context.h
src/OpenGL/libGLESv2/libGLESv2.cpp
src/OpenGL/libGLESv2/libGLESv3.cpp

index bc6064c..cc7bb01 100644 (file)
@@ -3240,7 +3240,7 @@ void Context::clear(GLbitfield mask)
        }\r
 }\r
 \r
-void Context::drawArrays(GLenum mode, GLint first, GLsizei count)\r
+void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)\r
 {\r
     if(!mState.currentProgram)\r
     {\r
@@ -3285,7 +3285,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
     }\r
 }\r
 \r
-void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)\r
+void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)\r
 {\r
     if(!mState.currentProgram)\r
     {\r
@@ -4085,7 +4085,8 @@ const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt)
                (const GLubyte*)"GL_ANGLE_texture_compression_dxt3",\r
                (const GLubyte*)"GL_ANGLE_texture_compression_dxt5",\r
 #endif\r
-               (const GLubyte*)"GL_NV_fence"\r
+               (const GLubyte*)"GL_NV_fence",\r
+               (const GLubyte*)"GL_EXT_instanced_arrays",\r
        };\r
        static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions);\r
 \r
index b2bd8ee..c125837 100644 (file)
@@ -552,8 +552,8 @@ public:
 \r
     void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels);\r
     void clear(GLbitfield mask);\r
-    void drawArrays(GLenum mode, GLint first, GLsizei count);\r
-    void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);\r
+    void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount = 1);\r
+    void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount = 1);\r
     void finish();\r
     void flush();\r
 \r
index e528154..70f5c46 100644 (file)
@@ -1823,6 +1823,109 @@ void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const G
        }\r
 }\r
 \r
+void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)\r
+{\r
+       TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",\r
+               mode, first, count, instanceCount);\r
+\r
+       switch(mode)\r
+       {\r
+       case GL_POINTS:\r
+       case GL_LINES:\r
+       case GL_LINE_LOOP:\r
+       case GL_LINE_STRIP:\r
+       case GL_TRIANGLES:\r
+       case GL_TRIANGLE_FAN:\r
+       case GL_TRIANGLE_STRIP:\r
+               break;\r
+       default:\r
+               return error(GL_INVALID_ENUM);\r
+       }\r
+\r
+       if(count < 0 || instanceCount < 0)\r
+       {\r
+               return error(GL_INVALID_VALUE);\r
+       }\r
+\r
+       es2::Context *context = es2::getContext();\r
+\r
+       if(context)\r
+       {\r
+               es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
+               if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))\r
+               {\r
+                       return error(GL_INVALID_OPERATION);\r
+               }\r
+\r
+               context->drawArrays(mode, first, count, instanceCount);\r
+       }\r
+}\r
+\r
+void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)\r
+{\r
+       TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = 0x%0.8p, GLsizei instanceCount = %d)",\r
+               mode, count, type, indices, instanceCount);\r
+\r
+       switch(mode)\r
+       {\r
+       case GL_POINTS:\r
+       case GL_LINES:\r
+       case GL_LINE_LOOP:\r
+       case GL_LINE_STRIP:\r
+       case GL_TRIANGLES:\r
+       case GL_TRIANGLE_FAN:\r
+       case GL_TRIANGLE_STRIP:\r
+               break;\r
+       default:\r
+               return error(GL_INVALID_ENUM);\r
+       }\r
+\r
+       switch(type)\r
+       {\r
+       case GL_UNSIGNED_BYTE:\r
+       case GL_UNSIGNED_SHORT:\r
+       case GL_UNSIGNED_INT:\r
+               break;\r
+       default:\r
+               return error(GL_INVALID_ENUM);\r
+       }\r
+\r
+       if(count < 0 || instanceCount < 0)\r
+       {\r
+               return error(GL_INVALID_VALUE);\r
+       }\r
+\r
+       es2::Context *context = es2::getContext();\r
+\r
+       if(context)\r
+       {\r
+               es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
+               if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())\r
+               {\r
+                       return error(GL_INVALID_OPERATION);\r
+               }\r
+\r
+               context->drawElements(mode, 0, UINT_MAX, count, type, indices, instanceCount);\r
+       }\r
+}\r
+\r
+void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)\r
+{\r
+       TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);\r
+\r
+       es2::Context *context = es2::getContext();\r
+\r
+       if(context)\r
+       {\r
+               if(index >= es2::MAX_VERTEX_ATTRIBS)\r
+               {\r
+                       return error(GL_INVALID_VALUE);\r
+               }\r
+\r
+               context->setVertexAttribDivisor(index, divisor);\r
+       }\r
+}\r
+\r
 void GL_APIENTRY glEnable(GLenum cap)\r
 {\r
        TRACE("(GLenum cap = 0x%X)", cap);\r
@@ -6778,6 +6881,9 @@ __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
                EXTENSION(glGetQueryObjectuivEXT),\r
                EXTENSION(glEGLImageTargetTexture2DOES),\r
                EXTENSION(glEGLImageTargetRenderbufferStorageOES),\r
+               EXTENSION(glDrawElementsInstancedEXT),\r
+               EXTENSION(glDrawArraysInstancedEXT),\r
+               EXTENSION(glVertexAttribDivisorEXT),\r
 \r
                #undef EXTENSION\r
        };\r
index 4d4964a..8b97b34 100644 (file)
@@ -2618,10 +2618,10 @@ void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex,
        UNIMPLEMENTED();\r
 }\r
 \r
-void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)\r
+void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)\r
 {\r
-       TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instancecount = %d)",\r
-             mode, first, count, instancecount);\r
+       TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",\r
+             mode, first, count, instanceCount);\r
 \r
        switch(mode)\r
        {\r
@@ -2637,7 +2637,7 @@ void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
                return error(GL_INVALID_ENUM);\r
        }\r
 \r
-       if(count < 0 || instancecount < 0)\r
+       if(count < 0 || instanceCount < 0)\r
        {\r
                return error(GL_INVALID_VALUE);\r
        }\r
@@ -2651,15 +2651,15 @@ void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
                {\r
                        return error(GL_INVALID_OPERATION);\r
                }\r
-       }\r
 \r
-       UNIMPLEMENTED();\r
+               context->drawArrays(mode, first, count, instanceCount);\r
+       }\r
 }\r
 \r
-void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount)\r
+void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)\r
 {\r
-       TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = 0x%0.8p, GLsizei instancecount = %d)",\r
-             mode, count, type, indices, instancecount);\r
+       TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = 0x%0.8p, GLsizei instanceCount = %d)",\r
+             mode, count, type, indices, instanceCount);\r
 \r
        switch(mode)\r
        {\r
@@ -2685,7 +2685,7 @@ void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type
                return error(GL_INVALID_ENUM);\r
        }\r
 \r
-       if(count < 0 || instancecount < 0)\r
+       if(count < 0 || instanceCount < 0)\r
        {\r
                return error(GL_INVALID_VALUE);\r
        }\r
@@ -2699,9 +2699,9 @@ void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type
                {\r
                        return error(GL_INVALID_OPERATION);\r
                }\r
-       }\r
 \r
-       UNIMPLEMENTED();\r
+               context->drawElements(mode, 0, UINT_MAX, count, type, indices, instanceCount);\r
+       }\r
 }\r
 \r
 GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)\r