[Mesa-dev] [PATCH] i965/fs: Take the sample mask into account in FIND_LIVE_CHANNEL
Francisco Jerez
currojerez at riseup.net
Wed Sep 14 07:02:55 UTC 2016
Jason Ekstrand <jason at jlekstrand.net> writes:
> Just looking at the channel enables is not sufficient, at least not on Sky
> Lake. Channels that are disabled by the sample_mask may show up in the
> channel enable register as being enabled even if they are not executing.
> This can cause FIND_LIVE_CHANNEL to return a channel that isn't actually
> executing. In our handling of interpolateAtSample we do a clever trick
> with emit_uniformize to call the interpolator once for each unique sample
> id. Thanks to FIND_LIVE_CHANNEL returning a dead channel, we can get an
> infinite loop which hangs the GPU.
>
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
NAK, FIND_LIVE_CHANNEL returns channels from the EU execution mask by
design (see the doxygen comment in brw_defines.h), which is necessary
for the instruction to return a well-defined result when only helper
invocations are enabled in the execution mask. Several users of the
instruction are likely to be relying on this.
And isn't interpolateAtSample supposed to give a well-defined result too
when it's run from a helper invocation?
> ---
> src/mesa/drivers/dri/i965/brw_eu.h | 3 ++-
> src/mesa/drivers/dri/i965/brw_eu_emit.c | 22 +++++++++++++++-------
> src/mesa/drivers/dri/i965/brw_fs_builder.h | 3 ++-
> src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 2 +-
> src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 2 +-
> 5 files changed, 21 insertions(+), 11 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
> index 3e52764..9aaab78 100644
> --- a/src/mesa/drivers/dri/i965/brw_eu.h
> +++ b/src/mesa/drivers/dri/i965/brw_eu.h
> @@ -488,7 +488,8 @@ brw_pixel_interpolator_query(struct brw_codegen *p,
>
> void
> brw_find_live_channel(struct brw_codegen *p,
> - struct brw_reg dst);
> + struct brw_reg dst,
> + struct brw_reg sample_mask);
>
> void
> brw_broadcast(struct brw_codegen *p,
> diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
> index 3b12030..f593a8d 100644
> --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
> +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
> @@ -3361,7 +3361,8 @@ brw_pixel_interpolator_query(struct brw_codegen *p,
> }
>
> void
> -brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst)
> +brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst,
> + struct brw_reg sample_mask)
> {
> const struct gen_device_info *devinfo = p->devinfo;
> const unsigned exec_size = 1 << brw_inst_exec_size(devinfo, p->current);
> @@ -3377,13 +3378,20 @@ brw_find_live_channel(struct brw_codegen *p, struct brw_reg dst)
>
> if (devinfo->gen >= 8) {
> /* Getting the first active channel index is easy on Gen8: Just find
> - * the first bit set in the mask register. The same register exists
> - * on HSW already but it reads back as all ones when the current
> - * instruction has execution masking disabled, so it's kind of
> - * useless.
> + * the first bit set in the mask register AND the sample mask. The
> + * same register exists on HSW already but it reads back as all ones
> + * when the current instruction has execution masking disabled, so
> + * it's kind of useless.
> */
> - inst = brw_FBL(p, vec1(dst),
> - retype(brw_mask_reg(0), BRW_REGISTER_TYPE_UD));
> + struct brw_reg mask_reg = retype(brw_mask_reg(0),
> + BRW_REGISTER_TYPE_UD);
> + if (sample_mask.file != BRW_IMMEDIATE_VALUE ||
> + sample_mask.ud != 0xffffffff) {
> + brw_AND(p, vec1(dst), mask_reg, sample_mask);
> + mask_reg = vec1(dst);
> + }
> +
> + inst = brw_FBL(p, vec1(dst), mask_reg);
>
> /* Quarter control has the effect of magically shifting the value of
> * this register so you'll get the first active channel relative to
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_builder.h b/src/mesa/drivers/dri/i965/brw_fs_builder.h
> index 483672f..45b5f88 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_builder.h
> +++ b/src/mesa/drivers/dri/i965/brw_fs_builder.h
> @@ -407,7 +407,8 @@ namespace brw {
> const dst_reg chan_index = vgrf(BRW_REGISTER_TYPE_UD);
> const dst_reg dst = vgrf(src.type);
>
> - ubld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, chan_index);
> + ubld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, chan_index,
> + sample_mask_reg());
> ubld.emit(SHADER_OPCODE_BROADCAST, dst, src, component(chan_index, 0));
>
> return src_reg(component(dst, 0));
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
> index 2f4ba7b..d923b0b 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
> @@ -2041,7 +2041,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
> break;
>
> case SHADER_OPCODE_FIND_LIVE_CHANNEL:
> - brw_find_live_channel(p, dst);
> + brw_find_live_channel(p, dst, src[0]);
> break;
>
> case SHADER_OPCODE_BROADCAST:
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> index 256abae..63fca6f 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
> @@ -1863,7 +1863,7 @@ generate_code(struct brw_codegen *p,
> break;
>
> case SHADER_OPCODE_FIND_LIVE_CHANNEL:
> - brw_find_live_channel(p, dst);
> + brw_find_live_channel(p, dst, brw_null_reg());
> break;
>
> case SHADER_OPCODE_BROADCAST:
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 212 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160914/0200d4bc/attachment.sig>
More information about the mesa-dev
mailing list