gallium: add void *user_buffer in pipe_index_buffer
authorMarek Olšák <maraeo@gmail.com>
Tue, 24 Apr 2012 19:14:44 +0000 (21:14 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 29 Apr 2012 23:14:28 +0000 (01:14 +0200)
Adapted drivers: i915, llvmpipe, r300, r600, radeonsi, softpipe.

User index buffers have been disabled in nv30, nv50, nvc0 and svga to keep
things working.

23 files changed:
src/gallium/auxiliary/util/u_index_modify.c
src/gallium/auxiliary/util/u_index_modify.h
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/drivers/i915/i915_context.c
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
src/gallium/drivers/nv30/nv30_draw.c
src/gallium/drivers/nv30/nv30_screen.c
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_translate.c
src/gallium/drivers/r300/r300_screen_buffer.c
src/gallium/drivers/r300/r300_screen_buffer.h
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/r600/r600_translate.c
src/gallium/drivers/radeonsi/r600_buffer.c
src/gallium/drivers/radeonsi/r600_state_common.c
src/gallium/drivers/radeonsi/r600_translate.c
src/gallium/drivers/softpipe/sp_draw_arrays.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_draw.c

index d0a28b5fdfadd5fdac6d5d35c978131db1b51ea3..5e3fd463eb4a33a808663f3da0e3a3ad736fda80 100644 (file)
 /* Ubyte indices. */
 
 void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
-                                       struct pipe_resource *elts,
+                                       struct pipe_index_buffer *ib,
                                        int index_bias,
                                        unsigned start,
                                        unsigned count,
                                        void *out)
 {
-    struct pipe_transfer *src_transfer;
-    unsigned char *in_map;
+    struct pipe_transfer *src_transfer = NULL;
+    const unsigned char *in_map;
     unsigned short *out_map = out;
     unsigned i;
 
-    in_map = pipe_buffer_map(context, elts,
-                             PIPE_TRANSFER_READ |
-                             PIPE_TRANSFER_UNSYNCHRONIZED,
-                             &src_transfer);
+    if (ib->user_buffer) {
+       in_map = ib->user_buffer;
+    } else {
+       in_map = pipe_buffer_map(context, ib->buffer,
+                                PIPE_TRANSFER_READ |
+                                PIPE_TRANSFER_UNSYNCHRONIZED,
+                                &src_transfer);
+    }
     in_map += start;
 
     for (i = 0; i < count; i++) {
@@ -50,11 +54,13 @@ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
         out_map++;
     }
 
-    pipe_buffer_unmap(context, src_transfer);
+    if (src_transfer)
+       pipe_buffer_unmap(context, src_transfer);
 }
 
 void util_shorten_ubyte_elts(struct pipe_context *context,
-                            struct pipe_resource **elts,
+                            struct pipe_index_buffer *ib,
+                            struct pipe_resource **out_buf,
                             int index_bias,
                             unsigned start,
                             unsigned count)
@@ -70,31 +76,36 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
 
     out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
                               &dst_transfer);
-    util_shorten_ubyte_elts_to_userptr(context, *elts, index_bias,
+    util_shorten_ubyte_elts_to_userptr(context, ib, index_bias,
                                        start, count, out_map);
     pipe_buffer_unmap(context, dst_transfer);
 
-    *elts = new_elts;
+    pipe_resource_reference(out_buf, NULL);
+    *out_buf = new_elts;
 }
 
 
 /* Ushort indices. */
 
 void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
