}
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
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;
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;
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;
}
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;