Commit 250d33fb by Jamie Madill

Move draw call validation to new functions.

Separate draw call validation functions will give us a flexible base for refactoring and cleaning up all draw call validation. BUG=angle:571 Change-Id: Ia8e3c83cfe48fedb8f2c7aef1fb282f646c66e82 Reviewed-on: https://chromium-review.googlesource.com/202974Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3891fd27
...@@ -1577,29 +1577,13 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -1577,29 +1577,13 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
try try
{ {
if (count < 0 || first < 0)
{
return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext(); gl::Context *context = gl::getNonLostContext();
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
if (context) if (context)
{ {
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); if (!ValidateDrawArrays(context, mode, first, count))
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{ {
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode return;
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
} }
context->drawArrays(mode, first, count, 0); context->drawArrays(mode, first, count, 0);
...@@ -1617,35 +1601,16 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun ...@@ -1617,35 +1601,16 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
try try
{ {
if (count < 0 || first < 0 || primcount < 0) gl::Context *context = gl::getNonLostContext();
{
return gl::error(GL_INVALID_VALUE);
}
if (primcount > 0) if (context)
{ {
gl::Context *context = gl::getNonLostContext(); if (!ValidateDrawArraysInstanced(context, mode, first, count, primcount))
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{ {
return gl::error(GL_INVALID_OPERATION); return;
} }
if (context) context->drawArrays(mode, first, count, primcount);
{
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
context->drawArrays(mode, first, count, primcount);
}
} }
} }
catch (...) catch (...)
...@@ -1661,42 +1626,13 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv ...@@ -1661,42 +1626,13 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
try try
{ {
if (count < 0)
{
return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext(); gl::Context *context = gl::getNonLostContext();
if (context) if (context)
{ {
switch (type) if (!ValidateDrawElements(context, mode, count, type, indices))
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->getCaps().extensions.elementIndexUint)
{
return gl::error(GL_INVALID_ENUM);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{ {
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced return;
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
} }
context->drawElements(mode, count, type, indices, 0); context->drawElements(mode, count, type, indices, 0);
...@@ -1715,48 +1651,16 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t ...@@ -1715,48 +1651,16 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
try try
{ {
if (count < 0 || primcount < 0) gl::Context *context = gl::getNonLostContext();
{
return gl::error(GL_INVALID_VALUE);
}
if (primcount > 0) if (context)
{ {
gl::Context *context = gl::getNonLostContext(); if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount))
if (context)
{ {
switch (type) return;
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->getCaps().extensions.elementIndexUint)
{
return gl::error(GL_INVALID_ENUM);
}
break;
default:
return gl::error(GL_INVALID_ENUM);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION);
}
context->drawElements(mode, count, type, indices, primcount);
} }
context->drawElements(mode, count, type, indices, primcount);
} }
} }
catch (...) catch (...)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
#include "libGLESv2/Query.h" #include "libGLESv2/Query.h"
#include "libGLESv2/ProgramBinary.h" #include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/TransformFeedback.h"
#include "common/mathutil.h" #include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
...@@ -1288,4 +1289,139 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1288,4 +1289,139 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return true; return true;
} }
bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
{
if (count < 0 || first < 0)
{
return gl::error(GL_INVALID_VALUE, false);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION, false);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false);
}
// No-op if zero count
return (count > 0);
}
bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (count < 0 || first < 0 || primcount < 0)
{
return gl::error(GL_INVALID_VALUE, false);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION, false);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
curTransformFeedback->getDrawMode() != mode)
{
// It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
// that does not match the current transform feedback object's draw mode (if transform feedback
// is active), (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false);
}
// No-op if zero count or zero primitive count
return (primcount > 0 && count > 0);
}
bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
if (count < 0)
{
return gl::error(GL_INVALID_VALUE, false);
}
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->getCaps().extensions.elementIndexUint)
{
return gl::error(GL_INVALID_ENUM, false);
}
break;
default:
return gl::error(GL_INVALID_ENUM, false);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION, false);
}
// No-op if zero count
return (count > 0);
}
bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount)
{
if (count < 0 || primcount < 0)
{
return gl::error(GL_INVALID_VALUE, false);
}
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->getCaps().extensions.elementIndexUint)
{
return gl::error(GL_INVALID_ENUM, false);
}
break;
default:
return gl::error(GL_INVALID_ENUM, false);
}
gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback();
if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
{
// It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
// while transform feedback is active, (3.0.2, section 2.14, pg 86)
return gl::error(GL_INVALID_OPERATION, false);
}
// Check for mapped buffers
if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
{
return gl::error(GL_INVALID_OPERATION, false);
}
// No-op if zero count or zero primitive count
return (primcount > 0 && count > 0);
}
} }
...@@ -58,6 +58,12 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -58,6 +58,12 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
GLint border, GLenum *textureInternalFormatOut); GLint border, GLenum *textureInternalFormatOut);
bool ValidateDrawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count);
bool ValidateDrawArraysInstanced(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount);
bool ValidateDrawElements(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
bool ValidateDrawElementsInstanced(const gl::Context *context, GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount);
} }
#endif // LIBGLESV2_VALIDATION_ES_H #endif // LIBGLESV2_VALIDATION_ES_H
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