mesa/vbo: move some Draw checks out of validation
These checks do not generate any errors. Move them so we can add KHR_no_error support and still make sure we do these checks. Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
@@ -290,15 +290,6 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
|
|||||||
"%s(tess ctrl shader is missing)", function);
|
"%s(tess ctrl shader is missing)", function);
|
||||||
return false;
|
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;
|
break;
|
||||||
|
|
||||||
case API_OPENGL_CORE:
|
case API_OPENGL_CORE:
|
||||||
@@ -312,32 +303,10 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
|
|||||||
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function);
|
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
|
case API_OPENGLES:
|
||||||
* 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:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -700,14 +669,6 @@ validate_DrawElements_common(struct gl_context *ctx,
|
|||||||
if (!check_valid_to_render(ctx, caller))
|
if (!check_valid_to_render(ctx, caller))
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -179,6 +179,60 @@ check_draw_arrays_data(struct gl_context *ctx, GLint start, GLsizei count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Print info/data for glDrawArrays(), for debugging.
|
||||||
*/
|
*/
|
||||||
@@ -410,6 +464,9 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
|
|||||||
struct vbo_context *vbo = vbo_context(ctx);
|
struct vbo_context *vbo = vbo_context(ctx);
|
||||||
struct _mesa_prim prim[2];
|
struct _mesa_prim prim[2];
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_bind_arrays(ctx);
|
vbo_bind_arrays(ctx);
|
||||||
|
|
||||||
/* OpenGL 4.5 says that primitive restart is ignored with non-indexed
|
/* OpenGL 4.5 says that primitive restart is ignored with non-indexed
|
||||||
@@ -739,6 +796,25 @@ dump_element_buffer(struct gl_context *ctx, GLenum type)
|
|||||||
#endif
|
#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.
|
* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
|
||||||
* Do the rendering for a glDrawElements or glDrawRangeElements call after
|
* Do the rendering for a glDrawElements or glDrawRangeElements call after
|
||||||
@@ -757,6 +833,9 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
|
|||||||
struct _mesa_index_buffer ib;
|
struct _mesa_index_buffer ib;
|
||||||
struct _mesa_prim prim[1];
|
struct _mesa_prim prim[1];
|
||||||
|
|
||||||
|
if (skip_draw_elements(ctx, count, indices))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_bind_arrays(ctx);
|
vbo_bind_arrays(ctx);
|
||||||
|
|
||||||
ib.count = count;
|
ib.count = count;
|
||||||
@@ -1230,6 +1309,9 @@ vbo_exec_MultiDrawElements(GLenum mode,
|
|||||||
primcount))
|
primcount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
@@ -1248,6 +1330,9 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
|
|||||||
primcount))
|
primcount))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
|
||||||
basevertex);
|
basevertex);
|
||||||
}
|
}
|
||||||
@@ -1275,6 +1360,9 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_bind_arrays(ctx);
|
vbo_bind_arrays(ctx);
|
||||||
|
|
||||||
/* init most fields to zero */
|
/* init most fields to zero */
|
||||||
@@ -1482,6 +1570,9 @@ vbo_exec_DrawArraysIndirect(GLenum mode, const GLvoid *indirect)
|
|||||||
if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
|
if (!_mesa_validate_DrawArraysIndirect(ctx, mode, indirect))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_drawarraysindirect(ctx, mode, indirect);
|
vbo_validated_drawarraysindirect(ctx, mode, indirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1499,6 +1590,9 @@ vbo_exec_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect)
|
|||||||
if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
|
if (!_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
|
vbo_validated_drawelementsindirect(ctx, mode, type, indirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1521,6 +1615,9 @@ vbo_exec_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
|
|||||||
primcount, stride))
|
primcount, stride))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
|
vbo_validated_multidrawarraysindirect(ctx, mode, indirect,
|
||||||
primcount, stride);
|
primcount, stride);
|
||||||
}
|
}
|
||||||
@@ -1546,6 +1643,9 @@ vbo_exec_MultiDrawElementsIndirect(GLenum mode, GLenum type,
|
|||||||
primcount, stride))
|
primcount, stride))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
|
vbo_validated_multidrawelementsindirect(ctx, mode, type, indirect,
|
||||||
primcount, stride);
|
primcount, stride);
|
||||||
}
|
}
|
||||||
@@ -1634,6 +1734,9 @@ vbo_exec_MultiDrawArraysIndirectCount(GLenum mode, GLintptr indirect,
|
|||||||
maxdrawcount, stride))
|
maxdrawcount, stride))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount,
|
vbo_validated_multidrawarraysindirectcount(ctx, mode, indirect, drawcount,
|
||||||
maxdrawcount, stride);
|
maxdrawcount, stride);
|
||||||
}
|
}
|
||||||
@@ -1662,6 +1765,9 @@ vbo_exec_MultiDrawElementsIndirectCount(GLenum mode, GLenum type,
|
|||||||
maxdrawcount, stride))
|
maxdrawcount, stride))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (skip_validated_draw(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
|
vbo_validated_multidrawelementsindirectcount(ctx, mode, type, indirect,
|
||||||
drawcount, maxdrawcount,
|
drawcount, maxdrawcount,
|
||||||
stride);
|
stride);
|
||||||
|
Reference in New Issue
Block a user