From: Marek Olšák Date: Fri, 9 Dec 2011 16:00:23 +0000 (+0100) Subject: mesa: implement DrawTransformFeedback from ARB_transform_feedback2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14bb957b996dcc5392b8fa589bd3ffa5c55cb6b4;p=mesa.git mesa: implement DrawTransformFeedback from ARB_transform_feedback2 It's like DrawArrays, but the count is taken from a transform feedback object. This removes DrawTransformFeedback from dd_function_table and adds the same function to GLvertexformat (with the function parameters matching GL). The vbo_draw_func callback has a new parameter "struct gl_transform_feedback_object *tfb_vertcount". The rest of the code just validates states and forwards the transform feedback object into vbo_draw_func. --- diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index bf3c95cbebc..6627a484a42 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -517,7 +517,8 @@ void brw_draw_prims( struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index ) + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount ) { bool retval; diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index 1fe417296f6..b91041932e1 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -41,7 +41,8 @@ void brw_draw_prims( struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index ); + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c index d8b331cca76..de04d1897c1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -219,7 +219,8 @@ TAG(vbo_render_prims)(struct gl_context *ctx, const struct gl_client_array **arr const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, - GLuint min_index, GLuint max_index); + GLuint min_index, GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount); static GLboolean vbo_maybe_split(struct gl_context *ctx, const struct gl_client_array **arrays, @@ -430,7 +431,8 @@ TAG(vbo_render_prims)(struct gl_context *ctx, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, - GLuint min_index, GLuint max_index) + GLuint min_index, GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount) { struct nouveau_render_state *render = to_render_state(ctx); @@ -464,7 +466,8 @@ TAG(vbo_check_render_prims)(struct gl_context *ctx, const struct _mesa_prim *prims, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, - GLuint min_index, GLuint max_index) + GLuint min_index, GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount) { struct nouveau_context *nctx = to_nouveau_context(ctx); @@ -472,11 +475,13 @@ TAG(vbo_check_render_prims)(struct gl_context *ctx, if (nctx->fallback == HWTNL) TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib, - index_bounds_valid, min_index, max_index); + index_bounds_valid, min_index, max_index, + tfb_vertcount); if (nctx->fallback == SWTNL) _tnl_vbo_draw_prims(ctx, arrays, prims, nr_prims, ib, - index_bounds_valid, min_index, max_index); + index_bounds_valid, min_index, max_index, + tfb_vertcount); } void diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index efdecb212aa..945f12752d3 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -474,3 +474,37 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, return GL_TRUE; } + + +#if FEATURE_EXT_transform_feedback + +GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, + GLenum mode, + struct gl_transform_feedback_object *obj) +{ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (!_mesa_valid_prim_mode(ctx, mode)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawTransformFeedback(mode)"); + return GL_FALSE; + } + + if (!obj) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback(name)"); + return GL_FALSE; + } + + if (!obj->EndedAnytime) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback"); + return GL_FALSE; + } + + if (!check_valid_to_render(ctx, "glDrawTransformFeedback")) { + return GL_FALSE; + } + + return GL_TRUE; +} + +#endif diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h index 7d6a66012df..f4948424c36 100644 --- a/src/mesa/main/api_validate.h +++ b/src/mesa/main/api_validate.h @@ -29,9 +29,11 @@ #include "glheader.h" +#include "mfeatures.h" struct gl_buffer_object; struct gl_context; +struct gl_transform_feedback_object; extern GLuint @@ -70,5 +72,13 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, const GLvoid *indices, GLsizei primcount, GLint basevertex); +#if FEATURE_EXT_transform_feedback + +extern GLboolean +_mesa_validate_DrawTransformFeedback(struct gl_context *ctx, + GLenum mode, + struct gl_transform_feedback_object *obj); + +#endif #endif diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index d6f70d1c49e..01cfff8ab7c 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -964,8 +964,6 @@ struct dd_function_table { struct gl_transform_feedback_object *obj); void (*ResumeTransformFeedback)(struct gl_context *ctx, struct gl_transform_feedback_object *obj); - void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj); /** * \name GL_NV_texture_barrier interface @@ -1194,6 +1192,7 @@ typedef struct { void (GLAPIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex); + void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint name); /*@}*/ /** diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 19343497689..0e29dc0dc79 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2355,6 +2355,8 @@ struct gl_transform_feedback_object GLint RefCount; GLboolean Active; /**< Is transform feedback enabled? */ GLboolean Paused; /**< Is transform feedback paused? */ + GLboolean EndedAnytime; /**< Has EndTransformFeedback been called + at least once? */ /** The feedback buffers */ GLuint BufferNames[MAX_FEEDBACK_ATTRIBS]; diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c index 799245d4ed5..824f66a3528 100644 --- a/src/mesa/main/transformfeedback.c +++ b/src/mesa/main/transformfeedback.c @@ -294,18 +294,6 @@ resume_transform_feedback(struct gl_context *ctx, /* nop */ } -/** Default fallback for ctx->Driver.DrawTransformFeedback() */ -static void -draw_transform_feedback(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj) -{ - /* XXX to do */ - /* - * Get number of vertices in obj's feedback buffer. - * Call ctx->Exec.DrawArrays(mode, 0, count); - */ -} - /** * Plug in default device driver functions for transform feedback. @@ -320,7 +308,6 @@ _mesa_init_transform_feedback_functions(struct dd_function_table *driver) driver->EndTransformFeedback = end_transform_feedback; driver->PauseTransformFeedback = pause_transform_feedback; driver->ResumeTransformFeedback = resume_transform_feedback; - driver->DrawTransformFeedback = draw_transform_feedback; } @@ -342,7 +329,6 @@ _mesa_init_transform_feedback_dispatch(struct _glapi_table *disp) SET_IsTransformFeedback(disp, _mesa_IsTransformFeedback); SET_PauseTransformFeedback(disp, _mesa_PauseTransformFeedback); SET_ResumeTransformFeedback(disp, _mesa_ResumeTransformFeedback); - SET_DrawTransformFeedback(disp, _mesa_DrawTransformFeedback); } @@ -401,6 +387,7 @@ _mesa_EndTransformFeedback(void) FLUSH_VERTICES(ctx, _NEW_TRANSFORM_FEEDBACK); ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; + ctx->TransformFeedback.CurrentObject->EndedAnytime = GL_TRUE; assert(ctx->Driver.EndTransformFeedback); ctx->Driver.EndTransformFeedback(ctx, obj); @@ -714,8 +701,8 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, -static struct gl_transform_feedback_object * -lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) +struct gl_transform_feedback_object * +_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) { if (name == 0) { return ctx->TransformFeedback.DefaultObject; @@ -780,7 +767,7 @@ _mesa_IsTransformFeedback(GLuint name) ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - if (name && lookup_transform_feedback_object(ctx, name)) + if (name && _mesa_lookup_transform_feedback_object(ctx, name)) return GL_TRUE; else return GL_FALSE; @@ -809,7 +796,7 @@ _mesa_BindTransformFeedback(GLenum target, GLuint name) return; } - obj = lookup_transform_feedback_object(ctx, name); + obj = _mesa_lookup_transform_feedback_object(ctx, name); if (!obj) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTransformFeedback(name=%u)", name); @@ -844,7 +831,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names) for (i = 0; i < n; i++) { if (names[i] > 0) { struct gl_transform_feedback_object *obj - = lookup_transform_feedback_object(ctx, names[i]); + = _mesa_lookup_transform_feedback_object(ctx, names[i]); if (obj) { if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -912,40 +899,4 @@ _mesa_ResumeTransformFeedback(void) ctx->Driver.ResumeTransformFeedback(ctx, obj); } - -/** - * Draw the vertex data in a transform feedback object. - * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. - * \param name the transform feedback object - * The number of vertices comes from the transform feedback object. - * User still has to setup of the vertex attribute info with - * glVertexPointer, glColorPointer, etc. - * Part of GL_ARB_transform_feedback2. - */ -void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - lookup_transform_feedback_object(ctx, name); - - if (mode > GL_POLYGON) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glDrawTransformFeedback(mode=0x%x)", mode); - return; - } - if (!obj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawTransformFeedback(name = %u)", name); - return; - } - - /* XXX check if EndTransformFeedback has never been called while - * the object was bound - */ - - assert(ctx->Driver.DrawTransformFeedback); - ctx->Driver.DrawTransformFeedback(ctx, mode, obj); -} - #endif /* FEATURE_EXT_transform_feedback */ diff --git a/src/mesa/main/transformfeedback.h b/src/mesa/main/transformfeedback.h index 9447effa928..8a6672d58de 100644 --- a/src/mesa/main/transformfeedback.h +++ b/src/mesa/main/transformfeedback.h @@ -87,6 +87,9 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, /*** GL_ARB_transform_feedback2 ***/ +struct gl_transform_feedback_object * +_mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name); + extern void GLAPIENTRY _mesa_GenTransformFeedbacks(GLsizei n, GLuint *names); @@ -105,9 +108,6 @@ _mesa_PauseTransformFeedback(void); extern void GLAPIENTRY _mesa_ResumeTransformFeedback(void); -extern void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name); - #else /* FEATURE_EXT_transform_feedback */ static inline GLboolean diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index 6fcc0a33627..b6041bd787e 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -245,6 +245,13 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, const GLvoid *indices, GLint basevertex); +#if FEATURE_EXT_transform_feedback + +extern void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name); + +#endif + extern void GLAPIENTRY _mesa_PrimitiveRestartIndex(GLuint index); diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c index 03735d779b8..f3cca937d0c 100644 --- a/src/mesa/main/vtxfmt.c +++ b/src/mesa/main/vtxfmt.c @@ -107,6 +107,7 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt ) SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced); SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced); SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex); + SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback); /* GL_NV_vertex_program */ SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV); diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 32d465c5cce..2c21dc9a776 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -251,7 +251,8 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) rs->array[0].Ptr = (GLubyte *) v; /* draw the point */ - st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1); + st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1, + NULL); /* restore draw's rasterization stage depending on rendermode */ if (ctx->RenderMode == GL_FEEDBACK) { diff --git a/src/mesa/state_tracker/st_cb_xformfb.c b/src/mesa/state_tracker/st_cb_xformfb.c index e415b186aa7..a17b54d326e 100644 --- a/src/mesa/state_tracker/st_cb_xformfb.c +++ b/src/mesa/state_tracker/st_cb_xformfb.c @@ -105,18 +105,6 @@ st_resume_transform_feedback(struct gl_context *ctx, } -static void -st_draw_transform_feedback(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj) -{ - /* XXX to do */ - /* - * Get number of vertices in obj's feedback buffer. - * Call ctx->Exec.DrawArrays(mode, 0, count); - */ -} - - void st_init_xformfb_functions(struct dd_function_table *functions) { @@ -128,7 +116,6 @@ st_init_xformfb_functions(struct dd_function_table *functions) functions->EndTransformFeedback = st_end_transform_feedback; functions->PauseTransformFeedback = st_pause_transform_feedback; functions->ResumeTransformFeedback = st_resume_transform_feedback; - functions->DrawTransformFeedback = st_draw_transform_feedback; } #endif /* FEATURE_EXT_transform_feedback */ diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index fd1c8ee4879..86478bbceba 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -926,7 +926,8 @@ st_draw_vbo(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index) + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; @@ -939,6 +940,7 @@ st_draw_vbo(struct gl_context *ctx, /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); + assert(!tfb_vertcount); if (ib) { /* Gallium probably doesn't want this in some cases. */ diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h index a7b50ce977a..2623cdbb1ff 100644 --- a/src/mesa/state_tracker/st_draw.h +++ b/src/mesa/state_tracker/st_draw.h @@ -55,7 +55,8 @@ st_draw_vbo(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index); + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount); extern void st_feedback_draw_vbo(struct gl_context *ctx, @@ -65,7 +66,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index); + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount); /* Internal function: */ diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index a7e6a0f1b71..4c1e67495b7 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -97,7 +97,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index) + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 03424d7a494..83ded1949c9 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -430,7 +430,8 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index) + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount) { if (!index_bounds_valid) vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index); diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index 24a0c725008..d3889811e21 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -92,7 +92,8 @@ _tnl_vbo_draw_prims( struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index); + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount ); extern void _mesa_load_tracked_matrices(struct gl_context *ctx); diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 9fbb07f3d72..f357657afa7 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -36,6 +36,7 @@ struct gl_client_array; struct gl_context; +struct gl_transform_feedback_object; struct _mesa_prim { GLuint mode:8; /**< GL_POINTS, GL_LINES, GL_QUAD_STRIP, etc */ @@ -77,7 +78,8 @@ typedef void (*vbo_draw_func)( struct gl_context *ctx, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, - GLuint max_index ); + GLuint max_index, + struct gl_transform_feedback_object *tfb_vertcount ); diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 97221a54d44..a6e41e9c5e5 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -34,6 +34,7 @@ #include "main/bufferobj.h" #include "main/enums.h" #include "main/macros.h" +#include "main/transformfeedback.h" #include "vbo_context.h" @@ -608,7 +609,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, /* draw one or two prims */ check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, exec->array.inputs, prim, primCount, NULL, - GL_TRUE, start, start + count - 1); + GL_TRUE, start, start + count - 1, NULL); } } else { @@ -618,7 +619,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, - GL_TRUE, start, start + count - 1); + GL_TRUE, start, start + count - 1, + NULL); } } @@ -824,7 +826,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, - index_bounds_valid, start, end ); + index_bounds_valid, start, end, NULL ); } @@ -1168,7 +1170,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib, - GL_FALSE, ~0, ~0); + GL_FALSE, ~0, ~0, NULL); } else { /* render one prim at a time */ for (i = 0; i < primcount; i++) { @@ -1193,7 +1195,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, check_buffers_are_unmapped(exec->array.inputs); vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, - GL_FALSE, ~0, ~0); + GL_FALSE, ~0, ~0, NULL); } } @@ -1245,6 +1247,76 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, basevertex); } +#if FEATURE_EXT_transform_feedback + +static void +vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, + struct gl_transform_feedback_object *obj, + GLuint numInstances) +{ + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; + struct _mesa_prim prim[2]; + + vbo_bind_arrays(ctx); + + /* Again... because we may have changed the bitmask of per-vertex varying + * attributes. If we regenerate the fixed-function vertex program now + * we may be able to prune down the number of vertex attributes which we + * need in the shader. + */ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* init most fields to zero */ + memset(prim, 0, sizeof(prim)); + prim[0].begin = 1; + prim[0].end = 1; + prim[0].mode = mode; + prim[0].num_instances = numInstances; + + /* Maybe we should do some primitive splitting for primitive restart + * (like in DrawArrays), but we have no way to know how many vertices + * will be rendered. */ + + check_buffers_are_unmapped(exec->array.inputs); + vbo->draw_prims(ctx, exec->array.inputs, prim, 1, NULL, + GL_TRUE, 0, 0, obj); +} + +/** + * Like DrawArrays, but take the count from a transform feedback object. + * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. + * \param name the transform feedback object + * User still has to setup of the vertex attribute info with + * glVertexPointer, glColorPointer, etc. + * Part of GL_ARB_transform_feedback2. + */ +static void GLAPIENTRY +vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj = + _mesa_lookup_transform_feedback_object(ctx, name); + + if (MESA_VERBOSE & VERBOSE_DRAW) + _mesa_debug(ctx, "glDrawTransformFeedback(%s, %d)\n", + _mesa_lookup_enum_by_nr(mode), name); + + if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj)) { + return; + } + + FLUSH_CURRENT(ctx, 0); + + if (!_mesa_valid_to_render(ctx, "glDrawTransformFeedback")) { + return; + } + + vbo_draw_transform_feedback(ctx, mode, obj, 1); +} + +#endif /** * Plug in the immediate-mode vertex array drawing commands into the @@ -1263,6 +1335,7 @@ vbo_exec_array_init( struct vbo_exec_context *exec ) exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced; exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced; exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex; + exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback; } @@ -1338,3 +1411,13 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode, vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices, primcount, basevertex); } + +#if FEATURE_EXT_transform_feedback + +void GLAPIENTRY +_mesa_DrawTransformFeedback(GLenum mode, GLuint name) +{ + vbo_exec_DrawTransformFeedback(mode, name); +} + +#endif diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 4962b54e1f7..dd5363bebe4 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -411,7 +411,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) NULL, GL_TRUE, 0, - exec->vtx.vert_count - 1); + exec->vtx.vert_count - 1, + NULL); /* If using a real VBO, get new storage -- unless asked not to. */ diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index 97c8d1297a2..597a8f46994 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -233,7 +233,8 @@ void vbo_rebase_prims( struct gl_context *ctx, ib, GL_TRUE, 0, - max_index - min_index ); + max_index - min_index, + NULL ); if (tmp_indices) free(tmp_indices); diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 9d8bada04cf..9521367475e 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -998,6 +998,16 @@ _save_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, } +static void GLAPIENTRY +_save_DrawTransformFeedback(GLenum mode, GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; + (void) name; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback"); +} + + static void GLAPIENTRY _save_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { @@ -1347,6 +1357,7 @@ _save_vtxfmt_init(struct gl_context *ctx) vfmt->DrawRangeElements = _save_DrawRangeElements; vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex; vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex; + vfmt->DrawTransformFeedback = _save_DrawTransformFeedback; vfmt->MultiDrawElementsEXT = _save_MultiDrawElements; vfmt->MultiDrawElementsBaseVertex = _save_MultiDrawElementsBaseVertex; } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 0773786b362..fa93ca48f43 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -299,7 +299,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) NULL, GL_TRUE, 0, /* Node is a VBO, so this is ok */ - node->count - 1); + node->count - 1, + NULL); } } diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 4dcf71ef56e..b53293c3120 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -196,7 +196,8 @@ flush( struct copy_context *copy ) ©->dstib, GL_TRUE, 0, - copy->dstbuf_nr - 1 ); + copy->dstbuf_nr - 1, + NULL ); /* Reset all pointers: */ diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index f6aa576b6c8..9e596f66891 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -89,7 +89,8 @@ static void flush_vertex( struct split_context *split ) split->ib ? &ib : NULL, !split->ib, split->min_index, - split->max_index); + split->max_index, + NULL); split->dstprim_nr = 0; split->min_index = ~0;