panfrost/midgard: Allow fp16 in scalar ALU

The packing is a little different, so implement that.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Alyssa Rosenzweig
2019-07-01 18:35:28 -07:00
parent d8c084d2ca
commit e69cf1fed9
2 changed files with 52 additions and 16 deletions

View File

@@ -29,11 +29,15 @@
* this, we just demote vector ALU payloads to scalar. */ * this, we just demote vector ALU payloads to scalar. */
static int static int
component_from_mask(unsigned mask) component_from_mask(unsigned mask, bool full)
{ {
for (int c = 0; c < 4; ++c) { for (int c = 0; c < 8; ++c) {
if (mask & (3 << (2 * c))) if (mask & (1 << c))
return c; return c;
/* Full uses every other bit */
if (full)
c++;
} }
assert(0); assert(0);
@@ -41,17 +45,35 @@ component_from_mask(unsigned mask)
} }
static unsigned 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; midgard_vector_alu_src v;
memcpy(&v, &u, sizeof(v)); memcpy(&v, &u, sizeof(v));
/* TODO: Integers */ /* TODO: Integers */
midgard_scalar_alu_src s = { unsigned component = v.swizzle & 3;
.full = !v.half, bool upper = false; /* TODO */
.component = (v.swizzle & 3) << 1
}; 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) { if (is_int) {
/* TODO */ /* TODO */
@@ -70,16 +92,17 @@ static midgard_scalar_alu
vector_to_scalar_alu(midgard_vector_alu v, midgard_instruction *ins) vector_to_scalar_alu(midgard_vector_alu v, midgard_instruction *ins)
{ {
bool is_int = midgard_is_integer_op(v.op); 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 */ /* The output component is from the mask */
midgard_scalar_alu s = { midgard_scalar_alu s = {
.op = v.op, .op = v.op,
.src1 = vector_to_scalar_source(v.src1, is_int), .src1 = vector_to_scalar_source(v.src1, is_int, is_full),
.src2 = vector_to_scalar_source(v.src2, is_int), .src2 = vector_to_scalar_source(v.src2, is_int, is_full),
.unknown = 0, .unknown = 0,
.outmod = v.outmod, .outmod = v.outmod,
.output_full = 1, /* TODO: Half */ .output_full = is_full,
.output_component = component_from_mask(v.mask) << 1, .output_component = component_from_mask(v.mask, is_full),
}; };
/* Inline constant is passed along rather than trying to extract it /* Inline constant is passed along rather than trying to extract it

View File

@@ -44,14 +44,19 @@ swizzle_to_access_mask(unsigned swizzle)
/* Does the mask cover more than a scalar? */ /* Does the mask cover more than a scalar? */
static bool static bool
is_single_component_mask(unsigned mask) is_single_component_mask(unsigned mask, bool full)
{ {
int components = 0; int components = 0;
for (int c = 0; c < 4; ++c) for (int c = 0; c < 8; ++c) {
if (mask & (3 << (2 * c))) if (mask & (1 << c))
components++; components++;
/* Full uses 2-bit components */
if (full)
c++;
}
return components == 1; return components == 1;
} }
@@ -193,9 +198,17 @@ schedule_bundle(compiler_context *ctx, midgard_block *block, midgard_instruction
bool vectorable = units & UNITS_ANY_VECTOR; bool vectorable = units & UNITS_ANY_VECTOR;
bool scalarable = units & UNITS_SCALAR; 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); 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) if (!vector)
assert(units & UNITS_SCALAR); assert(units & UNITS_SCALAR);