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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev