mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-08 18:40:28 +01:00
freedreno/decode: Allow direct access to domain bitfield
For parsing packets or descriptors, it is useful to be able to use pkt.FOO instead pkt[2].FOO. This makes it easier when fields move between dwords in the domain. Signed-off-by: Rob Clark <rob.clark@oss.qualcomm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39573>
This commit is contained in:
parent
6d7a056c8b
commit
ebde70cdce
1 changed files with 75 additions and 45 deletions
|
|
@ -190,6 +190,47 @@ pushdecval(struct lua_State *L, struct rnn *rnn, uint64_t regval,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pushfield(lua_State *L, struct rnntypeinfo *info, struct rnn *rnn,
|
||||
uint64_t offset, const char *name)
|
||||
{
|
||||
struct rnnbitfield **bitfields;
|
||||
int bitfieldsnum;
|
||||
int i;
|
||||
|
||||
switch (info->type) {
|
||||
case RNN_TTYPE_BITSET:
|
||||
bitfields = info->ebitset->bitfields;
|
||||
bitfieldsnum = info->ebitset->bitfieldsnum;
|
||||
break;
|
||||
case RNN_TTYPE_INLINE_BITSET:
|
||||
bitfields = info->bitfields;
|
||||
bitfieldsnum = info->bitfieldsnum;
|
||||
break;
|
||||
default:
|
||||
printf("invalid register type: %d\n", info->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < bitfieldsnum; i++) {
|
||||
struct rnnbitfield *bf = bitfields[i];
|
||||
if (!strcmp(name, bf->name)) {
|
||||
uint32_t regval = rnn_val(rnn, offset);
|
||||
|
||||
regval &= typeinfo_mask(&bf->typeinfo);
|
||||
regval >>= bf->typeinfo.low;
|
||||
regval <<= bf->typeinfo.shr;
|
||||
|
||||
DBG("name=%s, info=%p, type=%d, regval=%x", name, info,
|
||||
bf->typeinfo.type, regval);
|
||||
|
||||
return pushdecval(L, rnn, regval, &bf->typeinfo);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_rnn_etype(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
|
||||
uint64_t offset)
|
||||
|
|
@ -324,42 +365,13 @@ l_rnn_reg_meta_index(lua_State *L)
|
|||
const char *name = lua_tostring(L, 2);
|
||||
struct rnndelem *elem = rnndoff->elem;
|
||||
struct rnntypeinfo *info = &elem->typeinfo;
|
||||
struct rnnbitfield **bitfields;
|
||||
int bitfieldsnum;
|
||||
int i;
|
||||
|
||||
switch (info->type) {
|
||||
case RNN_TTYPE_BITSET:
|
||||
bitfields = info->ebitset->bitfields;
|
||||
bitfieldsnum = info->ebitset->bitfieldsnum;
|
||||
break;
|
||||
case RNN_TTYPE_INLINE_BITSET:
|
||||
bitfields = info->bitfields;
|
||||
bitfieldsnum = info->bitfieldsnum;
|
||||
break;
|
||||
default:
|
||||
printf("invalid register type: %d\n", info->type);
|
||||
return 0;
|
||||
}
|
||||
int ret = pushfield(L, info, rnndoff->rnn, rnndoff->offset, name);
|
||||
|
||||
for (i = 0; i < bitfieldsnum; i++) {
|
||||
struct rnnbitfield *bf = bitfields[i];
|
||||
if (!strcmp(name, bf->name)) {
|
||||
uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
|
||||
if (!ret)
|
||||
printf("invalid member: %s\n", name);
|
||||
|
||||
regval &= typeinfo_mask(&bf->typeinfo);
|
||||
regval >>= bf->typeinfo.low;
|
||||
regval <<= bf->typeinfo.shr;
|
||||
|
||||
DBG("name=%s, info=%p, subelemsnum=%d, type=%d, regval=%x", name, info,
|
||||
rnndoff->elem->subelemsnum, bf->typeinfo.type, regval);
|
||||
|
||||
return pushdecval(L, rnndoff->rnn, regval, &bf->typeinfo);
|
||||
}
|
||||
}
|
||||
|
||||
printf("invalid member: %s\n", name);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -760,21 +772,39 @@ script_draw(const char *primtype, uint32_t nindx)
|
|||
static int
|
||||
l_rnn_meta_dom_index(lua_State *L)
|
||||
{
|
||||
struct rnn *rnn = lua_touserdata(L, 1);
|
||||
uint32_t offset = (uint32_t)lua_tonumber(L, 2);
|
||||
struct rnndelem *elem;
|
||||
struct rnndec *rnndec = lua_touserdata(L, 1);
|
||||
struct rnn *rnn = &rnndec->base;
|
||||
|
||||
/* TODO might be nicer if the arg isn't a number, to search the domain
|
||||
* for matching bitfields.. so that the script could do something like
|
||||
* 'pkt.WIDTH' insteadl of 'pkt[1].WIDTH', ie. not have to remember the
|
||||
* offset of the dword containing the bitfield..
|
||||
*/
|
||||
if (lua_isnumber(L, 2)) {
|
||||
/* index as an array, is pkt[0].FOO: */
|
||||
uint32_t offset = (uint32_t)lua_tonumber(L, 2);
|
||||
struct rnndelem *elem = rnn_regoff(rnn, offset);
|
||||
if (elem)
|
||||
return l_rnn_etype(L, rnn, elem, elem->offset);
|
||||
} else if (lua_isstring(L, 2)) {
|
||||
/* If not indexed like an array, search thru all
|
||||
* the elements in the domain finding the matching
|
||||
* subelem.
|
||||
*
|
||||
* This handles the pkt.FOO case
|
||||
*/
|
||||
const char *name = lua_tostring(L, 2);
|
||||
|
||||
elem = rnn_regoff(rnn, offset);
|
||||
if (!elem)
|
||||
return 0;
|
||||
for (unsigned i = 0; i < rnndec->sizedwords; i++) {
|
||||
struct rnndelem *elem = rnn_regoff(rnn, i);
|
||||
if (!elem)
|
||||
continue;
|
||||
|
||||
return l_rnn_etype(L, rnn, elem, elem->offset);
|
||||
if (!strcmp(name, elem->name))
|
||||
return l_rnn_etype(L, rnn, elem, elem->offset);
|
||||
|
||||
int ret = pushfield(L, &elem->typeinfo, rnn, i, name);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue