freedreno/rnn: Support stripes in rnndec_decodereg
We'll need this for finding where INDIRECT/STRIDE are in CP_DRAW_INDIRECT_MULTI, since they are in different locations in each variant. This is tricky because we need to bubble up success/failure to the upper levels, and 0 could be a valid offset if the stripe is inside an array or in a packet. Hence we refactor tryreg to return success/failure separately, although I stopped short of modifying rnndec_decodereg itself. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6104>
This commit is contained in:
@@ -481,12 +481,15 @@ struct rnndecaddrinfo *rnndec_decodeaddr(struct rnndeccontext *ctx, struct rnndo
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint64_t tryreg(struct rnndeccontext *ctx, struct rnndelem **elems, int elemsnum,
|
||||
int dwidth, const char *name)
|
||||
static unsigned tryreg(struct rnndeccontext *ctx, struct rnndelem **elems, int elemsnum,
|
||||
int dwidth, const char *name, uint64_t *offset)
|
||||
{
|
||||
int i;
|
||||
unsigned ret;
|
||||
const char *suffix = strchr(name, '[');
|
||||
unsigned n = suffix ? (suffix - name) : strlen(name);
|
||||
const char *dotsuffix = strchr(name, '.');
|
||||
unsigned dotn = dotsuffix ? (dotsuffix - name) : strlen(name);
|
||||
|
||||
const char *child = NULL;
|
||||
unsigned idx = 0;
|
||||
@@ -501,22 +504,35 @@ static uint64_t tryreg(struct rnndeccontext *ctx, struct rnndelem **elems, int e
|
||||
struct rnndelem *elem = elems[i];
|
||||
if (!rnndec_varmatch(ctx, &elem->varinfo))
|
||||
continue;
|
||||
int match = (strlen(elem->name) == n) && !strncmp(elem->name, name, n);
|
||||
int match = elem->name && (strlen(elem->name) == n) && !strncmp(elem->name, name, n);
|
||||
switch (elem->type) {
|
||||
case RNN_ETYPE_REG:
|
||||
if (match) {
|
||||
assert(!suffix);
|
||||
return elem->offset;
|
||||
*offset = elem->offset;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case RNN_ETYPE_STRIPE:
|
||||
assert(0); // TODO
|
||||
if (elem->name) {
|
||||
if (!dotsuffix)
|
||||
break;
|
||||
if (strlen(elem->name) != dotn || strncmp(elem->name, name, dotn))
|
||||
break;
|
||||
}
|
||||
ret = tryreg(ctx, elem->subelems, elem->subelemsnum, dwidth,
|
||||
elem->name ? dotsuffix : name, offset);
|
||||
if (ret)
|
||||
return 1;
|
||||
break;
|
||||
case RNN_ETYPE_ARRAY:
|
||||
if (match) {
|
||||
assert(suffix);
|
||||
return elem->offset + (idx * elem->stride) +
|
||||
tryreg(ctx, elem->subelems, elem->subelemsnum, dwidth, child);
|
||||
ret = tryreg(ctx, elem->subelems, elem->subelemsnum, dwidth, child, offset);
|
||||
if (ret) {
|
||||
*offset += elem->offset + (idx * elem->stride);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -528,5 +544,10 @@ static uint64_t tryreg(struct rnndeccontext *ctx, struct rnndelem **elems, int e
|
||||
|
||||
uint64_t rnndec_decodereg(struct rnndeccontext *ctx, struct rnndomain *domain, const char *name)
|
||||
{
|
||||
return tryreg(ctx, domain->subelems, domain->subelemsnum, domain->width, name);
|
||||
uint64_t offset;
|
||||
if (tryreg(ctx, domain->subelems, domain->subelemsnum, domain->width, name, &offset)) {
|
||||
return offset;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user