From 04a11b5f5e22155e5816e2da560b485eb0eaaec9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 27 Jul 2012 21:07:48 -0700 Subject: [PATCH] i965/gen6+: Add support for edge flags. Fixes the 3 new piglit edgeflag tests. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=40707 Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/brw_defines.h | 1 + src/mesa/drivers/dri/i965/brw_draw_upload.c | 50 +++++++++++++++++++-- src/mesa/drivers/dri/i965/brw_vs.c | 6 ++- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 73ade0a153a..3605c188d37 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -1008,6 +1008,7 @@ enum brw_message_target { # define BRW_VE0_FORMAT_SHIFT 16 # define BRW_VE0_VALID (1 << 26) # define GEN6_VE0_VALID (1 << 25) +# define GEN6_VE0_EDGE_FLAG_ENABLE (1 << 15) # define BRW_VE0_SRC_OFFSET_SHIFT 0 # define BRW_VE1_COMPONENT_NOSTORE 0 # define BRW_VE1_COMPONENT_STORE_SRC 1 diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index b606de226b1..9c41c5358a3 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -366,6 +366,18 @@ static void brw_prepare_vertices(struct brw_context *brw) struct brw_vertex_element *upload[VERT_ATTRIB_MAX]; GLuint nr_uploads = 0; + /* _NEW_POLYGON + * + * On gen6+, edge flags don't end up in the VUE (either in or out of the + * VS). Instead, they're uploaded as the last vertex element, and the data + * is passed sideband through the fixed function units. So, we need to + * prepare the vertex buffer for it, but it's not present in inputs_read. + */ + if (intel->gen >= 6 && (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL)) { + vs_inputs |= VERT_BIT_EDGEFLAG; + } + /* First build an array of pointers to ve's in vb.inputs_read */ if (0) @@ -707,6 +719,8 @@ static void brw_emit_vertices(struct brw_context *brw) assert(nr_elements <= 18); } + struct brw_vertex_element *gen6_edgeflag_input = NULL; + BEGIN_BATCH(1 + nr_elements * 2); OUT_BATCH((_3DSTATE_VERTEX_ELEMENTS << 16) | (2 * nr_elements - 1)); for (i = 0; i < brw->vb.nr_enabled; i++) { @@ -727,9 +741,19 @@ static void brw_emit_vertices(struct brw_context *brw) * glEdgeFlagPointer, on the other hand, gives us an unnormalized * integer ubyte. Just rewrite that to convert to a float. */ - if (input->attrib == VERT_ATTRIB_EDGEFLAG && - format == BRW_SURFACEFORMAT_R8_UINT) - format = BRW_SURFACEFORMAT_R8_SSCALED; + if (input->attrib == VERT_ATTRIB_EDGEFLAG) { + /* Gen6+ passes edgeflag as sideband along with the vertex, instead + * of in the VUE. We have to upload it sideband as the last vertex + * element according to the B-Spec. + */ + if (intel->gen >= 6) { + gen6_edgeflag_input = input; + continue; + } + + if (format == BRW_SURFACEFORMAT_R8_UINT) + format = BRW_SURFACEFORMAT_R8_SSCALED; + } switch (input->glarray->Size) { case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; @@ -765,6 +789,24 @@ static void brw_emit_vertices(struct brw_context *brw) ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT)); } + if (intel->gen >= 6 && gen6_edgeflag_input) { + uint32_t format = get_surface_type(gen6_edgeflag_input->glarray->Type, + gen6_edgeflag_input->glarray->Size, + gen6_edgeflag_input->glarray->Format, + gen6_edgeflag_input->glarray->Normalized, + gen6_edgeflag_input->glarray->Integer); + + OUT_BATCH((gen6_edgeflag_input->buffer << GEN6_VE0_INDEX_SHIFT) | + GEN6_VE0_VALID | + GEN6_VE0_EDGE_FLAG_ENABLE | + (format << BRW_VE0_FORMAT_SHIFT) | + (gen6_edgeflag_input->offset << BRW_VE0_SRC_OFFSET_SHIFT)); + OUT_BATCH((BRW_VE1_COMPONENT_STORE_SRC << BRW_VE1_COMPONENT_0_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) | + (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_3_SHIFT)); + } + if (brw->vs.prog_data->uses_vertexid) { uint32_t dw0 = 0, dw1 = 0; @@ -793,7 +835,7 @@ static void brw_emit_vertices(struct brw_context *brw) const struct brw_tracked_state brw_vertices = { .dirty = { - .mesa = 0, + .mesa = _NEW_POLYGON, .brw = BRW_NEW_BATCH | BRW_NEW_VERTICES, .cache = CACHE_NEW_VS_PROG, }, diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index d803dfa96d4..1e19183b4bf 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -326,8 +326,10 @@ static void brw_upload_vs_prog(struct brw_context *brw) } /* _NEW_POLYGON */ - key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL); + if (intel->gen < 6) { + key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL); + } /* _NEW_LIGHT | _NEW_BUFFERS */ key.clamp_vertex_color = ctx->Light._ClampVertexColor; -- 2.30.2