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 <jonathan@marek.ca> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
c12750527b
commit
887c2a6092
|
@ -51,25 +51,31 @@ set_type(unsigned idx, nir_alu_type type, BITSET_WORD *float_types,
|
|||
}
|
||||
|
||||
static void
|
||||
copy_types(unsigned a, unsigned b, BITSET_WORD *float_types,
|
||||
copy_type(unsigned src, unsigned dst, bool src_is_sink,
|
||||
BITSET_WORD *types, bool *progress)
|
||||
{
|
||||
if (!types)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_types(nir_src src, nir_dest *dest, BITSET_WORD *float_types,
|
||||
BITSET_WORD *int_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 (int_types && (BITSET_TEST(int_types, a) !=
|
||||
BITSET_TEST(int_types, b))) {
|
||||
*progress = true;
|
||||
BITSET_SET(int_types, a);
|
||||
BITSET_SET(int_types, b);
|
||||
}
|
||||
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
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue