nv50,nvc0: handle user constbufs without wrapping them in a resource
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 16 May 2012 18:52:41 +0000 (20:52 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 17 May 2012 13:24:58 +0000 (15:24 +0200)
14 files changed:
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_shader_state.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_stateobj.h
src/gallium/drivers/nvc0/nvc0_context.c
src/gallium/drivers/nvc0/nvc0_context.h
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/nvc0/nvc0_screen.h
src/gallium/drivers/nvc0/nvc0_state.c
src/gallium/drivers/nvc0/nvc0_state_validate.c
src/gallium/drivers/nvc0/nvc0_stateobj.h

index 558fe0b3684d578ef2f7be14a46566a8678add59..1e6bbaf8eb81911a12eaf7a16e04254510d93b6d 100644 (file)
@@ -86,8 +86,9 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
       for (i = 0; i < nv50->num_textures[s]; ++i)
          pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
 
-      for (i = 0; i < 16; ++i)
-         pipe_resource_reference(&nv50->constbuf[s][i], NULL);
+      for (i = 0; i < NV50_MAX_PIPE_CONSTBUFS; ++i)
+         if (!nv50->constbuf[s][i].user)
+            pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL);
    }
 }
 
index 44a0ba0f5616d31aaf3727b70cf79b58100c2048..8f5363b3684f1619ea1c01eb4e1a57ad96e761de 100644 (file)
@@ -90,6 +90,7 @@ struct nv50_context {
       uint32_t semantic_color;
       uint32_t semantic_psize;
       int32_t index_bias;
+      boolean uniform_buffer_bound[3];
       boolean prim_restart;
       boolean point_sprite;
       boolean rt_serialize;
@@ -113,7 +114,7 @@ struct nv50_context {
    struct nv50_program *gmtyprog;
    struct nv50_program *fragprog;
 
-   struct pipe_resource *constbuf[3][16];
+   struct nv50_constbuf constbuf[3][NV50_MAX_PIPE_CONSTBUFS];
    uint16_t constbuf_dirty[3];
    uint16_t constbuf_valid[3];
 
@@ -163,6 +164,20 @@ nv50_context_screen(struct nv50_context *nv50)
    return nv50_screen(&nv50->base.screen->base);
 }
 
+/* return index used in nv50_context arrays for a specific shader type */
+static INLINE unsigned
+nv50_context_shader_stage(unsigned pipe)
+{
+   switch (pipe) {
+   case PIPE_SHADER_VERTEX: return 0;
+   case PIPE_SHADER_FRAGMENT: return 1;
+   case PIPE_SHADER_GEOMETRY: return 2;
+   case PIPE_SHADER_COMPUTE: return 3;
+   default:
+      assert(!"invalid/unhandled shader type");
+      return 0;
+   }
+}
 
 /* nv50_context.c */
 struct pipe_context *nv50_create(struct pipe_screen *, void *);
index c96e028b2a2677fcc2126459ace0f45920c487d5..9f356ff6556e5312e145a588741e41dbef3d02a5 100644 (file)
@@ -196,7 +196,7 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
    case PIPE_SHADER_CAP_MAX_CONSTS:
       return 65536 / 16;
    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
-      return 14;
+      return NV50_MAX_PIPE_CONSTBUFS;
    case PIPE_SHADER_CAP_MAX_ADDRS:
       return 1;
    case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
@@ -437,10 +437,7 @@ nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
    PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
    PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
 
-   BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
-   PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
-   PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
-   PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
+   BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3);
    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
    PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
index 9eae08ea1d359c5cefd6a176157dbfbd61a87b86..4292f7fc9a6c38a3f761e87656ba2dcb46080b7d 100644 (file)
@@ -12,6 +12,9 @@
 #define NV50_TIC_MAX_ENTRIES 2048
 #define NV50_TSC_MAX_ENTRIES 2048
 
+/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */
+#define NV50_MAX_PIPE_CONSTBUFS 14
+
 struct nv50_context;
 
 #define NV50_CODE_BO_SIZE_LOG2 19
