"%s(tess ctrl shader is missing)", function);
return false;
}
-
- /* For ES2, we can draw if we have a vertex program/shader). */
- return ctx->VertexProgram._Current != NULL;
-
- case API_OPENGLES:
- /* For OpenGL ES, only draw if we have vertex positions
- */
- if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled)
- return false;
break;
case API_OPENGL_CORE:
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function);
return false;
}
+ break;
- /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
- * says:
- *
- * "If there is no active program for the vertex or fragment shader
- * stages, the results of vertex and/or fragment processing will be
- * undefined. However, this is not an error."
- *
- * The fragment shader is not tested here because other state (e.g.,
- * GL_RASTERIZER_DISCARD) affects whether or not we actually care.
- */
- return ctx->VertexProgram._Current != NULL;
-
+ case API_OPENGLES:
case API_OPENGL_COMPAT:
- if (ctx->VertexProgram._Current != NULL) {
- /* Draw regardless of whether or not we have any vertex arrays.
- * (Ex: could draw a point using a constant vertex pos)
- */
- return true;
- } else {
- /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic
- * array [0]).
- */
- return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled ||
- ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled);
- }
break;
default:
if (!check_valid_to_render(ctx, caller))
return false;
- /* Not using a VBO for indices, so avoid NULL pointer derefs later.
- */
- if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL)
- return false;
-
- if (count == 0)
- return false;
-
return true;
}
}
+/**
+ * Check if we should skip the draw call even after validation was successful.
+ */
+static bool
+skip_validated_draw(struct gl_context *ctx)
+{
+ switch (ctx->API) {
+ case API_OPENGLES2:
+ /* For ES2, we can draw if we have a vertex program/shader). */
+ return ctx->VertexProgram._Current == NULL;
+
+ case API_OPENGLES:
+ /* For OpenGL ES, only draw if we have vertex positions
+ */
+ if (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled)
+ return false;
+ break;
+
+ case API_OPENGL_CORE:
+ /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
+ * says:
+ *
+ * "If there is no active program for the vertex or fragment shader
+ * stages, the results of vertex and/or fragment processing will be
+ * undefined. However, this is not an error."
+ *
+ * The fragment shader is not tested here because other state (e.g.,
+ * GL_RASTERIZER_DISCARD) affects whether or not we actually care.
+ */
+ return ctx->VertexProgram._Current == NULL;
+
+ case API_OPENGL_COMPAT:
+ if (ctx->VertexProgram._Current != NULL) {
+ /* Draw regardless of whether or not we have any vertex arrays.
+ * (Ex: could draw a point using a constant vertex pos)
+ */
+ return false;
+ } else {
+ /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic
+ * array [0]).
+ */
+ return (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled &&
+ !ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled);
+ }
+ break;
+
+ default:
+ unreachable("Invalid API value in check_valid_to_render()");
+ }
+
+ return false;
+}
+
+
/**
* Print info/data for glDrawArrays(), for debugging.
*/
struct vbo_context *vbo = vbo_context(ctx);
struct _mesa_prim prim[2];
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_bind_arrays(ctx);
/* OpenGL 4.5 says that primitive restart is ignored with non-indexed
#endif
+static bool
+skip_draw_elements(struct gl_context *ctx, GLsizei count,
+ const GLvoid *indices)
+{
+ if (count == 0)
+ return true;
+
+ /* Not using a VBO for indices, so avoid NULL pointer derefs later.
+ */
+ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL)
+ return true;
+
+ if (skip_validated_draw(ctx))
+ return true;
+
+ return false;
+}
+
+
/**
* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
* Do the rendering for a glDrawElements or glDrawRangeElements call after
struct _mesa_index_buffer ib;
struct _mesa_prim prim[1];
+ if (skip_draw_elements(ctx, count, indices))
+ return;
+
vbo_bind_arrays(ctx);
ib.count = count;
primcount))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
NULL);
}
primcount))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
basevertex);
}
return;
}
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_bind_arrays(ctx);
/* init most fields to zero */
if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_drawarraysindirect(ctx, mode, indirect);
}
if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
}
primcount, stride))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
primcount, stride);
}
primcount, stride))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
primcount, stride);
}
maxdrawcount, stride))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount,
maxdrawcount, stride);
}
maxdrawcount, stride))
return;
+ if (skip_validated_draw(ctx))
+ return;
+
vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
drawcount, maxdrawcount,
stride);