From 62a18da34153dd0e167a2944fc00812c1471c0fb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 8 Apr 2013 10:56:23 -0700 Subject: [PATCH] i965/gen7: Skip resetting SOL offsets at batch start with HW contexts. The software-tracked transform feedback offsets (svbi_0_starting_index) are incorrect in the presence of primitive restart, so we can't reliably compute offsets for our buffer pointers after a batch flush. Thanks to HW contexts, our transform feedback offsets are now saved, so we can just keep using the ones from before the batch wrap. Fixes piglit OpenGL 3.1/primitive-restart-xfb flush Reviewed-by: Paul Berry NOTE: This is a candidate for the 9.1 branch. --- src/mesa/drivers/dri/i965/gen6_sol.c | 9 +++++++++ src/mesa/drivers/dri/i965/gen7_sol_state.c | 18 ++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/i965/gen6_sol.c b/src/mesa/drivers/dri/i965/gen6_sol.c index 9c09adee00b..a7b63f67e87 100644 --- a/src/mesa/drivers/dri/i965/gen6_sol.c +++ b/src/mesa/drivers/dri/i965/gen6_sol.c @@ -159,6 +159,7 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode, struct gl_transform_feedback_object *obj) { struct brw_context *brw = brw_context(ctx); + struct intel_context *intel = &brw->intel; const struct gl_shader_program *vs_prog = ctx->Shader.CurrentVertexProgram; const struct gl_transform_feedback_info *linked_xfb_info = @@ -180,6 +181,14 @@ brw_begin_transform_feedback(struct gl_context *ctx, GLenum mode, brw->sol.svbi_0_starting_index = 0; brw->sol.svbi_0_max_index = max_index; brw->sol.offset_0_batch_start = 0; + + if (intel->gen >= 7) { + /* Ask the kernel to reset the SO offsets for any previous transform + * feedback, so we start at the start of the user's buffer. (note: these + * are not the query counters) + */ + intel->batch.needs_sol_reset = true; + } } void diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c b/src/mesa/drivers/dri/i965/gen7_sol_state.c index c83b2df7003..03709eafba9 100644 --- a/src/mesa/drivers/dri/i965/gen7_sol_state.c +++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c @@ -82,12 +82,14 @@ upload_3dstate_so_buffers(struct brw_context *brw) end = ALIGN(start + xfb_obj->Size[i], 4); assert(end <= bo->size); - /* Offset the starting offset by the current vertex index into the - * feedback buffer, offset register is always set to 0 at the start of the - * batchbuffer. + /* If we don't have hardware contexts, then we reset our offsets at the + * start of every batch, so we track the number of vertices written in + * software and increment our pointers by that many. */ - start += brw->sol.offset_0_batch_start * stride; - assert(start <= end); + if (!intel->hw_ctx) { + start += brw->sol.offset_0_batch_start * stride; + assert(start <= end); + } BEGIN_BATCH(4); OUT_BATCH(_3DSTATE_SO_BUFFER << 16 | (4 - 2)); @@ -244,7 +246,11 @@ upload_sol_state(struct brw_context *brw) /* BRW_NEW_VUE_MAP_GEOM_OUT */ upload_3dstate_so_decl_list(brw, &brw->vue_map_geom_out); - intel->batch.needs_sol_reset = true; + /* If we don't have hardware contexts, then some other client may have + * changed the SO write offsets, and we need to rewrite them. + */ + if (!intel->hw_ctx) + intel->batch.needs_sol_reset = true; } /* Finally, set up the SOL stage. This command must always follow updates to -- 2.30.2