<div dir="ltr">On 9 September 2013 13:24, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>On 09/03/2013 06:18 PM, Paul Berry wrote:<br>
> Previously, on Gen6+, we laid out the vertex (or geometry) shader VUE<br>
> map differently depending whether user clipping was active. If it was<br>
> active, we put the clip distances in slots 2 and 3 (where the clipper<br>
> expects them); if it was inactive, we assigned them in the order of<br>
> the gl_varying_slot enum.<br>
><br>
> This made for unnecessary recompiles, since turning clipping on/off<br>
> for a shader that used gl_ClipDistance might rearrange the varyings.<br>
> It also required extra bookkeeping, since it required the user<br>
> clipping flag to be provided to brw_compute_vue_map() as a parameter.<br>
><br>
> With this patch, we always put clip distances at in slots 2 and 3 if<br>
> they are written to. do_vs_prog() and do_gs_prog() are responsible<br>
> for ensuring that clip distances are written to when user clipping is<br>
> enabled (as do_vs_prog() previously did for gen4-5).<br>
><br>
> This makes the only input to brw_compute_vue_map() a bitfield of which<br>
> varyings the shader writes to, a fact that we'll take advantage of in<br>
> forthcoming patches.<br>
> ---<br>
> src/mesa/drivers/dri/i965/brw_context.h | 2 +-<br>
> src/mesa/drivers/dri/i965/brw_vec4_gs.c | 15 ++++++++++++---<br>
> src/mesa/drivers/dri/i965/brw_vs.c | 26 +++++++++++++-------------<br>
> 3 files changed, 26 insertions(+), 17 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h<br>
> index 167ed4a..0c1fd9e 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_context.h<br>
> +++ b/src/mesa/drivers/dri/i965/brw_context.h<br>
> @@ -436,7 +436,7 @@ static inline GLuint brw_varying_to_offset(struct brw_vue_map *vue_map,<br>
> }<br>
><br>
> void brw_compute_vue_map(struct brw_context *brw, struct brw_vue_map *vue_map,<br>
> - GLbitfield64 slots_valid, bool userclip_active);<br>
> + GLbitfield64 slots_valid);<br>
><br>
><br>
> /**<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs.c b/src/mesa/drivers/dri/i965/brw_vec4_gs.c<br>
> index 7ab03ac..94c4017 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_vec4_gs.c<br>
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs.c<br>
> @@ -62,9 +62,18 @@ do_gs_prog(struct brw_context *brw,<br>
> c.prog_data.base.param = rzalloc_array(NULL, const float *, param_count);<br>
> c.prog_data.base.pull_param = rzalloc_array(NULL, const float *, param_count);<br>
><br>
> - brw_compute_vue_map(brw, &c.prog_data.base.vue_map,<br>
> - gp->program.Base.OutputsWritten,<br>
> - c.key.base.userclip_active);<br>
> + GLbitfield64 outputs_written = gp->program.Base.OutputsWritten;<br>
> +<br>
> + /* In order for legacy clipping to work, we need to populate the clip<br>
> + * distance varying slots whenever clipping is enabled, even if the vertex<br>
> + * shader doesn't write to gl_ClipDistance.<br>
> + */<br>
> + if (c.key.base.userclip_active) {<br>
> + outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0);<br>
> + outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1);<br>
> + }<br>
> +<br>
> + brw_compute_vue_map(brw, &c.prog_data.base.vue_map, outputs_written);<br>
<br>
</div></div>Having both of the callers of brw_compute_vue_map do this same dance<br>
before calling seems weird. I want to understand this better... The VS<br>
and GS code adds clip distance as a written output because fixed<br>
function hardware is going to read it when user clipping is enabled.<br>
This then gets captured in the vue_map... so when the next patch adds<br>
another caller to brw_compute_vue_map, it doesn't need to know that user<br>
clipping was enabled (vs. gl_ClipDistance being written). Yeah?<br></blockquote><div><br></div><div>Correct. The geometry shader doesn't care why the VS chose to include clip distance in the VUE map. It just needs to know what's in the VUE map so that it knows where to look for each of its inputs. Effectively the call to brw_compute_vue_map that is added in patch 9 is just rebuilding an already-known VUE map so that we don't have to waste space in the GS program key storing the whole map.<br>
<br></div><div>I agree with you that the code duplication isn't great (in fact there's a lot of code duplication between do_gs_prog and do_vs_prog, and that doesn't thrill me), but I think the benefit in this case is that it makes for a clean separation of concerns between deciding what varyings need to be in the VUE (which is the job of do_{vs,gs}_prog) and deciding what order they should go in (which is the job of brw_compute_vue_map). We might, for instance, decide in the future that as an optimization, do_vs_prog will only add clip distances to the VUE map if user clipping is enabled AND there's no GS.
</div></div></div></div>