nvc0: upload constants with m2mf for the time being
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 9 Dec 2010 13:35:26 +0000 (14:35 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 9 Dec 2010 13:35:26 +0000 (14:35 +0100)
I get mysterious lockups with the dedicated CB upload ...

src/gallium/drivers/nvc0/nvc0_context.h
src/gallium/drivers/nvc0/nvc0_state_validate.c

index 1b2f96429b89c7e96adc66c1ef05e6553d66d510..61a9b888786542a5d54fd32fdffd2ddf3746a7d3 100644 (file)
@@ -79,6 +79,7 @@ struct nvc0_context {
       uint8_t num_textures[5];
       uint8_t num_samplers[5];
       uint16_t scissor;
+      uint8_t uniform_buffer_bound; /* workaround */
    } state;
 
    struct nvc0_blend_stateobj *blend;
@@ -196,9 +197,15 @@ nvc0_create_sampler_view(struct pipe_context *,
                          const struct pipe_sampler_view *);
 
 /* nvc0_transfer.c */
-void nvc0_m2mf_push_linear(struct nvc0_context *nvc0,
-                           struct nouveau_bo *dst, unsigned domain, int offset,
-                           unsigned size, void *data);
+void
+nvc0_m2mf_push_linear(struct nvc0_context *nvc0,
+                     struct nouveau_bo *dst, unsigned domain, int offset,
+                     unsigned size, void *data);
+void
+nvc0_m2mf_copy_linear(struct nvc0_context *nvc0,
+                     struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
+                     struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
+                     unsigned size);
 
 /* nvc0_vbo.c */
 void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *);
index a024831d60a3c4b9a5b27390da276497fe6e701d..2b38ebc8ba089ce49be788fd396310b1767ce02f 100644 (file)
@@ -231,10 +231,13 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
 
    for (s = 0; s < 5; ++s) {
       struct nvc0_resource *res;
-      int i, j;
+      int i;
 
       while (nvc0->constbuf_dirty[s]) {
-         unsigned offset = 0;
+         unsigned base = 0;
+         unsigned offset = 0, words = 0;
+         boolean rebind = TRUE;
+
          i = ffs(nvc0->constbuf_dirty[s]) - 1;
          nvc0->constbuf_dirty[s] &= ~(1 << i);
 
@@ -242,33 +245,70 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
          if (!res) {
             BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
             OUT_RING  (chan, (i << 4) | 0);
+            if (i == 0)
+               nvc0->state.uniform_buffer_bound &= ~(1 << s);
             continue;
          }
 
-         if (i == 0 && !nvc0_resource_mapped_by_gpu(&res->base)) {
-            offset = s << 16;
-            bo = nvc0->screen->uniforms;
+         if (!nvc0_resource_mapped_by_gpu(&res->base)) {
+            if (i == 0) {
+               base = s << 16;
+               bo = nvc0->screen->uniforms;
+
+               if (nvc0->state.uniform_buffer_bound & (1 << s))
+                  rebind = FALSE;
+               else
+                  nvc0->state.uniform_buffer_bound |= (1 << s);
+            } else {
+               bo = res->bo;
+            }
+#if 1
+            nvc0_m2mf_push_linear(nvc0, bo, NOUVEAU_BO_VRAM,
+                                  base, res->base.width0, res->data);
+            BEGIN_RING(chan, RING_3D_(0x021c), 1);
+            OUT_RING  (chan, 0x1111);
+#else
+            words = res->base.width0 / 4;
+#endif
          } else {
             bo = res->bo;
+            if (i == 0)
+               nvc0->state.uniform_buffer_bound &= ~(1 << s);
+         }
+
+         if (bo != nvc0->screen->uniforms)
             nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res,
                                      NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+
+         if (rebind) {
+            BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+            OUT_RING  (chan, align(res->base.width0, 0x100));
+            OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+            OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+            BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
+            OUT_RING  (chan, (i << 4) | 1);
          }
 
-         BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
-         OUT_RING  (chan, align(res->base.width0, 0x100));
-         OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-         OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-         BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
-         OUT_RING  (chan, (i << 4) | 1);
-
-         BEGIN_RING(chan, RING_3D(CB_SIZE), 4);
-         OUT_RING  (chan, align(res->base.width0, 0x100));
-         OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-         OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-         OUT_RING  (chan, 0);
-        BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), res->base.width0 / 4);
-         for (j = 0; j < res->base.width0 / 4; ++j)
-            OUT_RING(chan, ((uint32_t *)res->data)[j]);
+         while (words) {
+            unsigned nr = AVAIL_RING(chan);
+
+            if (nr < 16) {
+               FIRE_RING(chan);
+               continue;
+            }
+            nr = MIN2(MIN2(nr - 6, words), NV04_PFIFO_MAX_PACKET_LEN - 1);
+
+            BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+            OUT_RING  (chan, align(res->base.width0, 0x100));
+            OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+            OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+            BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1);
+            OUT_RING  (chan, offset);
+            OUT_RINGp (chan, &res->data[offset], nr);
+
+            offset += nr * 4;
+            words -= nr;
+         }
       }
    }
 }
@@ -293,10 +333,10 @@ static struct state_validate {
     { nvc0_tevlprog_validate,      NVC0_NEW_TEVLPROG },
     { nvc0_gmtyprog_validate,      NVC0_NEW_GMTYPROG },
     { nvc0_fragprog_validate,      NVC0_NEW_FRAGPROG },
-    { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS },
+    { nvc0_constbufs_validate,     NVC0_NEW_CONSTBUF },
     { nvc0_validate_textures,      NVC0_NEW_TEXTURES },
     { nvc0_validate_samplers,      NVC0_NEW_SAMPLERS },
-    { nvc0_constbufs_validate,     NVC0_NEW_CONSTBUF }
+    { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS }
 };
 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
 
@@ -311,8 +351,6 @@ nvc0_state_validate(struct nvc0_context *nvc0)
    nvc0->screen->cur_ctx = nvc0;
 
    if (nvc0->dirty) {
-      FIRE_RING(nvc0->screen->base.channel);
-
       for (i = 0; i < validate_list_len; ++i) {
          struct state_validate *validate = &validate_list[i];