diff options
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/midgard_emit.c | 47 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/midgard_schedule.c | 21 |
2 files changed, 52 insertions, 16 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/midgard_emit.c b/src/gallium/drivers/panfrost/midgard/midgard_emit.c index 3c331551dd8..701ef1074ff 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_emit.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_emit.c @@ -29,11 +29,15 @@ * this, we just demote vector ALU payloads to scalar. */ static int -component_from_mask(unsigned mask) +component_from_mask(unsigned mask, bool full) { - for (int c = 0; c < 4; ++c) { - if (mask & (3 << (2 * c))) + for (int c = 0; c < 8; ++c) { + if (mask & (1 << c)) return c; + + /* Full uses every other bit */ + if (full) + c++; } assert(0); @@ -41,17 +45,35 @@ component_from_mask(unsigned mask) } static unsigned -vector_to_scalar_source(unsigned u, bool is_int) +vector_to_scalar_source(unsigned u, bool is_int, bool is_full) { midgard_vector_alu_src v; memcpy(&v, &u, sizeof(v)); /* TODO: Integers */ - midgard_scalar_alu_src s = { - .full = !v.half, - .component = (v.swizzle & 3) << 1 - }; + unsigned component = v.swizzle & 3; + bool upper = false; /* TODO */ + + midgard_scalar_alu_src s = { 0 }; + + if (is_full) { + /* For a 32-bit op, just check the source half flag */ + s.full = !v.half; + } else if (!v.half) { + /* For a 16-bit op that's not subdivided, never full */ + s.full = false; + } else { + /* We can't do 8-bit scalar, abort! */ + assert(0); + } + + /* Component indexing takes size into account */ + + if (s.full) + s.component = component << 1; + else + s.component = component + (upper << 2); if (is_int) { /* TODO */ @@ -70,16 +92,17 @@ static midgard_scalar_alu vector_to_scalar_alu(midgard_vector_alu v, midgard_instruction *ins) { bool is_int = midgard_is_integer_op(v.op); + bool is_full = v.reg_mode == midgard_reg_mode_32; /* The output component is from the mask */ midgard_scalar_alu s = { .op = v.op, - .src1 = vector_to_scalar_source(v.src1, is_int), - .src2 = vector_to_scalar_source(v.src2, is_int), + .src1 = vector_to_scalar_source(v.src1, is_int, is_full), + .src2 = vector_to_scalar_source(v.src2, is_int, is_full), .unknown = 0, .outmod = v.outmod, - .output_full = 1, /* TODO: Half */ - .output_component = component_from_mask(v.mask) << 1, + .output_full = is_full, + .output_component = component_from_mask(v.mask, is_full), }; /* Inline constant is passed along rather than trying to extract it diff --git a/src/gallium/drivers/panfrost/midgard/midgard_schedule.c b/src/gallium/drivers/panfrost/midgard/midgard_schedule.c index c0dd5764595..77738731b8a 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_schedule.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_schedule.c @@ -44,14 +44,19 @@ swizzle_to_access_mask(unsigned swizzle) /* Does the mask cover more than a scalar? */ static bool -is_single_component_mask(unsigned mask) +is_single_component_mask(unsigned mask, bool full) { int components = 0; - for (int c = 0; c < 4; ++c) - if (mask & (3 << (2 * c))) + for (int c = 0; c < 8; ++c) { + if (mask & (1 << c)) components++; + /* Full uses 2-bit components */ + if (full) + c++; + } + return components == 1; } @@ -193,9 +198,17 @@ schedule_bundle(compiler_context *ctx, midgard_block *block, midgard_instruction bool vectorable = units & UNITS_ANY_VECTOR; bool scalarable = units & UNITS_SCALAR; - bool could_scalar = is_single_component_mask(ains->alu.mask); + bool full = ains->alu.reg_mode == midgard_reg_mode_32; + bool could_scalar = is_single_component_mask(ains->alu.mask, full); bool vector = vectorable && !(could_scalar && scalarable); + /* Only 16/32-bit can run on a scalar unit */ + could_scalar &= ains->alu.reg_mode != midgard_reg_mode_8; + could_scalar &= ains->alu.reg_mode != midgard_reg_mode_64; + + /* TODO: Check ahead-of-time for other scalar + * hazards that otherwise get aborted out */ + if (!vector) assert(units & UNITS_SCALAR); |