summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-12-31 16:11:56 -0500
committerIlia Mirkin <[email protected]>2016-01-07 18:38:46 -0500
commite1eab5a76f20061c005c8254b11ca1611ebda8f7 (patch)
tree21c68a493a7fb9e0cf60215c32f2a1409cf37aac /src/mesa/main
parent9327e2d312e5da58f1cf4dbb806c67fcefd892f5 (diff)
mesa: add support for ARB_indirect_parameters draw functions
Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_validate.c115
-rw-r--r--src/mesa/main/api_validate.h16
2 files changed, 131 insertions, 0 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index d693ec64ce4..2b629977644 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -920,6 +920,121 @@ _mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx,
return GL_TRUE;
}
+static GLboolean
+valid_draw_indirect_parameters(struct gl_context *ctx,
+ const char *name,
+ GLintptr drawcount)
+{
+ /* From the ARB_indirect_parameters specification:
+ * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or
+ * MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of
+ * four."
+ */
+ if (drawcount & 3) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "%s(drawcount is not a multiple of 4)", name);
+ return GL_FALSE;
+ }
+
+ /* From the ARB_indirect_parameters specification:
+ * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
+ * MultiDrawElementsIndirectCountARB if no buffer is bound to the
+ * PARAMETER_BUFFER_ARB binding point."
+ */
+ if (!_mesa_is_bufferobj(ctx->ParameterBuffer)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s: no buffer bound to PARAMETER_BUFFER", name);
+ return GL_FALSE;
+ }
+
+ if (_mesa_check_disallowed_mapping(ctx->ParameterBuffer)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(PARAMETER_BUFFER is mapped)", name);
+ return GL_FALSE;
+ }
+
+ /* From the ARB_indirect_parameters specification:
+ * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
+ * MultiDrawElementsIndirectCountARB if reading a <sizei> typed value
+ * from the buffer bound to the PARAMETER_BUFFER_ARB target at the offset
+ * specified by <drawcount> would result in an out-of-bounds access."
+ */
+ if (ctx->ParameterBuffer->Size < drawcount + sizeof(GLsizei)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(PARAMETER_BUFFER too small)", name);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx,
+ GLenum mode,
+ GLintptr indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ GLsizeiptr size = 0;
+ const unsigned drawArraysNumParams = 4;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
+ assert(stride != 0);
+
+ if (!valid_draw_indirect_multi(ctx, maxdrawcount, stride,
+ "glMultiDrawArraysIndirectCountARB"))
+ return GL_FALSE;
+
+ /* number of bytes of the indirect buffer which will be read */
+ size = maxdrawcount
+ ? (maxdrawcount - 1) * stride + drawArraysNumParams * sizeof(GLuint)
+ : 0;
+
+ if (!valid_draw_indirect(ctx, mode, (void *)indirect, size,
+ "glMultiDrawArraysIndirectCountARB"))
+ return GL_FALSE;
+
+ return valid_draw_indirect_parameters(
+ ctx, "glMultiDrawArraysIndirectCountARB", drawcount);
+}
+
+GLboolean
+_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx,
+ GLenum mode, GLenum type,
+ GLintptr indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ GLsizeiptr size = 0;
+ const unsigned drawElementsNumParams = 5;
+
+ FLUSH_CURRENT(ctx, 0);
+
+ /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
+ assert(stride != 0);
+
+ if (!valid_draw_indirect_multi(ctx, maxdrawcount, stride,
+ "glMultiDrawElementsIndirectCountARB"))
+ return GL_FALSE;
+
+ /* number of bytes of the indirect buffer which will be read */
+ size = maxdrawcount
+ ? (maxdrawcount - 1) * stride + drawElementsNumParams * sizeof(GLuint)
+ : 0;
+
+ if (!valid_draw_indirect_elements(ctx, mode, type,
+ (void *)indirect, size,
+ "glMultiDrawElementsIndirectCountARB"))
+ return GL_FALSE;
+
+ return valid_draw_indirect_parameters(
+ ctx, "glMultiDrawElementsIndirectCountARB", drawcount);
+}
+
static bool
check_valid_to_compute(struct gl_context *ctx, const char *function)
{
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index 5d030a7ba37..5b321e3ac99 100644
--- a/src/mesa/main/api_validate.h
+++ b/src/mesa/main/api_validate.h
@@ -106,6 +106,22 @@ _mesa_validate_MultiDrawElementsIndirect(struct gl_context *ctx,
GLsizei stride);
extern GLboolean
+_mesa_validate_MultiDrawArraysIndirectCount(struct gl_context *ctx,
+ GLenum mode,
+ GLintptr indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+
+extern GLboolean
+_mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx,
+ GLenum mode, GLenum type,
+ GLintptr indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+
+extern GLboolean
_mesa_validate_DispatchCompute(struct gl_context *ctx,
const GLuint *num_groups);