nv30: handle user index buffers
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 22 May 2012 13:33:12 +0000 (15:33 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 25 May 2012 20:42:54 +0000 (22:42 +0200)
src/gallium/drivers/nv30/nv30_push.c
src/gallium/drivers/nv30/nv30_screen.c
src/gallium/drivers/nv30/nv30_state.c
src/gallium/drivers/nv30/nv30_vbo.c

index 16575ee26868c4256a93f81bee49636a8b2ea332..c5867bfa11aee58527dfe0b2601b19e4ee646125 100644 (file)
@@ -37,7 +37,7 @@
 struct push_context {
    struct nouveau_pushbuf *push;
 
-   void *idxbuf;
+   const void *idxbuf;
 
    float edgeflag;
    int edgeflag_attr;
@@ -221,9 +221,12 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
    }
 
    if (info->indexed) {
-      ctx.idxbuf = nouveau_resource_map_offset(&nv30->base,
-                                               nv04_resource(nv30->idxbuf.buffer),
-                                               nv30->idxbuf.offset, NOUVEAU_BO_RD);
+      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 67de8c03f45fc7bcb958b2809115f35345e6cd52..f9e647dbd13aa367e8a845f2eff1273d6f6ef940 100644 (file)
@@ -79,8 +79,8 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
-      return 1;
    case PIPE_CAP_USER_INDEX_BUFFERS:
+      return 1;
    case PIPE_CAP_USER_VERTEX_BUFFERS:
       return 0;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index f65c8b71fdde0e239bc71850b4b51cd8761e0ba9..25755ba471d9abe69182730ca1aef4a8b6304bf8 100644 (file)
@@ -420,9 +420,12 @@ nv30_set_index_buffer(struct pipe_context *pipe,
 
     if (ib) {
        pipe_resource_reference(&nv30->idxbuf.buffer, ib->buffer);
-       memcpy(&nv30->idxbuf, ib, sizeof(nv30->idxbuf));
+       nv30->idxbuf.index_size = ib->index_size;
+       nv30->idxbuf.offset = ib->offset;
+       nv30->idxbuf.user_buffer = ib->user_buffer;
     } else {
        pipe_resource_reference(&nv30->idxbuf.buffer, NULL);
+       nv30->idxbuf.user_buffer = NULL;
     }
 }
 
index 78d106880d094a3d63add7bd1ee211de519ad9ff..128457f7aa903162c6bfe533ae6f10462b349dd0 100644 (file)
@@ -358,7 +358,7 @@ nv30_draw_arrays(struct nv30_context *nv30,
 }
 
 static void
-nv30_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
+nv30_draw_elements_inline_u08(struct nouveau_pushbuf *push, const uint8_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
@@ -383,7 +383,7 @@ nv30_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
 }
 
 static void
-nv30_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
+nv30_draw_elements_inline_u16(struct nouveau_pushbuf *push, const uint16_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
@@ -407,7 +407,7 @@ nv30_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
 }
 
 static void
-nv30_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
+nv30_draw_elements_inline_u32(struct nouveau_pushbuf *push, const uint32_t *map,
                               unsigned start, unsigned count)
 {
    map += start;
@@ -424,7 +424,8 @@ nv30_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
 }
 
 static void
-nv30_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
+nv30_draw_elements_inline_u32_short(struct nouveau_pushbuf *push,
+                                    const uint32_t *map,
                                     unsigned start, unsigned count)
 {
    map += start;
@@ -456,7 +457,6 @@ nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
    struct nouveau_pushbuf *push = nv30->base.pushbuf;
    struct nouveau_object *eng3d = nv30->screen->eng3d;
    unsigned prim = nv30_prim_gl(mode);
-   void *data;
 
 #if 0 /*XXX*/
    if (index_bias != nv30->state.index_bias) {
@@ -467,10 +467,12 @@ nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
 #endif
 
    if (eng3d->oclass == NV40_3D_CLASS && index_size > 1 &&
-       nouveau_resource_mapped_by_gpu(nv30->idxbuf.buffer)) {
+       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);
@@ -501,9 +503,13 @@ nv30_draw_elements(struct nv30_context *nv30, boolean shorten,
       PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
       PUSH_RESET(push, BUFCTX_IDXBUF);
    } else {
-      data = nouveau_resource_map_offset(&nv30->base,
-                                         nv04_resource(nv30->idxbuf.buffer),
-                                         nv30->idxbuf.offset, NOUVEAU_BO_RD);
+      const void *data;
+      if (nv30->idxbuf.buffer)
+         data = nouveau_resource_map_offset(&nv30->base,
+                                            nv04_resource(nv30->idxbuf.buffer),
+                                            nv30->idxbuf.offset, NOUVEAU_BO_RD);
+      else
+         data = nv30->idxbuf.user_buffer;
       if (!data)
          return;
 
@@ -577,8 +583,6 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    } else {
       boolean shorten = info->max_index <= 65535;
 
-      assert(nv30->idxbuf.buffer);
-
       if (info->primitive_restart != nv30->state.prim_restart) {
          if (info->primitive_restart) {
             BEGIN_NV04(push, NV40_3D(PRIM_RESTART_ENABLE), 2);