diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/api_validate.c | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 6ccb9e7ab21..7b91fdff55f 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -35,7 +35,6 @@ #include "state.h" #include "transformfeedback.h" #include "uniforms.h" -#include "vbo/vbo.h" #include "program/prog_print.h" @@ -829,6 +828,69 @@ need_xfb_remaining_prims_check(const struct gl_context *ctx) } +/** + * Figure out the number of transform feedback primitives that will be output + * considering the drawing mode, number of vertices, and instance count, + * assuming that no geometry shading is done and primitive restart is not + * used. + * + * This is used by driver back-ends in implementing the PRIMITIVES_GENERATED + * and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries. It is also used to + * pre-validate draw calls in GLES3 (where draw calls only succeed if there is + * enough room in the transform feedback buffer for the result). + */ +static size_t +count_tessellated_primitives(GLenum mode, GLuint count, GLuint num_instances) +{ + size_t num_primitives; + switch (mode) { + case GL_POINTS: + num_primitives = count; + break; + case GL_LINE_STRIP: + num_primitives = count >= 2 ? count - 1 : 0; + break; + case GL_LINE_LOOP: + num_primitives = count >= 2 ? count : 0; + break; + case GL_LINES: + num_primitives = count / 2; + break; + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + num_primitives = count >= 3 ? count - 2 : 0; + break; + case GL_TRIANGLES: + num_primitives = count / 3; + break; + case GL_QUAD_STRIP: + num_primitives = count >= 4 ? ((count / 2) - 1) * 2 : 0; + break; + case GL_QUADS: + num_primitives = (count / 4) * 2; + break; + case GL_LINES_ADJACENCY: + num_primitives = count / 4; + break; + case GL_LINE_STRIP_ADJACENCY: + num_primitives = count >= 4 ? count - 3 : 0; + break; + case GL_TRIANGLES_ADJACENCY: + num_primitives = count / 6; + break; + case GL_TRIANGLE_STRIP_ADJACENCY: + num_primitives = count >= 6 ? (count - 4) / 2 : 0; + break; + default: + assert(!"Unexpected primitive type in count_tessellated_primitives"); + num_primitives = 0; + break; + } + return num_primitives * num_instances; +} + + static bool validate_draw_arrays(struct gl_context *ctx, const char *func, GLenum mode, GLsizei count, GLsizei numInstances) @@ -849,7 +911,7 @@ validate_draw_arrays(struct gl_context *ctx, const char *func, if (need_xfb_remaining_prims_check(ctx)) { struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; - size_t prim_count = vbo_count_tessellated_primitives(mode, count, numInstances); + size_t prim_count = count_tessellated_primitives(mode, count, numInstances); if (xfb_obj->GlesRemainingPrims < prim_count) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(exceeds transform feedback size)", func); @@ -937,7 +999,7 @@ _mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode, size_t xfb_prim_count = 0; for (i = 0; i < primcount; ++i) - xfb_prim_count += vbo_count_tessellated_primitives(mode, count[i], 1); + xfb_prim_count += count_tessellated_primitives(mode, count[i], 1); if (xfb_obj->GlesRemainingPrims < xfb_prim_count) { _mesa_error(ctx, GL_INVALID_OPERATION, |