summaryrefslogtreecommitdiffstats
path: root/src/mesa/vbo
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 /src/mesa/vbo
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.
Diffstat (limited to 'src/mesa/vbo')
-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
8 files changed, 112 insertions, 11 deletions
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;