[Mesa-dev] [PATCH 7/7] i965/fs: Fix readInvocationARB and readFirstInvocationARB
Jason Ekstrand
jason at jlekstrand.net
Mon Aug 28 14:51:33 UTC 2017
The readInvocationARB built-in maps fairly nicely to our BROADCAST
opcode. However, the current implementation isn't quite right. This
commit fixes three different issues:
1) It was blindly taking component 0 of the index value even if that
channel is disabled. We need emit_uniformize() to fix this.
2) It didn't handle invalid index values particularly gracefully.
These can actually cause assertion failures in the compiler because
we may try to access out-of-bounds on a register. This commit
solves this by using invocation & (dispatch_width - 1).
3) Neither readInvocationARB nor readFirstInvocationARB properly
handled 64-bit types because they manually stomped the destination
type to D regardless of bit-size.
---
src/intel/compiler/brw_fs_nir.cpp | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp
index a882979..f5ace4f 100644
--- a/src/intel/compiler/brw_fs_nir.cpp
+++ b/src/intel/compiler/brw_fs_nir.cpp
@@ -4240,21 +4240,29 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
case nir_intrinsic_read_invocation: {
const fs_reg value = get_nir_src(instr->src[0]);
- const fs_reg invocation = get_nir_src(instr->src[1]);
+ const fs_reg invocation = get_nir_src_imm(instr->src[1]);
fs_reg tmp = bld.vgrf(value.type);
- bld.exec_all().emit(SHADER_OPCODE_BROADCAST, tmp, value,
- component(invocation, 0));
+ /* Get rid of invalid values. Letting them wrap around seems fine. */
+ fs_reg idx;
+ if (invocation.file == BRW_IMMEDIATE_VALUE) {
+ idx = brw_imm_ud(invocation.ud & (dispatch_width - 1));
+ } else {
+ idx = fs_reg(VGRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
+ bld.group(1, 0).exec_all().AND(idx, bld.emit_uniformize(invocation),
+ brw_imm_ud(dispatch_width - 1));
+ idx = component(idx, 0);
+ }
- bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
- fs_reg(component(tmp, 0)));
+ bld.exec_all().emit(SHADER_OPCODE_BROADCAST, tmp, value, idx);
+
+ bld.MOV(retype(dest, value.type), fs_reg(component(tmp, 0)));
break;
}
case nir_intrinsic_read_first_invocation: {
const fs_reg value = get_nir_src(instr->src[0]);
- bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
- bld.emit_uniformize(value));
+ bld.MOV(retype(dest, value.type), bld.emit_uniformize(value));
break;
}
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list