index d070f07bbbc912fc408b507bcea41205127d88a8..df6764b216f09fbd5faaad167a7c349df0803c2d 100644 (file)
@@ -35,9 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
    unsigned s;
 
    for (s = 0; s < 3; ++s) {
-      struct nv04_resource *res;
-      int i;
-      unsigned p, b;
+      unsigned p;
 
       if (s == PIPE_SHADER_FRAGMENT)
          p = NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT;
@@ -48,68 +46,63 @@ nv50_constbufs_validate(struct nv50_context *nv50)
          p = NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX;
 
       while (nv50->constbuf_dirty[s]) {
-         struct nouveau_bo *bo;
-         unsigned start = 0;
-         unsigned words = 0;
-
-         i = ffs(nv50->constbuf_dirty[s]) - 1;
+         const int i = ffs(nv50->constbuf_dirty[s]) - 1;
          nv50->constbuf_dirty[s] &= ~(1 << i);
 
-         res = nv04_resource(nv50->constbuf[s][i]);
-         if (!res) {
-            if (i != 0) {
+         if (nv50->constbuf[s][i].user) {
+            const unsigned b = NV50_CB_PVP + s;
+            unsigned start = 0;
+            unsigned words = nv50->constbuf[s][0].size / 4;
+            if (i) {
+               NOUVEAU_ERR("user constbufs only supported in slot 0\n");
+               continue;
+            }
+            if (!nv50->state.uniform_buffer_bound[s]) {
+               nv50->state.uniform_buffer_bound[s] = TRUE;
                BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
-               PUSH_DATA (push, (i << 8) | p | 0);
+               PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
+            }
+            while (words) {
+               unsigned nr;
+
+               if (!PUSH_SPACE(push, 16))
+                  break;
+               nr = PUSH_AVAIL(push);
+               assert(nr >= 16);
+               nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
+
+               BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+               PUSH_DATA (push, (start << 8) | b);
+               BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+               PUSH_DATAp(push, &nv50->constbuf[s][0].u.data[start * 4], nr);
+
+               start += nr;
+               words -= nr;
             }
-            continue;
-         }
-
-         if (i == 0) {
-            b = NV50_CB_PVP + s;
-
-            /* always upload GL uniforms through CB DATA */
-            bo = nv50->screen->uniforms;
-            words = res->base.width0 / 4;
          } else {
-            b = s * 16 + i;
-
-            assert(0);
-
-            if (!nouveau_resource_mapped_by_gpu(&res->base)) {
-               nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
+            struct nv04_resource *res =
+               nv04_resource(nv50->constbuf[s][i].u.buf);
+            if (res) {
+               /* TODO: allocate persistent bindings */
+               const unsigned b = s * 16 + i;
+
+               assert(nouveau_resource_mapped_by_gpu(&res->base));
+
+               BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+               PUSH_DATAh(push, res->address + nv50->constbuf[s][i].offset);
+               PUSH_DATA (push, res->address + nv50->constbuf[s][i].offset);
+               PUSH_DATA (push, (b << 16) |
+                          (nv50->constbuf[s][i].size & 0xffff));
+               BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+               PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
 
-               BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
-               PUSH_DATA (push, 0);
+               BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
+            } else {
+               BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+               PUSH_DATA (push, (i << 8) | p | 0);
             }
-            BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
-            PUSH_DATAh(push, res->address);
-            PUSH_DATA (push, res->address);
-            PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff));
-            BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
-            PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
-
-            bo = res->bo;
-         }
-
-         if (bo != nv50->screen->uniforms)
-            BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
-
-         while (words) {
-            unsigned nr;
-
-            if (!PUSH_SPACE(push, 16))
-               break;
-            nr = PUSH_AVAIL(push);
-            assert(nr >= 16);
-            nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
-
-            BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
-            PUSH_DATA (push, (start << 8) | b);
-            BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
-            PUSH_DATAp(push, &res->data[start * 4], nr);
-
-            start += nr;
-            words -= nr;
+            if (i == 0)
+               nv50->state.uniform_buffer_bound[s] = FALSE;
          }
       }
    }
index 7f840e2b42e1ef45f633b121167d4e3cdd37a9b5..eea3ffd5270942f56b9db9677e7bc8e07fcec48c 100644 (file)
@@ -751,28 +751,36 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
 {
    struct nv50_context *nv50 = nv50_context(pipe);
    struct pipe_resource *res = cb ? cb->buffer : NULL;
+   const unsigned s = nv50_context_shader_stage(shader);
+   const unsigned i = index;
 
-   if (cb && cb->user_buffer) {
-      res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
-                                       cb->buffer_size,
-                                       PIPE_BIND_CONSTANT_BUFFER);
-   }
-
-   pipe_resource_reference(&nv50->constbuf[shader][index], res);
+   if (shader == PIPE_SHADER_COMPUTE)
+      return;
 
-   nv50->constbuf_dirty[shader] |= 1 << index;
-   if (res)
-      nv50->constbuf_valid[shader] |= 1 << index;
+   if (nv50->constbuf[s][i].user)
+      nv50->constbuf[s][i].u.buf = NULL;
    else
-      nv50->constbuf_valid[shader] &= ~(1 << index);
-
-   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
+   if (nv50->constbuf[s][i].u.buf)
+      nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i));
+
+   pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res);
+
+   nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
+   if (nv50->constbuf[s][i].user) {
+      nv50->constbuf[s][i].u.data = cb->user_buffer;
+      nv50->constbuf[s][i].size = cb->buffer_size;
+      nv50->constbuf_valid[s] |= 1 << i;
+   } else
+   if (res) {
+      nv50->constbuf[s][i].offset = cb->buffer_offset;
+      nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+      nv50->constbuf_valid[s] |= 1 << i;
+   } else {
+      nv50->constbuf_valid[s] &= ~(1 << i);
+   }
+   nv50->constbuf_dirty[s] |= 1 << i;
 
    nv50->dirty |= NV50_NEW_CONSTBUF;