-                                        struct pipe_resource *elts,
+                                        struct pipe_index_buffer *ib,
                                         int index_bias,
                                         unsigned start, unsigned count,
                                         void *out)
 {
     struct pipe_transfer *in_transfer = NULL;
-    unsigned short *in_map;
+    const unsigned short *in_map;
     unsigned short *out_map = out;
     unsigned i;
 
-    in_map = pipe_buffer_map(context, elts,
-                             PIPE_TRANSFER_READ |
-                             PIPE_TRANSFER_UNSYNCHRONIZED,
-                             &in_transfer);
+    if (ib->user_buffer) {
+       in_map = ib->user_buffer;
+    } else {
+       in_map = pipe_buffer_map(context, ib->buffer,
+                                PIPE_TRANSFER_READ |
+                                PIPE_TRANSFER_UNSYNCHRONIZED,
+                                &in_transfer);
+    }
     in_map += start;
 
     for (i = 0; i < count; i++) {
@@ -103,11 +114,13 @@ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
         out_map++;
     }
 
-    pipe_buffer_unmap(context, in_transfer);
+    if (in_transfer)
+       pipe_buffer_unmap(context, in_transfer);
 }
 
 void util_rebuild_ushort_elts(struct pipe_context *context,
-                             struct pipe_resource **elts,
+                             struct pipe_index_buffer *ib,
+                             struct pipe_resource **out_buf,
                              int index_bias,
                              unsigned start, unsigned count)
 {
@@ -122,31 +135,36 @@ void util_rebuild_ushort_elts(struct pipe_context *context,
 
     out_map = pipe_buffer_map(context, new_elts,
                               PIPE_TRANSFER_WRITE, &out_transfer);
-    util_rebuild_ushort_elts_to_userptr(context, *elts, index_bias,
+    util_rebuild_ushort_elts_to_userptr(context, ib, index_bias,
                                         start, count, out_map);
     pipe_buffer_unmap(context, out_transfer);
 
-    *elts = new_elts;
+    pipe_resource_reference(out_buf, NULL);
+    *out_buf = new_elts;
 }
 
 
 /* Uint indices. */
 
 void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
-                                      struct pipe_resource *elts,
+                                      struct pipe_index_buffer *ib,
                                       int index_bias,
                                       unsigned start, unsigned count,
                                       void *out)
 {
     struct pipe_transfer *in_transfer = NULL;
-    unsigned int *in_map;
+    const unsigned int *in_map;
     unsigned int *out_map = out;
     unsigned i;
 
-    in_map = pipe_buffer_map(context, elts,
-                             PIPE_TRANSFER_READ |
-                             PIPE_TRANSFER_UNSYNCHRONIZED,
-                             &in_transfer);
+    if (ib->user_buffer) {
+       in_map = ib->user_buffer;
+    } else {
+       in_map = pipe_buffer_map(context, ib->buffer,
+                                PIPE_TRANSFER_READ |
+                                PIPE_TRANSFER_UNSYNCHRONIZED,
+                                &in_transfer);
+    }
     in_map += start;
 
     for (i = 0; i < count; i++) {
@@ -155,11 +173,13 @@ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
         out_map++;
     }
 
-    pipe_buffer_unmap(context, in_transfer);
+    if (in_transfer)
+       pipe_buffer_unmap(context, in_transfer);
 }
 
 void util_rebuild_uint_elts(struct pipe_context *context,
-                           struct pipe_resource **elts,
+                           struct pipe_index_buffer *ib,
+                           struct pipe_resource **out_buf,
                            int index_bias,
                            unsigned start, unsigned count)
 {
@@ -174,9 +194,10 @@ void util_rebuild_uint_elts(struct pipe_context *context,
 
     out_map = pipe_buffer_map(context, new_elts,
                               PIPE_TRANSFER_WRITE, &out_transfer);
-    util_rebuild_uint_elts_to_userptr(context, *elts, index_bias,
+    util_rebuild_uint_elts_to_userptr(context, ib, index_bias,
                                       start, count, out_map);
     pipe_buffer_unmap(context, out_transfer);
 
-    *elts = new_elts;
+    pipe_resource_reference(out_buf, NULL);
+    *out_buf = new_elts;
 }
index 1e9de3dfac883feb378dd439fa71580fe069a8c6..6afce50b9847c1d76e496230dedc02b9a466ab0c 100644 (file)
 
 struct pipe_context;
 struct pipe_resource;
+struct pipe_index_buffer;
 
 void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
-                                       struct pipe_resource *elts,
+                                       struct pipe_index_buffer *ib,
                                        int index_bias,
                                        unsigned start,
                                        unsigned count,
                                        void *out);
 
 void util_shorten_ubyte_elts(struct pipe_context *context,
-                            struct pipe_resource **elts,
+                            struct pipe_index_buffer *ib,
+                            struct pipe_resource **out_buf,
                             int index_bias,
                             unsigned start,
                             unsigned count);
@@ -42,26 +44,28 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
 
 
 void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
-                                        struct pipe_resource *elts,
+                                        struct pipe_index_buffer *ib,
                                         int index_bias,
                                         unsigned start, unsigned count,
                                         void *out);
 
 void util_rebuild_ushort_elts(struct pipe_context *context,
-                             struct pipe_resource **elts,
+                             struct pipe_index_buffer *ib,
+                             struct pipe_resource **out_buf,
                              int index_bias,
                              unsigned start, unsigned count);
 
 
 
 void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
-                                      struct pipe_resource *elts,
+                                      struct pipe_index_buffer *ib,
                                       int index_bias,
                                       unsigned start, unsigned count,
                                       void *out);
 
 void util_rebuild_uint_elts(struct pipe_context *context,
-                           struct pipe_resource **elts,
+                           struct pipe_index_buffer *ib,
+                           struct pipe_resource **out_buf,
                            int index_bias,
                            unsigned start, unsigned count);
 
