nir/opt_large_constants: Handle small float arrays
Handles small arrays of integer, positive floats. RADV fossils: Totals from 65 (0.05% of 131205) affected shaders: Instrs: 30001 -> 29936 (-0.22%); split: -0.39%, +0.18% CodeSize: 165676 -> 164996 (-0.41%); split: -0.53%, +0.12% Latency: 126873 -> 127178 (+0.24%); split: -0.29%, +0.53% InvThroughput: 26640 -> 26895 (+0.96%); split: -0.48%, +1.44% VClause: 425 -> 371 (-12.71%) SClause: 982 -> 981 (-0.10%); split: -0.92%, +0.81% Copies: 2072 -> 1939 (-6.42%); split: -6.52%, +0.10% PreVGPRs: 1553 -> 1537 (-1.03%) Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9000>
This commit is contained in:

committed by
Marge Bot

parent
e38522608f
commit
3aa3eb8ddd
@@ -113,6 +113,7 @@ write_const_values(void *dst, const nir_const_value *src,
|
|||||||
struct small_constant {
|
struct small_constant {
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
uint32_t bit_size;
|
uint32_t bit_size;
|
||||||
|
bool is_float;
|
||||||
uint32_t bit_stride;
|
uint32_t bit_stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -251,9 +252,26 @@ get_small_constant(struct var_info *info, glsl_type_size_align_func size_align)
|
|||||||
nir_const_value values[64];
|
nir_const_value values[64];
|
||||||
read_const_values(values, info->constant_data, array_len, bit_size);
|
read_const_values(values, info->constant_data, array_len, bit_size);
|
||||||
|
|
||||||
|
bool is_float = true;
|
||||||
|
if (bit_size < 16) {
|
||||||
|
is_float = false;
|
||||||
|
} else {
|
||||||
|
for (unsigned i = 0; i < array_len; i++) {
|
||||||
|
/* See if it's an easily convertible float.
|
||||||
|
* TODO: Compute greatest common divisor to support non-integer floats.
|
||||||
|
* TODO: Compute min value and add it to the result of
|
||||||
|
* build_small_constant_load for handling negative floats.
|
||||||
|
*/
|
||||||
|
uint64_t u = nir_const_value_as_float(values[i], bit_size);
|
||||||
|
nir_const_value fc = nir_const_value_for_float(u, bit_size);
|
||||||
|
is_float &= !memcmp(&fc, &values[i], bit_size / 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t used_bits = 0;
|
uint32_t used_bits = 0;
|
||||||
for (unsigned i = 0; i < array_len; i++) {
|
for (unsigned i = 0; i < array_len; i++) {
|
||||||
uint64_t u64_elem = nir_const_value_as_uint(values[i], bit_size);
|
uint64_t u64_elem = is_float ? nir_const_value_as_float(values[i], bit_size)
|
||||||
|
: nir_const_value_as_uint(values[i], bit_size);
|
||||||
if (!u64_elem)
|
if (!u64_elem)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -272,13 +290,16 @@ get_small_constant(struct var_info *info, glsl_type_size_align_func size_align)
|
|||||||
info->is_small = true;
|
info->is_small = true;
|
||||||
|
|
||||||
for (unsigned i = 0; i < array_len; i++) {
|
for (unsigned i = 0; i < array_len; i++) {
|
||||||
uint64_t u64_elem = nir_const_value_as_uint(values[i], bit_size);
|
uint64_t u64_elem = is_float ? nir_const_value_as_float(values[i], bit_size)
|
||||||
|
: nir_const_value_as_uint(values[i], bit_size);
|
||||||
|
|
||||||
info->small_constant.data |= u64_elem << (i * used_bits);
|
info->small_constant.data |= u64_elem << (i * used_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit bit_size >= 32 to avoid unnecessary conversions. */
|
/* Limit bit_size >= 32 to avoid unnecessary conversions. */
|
||||||
info->small_constant.bit_size =
|
info->small_constant.bit_size =
|
||||||
MAX2(util_next_power_of_two(used_bits * array_len), 32);
|
MAX2(util_next_power_of_two(used_bits * array_len), 32);
|
||||||
|
info->small_constant.is_float = is_float;
|
||||||
info->small_constant.bit_stride = used_bits;
|
info->small_constant.bit_stride = used_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,8 +324,11 @@ build_small_constant_load(nir_builder *b, nir_deref_instr *deref,
|
|||||||
/* Booleans are special-cased to be 32-bit */
|
/* Booleans are special-cased to be 32-bit */
|
||||||
assert(glsl_type_is_boolean(deref->type));
|
assert(glsl_type_is_boolean(deref->type));
|
||||||
ret = nir_ine_imm(b, ret, 0);
|
ret = nir_ine_imm(b, ret, 0);
|
||||||
} else if (bit_size != constant->bit_size) {
|
} else {
|
||||||
ret = nir_u2uN(b, ret, bit_size);
|
if (constant->is_float)
|
||||||
|
ret = nir_u2fN(b, ret, bit_size);
|
||||||
|
else if (bit_size != constant->bit_size)
|
||||||
|
ret = nir_u2uN(b, ret, bit_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
Reference in New Issue
Block a user