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