Beispiel #1
0
static void
nvc0_compute_validate_constbufs(struct nvc0_context *nvc0)
{
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   const int s = 5;

   while (nvc0->constbuf_dirty[s]) {
      int i = ffs(nvc0->constbuf_dirty[s]) - 1;
      nvc0->constbuf_dirty[s] &= ~(1 << i);

      if (nvc0->constbuf[s][i].user) {
         struct nouveau_bo *bo = nvc0->screen->uniform_bo;
         const unsigned base = NVC0_CB_USR_INFO(s);
         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_CP(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_CP(CB_BIND), 1);
            PUSH_DATA (push, (0 << 8) | 1);
         }
         nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
                         base, nvc0->state.uniform_buffer_bound[s],
                         0, (size + 3) / 4,
                         nvc0->constbuf[s][0].u.data);
      } else {
         struct nv04_resource *res =
            nv04_resource(nvc0->constbuf[s][i].u.buf);
         if (res) {
            BEGIN_NVC0(push, NVC0_CP(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_CP(CB_BIND), 1);
            PUSH_DATA (push, (i << 8) | 1);

            BCTX_REFN(nvc0->bufctx_cp, CP_CB(i), res, RD);

            res->cb_bindings[s] |= 1 << i;
         } else {
            BEGIN_NVC0(push, NVC0_CP(CB_BIND), 1);
            PUSH_DATA (push, (i << 8) | 0);
         }
         if (i == 0)
            nvc0->state.uniform_buffer_bound[s] = 0;
      }
   }

   nvc0_compute_invalidate_constbufs(nvc0);

   BEGIN_NVC0(push, NVC0_CP(FLUSH), 1);
   PUSH_DATA (push, NVC0_COMPUTE_FLUSH_CB);
}
Beispiel #2
0
/* This happens rather often with DTD9/st. */
static void
nvc0_cb_push(struct nouveau_context *nv,
             struct nv04_resource *res,
             unsigned offset, unsigned words, const uint32_t *data)
{
   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
   struct nvc0_constbuf *cb = NULL;
   int s;

   /* Go through all the constbuf binding points of this buffer and try to
    * find one which contains the region to be updated.
    */
   for (s = 0; s < 6 && !cb; s++) {
      uint16_t bindings = res->cb_bindings[s];
      while (bindings) {
         int i = ffs(bindings) - 1;
         uint32_t cb_offset = nvc0->constbuf[s][i].offset;

         bindings &= ~(1 << i);
         if (cb_offset <= offset &&
             cb_offset + nvc0->constbuf[s][i].size >= offset + words * 4) {
            cb = &nvc0->constbuf[s][i];
            break;
         }
      }
   }

   if (cb) {
      nvc0_cb_bo_push(nv, res->bo, res->domain,
                      res->offset + cb->offset, cb->size,
                      offset - cb->offset, words, data);
   } else {
      nv->push_data(nv, res->bo, res->offset + offset, res->domain,
                    words * 4, data);
   }
}