mesa: only verify that enabled arrays have backing buffers
[mesa.git] / src / mesa / main / api_validate.c
index 05691d25da0d907215a0347ae66a4e9e4f374292..071c16d1a1d8a99200a84731b1e744b68089764a 100644 (file)
@@ -152,7 +152,7 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
          /* If drawing to integer-valued color buffers, there must be an
           * active fragment shader (GL_EXT_texture_integer).
           */
-         if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
+         if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerBuffers) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(integer format but no fragment shader)", where);
             return GL_FALSE;
@@ -925,7 +925,7 @@ valid_draw_indirect(struct gl_context *ctx,
     * buffer bound.
     */
    if (_mesa_is_gles31(ctx) &&
-       ctx->Array.VAO->_Enabled != ctx->Array.VAO->VertexAttribBufferMask) {
+       ctx->Array.VAO->_Enabled & ~ctx->Array.VAO->VertexAttribBufferMask) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(No VBO bound)", name);
       return GL_FALSE;
    }
@@ -1285,6 +1285,7 @@ GLboolean
 _mesa_validate_DispatchCompute(struct gl_context *ctx,
                                const GLuint *num_groups)
 {
+   struct gl_shader_program *prog;
    int i;
    FLUSH_CURRENT(ctx, 0);
 
@@ -1317,6 +1318,101 @@ _mesa_validate_DispatchCompute(struct gl_context *ctx,
       }
    }
 
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated by DispatchCompute if the active
+    *  program for the compute shader stage has a variable work group size."
+    */
+   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->Comp.LocalSizeVariable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glDispatchCompute(variable work group size forbidden)");
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+GLboolean
+_mesa_validate_DispatchComputeGroupSizeARB(struct gl_context *ctx,
+                                           const GLuint *num_groups,
+                                           const GLuint *group_size)
+{
+   struct gl_shader_program *prog;
+   GLuint total_invocations = 1;
+   int i;
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB"))
+      return GL_FALSE;
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated by
+    *  DispatchComputeGroupSizeARB if the active program for the compute
+    *  shader stage has a fixed work group size."
+    */
+   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (!prog->Comp.LocalSizeVariable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glDispatchComputeGroupSizeARB(fixed work group size "
+                  "forbidden)");
+      return GL_FALSE;
+   }
+
+   for (i = 0; i < 3; i++) {
+      /* The ARB_compute_variable_group_size spec says:
+       *
+       * "An INVALID_VALUE error is generated if any of num_groups_x,
+       *  num_groups_y and num_groups_z are greater than or equal to the
+       *  maximum work group count for the corresponding dimension."
+       */
+      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i);
+         return GL_FALSE;
+      }
+
+      /* The ARB_compute_variable_group_size spec says:
+       *
+       * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
+       *  any of <group_size_x>, <group_size_y>, or <group_size_z> is less than
+       *  or equal to zero or greater than the maximum local work group size
+       *  for compute shaders with variable group size
+       *  (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding
+       *  dimension."
+       *
+       * However, the "less than" is a spec bug because they are declared as
+       * unsigned integers.
+       */
+      if (group_size[i] == 0 ||
+          group_size[i] > ctx->Const.MaxComputeVariableGroupSize[i]) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i);
+         return GL_FALSE;
+      }
+
+      total_invocations *= group_size[i];
+   }
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
+    *  the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds
+    *  the implementation-dependent maximum local work group invocation count
+    *  for compute shaders with variable group size
+    *  (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)."
+    */
+   if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glDispatchComputeGroupSizeARB(product of local_sizes "
+                  "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB "
+                  "(%d > %d))", total_invocations,
+                  ctx->Const.MaxComputeVariableGroupInvocations);
+      return GL_FALSE;
+   }
+
    return GL_TRUE;
 }
 
@@ -1326,6 +1422,7 @@ valid_dispatch_indirect(struct gl_context *ctx,
                         GLsizei size, const char *name)
 {
    const uint64_t end = (uint64_t) indirect + size;
+   struct gl_shader_program *prog;
 
    if (!check_valid_to_compute(ctx, name))
       return GL_FALSE;
@@ -1371,6 +1468,18 @@ valid_dispatch_indirect(struct gl_context *ctx,
       return GL_FALSE;
    }
 
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated if the active program for the
+    *  compute shader stage has a variable work group size."
+    */
+   prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->Comp.LocalSizeVariable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(variable work group size forbidden)", name);
+      return GL_FALSE;
+   }
+
    return GL_TRUE;
 }