index e60378c31c7e789720c7c97bba3e76d4fa27df19..400fada18302da9a583491c1932154896d4f9c6f 100644 (file)
@@ -307,10 +307,10 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
       unsigned offset = ib->offset + start_index * ib->index_size;
       uint8_t *map;
 
-      assert(ib->buffer && ib->index_size);
+      assert((ib->buffer || ib->user_buffer) && ib->index_size);
 
-      if (ib->buffer->user_ptr) {
-         map = ib->buffer->user_ptr + offset;
+      if (ib->user_buffer) {
+         map = (uint8_t*)ib->user_buffer + offset;
       } else {
          map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset,
                                      num_indices * ib->index_size,
@@ -760,11 +760,10 @@ void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
 {
    struct pipe_context *pipe = mgr->pipe;
 
-   if (ib && ib->buffer) {
+   if (ib) {
       assert(ib->offset % ib->index_size == 0);
       pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer);
-      mgr->index_buffer.offset = ib->offset;
-      mgr->index_buffer.index_size = ib->index_size;
+      memcpy(&mgr->index_buffer, ib, sizeof(*ib));
    } else {
       pipe_resource_reference(&mgr->index_buffer.buffer, NULL);
    }
@@ -887,8 +886,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
    unsigned i;
    unsigned restart_index = info->restart_index;
 
-   if (ib->buffer->user_ptr) {
-      indices = ib->buffer->user_ptr +
+   if (ib->user_buffer) {
+      indices = (uint8_t*)ib->user_buffer +
                 ib->offset + info->start * ib->index_size;
    } else {
       indices = pipe_buffer_map_range(pipe, ib->buffer,
index 052a059c2689493933b22fe1d56407b860fcb21a..f3c7b30527c23da61c64498468da84c5152d9b14 100644 (file)
@@ -53,7 +53,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct i915_context *i915 = i915_context(pipe);
    struct draw_context *draw = i915->draw;
-   void *mapped_indices = NULL;
+   const void *mapped_indices = NULL;
 
 
    /*
@@ -67,8 +67,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    /*
     * Map index buffer, if present
     */
-   if (info->indexed && i915->index_buffer.buffer)
-      mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+   if (info->indexed) {
+      mapped_indices = i915->index_buffer.user_buffer;
+      if (!mapped_indices)
+         mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+   }
    draw_set_mapped_index_buffer(draw, mapped_indices);
 
    if (i915->constants[PIPE_SHADER_VERTEX])
index 5a4a9bd68017d0da75d29d54b3bce23eff21b56f..225b80e3dfbac8c56f5f579ec669291345a150f4 100644 (file)
@@ -54,7 +54,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct llvmpipe_context *lp = llvmpipe_context(pipe);
    struct draw_context *draw = lp->draw;
-   void *mapped_indices = NULL;
+   const void *mapped_indices = NULL;
    unsigned i;
 
    if (!llvmpipe_check_render_cond(lp))
@@ -74,8 +74,11 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    }
 
    /* Map index buffer, if present */
-   if (info->indexed && lp->index_buffer.buffer)
-      mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+   if (info->indexed) {
+      mapped_indices = lp->index_buffer.user_buffer;
+      if (!mapped_indices)
+         mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+   }
 
    draw_set_mapped_index_buffer(draw, mapped_indices);
 
index c6907fa806f83981aa2c25ff5cd3937b8cb13a10..29e63953838960f2a3b5292d2e2413fe2f014acc 100644 (file)
@@ -412,7 +412,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    }
 
    if (info->indexed) {
-      void *map = pipe_buffer_map(pipe, nv30->idxbuf.buffer,
+      const void *map = nv30->idxbuf.user_buffer;
+      if (!map)
+         pipe_buffer_map(pipe, nv30->idxbuf.buffer,
                                   PIPE_TRANSFER_UNSYNCHRONIZED |
                                   PIPE_TRANSFER_READ, &transferi);
       draw_set_index_buffer(draw, &nv30->idxbuf);
@@ -424,7 +426,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    draw_vbo(draw, info);
    draw_flush(draw);
 
-   if (info->indexed)
+   if (info->indexed && transferi)
       pipe_buffer_unmap(pipe, transferi);
    for (i = 0; i < nv30->num_vtxbufs; i++)
       if (transfer[i])
index 5d550d13b5e5ec025888ea48628af1cf43022862..c3e50a583167595b965a82d4911e1de688eabd7e 100644 (file)
@@ -78,9 +78,9 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
-   case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
+   case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_VERTEX_BUFFERS:
       return 0;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index 61925ac23c9048f2604c9a3ba84fd9763253a560..a6dfbedf299a6c6f031b0caf5b641847876c689c 100644 (file)
@@ -150,8 +150,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
    case PIPE_CAP_USER_VERTEX_BUFFERS:
-      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_INDEX_BUFFERS:
+      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index 846b21ad6c9b1fb16be9b5d019321789c7a8f3fc..5d6befd45b7739c7d25db57b7bba05acb8c60ca1 100644 (file)
@@ -140,8 +140,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
    case PIPE_CAP_USER_VERTEX_BUFFERS:
-      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_INDEX_BUFFERS:
+      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index ca57a5c785793283af95be3ee63ea1e1589575d4..b58f514c35851d3df8e18b2ce3e9787ac2adc3d0 100644 (file)
@@ -692,7 +692,8 @@ void r300_stop_query(struct r300_context *r300);
 
 /* r300_render_translate.c */
 void r300_translate_index_buffer(struct r300_context *r300,
-                                 struct pipe_resource **index_buffer,
+                                 struct pipe_index_buffer *ib,
+                                 struct pipe_resource **out_index_buffer,
                                  unsigned *index_size, unsigned index_offset,
                                  unsigned *start, unsigned count);
 
index 76165f51a1bb6ccf4e23bb3348729acb62975ff9..56f480d335856f5ad5056d82329b24e619a3b470 100644 (file)
@@ -508,9 +508,9 @@ static void r300_emit_draw_elements(struct r300_context *r300,
 static void r300_draw_elements_immediate(struct r300_context *r300,
                                          const struct pipe_draw_info *info)
 {
-    uint8_t *ptr1;
-    uint16_t *ptr2;
-    uint32_t *ptr4;
+    const uint8_t *ptr1;
+    const uint16_t *ptr2;
+    const uint32_t *ptr4;
     unsigned index_size = r300->index_buffer.index_size;
     unsigned i, count_dwords = index_size == 4 ? info->count :
                                                  (info->count + 1) / 2;
@@ -529,7 +529,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
 
     switch (index_size) {
     case 1:
-        ptr1 = r300->index_buffer.buffer->user_ptr;
+        ptr1 = (uint8_t*)r300->index_buffer.user_buffer;
         ptr1 += info->start;
 
         OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -553,7 +553,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
         break;
 
     case 2:
-        ptr2 = (uint16_t*)r300->index_buffer.buffer->user_ptr;
+        ptr2 = (uint16_t*)r300->index_buffer.user_buffer;
         ptr2 += info->start;
 
         OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -572,7 +572,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
         break;
 
     case 4:
-        ptr4 = (uint32_t*)r300->index_buffer.buffer->user_ptr;
+        ptr4 = (uint32_t*)r300->index_buffer.user_buffer;
         ptr4 += info->start;
 
         OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
@@ -606,15 +606,15 @@ static void r300_draw_elements(struct r300_context *r300,
     uint16_t indices3[3];
 
     if (info->index_bias && !r300->screen->caps.is_r500) {
-        r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset);
+        r300_split_index_bias(r300, info->index_bias, &buffer_offset,
+                              &index_offset);
     }
 
-    r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
-                                &start, count);
+    r300_translate_index_buffer(r300, &r300->index_buffer, &indexBuffer,
+                                &indexSize, index_offset, &start, count);
 
     /* Fallback for misaligned ushort indices. */
-    if (indexSize == 2 && (start & 1) &&
-        !indexBuffer->user_ptr) {
+    if (indexSize == 2 && (start & 1) && indexBuffer) {
         /* If we got here, then orgIndexBuffer == indexBuffer. */
         uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->cs_buf,
                                               r300->cs,
@@ -632,10 +632,10 @@ static void r300_draw_elements(struct r300_context *r300,
         }
         r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->cs_buf);
     } else {
-        if (indexBuffer->user_ptr)
+        if (r300->index_buffer.user_buffer)
             r300_upload_index_buffer(r300, &indexBuffer, indexSize,
                                      &start, count,
-                                     indexBuffer->user_ptr);
+                                     r300->index_buffer.user_buffer);
     }
 
     /* 19 dwords for emit_draw_elements. Give up if the function fails. */
@@ -795,7 +795,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
     struct pipe_draw_info info = *dinfo;
 
-    info.indexed = info.indexed && r300->index_buffer.buffer;
+    info.indexed = info.indexed;
 
     if (r300->skip_rendering ||
         !u_trim_pipe_prim(info.mode, &info.count)) {
@@ -824,7 +824,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
 
         if (info.instance_count <= 1) {
             if (info.count <= 8 &&
-                r300->index_buffer.buffer->user_ptr) {
+                r300->index_buffer.user_buffer) {
                 r300_draw_elements_immediate(r300, &info);
             } else {
                 r300_draw_elements(r300, &info, -1);
@@ -858,8 +858,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
     struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
     struct pipe_transfer *ib_transfer = NULL;
     int i;
-    void *indices = NULL;
-    boolean indexed = info->indexed && r300->index_buffer.buffer;
+    const void *indices = NULL;
+    boolean indexed = info->indexed;
 
     if (r300->skip_rendering) {
         return;
@@ -887,9 +887,13 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
     }
 
     if (indexed) {
-        indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
-                                  PIPE_TRANSFER_READ |
-                                  PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
+        if (r300->index_buffer.user_buffer) {
+            indices = r300->index_buffer.user_buffer;
+        } else {
+            indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
+                                      PIPE_TRANSFER_READ |
+                                      PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
+        }
     }
 
     draw_set_mapped_index_buffer(r300->draw, indices);
@@ -909,7 +913,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
     }
 
     if (indexed) {
-        pipe_buffer_unmap(pipe, ib_transfer);
+        if (ib_transfer)
+            pipe_buffer_unmap(pipe, ib_transfer);
         draw_set_mapped_index_buffer(r300->draw, NULL);
     }
 }
index 022e8a7fc7044adbbac18746708233f269eea9d7..caeeec059090aa26a46f737a2bc0e59677539a88 100644 (file)
 
 
 void r300_translate_index_buffer(struct r300_context *r300,
-                                 struct pipe_resource **index_buffer,
+                                 struct pipe_index_buffer *ib,
+                                 struct pipe_resource **out_buffer,
                                  unsigned *index_size, unsigned index_offset,
                                  unsigned *start, unsigned count)
 {
-    struct pipe_resource *out_buffer = NULL;
     unsigned out_offset;
     void *ptr;
 
     switch (*index_size) {
     case 1:
+        *out_buffer = NULL;
         u_upload_alloc(r300->uploader, 0, count * 2,
-                       &out_offset, &out_buffer, &ptr);
+                       &out_offset, out_buffer, &ptr);
 
         util_shorten_ubyte_elts_to_userptr(
-                &r300->context, *index_buffer, index_offset,
+                &r300->context, ib, index_offset,
                 *start, count, ptr);
 
-       *index_buffer = NULL;
-        pipe_resource_reference(index_buffer, out_buffer);
         *index_size = 2;
         *start = out_offset / 2;
         break;
 
     case 2:
         if (index_offset) {
+            *out_buffer = NULL;
             u_upload_alloc(r300->uploader, 0, count * 2,
-                           &out_offset, &out_buffer, &ptr);
+                           &out_offset, out_buffer, &ptr);
 
-            util_rebuild_ushort_elts_to_userptr(&r300->context, *index_buffer,
+            util_rebuild_ushort_elts_to_userptr(&r300->context, ib,
                                                 index_offset, *start,
                                                 count, ptr);
 
-           *index_buffer = NULL;
-            pipe_resource_reference(index_buffer, out_buffer);
             *start = out_offset / 2;
         }
         break;
 
     case 4:
         if (index_offset) {
+            *out_buffer = NULL;
             u_upload_alloc(r300->uploader, 0, count * 4,
-                           &out_offset, &out_buffer, &ptr);
+                           &out_offset, out_buffer, &ptr);
 
-            util_rebuild_uint_elts_to_userptr(&r300->context, *index_buffer,
+            util_rebuild_uint_elts_to_userptr(&r300->context, ib,
                                               index_offset, *start,
                                               count, ptr);
 
-           *index_buffer = NULL;
-            pipe_resource_reference(index_buffer, out_buffer);
             *start = out_offset / 4;
         }
         break;
index d05c91492878c7c1618a89e9440570aba1454a95..b7deb5f49a5e722e28e905ede5b44c2bd6d1ace3 100644 (file)
@@ -35,7 +35,7 @@
 void r300_upload_index_buffer(struct r300_context *r300,
                              struct pipe_resource **index_buffer,
                              unsigned index_size, unsigned *start,
-                             unsigned count, uint8_t *ptr)
+                             unsigned count, const uint8_t *ptr)
 {
     unsigned index_offset;
 
index 360ec509cc53d645b6f9259af3d2dfe7f7fa15b7..482b6e424ed9358dc447947828b4fe4760ba017f 100644 (file)
@@ -39,7 +39,7 @@
 void r300_upload_index_buffer(struct r300_context *r300,
                              struct pipe_resource **index_buffer,
                              unsigned index_size, unsigned *start,
-                             unsigned count, uint8_t *ptr);
+                             unsigned count, const uint8_t *ptr);
 
 struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
                                         const struct pipe_resource *templ);
index 6f888df6a301603c04adc868a66536363263b3c4..9e1f016f2946e04c0ee1fe5f7d9c0da39bdf52a9 100644 (file)
@@ -751,7 +751,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
        uint8_t *ptr;
 
        if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
-           (info.indexed && !rctx->index_buffer.buffer) ||
            !r600_conv_pipe_prim(info.mode, &prim)) {
                assert(0);
                return;
@@ -767,14 +766,15 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
        if (info.indexed) {
                /* Initialize the index buffer struct. */
                pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
+               ib.user_buffer = rctx->index_buffer.user_buffer;
                ib.index_size = rctx->index_buffer.index_size;
                ib.offset = rctx->index_buffer.offset + info.start * ib.index_size;
 
                /* Translate or upload, if needed. */
                r600_translate_index_buffer(rctx, &ib, info.count);
 
-               ptr = ib.buffer->user_ptr;
-               if (ptr) {
+               ptr = (uint8_t*)ib.user_buffer;
+               if (!ib.buffer && ptr) {
                        u_upload_data(rctx->uploader, 0, info.count * ib.index_size,
                                      ptr, &ib.offset, &ib.buffer);
                }
index af3b8cad3aac07187eff5f713044d53b88366818..c054c865e02a9b5ffec69d2e3afbe5490479988f 100644 (file)
@@ -42,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600,
                               &out_offset, &out_buffer, &ptr);
 
                util_shorten_ubyte_elts_to_userptr(
-                               &r600->context, ib->buffer, 0, ib->offset, count, ptr);
+                               &r600->context, ib, 0, ib->offset, count, ptr);
 
                pipe_resource_reference(&ib->buffer, NULL);
                ib->buffer = out_buffer;
index 912c4ebcdc9d7eaed91ddfdf6f78e238ca17a43d..7e8e2ca68871abf53e4a454d1d074752017a874a 100644 (file)
@@ -211,10 +211,8 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
 void r600_upload_index_buffer(struct r600_context *rctx,
                              struct pipe_index_buffer *ib, unsigned count)
 {
-       struct r600_resource *rbuffer = r600_resource(ib->buffer);
-
        u_upload_data(rctx->uploader, 0, count * ib->index_size,
-                     rbuffer->b.b.user_ptr, &ib->offset, &ib->buffer);
+                     ib->user_buffer, &ib->offset, &ib->buffer);
 }
 
 void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer,
index 1970b52312deccd9601cbc7e728b97eba8dfb15d..05a201ce3bc44746a00fdb3aee74e8ed298e0894 100644 (file)
@@ -731,7 +731,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
                /* Translate or upload, if needed. */
                r600_translate_index_buffer(rctx, &ib, info.count);
 
-               if (ib.buffer->user_ptr) {
+               if (ib.user_buffer) {
                        r600_upload_index_buffer(rctx, &ib, info.count);
                }
 
index 985f1f6f8dcaf2503eef4ed4e474f592542f2902..8633d770d10eed3a004f0c7dade18803be775af3 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "util/u_index_modify.h"
-#include "util/u_inlines.h"
 #include "util/u_upload_mgr.h"
 #include "radeonsi_pipe.h"
 
@@ -43,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600,
                               &out_offset, &out_buffer, &ptr);
 
                util_shorten_ubyte_elts_to_userptr(
-                               &r600->context, ib->buffer, 0, ib->offset, count, ptr);
+                               &r600->context, ib, 0, ib->offset, count, ptr);
 
                pipe_resource_reference(&ib->buffer, NULL);
                ib->buffer = out_buffer;
index f2ffe590f85b1ae741761f0074b32f050b84a88a..7a2274565d5121e822157cf91a37530d2ddaa31f 100644 (file)
@@ -61,7 +61,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
 {
    struct softpipe_context *sp = softpipe_context(pipe);
    struct draw_context *draw = sp->draw;
-   void *mapped_indices = NULL;
+   const void *mapped_indices = NULL;
    unsigned i;
 
    if (!softpipe_check_render_cond(sp))
@@ -84,8 +84,11 @@ softpipe_draw_vbo(struct pipe_context *pipe,
    }
 
    /* Map index buffer, if present */
-   if (info->indexed && sp->index_buffer.buffer)
-      mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+   if (info->indexed) {
+      mapped_indices = sp->index_buffer.user_buffer;
+      if (!mapped_indices)
+         mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+   }
 
    draw_set_mapped_index_buffer(draw, mapped_indices);
 
index f37d1724657478308bcc09ebbe9957e24921409d..ac2d35e5ea4a529f3232a9004fd3f476331d2bf0 100644 (file)
@@ -161,8 +161,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TEXTURE_SWIZZLE:
       return 1;
    case PIPE_CAP_USER_VERTEX_BUFFERS:
-      return 0;
    case PIPE_CAP_USER_INDEX_BUFFERS:
+      return 0;
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index f281791eeadf21d8b542810b003868e910b2d762..ceb6c6b7ef19bffbcbc5ffaec5bb548f0ca85905 100644 (file)
@@ -517,6 +517,7 @@ struct pipe_index_buffer
    unsigned index_size;  /**< size of an index, in bytes */
    unsigned offset;  /**< offset to start of data in buffer, in bytes */
    struct pipe_resource *buffer; /**< the actual buffer */
+   const void *user_buffer;  /**< pointer to a user buffer if buffer == NULL */
 };
 
 
index 09f41abc13ba056be58fb5cc063971976bc1b51d..3789083b36b1e09afab22d4c6a4a7775514829a7 100644 (file)
@@ -581,7 +581,6 @@ setup_index_buffer(struct st_context *st,
                    const struct _mesa_index_buffer *ib,
                    struct pipe_index_buffer *ibuffer)
 {
-   struct pipe_context *pipe = st->pipe;
    struct gl_buffer_object *bufobj = ib->obj;
 
    ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
@@ -589,8 +588,7 @@ setup_index_buffer(struct st_context *st,
    /* get/create the index buffer object */
    if (_mesa_is_bufferobj(bufobj)) {
       /* indices are in a real VBO */
-      struct st_buffer_object *stobj = st_buffer_object(bufobj);
-      pipe_resource_reference(&ibuffer->buffer, stobj->buffer);
+      ibuffer->buffer = st_buffer_object(bufobj)->buffer;
       ibuffer->offset = pointer_to_offset(ib->ptr);
    }
    else if (st->indexbuf_uploader) {
@@ -599,10 +597,7 @@ setup_index_buffer(struct st_context *st,
    }
    else {
       /* indices are in user space memory */
-      ibuffer->buffer =
-         pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
-                                 ib->count * ibuffer->index_size,
-                                 PIPE_BIND_INDEX_BUFFER);
+      ibuffer->user_buffer = ib->ptr;
    }
 
    cso_set_index_buffer(st->cso_context, ibuffer);
@@ -760,10 +755,10 @@ handle_fallback_primitive_restart(struct cso_context *cso,
    unsigned num_sub_prims;
 
    assert(info.indexed);
-   assert(ibuffer->buffer);
+   assert(ibuffer->buffer || ibuffer->user_buffer);
    assert(ib);
 
-   if (!ibuffer->buffer || !ib)
+   if (!ibuffer->buffer || !ibuffer->user_buffer || !ib)
       return;
 
    info.primitive_restart = FALSE;
@@ -1021,7 +1016,9 @@ st_draw_vbo(struct gl_context *ctx,
          cso_draw_vbo(st->cso_context, &info);
    }
 
-   pipe_resource_reference(&ibuffer.buffer, NULL);
+   if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
+      pipe_resource_reference(&ibuffer.buffer, NULL);
+   }
 }