intel/fs: Fix IsHelperInvocation for the case no discard/demote are used
Use emit_predicate_on_sample_mask() helper that does check where to
get the correct mask depending on whether discard/demote was used or
not.
Fixes: 45f5db5a84
("intel/fs: Implement "demote to helper invocation"")
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15400>
This commit is contained in:
parent
bb311c22df
commit
f82731d0d7
|
@ -5478,6 +5478,33 @@ emit_predicate_on_sample_mask(const fs_builder &bld, fs_inst *inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fs_visitor::emit_is_helper_invocation(fs_reg result)
|
||||||
|
{
|
||||||
|
/* Unlike the regular gl_HelperInvocation, that is defined at dispatch,
|
||||||
|
* the helperInvocationEXT() (aka SpvOpIsHelperInvocationEXT) takes into
|
||||||
|
* consideration demoted invocations.
|
||||||
|
*/
|
||||||
|
result.type = BRW_REGISTER_TYPE_UD;
|
||||||
|
|
||||||
|
bld.MOV(result, brw_imm_ud(0));
|
||||||
|
|
||||||
|
/* See sample_mask_reg() for why we split SIMD32 into SIMD16 here. */
|
||||||
|
unsigned width = bld.dispatch_width();
|
||||||
|
for (unsigned i = 0; i < DIV_ROUND_UP(width, 16); i++) {
|
||||||
|
const fs_builder b = bld.group(MIN2(width, 16), i);
|
||||||
|
|
||||||
|
fs_inst *mov = b.MOV(offset(result, b, i), brw_imm_ud(~0));
|
||||||
|
|
||||||
|
/* The at() ensures that any code emitted to get the predicate happens
|
||||||
|
* before the mov right above. This is not an issue elsewhere because
|
||||||
|
* lowering code already set up the builder this way.
|
||||||
|
*/
|
||||||
|
emit_predicate_on_sample_mask(b.at(NULL, mov), mov);
|
||||||
|
mov->predicate_inverse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predicate the specified instruction on the vector mask.
|
* Predicate the specified instruction on the vector mask.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -203,6 +203,7 @@ public:
|
||||||
void emit_dummy_fs();
|
void emit_dummy_fs();
|
||||||
void emit_repclear_shader();
|
void emit_repclear_shader();
|
||||||
void emit_fragcoord_interpolation(fs_reg wpos);
|
void emit_fragcoord_interpolation(fs_reg wpos);
|
||||||
|
void emit_is_helper_invocation(fs_reg result);
|
||||||
fs_reg emit_frontfacing_interpolation();
|
fs_reg emit_frontfacing_interpolation();
|
||||||
fs_reg emit_samplepos_setup();
|
fs_reg emit_samplepos_setup();
|
||||||
fs_reg emit_sampleid_setup();
|
fs_reg emit_sampleid_setup();
|
||||||
|
|
|
@ -3458,22 +3458,9 @@ fs_visitor::nir_emit_fs_intrinsic(const fs_builder &bld,
|
||||||
bld.MOV(dest, fetch_render_target_array_index(bld));
|
bld.MOV(dest, fetch_render_target_array_index(bld));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nir_intrinsic_is_helper_invocation: {
|
case nir_intrinsic_is_helper_invocation:
|
||||||
/* Unlike the regular gl_HelperInvocation, that is defined at dispatch,
|
emit_is_helper_invocation(dest);
|
||||||
* the helperInvocationEXT() (aka SpvOpIsHelperInvocationEXT) takes into
|
|
||||||
* consideration demoted invocations. That information is stored in
|
|
||||||
* f0.1.
|
|
||||||
*/
|
|
||||||
dest.type = BRW_REGISTER_TYPE_UD;
|
|
||||||
|
|
||||||
bld.MOV(dest, brw_imm_ud(0));
|
|
||||||
|
|
||||||
fs_inst *mov = bld.MOV(dest, brw_imm_ud(~0));
|
|
||||||
mov->predicate = BRW_PREDICATE_NORMAL;
|
|
||||||
mov->predicate_inverse = true;
|
|
||||||
mov->flag_subreg = sample_mask_flag_subreg(this);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case nir_intrinsic_load_helper_invocation:
|
case nir_intrinsic_load_helper_invocation:
|
||||||
case nir_intrinsic_load_sample_mask_in:
|
case nir_intrinsic_load_sample_mask_in:
|
||||||
|
|
Loading…
Reference in New Issue