-
-   if (cb && cb->user_buffer) {
-      pipe_resource_reference(&res, NULL);
-   }
 }
 
 /* =============================================================================
index 8a9260c937e325c6a51abfd92e0f5cd064bc6d72..eec146552b440ec557ac37dbe4f9b7527066515a 100644 (file)
@@ -34,6 +34,16 @@ struct nv50_zsa_stateobj {
    uint32_t state[29];
 };
 
+struct nv50_constbuf {
+   union {
+      struct pipe_resource *buf;
+      const uint8_t *data;
+   } u;
+   uint32_t size; /* max 65536 */
+   uint16_t offset;
+   boolean user; /* should only be TRUE if u.data is valid and non-NULL */
+};
+
 struct nv50_vertex_element {
    struct pipe_vertex_element pipe;
    uint32_t state;
index b0ab5bdc504cef93c751d1a80ac2b2745400c6fd..f93081465bdfbcad46dc4cff80939b0e33fa8978 100644 (file)
@@ -72,8 +72,9 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0)
       for (i = 0; i < nvc0->num_textures[s]; ++i)
          pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
 
-      for (i = 0; i < 16; ++i)
-         pipe_resource_reference(&nvc0->constbuf[s][i], NULL);
+      for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; ++i)
+         if (!nvc0->constbuf[s][i].user)
+            pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, NULL);
    }
 
    for (i = 0; i < nvc0->num_tfbbufs; ++i)
index d2dee03a19e4bde5d66d8ee8f72d7432abf6a0be..261cfb11007ebf79e3889fdf32d9698522f11ca8 100644 (file)
@@ -121,7 +121,7 @@ struct nvc0_context {
    struct nvc0_program *gmtyprog;
    struct nvc0_program *fragprog;
 
-   struct pipe_resource *constbuf[5][16];
+   struct nvc0_constbuf constbuf[5][NVC0_MAX_PIPE_CONSTBUFS];
    uint16_t constbuf_dirty[5];
 
    struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
@@ -168,6 +168,23 @@ nvc0_context(struct pipe_context *pipe)
    return (struct nvc0_context *)pipe;
 }
 
