[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