diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs.c | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_gs_emit.c | 30 |
3 files changed, 37 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 1e605efd6e4..ee3f94ca613 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -208,6 +208,12 @@ static void populate_key( struct brw_context *brw, linked_xfb_info->Outputs[i].OutputRegister; } } + /* On Gen6, GS is also used for rasterizer discard. */ + /* _NEW_TRANSFORM_FEEDBACK */ + if (ctx->TransformFeedback.RasterDiscard) { + key->need_gs_prog = true; + key->rasterizer_discard = true; + } } else { /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP * into simpler primitives. diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index 33d8d7ab5a7..7bf2248a5ed 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -50,6 +50,7 @@ struct brw_gs_prog_key { GLuint pv_first:1; GLuint need_gs_prog:1; GLuint userclip_active:1; + GLuint rasterizer_discard:1; /** * Number of varyings that are output to transform feedback. diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index 269a49559a5..1f96a164637 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -193,6 +193,28 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c, } /** + * De-allocate the URB entry that was previously allocated to this thread + * (without writing any vertex data to it), and terminate the thread. This is + * used to implement RASTERIZER_DISCARD functionality. + */ +static void brw_gs_terminate(struct brw_gs_compile *c) +{ + struct brw_compile *p = &c->func; + brw_urb_WRITE(p, + retype(brw_null_reg(), BRW_REGISTER_TYPE_UD), /* dest */ + 0, /* msg_reg_nr */ + c->reg.header, /* src0 */ + false, /* allocate */ + false, /* used */ + 1, /* msg_length */ + 0, /* response_length */ + true, /* eot */ + true, /* writes_complete */ + 0, /* offset */ + BRW_URB_SWIZZLE_NONE); +} + +/** * Send an FF_SYNC message to ensure that all previously spawned GS threads * have finished sending primitives down the pipeline, and to allocate a URB * entry for the first output vertex. Only needed when intel->needs_ff_sync @@ -409,6 +431,14 @@ gen6_sol_program(struct brw_gs_compile *c, struct brw_gs_prog_key *key, brw_gs_ff_sync(c, 1); + /* If RASTERIZER_DISCARD is enabled, we have nothing further to do, so + * release the URB that was just allocated, and terminate the thread. + */ + if (key->rasterizer_discard) { + brw_gs_terminate(c); + return; + } + brw_gs_overwrite_header_dw2_from_r0(c); switch (num_verts) { case 1: |