+static INLINE unsigned
+nvc0_shader_stage(unsigned pipe)
+{
+   switch (pipe) {
+   case PIPE_SHADER_VERTEX: return 0;
+/* case PIPE_SHADER_TESSELLATION_CONTROL: return 1; */
+/* case PIPE_SHADER_TESSELLATION_EVALUATION: return 2; */
+   case PIPE_SHADER_GEOMETRY: return 3;
+   case PIPE_SHADER_FRAGMENT: return 4;
+   case PIPE_SHADER_COMPUTE: return 5;
+   default:
+      assert(!"invalid PIPE_SHADER type");
+      return 0;
+   }
+}
+
+
 /* nvc0_context.c */
 struct pipe_context *nvc0_create(struct pipe_screen *, void *);
 void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
index 5d6befd45b7739c7d25db57b7bba05acb8c60ca1..498207f613d04308cd94495f1185176de1802d93 100644 (file)
@@ -190,7 +190,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
    case PIPE_SHADER_CAP_MAX_CONSTS:
       return 65536 / 16;
    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
-      return 14;
+      return NVC0_MAX_PIPE_CONSTBUFS;
    case PIPE_SHADER_CAP_MAX_ADDRS:
       return 1;
    case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
index 8bcc1470593268a6c297d1d1c9eaa13d8c83bc38..69cddf2c9b0113794175152800ed730104c45f02 100644 (file)
@@ -14,6 +14,9 @@
 #define NVC0_TIC_MAX_ENTRIES 2048
 #define NVC0_TSC_MAX_ENTRIES 2048
 
+/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */
+#define NVC0_MAX_PIPE_CONSTBUFS 14
+
 struct nvc0_context;
 
 struct nvc0_blitctx;
index 40161252a3daa25cb47313cb2bbff31f8ec92e79..cab238e7e06748de4dee695e2bff88b579e59220 100644 (file)
@@ -620,38 +620,33 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct pipe_resource *res = cb ? cb->buffer : NULL;
+   const unsigned s = nvc0_shader_stage(shader);
+   const unsigned i = index;
 
-   if (cb && cb->user_buffer) {
-      res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
-                                       cb->buffer_size,
-                                       PIPE_BIND_CONSTANT_BUFFER);
-   }
+   if (shader == PIPE_SHADER_COMPUTE)
+      return;
 
-   switch (shader) {
-   case PIPE_SHADER_VERTEX: shader = 0; break;
-      /*
-   case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break;
-   case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break;
-      */
-   case PIPE_SHADER_GEOMETRY: shader = 3; break;
-   case PIPE_SHADER_FRAGMENT: shader = 4; break;
-   default:
-      assert(0);
-      break;
-   }
+   if (nvc0->constbuf[s][i].user)
+      nvc0->constbuf[s][i].u.buf = NULL;
+   else
+   if (nvc0->constbuf[s][i].u.buf)
+      nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i));
 
-   if (nvc0->constbuf[shader][index])
-      nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index));
+   pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res);
 
-   pipe_resource_reference(&nvc0->constbuf[shader][index], res);
+   nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
+   if (nvc0->constbuf[s][i].user) {
+      nvc0->constbuf[s][i].u.data = cb->user_buffer;
+      nvc0->constbuf[s][i].size = cb->buffer_size;
+   } else
+   if (cb) {
+      nvc0->constbuf[s][i].offset = cb->buffer_offset;
+      nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+   }
 
-   nvc0->constbuf_dirty[shader] |= 1 << index;
+   nvc0->constbuf_dirty[s] |= 1 << i;
 
    nvc0->dirty |= NVC0_NEW_CONSTBUF;
