Luca Barbieri
2010-Apr-12 16:20 UTC
[Nouveau] [PATCH] Support writing out the pushbuffer in renouveau trace format (v2)
Changes in v2: - Unmap buffers we mapped, avoid assertion - Silence warnings This patch causes libdrm, when NOUVEAU_DUMP=1 is set, to write the pushbuffer to stdout instead of submitting it to the card. renouveau-parse can then be used to parse it and obtain a readable trace. This is very useful for debugging and optimizing the Gallium driver. --- nouveau/nouveau_private.h | 2 ++ nouveau/nouveau_pushbuf.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/nouveau/nouveau_private.h b/nouveau/nouveau_private.h index 5a952f7..aa8a9c8 100644 --- a/nouveau/nouveau_private.h +++ b/nouveau/nouveau_private.h @@ -40,6 +40,8 @@ #define CALPB_BUFFERS 4 #define CALPB_BUFSZ 16384 struct nouveau_pushbuf_priv { + char dump; + char no_submit; uint32_t cal_suffix0; uint32_t cal_suffix1; struct nouveau_bo *buffer[CALPB_BUFFERS]; diff --git a/nouveau/nouveau_pushbuf.c b/nouveau/nouveau_pushbuf.c index 28b8018..ac8ca2f 100644 --- a/nouveau/nouveau_pushbuf.c +++ b/nouveau/nouveau_pushbuf.c @@ -124,6 +124,9 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) if (ret) return ret; + nvpb->dump = !!getenv("NOUVEAU_DUMP"); + nvpb->no_submit = !!getenv("NOUVEAU_NO_SUBMIT"); + ret = nouveau_pushbuf_space(chan, 0); if (ret) return ret; @@ -235,6 +238,28 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) if (!nvpb->nr_push) return 0; + if(nvpb->dump) { + unsigned i; + for(i = 0; i < nvpb->nr_push; ++i) { + uint32_t *p, *pend; + struct nouveau_bo *bo = (struct nouveau_bo *)(unsigned long)nvpb->buffers[nvpb->push[i].bo_index].user_priv; + int mapped = 0; + if(!bo->map) + { + mapped = 1; + nouveau_bo_map(bo, NOUVEAU_BO_RD); + } + p = (uint32_t*)((char*)bo->map + nvpb->push[i].offset); + pend = (uint32_t*)((char*)p + nvpb->push[i].length); + printf("# pb #%i offset %i dwords %i\n", (int)i, (int)nvpb->push[i].offset, (int)(pend - p)); + for(; p < pend; ++p) + printf("%08x\n", *p); + printf("# end\n"); + if(mapped) + nouveau_bo_unmap(bo); + } + } + req.channel = chan->id; req.nr_push = nvpb->nr_push; req.push = (uint64_t)(unsigned long)nvpb->push; @@ -245,10 +270,12 @@ nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) req.suffix0 = nvpb->cal_suffix0; req.suffix1 = nvpb->cal_suffix1; - do { - ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_PUSHBUF, - &req, sizeof(req)); - } while (ret == -EAGAIN); + if(!nvpb->no_submit) { + do { + ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_PUSHBUF, + &req, sizeof(req)); + } while (ret == -EAGAIN); + } nvpb->cal_suffix0 = req.suffix0; nvpb->cal_suffix1 = req.suffix1; nvdev->base.vm_vram_size = req.vram_available; -- 1.7.0.1.147.g6d84b
Patrice Mandin
2010-Apr-13 19:19 UTC
[Nouveau] [PATCH] Support writing out the pushbuffer in renouveau trace format (v2)
Le Mon, 12 Apr 2010 18:20:52 +0200 Luca Barbieri <luca at luca-barbieri.com> a ?crit:> Changes in v2: > - Unmap buffers we mapped, avoid assertion > - Silence warnings > > This patch causes libdrm, when NOUVEAU_DUMP=1 is set, to write the > pushbuffer to stdout instead of submitting it to the card. > > renouveau-parse can then be used to parse it and obtain a readable > trace.And for more easier parsing, it would be nice to know which graphic objects are mapped to which handles (the 0x8800000N values). -- Patrice Mandin WWW: http://pmandin.atari.org/ Programmeur Linux, Atari Sp?cialit?: D?veloppement, jeux
Luca Barbieri
2010-Apr-14 02:02 UTC
[Nouveau] [PATCH] Support writing out the pushbuffer in renouveau trace format (v2)
Simply putting the dump in the renouveau directory where a renouveau dump was taken previously seems to work for me (probably because we use the same handle values as nVidia?). But yes, the tools should be improved here and dumping the objclass of the grobjs would be necessary for that.