[Freedreno] [RFC PATCH 3/5] freedreno: Handle A20x DRAWINDX format

Rob Clark robdclark at gmail.com
Tue Aug 4 12:48:23 PDT 2015


On Tue, Aug 4, 2015 at 1:53 PM, Martin Fuzzey <mfuzzey at parkeon.com> wrote:
> On A205 at least the index count is encoded differently.
>
> Signed-off-by: Martin Fuzzey <mfuzzey at parkeon.com>
> ---
>  src/gallium/drivers/freedreno/freedreno_draw.h |   31 ++++++++++++++++++++----
>  1 file changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h
> index 3224fb1..a6470d0 100644
> --- a/src/gallium/drivers/freedreno/freedreno_draw.h
> +++ b/src/gallium/drivers/freedreno/freedreno_draw.h
> @@ -51,6 +51,9 @@ fd_draw(struct fd_context *ctx, struct fd_ringbuffer *ring,
>                 uint32_t idx_size, uint32_t idx_offset,
>                 struct fd_bo *idx_bo)
>  {
> +       uint32_t num_args;
> +       uint32_t di_and, di_or;
> +
>         /* for debug after a lock up, write a unique counter value
>          * to scratch7 for each draw, to make it easier to match up
>          * register dumps to cmdstream.  The combination of IB
> @@ -74,18 +77,36 @@ fd_draw(struct fd_context *ctx, struct fd_ringbuffer *ring,
>                 OUT_RING(ring, 0);
>         }
>
> -       OUT_PKT3(ring, CP_DRAW_INDX, idx_bo ? 5 : 3);
> +       if (is_a20x(ctx->screen)) {
> +               /* A20x (or at least A205) stores NumIndices in the high bits
> +                 It also doesn't like bit 14 being set... */
> +               num_args = 2;
> +               di_and = ~((0xFFFF << 16) | (1 << 14));
> +               di_or = count << 16;
> +       } else {
> +               num_args = 3;
> +               di_and = ~0;
> +               di_or = 0;

hmm, it might be easier to just to split a20x out completely..  we
already have a different version of fd_draw() (and fd_draw_emit()) for
a4xx.. (although fd_draw_emit() and fd4_draw_emit() are slightly
different).  And fd_draw() already has an a320.0 workaround in it.
Maybe we should just stop trying to pretend it is all the same and
instead move fd_draw() and fd_draw_emit() into per-generation code,
where a3xx version handles a320.0 vs everything else, and a2xx version
has fd_draw_a20x() and fd_draw_a22x() versions..

It would be a small bit of duplication of code, but otoh, fd_draw()
and fd_draw_emit() are not called by any generic code (ie. all called
from either fd2 or fd3 code) so splitting it up gets rid of a few
conditional branches that wouldn't be needed (ie. a2xx never needs to
check for a3xx_p0 and a3xx never needs to check for a20x).

BR,
-R

> +       }
> +       if (idx_bo)
> +               num_args += 2;
> +
> +       OUT_PKT3(ring, CP_DRAW_INDX, num_args);
>         OUT_RING(ring, 0x00000000);        /* viz query info. */
>         if (vismode == USE_VISIBILITY) {
>                 /* leave vis mode blank for now, it will be patched up when
>                  * we know if we are binning or not
>                  */
> -               OUT_RINGP(ring, DRAW(primtype, src_sel, idx_type, 0, instances),
> -                               &ctx->draw_patches);
> +               OUT_RINGP(ring,
> +                       (DRAW(primtype, src_sel, idx_type, 0, instances) & di_and) | di_or,
> +                       &ctx->draw_patches);
>         } else {
> -               OUT_RING(ring, DRAW(primtype, src_sel, idx_type, vismode, instances));
> +               OUT_RING(ring,
> +                       (DRAW(primtype, src_sel, idx_type, vismode, instances) & di_and) | di_or);
>         }
> -       OUT_RING(ring, count);             /* NumIndices */
> +       if (!is_a20x(ctx->screen))
> +               OUT_RING(ring, count);             /* NumIndices */
> +
>         if (idx_bo) {
>                 OUT_RELOC(ring, idx_bo, idx_offset, 0, 0);
>                 OUT_RING (ring, idx_size);
>


More information about the Freedreno mailing list