-
-   if (cb->user_buffer) {
-      pipe_resource_reference(&res, NULL);
-   }
 }
 
 /* =============================================================================
index 5d34f2b0bcccaefdb3795aba2f48c15e06384370..c2d115e715f27f396756830fc94fce5906cc8925 100644 (file)
@@ -355,70 +355,53 @@ static void
 nvc0_constbufs_validate(struct nvc0_context *nvc0)
 {
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
-   struct nouveau_bo *bo;
    unsigned s;
 
    for (s = 0; s < 5; ++s) {
-      struct nv04_resource *res;
-      int i;
-
       while (nvc0->constbuf_dirty[s]) {
-         unsigned base = 0;
-         unsigned words = 0;
-         boolean rebind = TRUE;
-
-         i = ffs(nvc0->constbuf_dirty[s]) - 1;
+         int i = ffs(nvc0->constbuf_dirty[s]) - 1;
          nvc0->constbuf_dirty[s] &= ~(1 << i);
 
-         res = nv04_resource(nvc0->constbuf[s][i]);
-         if (!res) {
-            BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
-            PUSH_DATA (push, (i << 4) | 0);
-            if (i == 0)
-               nvc0->state.uniform_buffer_bound[s] = 0;
-            continue;
-         }
-
-         if (!nouveau_resource_mapped_by_gpu(&res->base)) {
-            if (i == 0 && (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) {
-               base = s << 16;
-               bo = nvc0->screen->uniform_bo;
-
-               if (nvc0->state.uniform_buffer_bound[s] >= res->base.width0)
-                  rebind = FALSE;
-               else
-                  nvc0->state.uniform_buffer_bound[s] =
-                     align(res->base.width0, 0x100);
-
-               words = res->base.width0 / 4;
-            } else {
-               nouveau_buffer_migrate(&nvc0->base, res, NOUVEAU_BO_VRAM);
-               bo = res->bo;
-               base = res->offset;
+         if (nvc0->constbuf[s][i].user) {
+            struct nouveau_bo *bo = nvc0->screen->uniform_bo;
+            const unsigned base = s << 16;
+            const unsigned size = nvc0->constbuf[s][0].size;
+            assert(i == 0); /* we really only want OpenGL uniforms here */
+            assert(nvc0->constbuf[s][0].u.data);
+
+            if (nvc0->state.uniform_buffer_bound[s] < size) {
+               nvc0->state.uniform_buffer_bound[s] = align(size, 0x100);
+
+               BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+               PUSH_DATA (push, nvc0->state.uniform_buffer_bound[s]);
+               PUSH_DATAh(push, bo->offset + base);
+               PUSH_DATA (push, bo->offset + base);
+               BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+               PUSH_DATA (push, (0 << 4) | 1);
             }
+            nvc0_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM,
+                         base, nvc0->state.uniform_buffer_bound[s],
+                         0, (size + 3) / 4,
+                         nvc0->constbuf[s][0].u.data);
          } else {
-            bo = res->bo;
-            base = res->offset;
+            struct nv04_resource *res =
+               nv04_resource(nvc0->constbuf[s][i].u.buf);
+            if (res) {
+               BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+               PUSH_DATA (push, nvc0->constbuf[s][i].size);
+               PUSH_DATAh(push, res->address + nvc0->constbuf[s][i].offset);
+               PUSH_DATA (push, res->address + nvc0->constbuf[s][i].offset);
+               BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+               PUSH_DATA (push, (i << 4) | 1);
+
+               BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
+            } else {
+               BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+               PUSH_DATA (push, (i << 4) | 0);
+            }
             if (i == 0)
                nvc0->state.uniform_buffer_bound[s] = 0;
          }
-
-         if (bo != nvc0->screen->uniform_bo)
-            BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
-
-         if (rebind) {
-            BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
-            PUSH_DATA (push, align(res->base.width0, 0x100));
-            PUSH_DATAh(push, bo->offset + base);
-            PUSH_DATA (push, bo->offset + base);
-            BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
-            PUSH_DATA (push, (i << 4) | 1);
-         }
-
-         if (words)
-            nvc0_cb_push(&nvc0->base,
-                         bo, NOUVEAU_BO_VRAM, base, res->base.width0,
-                         0, words, (const uint32_t *)res->data);
       }
    }
 }
index 16d336cfab28003cdaddf7bbd6cc75433423d5f7..5afbffb7d22affaffc040e760440113ace05bea7 100644 (file)
@@ -32,6 +32,16 @@ struct nvc0_zsa_stateobj {
    uint32_t state[26];
 };
 
+struct nvc0_constbuf {
+   union {
+      struct pipe_resource *buf;
+      const void *data;
+   } u;
+   uint32_t size;
+   uint16_t offset;
+   boolean user; /* should only be TRUE if u.data is valid and non-NULL */
+};
+
 struct nvc0_vertex_element {
    struct pipe_vertex_element pipe;
    uint32_t state;