From 4b940532fbd147e06d881e29448b858be3d37f01 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 28 Jul 2020 13:42:23 +0200 Subject: [PATCH] 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: --- src/freedreno/rnn/rnndec.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/freedreno/rnn/rnndec.c b/src/freedreno/rnn/rnndec.c index fdc2c3024bd..db92de332f6 100644 --- a/src/freedreno/rnn/rnndec.c +++ b/src/freedreno/rnn/rnndec.c @@ -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; + } } -- 2.30.2