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:
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user