Ejemplo n.º 1
0
static void
nv30_render_draw_elements(struct vbuf_render *render,
                          const ushort *indices, uint count)
{
   struct nv30_render *r = nv30_render(render);
   struct nv30_context *nv30 = r->nv30;
   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
   unsigned i;

   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
   for (i = 0; i < r->vertex_info.num_attribs; i++) {
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
   }

   if (!nv30_state_validate(nv30, FALSE))
      return;

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, r->prim);

   if (count & 1) {
      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_U32), 1);
      PUSH_DATA (push, *indices++);
   }

   count >>= 1;
   while (count) {
      unsigned npush = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
      count -= npush;

      BEGIN_NI04(push, NV30_3D(VB_ELEMENT_U16), npush);
      while (npush--) {
         PUSH_DATA(push, (indices[1] << 16) | indices[0]);
         indices += 2;
      }
   }

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
   PUSH_RESET(push, BUFCTX_VTXTMP);
}
static void
nv30_update_user_vbufs(struct nv30_context *nv30)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   uint32_t base, offset, size;
   int i;
   uint32_t written = 0;

   for (i = 0; i < nv30->vertex->num_elements; i++) {
      struct pipe_vertex_element *ve = &nv30->vertex->pipe[i];
      const int b = ve->vertex_buffer_index;
      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[b];
      struct nv04_resource *buf = nv04_resource(vb->buffer);

      if (!(nv30->vbo_user & (1 << b)))
         continue;

      if (!vb->stride) {
         nv30_emit_vtxattr(nv30, vb, ve, i);
         continue;
      }
      nv30_vbuf_range(nv30, b, &base, &size);

      if (!(written & (1 << b))) {
         written |= 1 << b;
         nouveau_user_buffer_upload(&nv30->base, buf, base, size);
      }

      offset = vb->buffer_offset + ve->src_offset;

      BEGIN_NV04(push, NV30_3D(VTXBUF(i)), 1);
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP, buf, offset,
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD,
                       0, NV30_3D_VTXBUF_DMA1);
   }
   nv30->base.vbo_dirty = TRUE;
}
Ejemplo n.º 3
0
static void
nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
{
   struct nv30_render *r = nv30_render(render);
   struct nv30_context *nv30 = r->nv30;
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   unsigned fn = nr >> 8, pn = nr & 0xff;
   unsigned ps = fn + (pn ? 1 : 0);
   unsigned i;

   BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
   for (i = 0; i < r->vertex_info.num_attribs; i++) {
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
                       nv04_resource(r->buffer), r->offset + r->vtxptr[i],
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
   }

   if (!nv30_state_validate(nv30, FALSE))
      return;

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, r->prim);

   BEGIN_NI04(push, NV30_3D(VB_VERTEX_BATCH), ps);
   while (fn--) {
      PUSH_DATA (push, 0xff000000 | start);
      start += 256;
   }

   if (pn)
      PUSH_DATA (push, ((pn - 1) << 24) | start);

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
   PUSH_RESET(push, BUFCTX_VTXTMP);
}
void
nv30_vbo_validate(struct nv30_context *nv30)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nv30_vertex_stateobj *vertex = nv30->vertex;
   struct pipe_vertex_element *ve;
   struct pipe_vertex_buffer *vb;
   unsigned i, redefine;

   nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
   if (!nv30->vertex || nv30->draw_flags)
      return;

   if (unlikely(vertex->need_conversion)) {
      nv30->vbo_fifo = ~0;
      nv30->vbo_user = 0;
   } else {
      nv30_prevalidate_vbufs(nv30);
   }

   if (!PUSH_SPACE(push, 128))
      return;

   redefine = MAX2(vertex->num_elements, nv30->state.num_vtxelts);
   BEGIN_NV04(push, NV30_3D(VTXFMT(0)), redefine);

   for (i = 0; i < vertex->num_elements; i++) {
      ve = &vertex->pipe[i];
      vb = &nv30->vtxbuf[ve->vertex_buffer_index];

      if (likely(vb->stride) || nv30->vbo_fifo)
         PUSH_DATA (push, (vb->stride << 8) | vertex->element[i].state);
      else
         PUSH_DATA (push, NV30_3D_VTXFMT_TYPE_V32_FLOAT);
   }

   for (; i < nv30->state.num_vtxelts; i++) {
      PUSH_DATA (push, NV30_3D_VTXFMT_TYPE_V32_FLOAT);
   }

   for (i = 0; i < vertex->num_elements; i++) {
      struct nv04_resource *res;
      unsigned offset;
      boolean user;

      ve = &vertex->pipe[i];
      vb = &nv30->vtxbuf[ve->vertex_buffer_index];
      user = (nv30->vbo_user & (1 << ve->vertex_buffer_index));

      res = nv04_resource(vb->buffer);

      if (nv30->vbo_fifo || unlikely(vb->stride == 0)) {
         if (!nv30->vbo_fifo)
            nv30_emit_vtxattr(nv30, vb, ve, i);
         continue;
      }

      offset = ve->src_offset + vb->buffer_offset;

      BEGIN_NV04(push, NV30_3D(VTXBUF(i)), 1);
      PUSH_RESRC(push, NV30_3D(VTXBUF(i)), user ? BUFCTX_VTXTMP : BUFCTX_VTXBUF,
                       res, offset, NOUVEAU_BO_LOW | NOUVEAU_BO_RD,
                       0, NV30_3D_VTXBUF_DMA1);
   }

   nv30->state.num_vtxelts = vertex->num_elements;
}