i965/gen7: Flush the batch between transform feedbacks.
authorEric Anholt <eric@anholt.net>
Fri, 30 Dec 2011 02:24:02 +0000 (18:24 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 6 Jan 2012 17:17:04 +0000 (09:17 -0800)
We need the kernel to reset our pointers to 0 in between.  Note that
the initialization of function pointer had to move to after
InitContext since we didn't have intel->gen set up yet.

Fixes piglit EXT_transform_feedback/immediate-reuse

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/gen7_sol_state.c

index f5c9d7aa3985158bc5112dee43c6263de55b0ad5..48c141c9c2e7a3d681b087aa5e3aeeb344148eab 100644 (file)
@@ -109,7 +109,8 @@ static void brwPrepareExecBegin(struct gl_context *ctx)
    }
 }
 
-static void brwInitDriverFunctions( struct dd_function_table *functions )
+static void brwInitDriverFunctions(struct intel_screen *screen,
+                                  struct dd_function_table *functions)
 {
    intelInitDriverFunctions( functions );
 
@@ -118,7 +119,11 @@ static void brwInitDriverFunctions( struct dd_function_table *functions )
 
    functions->PrepareExecBegin = brwPrepareExecBegin;
    functions->BeginTransformFeedback = brw_begin_transform_feedback;
-   functions->EndTransformFeedback = brw_end_transform_feedback;
+
+   if (screen->gen >= 7)
+      functions->EndTransformFeedback = gen7_end_transform_feedback;
+   else
+      functions->EndTransformFeedback = brw_end_transform_feedback;
 }
 
 bool
@@ -127,6 +132,8 @@ brwCreateContext(int api,
                 __DRIcontext *driContextPriv,
                 void *sharedContextPrivate)
 {
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
+   struct intel_screen *screen = sPriv->driverPrivate;
    struct dd_function_table functions;
    struct brw_context *brw = rzalloc(NULL, struct brw_context);
    struct intel_context *intel = &brw->intel;
@@ -138,7 +145,7 @@ brwCreateContext(int api,
       return false;
    }
 
-   brwInitDriverFunctions( &functions );
+   brwInitDriverFunctions(screen, &functions);
 
    if (!intelInitContext( intel, api, mesaVis, driContextPriv,
                          sharedContextPrivate, &functions )) {
index fb41fd1f04f4f215010d3c3bd93659986a2d00ef..873e172b88c4c58528afa43336c492488262daef 100644 (file)
@@ -1093,6 +1093,11 @@ void
 brw_end_transform_feedback(struct gl_context *ctx,
                            struct gl_transform_feedback_object *obj);
 
+/* gen7_sol_state.c */
+void
+gen7_end_transform_feedback(struct gl_context *ctx,
+                           struct gl_transform_feedback_object *obj);
+
 
 
 /*======================================================================
index c4e0622a6e0d43e97dfaa894747ee44b1c004644..81ffc0e7adecece9ebb833ee8cd3408ebaa88c45 100644 (file)
@@ -264,3 +264,19 @@ const struct brw_tracked_state gen7_sol_state = {
    },
    .emit = upload_sol_state,
 };
+
+void
+gen7_end_transform_feedback(struct gl_context *ctx,
+                           struct gl_transform_feedback_object *obj)
+{
+   /* Because we have to rely on the kernel to reset our SO write offsets, and
+    * we only get to do it once per batchbuffer, flush the batch after feedback
+    * so another transform feedback can get the write offset reset it needs.
+    *
+    * This also covers any cache flushing required.
+    */
+   struct brw_context *brw = brw_context(ctx);
+   struct intel_context *intel = &brw->intel;
+
+   intel_batchbuffer_flush(intel);
+}