Commit e8af6d1a by Alexis Hetu Committed by Alexis Hétu

Adding draw instanced functions

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