From 887c2a60923debf0facc4d95554ed87555d83620 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Fri, 31 May 2019 15:08:54 -0400 Subject: [PATCH] nir: fix gather_ssa_types Consts and undefs can be used as different types (common with "0" constant) so don't copy types from consts/undefs, only to them. It doesn't entirely solve the problem that the type given to the const could be wrong , but now the only realistic case is with "0" which is the same when casted to float, so it doesn't matter for lower_int_to_float. The other change is to get type information for load input/uniform and store output, and use that to get correct results. Signed-off-by: Jonathan Marek Reviewed-by: Jason Ekstrand --- src/compiler/nir/nir_gather_ssa_types.c | 88 +++++++++++++++---------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/src/compiler/nir/nir_gather_ssa_types.c b/src/compiler/nir/nir_gather_ssa_types.c index fa648fe3326..a1a7df0ca45 100644 --- a/src/compiler/nir/nir_gather_ssa_types.c +++ b/src/compiler/nir/nir_gather_ssa_types.c @@ -51,27 +51,33 @@ set_type(unsigned idx, nir_alu_type type, BITSET_WORD *float_types, } static void -copy_types(unsigned a, unsigned b, BITSET_WORD *float_types, - BITSET_WORD *int_types, bool *progress) +copy_type(unsigned src, unsigned dst, bool src_is_sink, + BITSET_WORD *types, bool *progress) { - /* If the bits do not agree then one of them is set but not both. Flag - * progress and set both bits. - */ - if (float_types && (BITSET_TEST(float_types, a) != - BITSET_TEST(float_types, b))) { - *progress = true; - BITSET_SET(float_types, a); - BITSET_SET(float_types, b); - } + if (!types) + return; - if (int_types && (BITSET_TEST(int_types, a) != - BITSET_TEST(int_types, b))) { + if (BITSET_TEST(types, dst)) { + if (BITSET_TEST(types, src)) + return; + BITSET_SET(types, src); + *progress = true; + } else if (BITSET_TEST(types, src) && !src_is_sink) { + BITSET_SET(types, dst); *progress = true; - BITSET_SET(int_types, a); - BITSET_SET(int_types, b); } } +static void +copy_types(nir_src src, nir_dest *dest, BITSET_WORD *float_types, + BITSET_WORD *int_types, bool *progress) +{ + bool src_is_sink = nir_src_is_const(src) || + src.ssa->parent_instr->type == nir_instr_type_ssa_undef; + copy_type(src.ssa->index, dest->ssa.index, src_is_sink, float_types, progress); + copy_type(src.ssa->index, dest->ssa.index, src_is_sink, int_types, progress); +} + /** Gather up ALU types for SSA values * * This pass attempts to determine, for each SSA value, the type of data (int @@ -107,9 +113,7 @@ nir_gather_ssa_types(nir_function_impl *impl, case nir_op_vec3: case nir_op_vec4: for (unsigned i = 0; i < info->num_inputs; i++) { - assert(alu->src[i].src.is_ssa); - copy_types(alu->src[i].src.ssa->index, - alu->dest.dest.ssa.index, + copy_types(alu->src[i].src, &alu->dest.dest, float_types, int_types, &progress); } break; @@ -118,11 +122,9 @@ nir_gather_ssa_types(nir_function_impl *impl, case nir_op_b32csel: set_type(alu->src[0].src.ssa->index, nir_type_bool, float_types, int_types, &progress); - copy_types(alu->src[1].src.ssa->index, - alu->dest.dest.ssa.index, + copy_types(alu->src[1].src, &alu->dest.dest, float_types, int_types, &progress); - copy_types(alu->src[2].src.ssa->index, - alu->dest.dest.ssa.index, + copy_types(alu->src[2].src, &alu->dest.dest, float_types, int_types, &progress); break; @@ -178,20 +180,35 @@ nir_gather_ssa_types(nir_function_impl *impl, break; } - default: { - /* For the most part, we leave other intrinsics alone. Most - * of them don't matter in OpenGL ES 2.0 drivers anyway. - * However, we should at least check if this is some sort of - * IO intrinsic and flag it's offset and index sources. - */ - nir_src *offset_src = nir_get_io_offset_src(intrin); - if (offset_src) { - assert(offset_src->is_ssa); - set_type(offset_src->ssa->index, nir_type_int, - float_types, int_types, &progress); - } + case nir_intrinsic_load_input: + case nir_intrinsic_load_uniform: + assert(intrin->dest.is_ssa); + set_type(intrin->dest.ssa.index, + nir_intrinsic_type(intrin), + float_types, int_types, &progress); + break; + + case nir_intrinsic_store_output: + assert(intrin->src[0].is_ssa); + set_type(intrin->src[0].ssa->index, + nir_intrinsic_type(intrin), + float_types, int_types, &progress); + break; + + default: break; } + + /* For the most part, we leave other intrinsics alone. Most + * of them don't matter in OpenGL ES 2.0 drivers anyway. + * However, we should at least check if this is some sort of + * IO intrinsic and flag it's offset and index sources. + */ + nir_src *offset_src = nir_get_io_offset_src(intrin); + if (offset_src) { + assert(offset_src->is_ssa); + set_type(offset_src->ssa->index, nir_type_int, + float_types, int_types, &progress); } break; } @@ -200,8 +217,7 @@ nir_gather_ssa_types(nir_function_impl *impl, nir_phi_instr *phi = nir_instr_as_phi(instr); assert(phi->dest.is_ssa); nir_foreach_phi_src(src, phi) { - assert(src->src.is_ssa); - copy_types(src->src.ssa->index, phi->dest.ssa.index, + copy_types(src->src, &phi->dest, float_types, int_types, &progress); } break; -- 2.30.2