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

_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to