nv50: emit constbuf relocs before uploading constants
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 18 Sep 2010 13:19:34 +0000 (15:19 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 18 Sep 2010 13:22:05 +0000 (15:22 +0200)
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_shader_state.c

index a8f772133721d17cabf4e1884bcf1d2e623669ed..7c9342b7471469a925769a86ff3003e0d87ff595 100644 (file)
@@ -221,6 +221,36 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
 #define BGN_RELOC(ch, bo, gr, m, n, fl) \
    OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
 
+void
+nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi)
+{
+       struct nouveau_bo *bo;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *tesla = screen->tesla;
+       unsigned size;
+       const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
+
+       switch (cbi) {
+       case NV50_CB_PMISC:
+               bo = screen->constbuf_misc[0];
+               size = 0x200;
+               break;
+       case NV50_CB_PVP:
+       case NV50_CB_PFP:
+       case NV50_CB_PGP:
+               bo = screen->constbuf_parm[cbi - NV50_CB_PVP];
+               size = 0;
+               break;
+       default:
+               return;
+       }
+
+       BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+       OUT_RELOCh(chan, bo, 0, rl);
+       OUT_RELOCl(chan, bo, 0, rl);
+       OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0);
+}
+
 void
 nv50_screen_relocs(struct nv50_screen *screen)
 {
@@ -243,12 +273,7 @@ nv50_screen_relocs(struct nv50_screen *screen)
        OUT_RELOCh(chan, screen->tsc, 0, rl);
        OUT_RELOCl(chan, screen->tsc, 0, rl);
 
-       BGN_RELOC (chan, screen->constbuf_misc[0],
-                  tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
-       OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
-       OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
-       OUT_RELOC (chan, screen->constbuf_misc[0],
-                  (NV50_CB_PMISC << 16) | 0x0200, rl, 0, 0);
+       nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC);
 
        BGN_RELOC (chan, screen->constbuf_misc[0],
                   tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
@@ -257,14 +282,8 @@ nv50_screen_relocs(struct nv50_screen *screen)
        OUT_RELOC (chan, screen->constbuf_misc[0],
                   (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
 
-       for (i = 0; i < 3; ++i) {
-               BGN_RELOC (chan, screen->constbuf_parm[i],
-                          tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
-               OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
-               OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
-               OUT_RELOC (chan, screen->constbuf_parm[i],
-                          ((NV50_CB_PVP + i) << 16) | 0x0000, rl, 0, 0);
-       }
+       for (i = 0; i < 3; ++i)
+               nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i);
 
        BGN_RELOC (chan, screen->stack_bo,
                   tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl);
index ad6bdeb27c80044035a93dbbacf62c752f0330ba..6e15230b486fa604cc35c4142483d4ab8b8b5e04 100644 (file)
@@ -39,6 +39,8 @@ nv50_screen(struct pipe_screen *screen)
 
 extern void nv50_screen_relocs(struct nv50_screen *);
 
+extern void nv50_screen_reloc_constbuf(struct nv50_screen *, unsigned cbi);
+
 struct nv50_format {
        uint32_t rt;
        uint32_t tic;
index 8057ec9fcf593782b4597a2194448ca38587ffe7..7d2989da05b83119cd02fc7eb46a5cda30a970e6 100644 (file)
@@ -47,10 +47,17 @@ nv50_transfer_constbuf(struct nv50_context *nv50,
    start = 0;
 
    while (count) {
-      unsigned nr = count;
-      nr = MIN2(nr, 2047);
+      unsigned nr = AVAIL_RING(chan);
+
+      if (nr < 8) {
+         FIRE_RING(chan);
+         continue;
+      }
+      nr = MIN2(count, nr - 7);
+      nr = MIN2(nr, 2074);
+
+      nv50_screen_reloc_constbuf(nv50->screen, cbi);
 
-      /* FIXME: emit relocs for unsuiTed MM */
       BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
       OUT_RING  (chan, (start << 8) | cbi);
       BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr);
@@ -77,8 +84,16 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
       unsigned start = 0;
 
       while (count) {
-         unsigned nr = count;
-         nr = MIN2(nr, 2047);
+         unsigned nr = AVAIL_RING(chan);
+
+         if (nr < 8) {
+            FIRE_RING(chan);
+            continue;
+         }
+         nr = MIN2(count, nr - 7);
+         nr = MIN2(nr, 2074);
+
+         nv50_screen_reloc_constbuf(nv50->screen, NV50_CB_PMISC);
 
          BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
          OUT_RING  (chan, (start << 8) | NV50_CB_PMISC);
@@ -111,8 +126,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
       break;
    default:
       assert(0);
-      cbi = 0;
-      break;
+      return;
    }
 
    nv50_transfer_constbuf(nv50, nv50->constbuf[p->type], p->parm_size, cbi);