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. */
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

View File

@@ -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);