pan/midgard: Handle get/set_swizzle for load/store arguments

Load/store's  main "argument 0" already has its swizzle handled
correctly (for stores, that is). But the tinier arguments, the compact
ones with a component select but not a full swizzle, those are not yet
handled. Let's do something about that!
This commit is contained in:
Alyssa Rosenzweig 2019-08-02 11:22:56 -07:00
parent 9aeb726045
commit 5d9b7a8ddb
2 changed files with 83 additions and 3 deletions

View File

@ -358,4 +358,41 @@ midgard_ldst_reg(unsigned reg, unsigned component)
return packed;
}
/* Unpacks a load/store argument */
static inline midgard_ldst_register_select
midgard_ldst_select(uint8_t u)
{
midgard_ldst_register_select sel;
memcpy(&sel, &u, sizeof(u));
return sel;
}
static inline uint8_t
midgard_ldst_pack(midgard_ldst_register_select sel)
{
uint8_t packed;
memcpy(&packed, &sel, sizeof(packed));
return packed;
}
/* Gets a swizzle like yyyy and returns y */
static inline unsigned
swizzle_to_component(unsigned swizzle)
{
unsigned c = swizzle & 3;
assert(((swizzle >> 2) & 3) == c);
assert(((swizzle >> 4) & 3) == c);
assert(((swizzle >> 6) & 3) == c);
return c;
}
static inline unsigned
component_to_swizzle(unsigned c)
{
return SWIZZLE(c, c, c, c);
}
#endif

View File

@ -44,8 +44,23 @@ mir_get_swizzle(midgard_instruction *ins, unsigned idx)
return s.swizzle;
} else if (ins->type == TAG_LOAD_STORE_4) {
assert(idx == 0);
return ins->load_store.swizzle;
/* Main swizzle of a load is on the destination */
if (!OP_IS_STORE(ins->load_store.op))
idx++;
switch (idx) {
case 0:
return ins->load_store.swizzle;
case 1:
case 2: {
uint8_t raw =
(idx == 2) ? ins->load_store.arg_2 : ins->load_store.arg_1;
return component_to_swizzle(midgard_ldst_select(raw).component);
}
default:
unreachable("Unknown load/store source");
}
} else if (ins->type == TAG_TEXTURE_4) {
switch (idx) {
case 0:
@ -78,7 +93,35 @@ mir_set_swizzle(midgard_instruction *ins, unsigned idx, unsigned new)
else
ins->alu.src2 = pack;
} else if (ins->type == TAG_LOAD_STORE_4) {
ins->load_store.swizzle = new;
/* Main swizzle of a load is on the destination */
if (!OP_IS_STORE(ins->load_store.op))
idx++;
switch (idx) {
case 0:
ins->load_store.swizzle = new;
break;
case 1:
case 2: {
uint8_t raw =
(idx == 2) ? ins->load_store.arg_2 : ins->load_store.arg_1;
midgard_ldst_register_select sel
= midgard_ldst_select(raw);
sel.component = swizzle_to_component(new);
uint8_t packed = midgard_ldst_pack(sel);
if (idx == 2)
ins->load_store.arg_2 = packed;
else
ins->load_store.arg_1 = packed;
break;
}
default:
assert(new == 0);
break;
}
} else if (ins->type == TAG_TEXTURE_4) {
switch (idx) {
case 0: