Esempio n. 1
0
static void
nv30_render_set_primitive(struct vbuf_render *render, unsigned prim)
{
   struct nv30_render *r = nv30_render(render);

   r->prim = nv30_prim_gl(prim);
}
static void
nv30_draw_arrays(struct nv30_context *nv30,
                 unsigned mode, unsigned start, unsigned count,
                 unsigned instance_count)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   unsigned prim;

   prim = nv30_prim_gl(mode);

   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, prim);
   while (count) {
      const unsigned mpush = 2047 * 256;
      unsigned npush  = (count > mpush) ? mpush : count;
      unsigned wpush  = ((npush + 255) & ~255) >> 8;

      count -= npush;

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

      if (npush)
         PUSH_DATA (push, ((npush - 1) << 24) | start);
   }
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
}
static void
nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
                   unsigned mode, unsigned start, unsigned count,
                   unsigned instance_count, int32_t index_bias)
{
   const unsigned index_size = nv30->idxbuf.index_size;
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_object *eng3d = nv30->screen->eng3d;
   unsigned prim = nv30_prim_gl(mode);

#if 0 /*XXX*/
   if (index_bias != nv30->state.index_bias) {
      BEGIN_NV04(push, NV30_3D(VB_ELEMENT_BASE), 1);
      PUSH_DATA (push, index_bias);
      nv30->state.index_bias = index_bias;
   }
#endif

   if (eng3d->oclass == NV40_3D_CLASS && index_size > 1 &&
       nv30->idxbuf.buffer) {
      struct nv04_resource *res = nv04_resource(nv30->idxbuf.buffer);
      unsigned offset = nv30->idxbuf.offset;

      assert(nouveau_resource_mapped_by_gpu(&res->base));

      BEGIN_NV04(push, NV30_3D(IDXBUF_OFFSET), 2);
      PUSH_RESRC(push, NV30_3D(IDXBUF_OFFSET), BUFCTX_IDXBUF, res, offset,
                       NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
      PUSH_MTHD (push, NV30_3D(IDXBUF_FORMAT), BUFCTX_IDXBUF, res->bo,
                       (index_size == 2) ? 0x00000010 : 0x00000000,
                       res->domain | NOUVEAU_BO_RD,
                       0, NV30_3D_IDXBUF_FORMAT_DMA1);
      BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
      PUSH_DATA (push, prim);
      while (count) {
         const unsigned mpush = 2047 * 256;
         unsigned npush  = (count > mpush) ? mpush : count;
         unsigned wpush  = ((npush + 255) & ~255) >> 8;

         count -= npush;

         BEGIN_NI04(push, NV30_3D(VB_INDEX_BATCH), wpush);
         while (npush >= 256) {
            PUSH_DATA (push, 0xff000000 | start);
            start += 256;
            npush -= 256;
         }

         if (npush)
            PUSH_DATA (push, ((npush - 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_IDXBUF);
   } else {
Esempio n. 4
0
void
nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
{
   struct push_context ctx;
   unsigned i, index_size;
   boolean apply_bias = info->indexed && info->index_bias;

   ctx.push = nv30->base.pushbuf;
   ctx.translate = nv30->vertex->translate;
   ctx.packet_vertex_limit = nv30->vertex->vtx_per_packet_max;
   ctx.vertex_words = nv30->vertex->vtx_size;

   for (i = 0; i < nv30->num_vtxbufs; ++i) {
      uint8_t *data;
      struct pipe_vertex_buffer *vb = &nv30->vtxbuf[i];
      struct nv04_resource *res = nv04_resource(vb->buffer);

      if (!vb->buffer && !vb->user_buffer) {
         continue;
      }

      data = nouveau_resource_map_offset(&nv30->base, res,
                                         vb->buffer_offset, NOUVEAU_BO_RD);

      if (apply_bias)
         data += info->index_bias * vb->stride;

      ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
   }

   if (info->indexed) {
      if (nv30->idxbuf.buffer)
         ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
            nv04_resource(nv30->idxbuf.buffer), nv30->idxbuf.offset,
            NOUVEAU_BO_RD);
      else
         ctx.idxbuf = nv30->idxbuf.user_buffer;
      if (!ctx.idxbuf) {
         nv30_state_release(nv30);
         return;
      }
      index_size = nv30->idxbuf.index_size;
      ctx.primitive_restart = info->primitive_restart;
      ctx.restart_index = info->restart_index;
   } else {
      ctx.idxbuf = NULL;
      index_size = 0;
      ctx.primitive_restart = FALSE;
      ctx.restart_index = 0;
   }

   if (nv30->screen->eng3d->oclass >= NV40_3D_CLASS) {
      BEGIN_NV04(ctx.push, NV40_3D(PRIM_RESTART_ENABLE), 2);
      PUSH_DATA (ctx.push, info->primitive_restart);
      PUSH_DATA (ctx.push, info->restart_index);
      nv30->state.prim_restart = info->primitive_restart;
   }

   ctx.prim = nv30_prim_gl(info->mode);

   PUSH_RESET(ctx.push, BUFCTX_IDXBUF);
   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (ctx.push, ctx.prim);
   switch (index_size) {
   case 0:
      emit_vertices_seq(&ctx, info->start, info->count);
      break;
   case 1:
      emit_vertices_i08(&ctx, info->start, info->count);
      break;
   case 2:
      emit_vertices_i16(&ctx, info->start, info->count);
      break;
   case 4:
      emit_vertices_i32(&ctx, info->start, info->count);
      break;
   default:
      assert(0);
      break;
   }
   BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (ctx.push, NV30_3D_VERTEX_BEGIN_END_STOP);

   if (info->indexed)
      nouveau_resource_unmap(nv04_resource(nv30->idxbuf.buffer));

   for (i = 0; i < nv30->num_vtxbufs; ++i) {
      if (nv30->vtxbuf[i].buffer) {
         nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer));
      }
   }

   nv30_state_release(nv30);
}