summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-12-09 17:00:23 +0100
committerChristoph Bumiller <[email protected]>2011-12-15 18:50:44 +0100
commit14bb957b996dcc5392b8fa589bd3ffa5c55cb6b4 (patch)
tree1dce64c3156c0df8ab638050dcc62365b6fb8197
parent3baaa1bbd72f67f6bc7374b2b6a16b0322006a65 (diff)
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.
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h3
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c15
-rw-r--r--src/mesa/main/api_validate.c34
-rw-r--r--src/mesa/main/api_validate.h10
-rw-r--r--src/mesa/main/dd.h3
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/main/transformfeedback.c61
-rw-r--r--src/mesa/main/transformfeedback.h6
-rw-r--r--src/mesa/main/varray.h7
-rw-r--r--src/mesa/main/vtxfmt.c1
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c3
-rw-r--r--src/mesa/state_tracker/st_cb_xformfb.c13
-rw-r--r--src/mesa/state_tracker/st_draw.c4
-rw-r--r--src/mesa/state_tracker/st_draw.h6
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c3
-rw-r--r--src/mesa/tnl/t_draw.c3
-rw-r--r--src/mesa/tnl/tnl.h3
-rw-r--r--src/mesa/vbo/vbo.h4
-rw-r--r--src/mesa/vbo/vbo_exec_array.c93
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c3
-rw-r--r--src/mesa/vbo/vbo_rebase.c3
-rw-r--r--src/mesa/vbo/vbo_save_api.c11
-rw-r--r--src/mesa/vbo/vbo_save_draw.c3
-rw-r--r--src/mesa/vbo/vbo_split_copy.c3
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c3
26 files changed, 205 insertions, 98 deletions
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
@@ -999,6 +999,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)
{
GET_CURRENT_CONTEXT(ctx);
@@ -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 )
&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;