intel/compiler: use nir_shader_instructions_pass in brw_nir_apply_attribute_workarounds
Changes: - removal of attr_wa_state (it's passed directly) - nir_metadata_preserve(..., nir_metadata_all) is called when pass doesn't make progress Signed-off-by: Marcin Ślusarz <marcin.slusarz@intel.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12324>
This commit is contained in:
parent
e1b325f587
commit
7810ca596c
|
@ -30,103 +30,94 @@
|
|||
* to produce the correct values.
|
||||
*/
|
||||
|
||||
struct attr_wa_state {
|
||||
nir_builder builder;
|
||||
bool impl_progress;
|
||||
const uint8_t *wa_flags;
|
||||
};
|
||||
|
||||
static bool
|
||||
apply_attr_wa_block(nir_block *block, struct attr_wa_state *state)
|
||||
apply_attr_wa_instr(nir_builder *b, nir_instr *instr, void *cb_data)
|
||||
{
|
||||
nir_builder *b = &state->builder;
|
||||
const uint8_t *attrib_wa_flags = cb_data;
|
||||
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic != nir_intrinsic_load_input)
|
||||
continue;
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic != nir_intrinsic_load_input)
|
||||
return false;
|
||||
|
||||
uint8_t wa_flags = state->wa_flags[intrin->const_index[0]];
|
||||
if (wa_flags == 0)
|
||||
continue;
|
||||
uint8_t wa_flags = attrib_wa_flags[intrin->const_index[0]];
|
||||
if (wa_flags == 0)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_after_instr(instr);
|
||||
b->cursor = nir_after_instr(instr);
|
||||
|
||||
nir_ssa_def *val = &intrin->dest.ssa;
|
||||
nir_ssa_def *val = &intrin->dest.ssa;
|
||||
|
||||
/* Do GL_FIXED rescaling for GLES2.0. Our GL_FIXED attributes
|
||||
* come in as floating point conversions of the integer values.
|
||||
*/
|
||||
if (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK) {
|
||||
nir_ssa_def *scaled =
|
||||
nir_fmul(b, val, nir_imm_float(b, 1.0f / 65536.0f));
|
||||
nir_ssa_def *comps[4];
|
||||
for (int i = 0; i < val->num_components; i++) {
|
||||
bool rescale = i < (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK);
|
||||
comps[i] = nir_channel(b, rescale ? scaled : val, i);
|
||||
}
|
||||
val = nir_vec(b, comps, val->num_components);
|
||||
/* Do GL_FIXED rescaling for GLES2.0. Our GL_FIXED attributes
|
||||
* come in as floating point conversions of the integer values.
|
||||
*/
|
||||
if (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK) {
|
||||
nir_ssa_def *scaled =
|
||||
nir_fmul(b, val, nir_imm_float(b, 1.0f / 65536.0f));
|
||||
nir_ssa_def *comps[4];
|
||||
for (int i = 0; i < val->num_components; i++) {
|
||||
bool rescale = i < (wa_flags & BRW_ATTRIB_WA_COMPONENT_MASK);
|
||||
comps[i] = nir_channel(b, rescale ? scaled : val, i);
|
||||
}
|
||||
|
||||
/* Do sign recovery for 2101010 formats if required. */
|
||||
if (wa_flags & BRW_ATTRIB_WA_SIGN) {
|
||||
/* sign recovery shift: <22, 22, 22, 30> */
|
||||
nir_ssa_def *shift = nir_imm_ivec4(b, 22, 22, 22, 30);
|
||||
val = nir_ishr(b, nir_ishl(b, val, shift), shift);
|
||||
}
|
||||
|
||||
/* Apply BGRA swizzle if required. */
|
||||
if (wa_flags & BRW_ATTRIB_WA_BGRA) {
|
||||
val = nir_swizzle(b, val, (unsigned[4]){2,1,0,3}, 4);
|
||||
}
|
||||
|
||||
if (wa_flags & BRW_ATTRIB_WA_NORMALIZE) {
|
||||
/* ES 3.0 has different rules for converting signed normalized
|
||||
* fixed-point numbers than desktop GL.
|
||||
*/
|
||||
if (wa_flags & BRW_ATTRIB_WA_SIGN) {
|
||||
/* According to equation 2.2 of the ES 3.0 specification,
|
||||
* signed normalization conversion is done by:
|
||||
*
|
||||
* f = c / (2^(b-1)-1)
|
||||
*
|
||||
* OpenGL 4.2+ uses this equation as well. Since most contexts
|
||||
* promote to the new higher version, and this is what Haswell+
|
||||
* hardware does anyway, we just always use this formula.
|
||||
*/
|
||||
nir_ssa_def *es3_normalize_factor =
|
||||
nir_imm_vec4(b, 1.0f / ((1 << 9) - 1), 1.0f / ((1 << 9) - 1),
|
||||
1.0f / ((1 << 9) - 1), 1.0f / ((1 << 1) - 1));
|
||||
val = nir_fmax(b,
|
||||
nir_fmul(b, nir_i2f32(b, val), es3_normalize_factor),
|
||||
nir_imm_float(b, -1.0f));
|
||||
} else {
|
||||
/* The following equation is from the OpenGL 3.2 specification:
|
||||
*
|
||||
* 2.1 unsigned normalization
|
||||
* f = c/(2^n-1)
|
||||
*/
|
||||
nir_ssa_def *normalize_factor =
|
||||
nir_imm_vec4(b, 1.0f / ((1 << 10) - 1), 1.0f / ((1 << 10) - 1),
|
||||
1.0f / ((1 << 10) - 1), 1.0f / ((1 << 2) - 1));
|
||||
|
||||
val = nir_fmul(b, nir_u2f32(b, val), normalize_factor);
|
||||
}
|
||||
}
|
||||
|
||||
if (wa_flags & BRW_ATTRIB_WA_SCALE) {
|
||||
val = (wa_flags & BRW_ATTRIB_WA_SIGN) ? nir_i2f32(b, val)
|
||||
: nir_u2f32(b, val);
|
||||
}
|
||||
|
||||
nir_ssa_def_rewrite_uses_after(&intrin->dest.ssa, val,
|
||||
val->parent_instr);
|
||||
state->impl_progress = true;
|
||||
val = nir_vec(b, comps, val->num_components);
|
||||
}
|
||||
|
||||
/* Do sign recovery for 2101010 formats if required. */
|
||||
if (wa_flags & BRW_ATTRIB_WA_SIGN) {
|
||||
/* sign recovery shift: <22, 22, 22, 30> */
|
||||
nir_ssa_def *shift = nir_imm_ivec4(b, 22, 22, 22, 30);
|
||||
val = nir_ishr(b, nir_ishl(b, val, shift), shift);
|
||||
}
|
||||
|
||||
/* Apply BGRA swizzle if required. */
|
||||
if (wa_flags & BRW_ATTRIB_WA_BGRA) {
|
||||
val = nir_swizzle(b, val, (unsigned[4]){2,1,0,3}, 4);
|
||||
}
|
||||
|
||||
if (wa_flags & BRW_ATTRIB_WA_NORMALIZE) {
|
||||
/* ES 3.0 has different rules for converting signed normalized
|
||||
* fixed-point numbers than desktop GL.
|
||||
*/
|
||||
if (wa_flags & BRW_ATTRIB_WA_SIGN) {
|
||||
/* According to equation 2.2 of the ES 3.0 specification,
|
||||
* signed normalization conversion is done by:
|
||||
*
|
||||
* f = c / (2^(b-1)-1)
|
||||
*
|
||||
* OpenGL 4.2+ uses this equation as well. Since most contexts
|
||||
* promote to the new higher version, and this is what Haswell+
|
||||
* hardware does anyway, we just always use this formula.
|
||||
*/
|
||||
nir_ssa_def *es3_normalize_factor =
|
||||
nir_imm_vec4(b, 1.0f / ((1 << 9) - 1), 1.0f / ((1 << 9) - 1),
|
||||
1.0f / ((1 << 9) - 1), 1.0f / ((1 << 1) - 1));
|
||||
val = nir_fmax(b,
|
||||
nir_fmul(b, nir_i2f32(b, val), es3_normalize_factor),
|
||||
nir_imm_float(b, -1.0f));
|
||||
} else {
|
||||
/* The following equation is from the OpenGL 3.2 specification:
|
||||
*
|
||||
* 2.1 unsigned normalization
|
||||
* f = c/(2^n-1)
|
||||
*/
|
||||
nir_ssa_def *normalize_factor =
|
||||
nir_imm_vec4(b, 1.0f / ((1 << 10) - 1), 1.0f / ((1 << 10) - 1),
|
||||
1.0f / ((1 << 10) - 1), 1.0f / ((1 << 2) - 1));
|
||||
|
||||
val = nir_fmul(b, nir_u2f32(b, val), normalize_factor);
|
||||
}
|
||||
}
|
||||
|
||||
if (wa_flags & BRW_ATTRIB_WA_SCALE) {
|
||||
val = (wa_flags & BRW_ATTRIB_WA_SIGN) ? nir_i2f32(b, val)
|
||||
: nir_u2f32(b, val);
|
||||
}
|
||||
|
||||
nir_ssa_def_rewrite_uses_after(&intrin->dest.ssa, val,
|
||||
val->parent_instr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -134,28 +125,8 @@ bool
|
|||
brw_nir_apply_attribute_workarounds(nir_shader *shader,
|
||||
const uint8_t *attrib_wa_flags)
|
||||
{
|
||||
bool progress = false;
|
||||
struct attr_wa_state state = {
|
||||
.wa_flags = attrib_wa_flags,
|
||||
};
|
||||
|
||||
nir_foreach_function(func, shader) {
|
||||
if (!func->impl)
|
||||
continue;
|
||||
|
||||
nir_builder_init(&state.builder, func->impl);
|
||||
state.impl_progress = false;
|
||||
|
||||
nir_foreach_block(block, func->impl) {
|
||||
apply_attr_wa_block(block, &state);
|
||||
}
|
||||
|
||||
if (state.impl_progress) {
|
||||
nir_metadata_preserve(func->impl, nir_metadata_block_index |
|
||||
nir_metadata_dominance);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
return nir_shader_instructions_pass(shader, apply_attr_wa_instr,
|
||||
nir_metadata_block_index |
|
||||
nir_metadata_dominance,
|
||||
(void *)attrib_wa_flags);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue