summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2011-12-09 16:40:32 -0800
committerPaul Berry <stereotype441@gmail.com>2011-12-20 15:00:29 -0800
commit63cf7fad13fc9cfdd2ae7b031426f79107000300 (patch)
tree1db2139bac237abcd17886292b9bd51e97583934
parentc3161b629f342b21756f4fdb4414417b82d3e033 (diff)
i965: Flush pipeline on EndTransformFeedback.
A common use case for transform feedback is to perform one draw operation that writes transform feedback output to a buffer, followed by a second draw operation that consumes that buffer as vertex input. Since vertex input is consumed at an earlier pipeline stage than writing transform feedback output, we need to flush the pipeline to ensure that the transform feedback output is completely written before the data is consumed. In an ideal world, we would do some dependency tracking, so that we would only flush the pipeline if the next draw call was about to consume data generated by a previous draw call in the same batch. However, since we don't have that sort of dependency tracking infrastructure right now, we just unconditionally flush the buffer every time glEndTransformFeedback() is called. This will cause a performance hit compared to the ideal case (since we will sometimes flush the pipeline unnecessarily), but fortunately the performance hit will be confined to circumstances where transform feedback is in use. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h5
-rw-r--r--src/mesa/drivers/dri/i965/gen6_sol.c16
3 files changed, 22 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index d8cad54667..2096be9f86 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -117,6 +117,7 @@ static void brwInitDriverFunctions( struct dd_function_table *functions )
brw_init_queryobj_functions(functions);
functions->PrepareExecBegin = brwPrepareExecBegin;
+ functions->EndTransformFeedback = brw_end_transform_feedback;
}
bool
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index febd4fe436..6fa71a3c14 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1076,6 +1076,11 @@ brw_update_sol_surface(struct brw_context *brw,
bool
brw_fprog_uses_noperspective(const struct gl_fragment_program *fprog);
+/* gen6_sol.c */
+void
+brw_end_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj);
+
/*======================================================================
diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c
index 491b39cce1..38aedcc429 100644
--- a/src/mesa/drivers/dri/i965/gen6_sol.c
+++ b/src/mesa/drivers/dri/i965/gen6_sol.c
@@ -27,6 +27,7 @@
*/
#include "brw_context.h"
+#include "intel_batchbuffer.h"
#include "brw_defines.h"
static void
@@ -69,3 +70,18 @@ const struct brw_tracked_state gen6_sol_surface = {
},
.emit = gen6_update_sol_surfaces,
};
+
+void
+brw_end_transform_feedback(struct gl_context *ctx,
+ struct gl_transform_feedback_object *obj)
+{
+ /* After EndTransformFeedback, it's likely that the client program will try
+ * to draw using the contents of the transform feedback buffer as vertex
+ * input. In order for this to work, we need to flush the data through at
+ * least the GS stage of the pipeline, and flush out the render cache. For
+ * simplicity, just do a full flush.
+ */
+ struct brw_context *brw = brw_context(ctx);
+ struct intel_context *intel = &brw->intel;
+ intel_batchbuffer_emit_mi_flush(intel);
+}