mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 21:08:11 +02:00
nir/opt_varyings: use nir_scalar
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36091>
This commit is contained in:
parent
2e06da1597
commit
9607852c30
1 changed files with 49 additions and 28 deletions
|
|
@ -629,7 +629,7 @@ struct scalar_slot {
|
|||
* computing the stored value. Used by constant and uniform propagation
|
||||
* to the next shader.
|
||||
*/
|
||||
nir_instr *value;
|
||||
nir_scalar value;
|
||||
} producer;
|
||||
|
||||
struct {
|
||||
|
|
@ -1594,9 +1594,9 @@ gather_outputs(struct nir_builder *builder, nir_intrinsic_instr *intr, void *cb_
|
|||
return false;
|
||||
|
||||
if (is_store) {
|
||||
nir_def *value = intr->src[0].ssa;
|
||||
nir_scalar value = nir_scalar_resolved(intr->src[0].ssa, 0);
|
||||
|
||||
const bool constant = value->parent_instr->type == nir_instr_type_load_const;
|
||||
const bool constant = nir_scalar_is_const(value);
|
||||
|
||||
/* If the store instruction is executed in a divergent block, the value
|
||||
* that's stored in the output becomes divergent.
|
||||
|
|
@ -1609,19 +1609,19 @@ gather_outputs(struct nir_builder *builder, nir_intrinsic_instr *intr, void *cb_
|
|||
intr->instr.block->divergent ||
|
||||
nir_src_is_divergent(&intr->src[0]);
|
||||
|
||||
if (!out->producer.value) {
|
||||
if (!out->producer.value.def) {
|
||||
/* This is the first store to this output. */
|
||||
BITSET_SET(linkage->output_equal_mask, slot);
|
||||
out->producer.value = value->parent_instr;
|
||||
out->producer.value = value;
|
||||
|
||||
/* Set whether the value is convergent. Such varyings can be
|
||||
* promoted to flat regardless of their original interpolation
|
||||
* mode.
|
||||
*/
|
||||
if (linkage->consumer_stage == MESA_SHADER_FRAGMENT && !divergent) {
|
||||
if (value->bit_size == 32)
|
||||
if (value.def->bit_size == 32)
|
||||
BITSET_SET(linkage->convergent32_mask, slot);
|
||||
else if (value->bit_size == 16)
|
||||
else if (value.def->bit_size == 16)
|
||||
BITSET_SET(linkage->convergent16_mask, slot);
|
||||
else
|
||||
unreachable("invalid store_output type");
|
||||
|
|
@ -1630,14 +1630,14 @@ gather_outputs(struct nir_builder *builder, nir_intrinsic_instr *intr, void *cb_
|
|||
/* There are multiple stores to the same output. If they store
|
||||
* different values, clear the mask.
|
||||
*/
|
||||
if (out->producer.value != value->parent_instr)
|
||||
if (!nir_scalar_equal(out->producer.value, value))
|
||||
BITSET_CLEAR(linkage->output_equal_mask, slot);
|
||||
|
||||
/* Update divergence information. */
|
||||
if (linkage->consumer_stage == MESA_SHADER_FRAGMENT && divergent) {
|
||||
if (value->bit_size == 32)
|
||||
if (value.def->bit_size == 32)
|
||||
BITSET_CLEAR(linkage->convergent32_mask, slot);
|
||||
else if (value->bit_size == 16)
|
||||
else if (value.def->bit_size == 16)
|
||||
BITSET_CLEAR(linkage->convergent16_mask, slot);
|
||||
else
|
||||
unreachable("invalid store_output type");
|
||||
|
|
@ -1650,9 +1650,9 @@ gather_outputs(struct nir_builder *builder, nir_intrinsic_instr *intr, void *cb_
|
|||
nir_instr *vertex_index_instr = vertex_index_src->ssa->parent_instr;
|
||||
|
||||
if (!is_sysval(vertex_index_instr, SYSTEM_VALUE_INVOCATION_ID)) {
|
||||
if (value->bit_size == 32)
|
||||
if (value.def->bit_size == 32)
|
||||
BITSET_SET(linkage->cross_invoc32_mask, slot);
|
||||
else if (value->bit_size == 16)
|
||||
else if (value.def->bit_size == 16)
|
||||
BITSET_SET(linkage->cross_invoc16_mask, slot);
|
||||
else
|
||||
unreachable("invalid store_output type");
|
||||
|
|
@ -2352,12 +2352,15 @@ clone_ssa_impl(struct linkage_info *linkage, nir_builder *b, nir_def *ssa)
|
|||
}
|
||||
|
||||
static nir_def *
|
||||
clone_ssa(struct linkage_info *linkage, nir_builder *b, nir_def *ssa)
|
||||
clone_ssa(struct linkage_info *linkage, nir_builder *b, nir_scalar scalar)
|
||||
{
|
||||
assert(!linkage->clones_ht);
|
||||
linkage->clones_ht = _mesa_pointer_hash_table_create(NULL);
|
||||
|
||||
nir_def *clone = clone_ssa_impl(linkage, b, ssa);
|
||||
nir_def *clone = clone_ssa_impl(linkage, b, scalar.def);
|
||||
|
||||
if (clone->num_components > 1)
|
||||
clone = nir_channel(b, clone, scalar.comp);
|
||||
|
||||
_mesa_hash_table_destroy(linkage->clones_ht, NULL);
|
||||
linkage->clones_ht = NULL;
|
||||
|
|
@ -2465,7 +2468,7 @@ propagate_uniform_expressions(struct linkage_info *linkage,
|
|||
*/
|
||||
nir_shader_clear_pass_flags(linkage->producer_builder.shader);
|
||||
|
||||
if (!is_uniform_expression(slot->producer.value, &state))
|
||||
if (!is_uniform_expression(slot->producer.value.def->parent_instr, &state))
|
||||
continue;
|
||||
|
||||
if (state.cost > linkage->max_varying_expression_cost)
|
||||
|
|
@ -2476,9 +2479,9 @@ propagate_uniform_expressions(struct linkage_info *linkage,
|
|||
* no effect.
|
||||
*/
|
||||
if (is_interpolated_color(linkage, i) &&
|
||||
(slot->producer.value->type != nir_instr_type_load_const ||
|
||||
nir_instr_as_load_const(slot->producer.value)->value[0].f32 < 0 ||
|
||||
nir_instr_as_load_const(slot->producer.value)->value[0].f32 > 1))
|
||||
(!nir_scalar_is_const(slot->producer.value) ||
|
||||
nir_scalar_as_float(slot->producer.value) < 0 ||
|
||||
nir_scalar_as_float(slot->producer.value) > 1))
|
||||
continue;
|
||||
|
||||
/* TEXn.zw can be propagated only if it's equal to (0, 1) because it's
|
||||
|
|
@ -2489,11 +2492,10 @@ propagate_uniform_expressions(struct linkage_info *linkage,
|
|||
|
||||
if (i % 8 == 0 || /* TEXn.x */
|
||||
i % 8 == 2 || /* TEXn.y */
|
||||
slot->producer.value->type != nir_instr_type_load_const)
|
||||
!nir_scalar_is_const(slot->producer.value))
|
||||
continue;
|
||||
|
||||
float value =
|
||||
nir_instr_as_load_const(slot->producer.value)->value[0].f32;
|
||||
float value = nir_scalar_as_float(slot->producer.value);
|
||||
|
||||
/* This ignores signed zeros, but those are destroyed by
|
||||
* interpolation, so it doesn't matter.
|
||||
|
|
@ -2516,8 +2518,7 @@ propagate_uniform_expressions(struct linkage_info *linkage,
|
|||
b->cursor = nir_before_instr(&loadi->instr);
|
||||
|
||||
/* Copy the uniform expression before the load. */
|
||||
nir_def *clone = clone_ssa(linkage, b,
|
||||
nir_instr_def(slot->producer.value));
|
||||
nir_def *clone = clone_ssa(linkage, b, slot->producer.value);
|
||||
|
||||
/* Interpolation converts Infs to NaNs. If we skip it, we need to
|
||||
* convert Infs to NaNs manually.
|
||||
|
|
@ -2703,6 +2704,24 @@ get_input_qualifier(struct linkage_info *linkage, unsigned i)
|
|||
return qual + pixel_location;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
nir_ht_scalar_hash(const void *key)
|
||||
{
|
||||
nir_scalar s;
|
||||
static_assert(offsetof(nir_scalar, def) == 0, "known layout");
|
||||
static_assert(offsetof(nir_scalar, comp) == sizeof(s.def), "no padding");
|
||||
static_assert(sizeof(s.comp) == sizeof(unsigned), "known layout");
|
||||
|
||||
/* Don't include structure padding of nir_scalar. */
|
||||
return _mesa_hash_data(key, offsetof(nir_scalar, comp) + sizeof(unsigned));
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_ht_scalar_equal(const void *a, const void *b)
|
||||
{
|
||||
return nir_scalar_equal(*(nir_scalar*)a, *(nir_scalar*)b);
|
||||
}
|
||||
|
||||
static void
|
||||
deduplicate_outputs(struct linkage_info *linkage,
|
||||
nir_opt_varyings_progress *progress)
|
||||
|
|
@ -2738,13 +2757,14 @@ deduplicate_outputs(struct linkage_info *linkage,
|
|||
|
||||
struct hash_table **table = &tables[qualifier];
|
||||
if (!*table)
|
||||
*table = _mesa_pointer_hash_table_create(NULL);
|
||||
*table = _mesa_hash_table_create(NULL, nir_ht_scalar_hash,
|
||||
nir_ht_scalar_equal);
|
||||
|
||||
nir_instr *value = slot->producer.value;
|
||||
nir_scalar value = slot->producer.value;
|
||||
|
||||
struct hash_entry *entry = _mesa_hash_table_search(*table, value);
|
||||
struct hash_entry *entry = _mesa_hash_table_search(*table, &value);
|
||||
if (!entry) {
|
||||
_mesa_hash_table_insert(*table, value, (void *)(uintptr_t)i);
|
||||
_mesa_hash_table_insert(*table, &value, (void *)(uintptr_t)i);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -3725,7 +3745,8 @@ try_move_postdominator(struct linkage_info *linkage,
|
|||
*/
|
||||
b = &linkage->producer_builder;
|
||||
b->cursor = nir_after_block_before_jump(block);
|
||||
nir_def *producer_clone = clone_ssa(linkage, b, postdom_def);
|
||||
nir_def *producer_clone = clone_ssa(linkage, b,
|
||||
nir_get_scalar(postdom_def, 0));
|
||||
|
||||
/* Boolean post-dominators are upcast in the producer because we can't
|
||||
* use 1-bit outputs.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue