[Mesa-dev] [PATCH 7/9] gallium: add void *user_buffer in pipe_vertex_buffer

Marek Olšák maraeo at gmail.com
Tue Apr 24 14:56:28 PDT 2012


This reduces CPU overhead in st_draw_vbo and removes a lot of unnecessary code
in that function which was required only to comply with the gallium interface,
but wasn't any useful really.

Adapted drivers: i915, llvmpipe, r300, softpipe.
No changes required in: r600, radeonsi.

User vertex buffers have been disabled in nv30, nv50, nvc0 and svga to keep
things working.
---
 src/gallium/auxiliary/draw/draw_llvm.c        |    5 +-
 src/gallium/auxiliary/util/u_draw.c           |    4 +
 src/gallium/auxiliary/util/u_vbuf.c           |   17 ++--
 src/gallium/drivers/i915/i915_state.c         |    4 +-
 src/gallium/drivers/llvmpipe/lp_draw_arrays.c |    4 +-
 src/gallium/drivers/nv30/nv30_draw.c          |    9 +-
 src/gallium/drivers/nv30/nv30_screen.c        |    3 +-
 src/gallium/drivers/nv50/nv50_screen.c        |    2 +-
 src/gallium/drivers/nvc0/nvc0_screen.c        |    2 +-
 src/gallium/drivers/r300/r300_render.c        |    8 +-
 src/gallium/drivers/softpipe/sp_draw_arrays.c |    4 +-
 src/gallium/drivers/svga/svga_screen.c        |    1 +
 src/gallium/include/pipe/p_state.h            |    1 +
 src/mesa/state_tracker/st_context.c           |    5 -
 src/mesa/state_tracker/st_context.h           |   12 --
 src/mesa/state_tracker/st_draw.c              |  142 +++----------------------
 src/mesa/state_tracker/st_draw_feedback.c     |   32 +++---
 17 files changed, 73 insertions(+), 182 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 620d6dc..7bf9d5e 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -236,12 +236,13 @@ static LLVMTypeRef
 create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name)
 {
    LLVMTargetDataRef target = gallivm->target;
-   LLVMTypeRef elem_types[3];
+   LLVMTypeRef elem_types[4];
    LLVMTypeRef vb_type;
 
    elem_types[0] =
    elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
-   elem_types[2] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
+   elem_types[2] =
+   elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
 
 #if HAVE_LLVM >= 0x0300
    vb_type = LLVMStructCreateNamed(gallivm->context, struct_name);
diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c
index d16575b..1f3eb88 100644
--- a/src/gallium/auxiliary/util/u_draw.c
+++ b/src/gallium/auxiliary/util/u_draw.c
@@ -62,6 +62,10 @@ util_draw_max_index(
       const struct util_format_description *format_desc;
       unsigned format_size;
 
+      if (!buffer->buffer) {
+         continue;
+      }
+
       assert(buffer->buffer->height0 == 1);
       assert(buffer->buffer->depth0 == 1);
       buffer_size = buffer->buffer->width0;
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 2d60c07..24258dc 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -275,8 +275,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
          unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
          uint8_t *map;
 
-         if (vb->buffer->user_ptr) {
-            map = vb->buffer->user_ptr + offset;
+         if (vb->user_buffer) {
+            map = (uint8_t*)vb->user_buffer + offset;
          } else {
             unsigned size = vb->stride ? num_vertices * vb->stride
                                        : sizeof(double)*4;
@@ -711,6 +711,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
       struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
 
       pipe_resource_reference(&orig_vb->buffer, vb->buffer);
+      orig_vb->user_buffer = vb->user_buffer;
 
       real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
       real_vb->stride = orig_vb->stride = vb->stride;
@@ -719,7 +720,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
          mgr->nonzero_stride_vb_mask |= 1 << i;
       }
 
-      if (!vb->buffer) {
+      if (!vb->buffer && !vb->user_buffer) {
          pipe_resource_reference(&real_vb->buffer, NULL);
          continue;
       }
@@ -731,7 +732,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
          continue;
       }
 
-      if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) {
+      if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
          mgr->user_vb_mask |= 1 << i;
          pipe_resource_reference(&real_vb->buffer, NULL);
          continue;
@@ -796,9 +797,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
          continue;
       }
 
-      assert(vb->buffer);
-
-      if (!vb->buffer->user_ptr) {
+      if (!vb->user_buffer) {
          continue;
       }
 
@@ -835,7 +834,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
    for (i = 0; i < nr_vbufs; i++) {
       unsigned start, end = end_offset[i];
       struct pipe_vertex_buffer *real_vb;
-      uint8_t *ptr;
+      const uint8_t *ptr;
 
       if (!end) {
          continue;
@@ -845,7 +844,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
       assert(start < end);
 
       real_vb = &mgr->real_vertex_buffer[i];
-      ptr = mgr->vertex_buffer[i].buffer->user_ptr;
+      ptr = mgr->vertex_buffer[i].user_buffer;
 
       u_upload_data(mgr->uploader, start, end - start, ptr + start,
                     &real_vb->buffer_offset, &real_vb->buffer);
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 40cef5a..d38d1ed 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -983,7 +983,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
 
    /* map new */
    for (i = 0; i < count; i++) {
-      void *buf = i915_buffer(buffers[i].buffer)->data;
+      const void *buf = buffers[i].user_buffer;
+      if (!buf)
+            buf = i915_buffer(buffers[i].buffer)->data;
       draw_set_mapped_vertex_buffer(draw, i, buf);
    }
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 239a596..5a4a9bd 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -67,7 +67,9 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
     * Map vertex buffers
     */
    for (i = 0; i < lp->num_vertex_buffers; i++) {
-      void *buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
+      const void *buf = lp->vertex_buffer[i].user_buffer;
+      if (!buf)
+         buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
       draw_set_mapped_vertex_buffer(draw, i, buf);
    }
 
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
index 61e3246..c6907fa 100644
--- a/src/gallium/drivers/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nv30/nv30_draw.c
@@ -366,7 +366,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nv30_context *nv30 = nv30_context(pipe);
    struct draw_context *draw = nv30->draw;
-   struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS];
+   struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS] = {NULL};
    struct pipe_transfer *transferi = NULL;
    int i;
 
@@ -403,7 +403,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    }
 
    for (i = 0; i < nv30->num_vtxbufs; i++) {
-      void *map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
+      const void *map = nv30->vtxbuf[i].user_buffer;
+      if (!map)
+         map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
                                   PIPE_TRANSFER_UNSYNCHRONIZED |
                                   PIPE_TRANSFER_READ, &transfer[i]);
       draw_set_mapped_vertex_buffer(draw, i, map);
@@ -425,7 +427,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    if (info->indexed)
       pipe_buffer_unmap(pipe, transferi);
    for (i = 0; i < nv30->num_vtxbufs; i++)
-      pipe_buffer_unmap(pipe, transfer[i]);
+      if (transfer[i])
+         pipe_buffer_unmap(pipe, transfer[i]);
 
    nv30->draw_dirty = 0;
    nv30_state_release(nv30);
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 32cbc55..1a43e56 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -78,10 +78,11 @@ 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_VERTEX_BUFFERS:
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
+   case PIPE_CAP_USER_VERTEX_BUFFERS:
+      return 0;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
       return 16;
    /* nv4x capabilities */
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 20a135b..61925ac 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -149,8 +149,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
-      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_VERTEX_BUFFERS:
+      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 366e6fb..846b21a 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -139,8 +139,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
-      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_VERTEX_BUFFERS:
+      return 0; /* state trackers will know better */
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 830b0d9..8e15564 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -873,7 +873,10 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
             indexed ? 256 : 6);
 
     for (i = 0; i < r300->nr_vertex_buffers; i++) {
-        if (r300->vertex_buffer[i].buffer) {
+        if (r300->vertex_buffer[i].user_buffer) {
+            draw_set_mapped_vertex_buffer(r300->draw, i,
+                                          r300->vertex_buffer[i].user_buffer);
+        } else if (r300->vertex_buffer[i].buffer) {
             void *buf = pipe_buffer_map(pipe,
                                   r300->vertex_buffer[i].buffer,
                                   PIPE_TRANSFER_READ |
@@ -899,7 +902,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
 
     for (i = 0; i < r300->nr_vertex_buffers; i++) {
         if (r300->vertex_buffer[i].buffer) {
-            pipe_buffer_unmap(pipe, vb_transfer[i]);
+            if (vb_transfer[i])
+                pipe_buffer_unmap(pipe, vb_transfer[i]);
             draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
         }
     }
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 2700407..f2ffe59 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -77,7 +77,9 @@ softpipe_draw_vbo(struct pipe_context *pipe,
 
    /* Map vertex buffers */
    for (i = 0; i < sp->num_vertex_buffers; i++) {
-      void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
+      const void *buf = sp->vertex_buffer[i].user_buffer;
+      if (!buf)
+         buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
       draw_set_mapped_vertex_buffer(draw, i, buf);
    }
 
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 51c8583..f37d172 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -161,6 +161,7 @@ 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:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 42510a6..f281791 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -447,6 +447,7 @@ struct pipe_vertex_buffer
    unsigned stride;    /**< stride to same attrib in next vertex, in bytes */
    unsigned buffer_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 */
 };
 
 
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index d4907db..1c44ddd 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -260,11 +260,6 @@ static void st_destroy_context_priv( struct st_context *st )
    st_destroy_drawpix(st);
    st_destroy_drawtex(st);
 
-   /* Unreference any user vertex buffers. */
-   for (i = 0; i < st->num_user_attribs; i++) {
-      pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
-   }
-
    for (i = 0; i < Elements(st->state.sampler_views); i++) {
       pipe_sampler_view_reference(&st->state.sampler_views[i], NULL);
    }
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 1af0d14..8ad6fe5 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -191,18 +191,6 @@ struct st_context
    int force_msaa;
    void *winsys_drawable_handle;
 
-   /* User vertex buffers. */
-   struct {
-      struct pipe_resource *buffer;
-
-      /** Element size */
-      GLuint element_size;
-
-      /** Attribute stride */
-      GLsizei stride;
-   } user_attrib[PIPE_MAX_ATTRIBS];
-   unsigned num_user_attribs;
-
    /* Active render condition. */
    struct pipe_query *render_condition;
    unsigned condition_mode;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index d866fd7..89bc9be 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -403,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx,
                           const struct st_vp_variant *vpv,
                           const struct gl_client_array **arrays,
                           struct pipe_vertex_buffer *vbuffer,
-                          struct pipe_vertex_element velements[],
-                          unsigned max_index,
-                          unsigned num_instances)
+                          struct pipe_vertex_element velements[])
 {
-   struct st_context *st = st_context(ctx);
-   struct pipe_context *pipe = st->pipe;
    GLuint attr;
    const GLubyte *low_addr = NULL;
    GLboolean usingVBO;      /* all arrays in a VBO? */
    struct gl_buffer_object *bufobj;
-   GLuint user_buffer_size = 0;
-   GLuint vertex_size = 0;  /* bytes per vertex, in bytes */
    GLsizei stride;
 
    /* Find the lowest address of the arrays we're drawing,
@@ -465,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx,
                                                          array->Normalized,
                                                          array->Integer);
       assert(velements[attr].src_format);
-
-      if (!usingVBO) {
-         /* how many bytes referenced by this attribute array? */
-         uint divisor = array->InstanceDivisor;
-         uint last_index = divisor ? num_instances / divisor : max_index;
-         uint bytes = src_offset + stride * last_index + element_size;
-
-         user_buffer_size = MAX2(user_buffer_size, bytes);
-
-         /* update vertex size */
-         vertex_size = MAX2(vertex_size, src_offset + element_size);
-      }
    }
 
    /*
@@ -485,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx,
    if (vpv->num_inputs == 0) {
       /* just defensive coding here */
       vbuffer->buffer = NULL;
+      vbuffer->user_buffer = NULL;
       vbuffer->buffer_offset = 0;
       vbuffer->stride = 0;
-      st->num_user_attribs = 0;
    }
    else if (usingVBO) {
       /* all interleaved arrays in a VBO */
@@ -498,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx,
          return GL_FALSE;
       }
 
-      vbuffer->buffer = NULL;
-      pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+      vbuffer->buffer = stobj->buffer;
+      vbuffer->user_buffer = NULL;
       vbuffer->buffer_offset = pointer_to_offset(low_addr);
       vbuffer->stride = stride;
-      st->num_user_attribs = 0;
    }
    else {
       /* all interleaved arrays in user memory */
-      vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
-                                                (void*) low_addr,
-                                                user_buffer_size,
-                                                PIPE_BIND_VERTEX_BUFFER);
+      vbuffer->buffer = NULL;
+      vbuffer->user_buffer = low_addr;
       vbuffer->buffer_offset = 0;
       vbuffer->stride = stride;
-
-      /* Track user vertex buffers. */
-      pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
-      st->user_attrib[0].element_size = vertex_size;
-      st->user_attrib[0].stride = stride;
-      st->num_user_attribs = 1;
    }
 
    return GL_TRUE;
@@ -537,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
                               const struct st_vp_variant *vpv,
                               const struct gl_client_array **arrays,
                               struct pipe_vertex_buffer vbuffer[],
-                              struct pipe_vertex_element velements[],
-                              unsigned max_index,
-                              unsigned num_instances)
+                              struct pipe_vertex_element velements[])
 {
-   struct st_context *st = st_context(ctx);
-   struct pipe_context *pipe = st->pipe;
    GLuint attr;
 
    for (attr = 0; attr < vpv->num_inputs; attr++) {
       const GLuint mesaAttr = vp->index_to_input[attr];
       const struct gl_client_array *array = arrays[mesaAttr];
       struct gl_buffer_object *bufobj = array->BufferObj;
-      GLuint element_size = array->_ElementSize;
       GLsizei stride = array->StrideB;
 
-      assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+      assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type));
 
       if (_mesa_is_bufferobj(bufobj)) {
          /* Attribute data is in a VBO.
@@ -566,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
             return GL_FALSE;
          }
 
-         vbuffer[attr].buffer = NULL;
-         pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer);
+         vbuffer[attr].buffer = stobj->buffer;
+         vbuffer[attr].user_buffer = NULL;
          vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr);
       }
       else {
          /* wrap user data */
-         uint bytes;
          void *ptr;
 
          if (array->Ptr) {
-            uint divisor = array->InstanceDivisor;
-            uint last_index = divisor ? num_instances / divisor : max_index;
-
-            bytes = stride * last_index + element_size;
-
             ptr = (void *) array->Ptr;
          }
          else {
             /* no array, use ctx->Current.Attrib[] value */
-            bytes = element_size = sizeof(ctx->Current.Attrib[0]);
             ptr = (void *) ctx->Current.Attrib[mesaAttr];
             stride = 0;
          }
 
          assert(ptr);
-         assert(bytes);
-
-         vbuffer[attr].buffer =
-            pipe_user_buffer_create(pipe->screen, ptr, bytes,
-                                    PIPE_BIND_VERTEX_BUFFER);
 
+         vbuffer[attr].buffer = NULL;
+         vbuffer[attr].user_buffer = ptr;
          vbuffer[attr].buffer_offset = 0;
-
-         /* Track user vertex buffers. */
-         pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer);
-         st->user_attrib[attr].element_size = element_size;
-         st->user_attrib[attr].stride = stride;
-         st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1);
-
-         if (!vbuffer[attr].buffer) {
-            /* probably ran out of memory */
-            return GL_FALSE;
-         }
       }
 
       /* common-case setup */
@@ -896,9 +843,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
  */
 static GLboolean
 st_validate_varrays(struct gl_context *ctx,
-                    const struct gl_client_array **arrays,
-                    unsigned max_index,
-                    unsigned num_instances)
+                    const struct gl_client_array **arrays)
 {
    struct st_context *st = st_context(ctx);
    const struct st_vertex_program *vp;
@@ -906,8 +851,6 @@ st_validate_varrays(struct gl_context *ctx,
    struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
    struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
    unsigned num_vbuffers, num_velements;
-   GLuint attr;
-   unsigned i;
 
    /* must get these after state validation! */
    vp = st->vp;
@@ -915,18 +858,12 @@ st_validate_varrays(struct gl_context *ctx,
 
    memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
 
-   /* Unreference any user vertex buffers. */
-   for (i = 0; i < st->num_user_attribs; i++) {
-      pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
-   }
-   st->num_user_attribs = 0;
-
    /*
     * Setup the vbuffer[] and velements[] arrays.
     */
    if (is_interleaved_arrays(vp, vpv, arrays)) {
-      if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
-                                     max_index, num_instances)) {
+      if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer,
+                                     velements)) {
          return GL_FALSE;
       }
 
@@ -937,8 +874,7 @@ st_validate_varrays(struct gl_context *ctx,
    }
    else {
       if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
-                                         vbuffer, velements, max_index,
-                                         num_instances)) {
+                                         vbuffer, velements)) {
          return GL_FALSE;
       }
 
@@ -949,14 +885,6 @@ st_validate_varrays(struct gl_context *ctx,
    cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer);
    cso_set_vertex_elements(st->cso_context, num_velements, velements);
 
-   /* unreference buffers (frees wrapped user-space buffer objects)
-    * This is OK, because the pipe driver should reference buffers by itself
-    * in set_vertex_buffers. */
-   for (attr = 0; attr < num_vbuffers; attr++) {
-      pipe_resource_reference(&vbuffer[attr].buffer, NULL);
-      assert(!vbuffer[attr].buffer);
-   }
-
    return GL_TRUE;
 }
 
@@ -982,7 +910,6 @@ st_draw_vbo(struct gl_context *ctx,
    struct pipe_index_buffer ibuffer = {0};
    struct pipe_draw_info info;
    unsigned i, num_instances = 1;
-   unsigned max_index_plus_base;
    GLboolean new_array =
       st->dirty.st &&
       (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
@@ -991,8 +918,6 @@ st_draw_vbo(struct gl_context *ctx,
    assert(ctx->NewState == 0x0);
 
    if (ib) {
-      int max_base_vertex = 0;
-
       /* Gallium probably doesn't want this in some cases. */
       if (!index_bounds_valid)
          if (!all_varyings_in_vbos(arrays))
@@ -1001,16 +926,7 @@ st_draw_vbo(struct gl_context *ctx,
 
       for (i = 0; i < nr_prims; i++) {
          num_instances = MAX2(num_instances, prims[i].num_instances);
-         max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex);
       }
-
-      /* Compute the sum of max_index and max_base_vertex.  That's the value
-       * we need to use when creating buffers.
-       */
-      if (max_index == ~0)
-         max_index_plus_base = max_index;
-      else
-         max_index_plus_base = max_index + max_base_vertex;
    }
    else {
       /* Get min/max index for non-indexed drawing. */
@@ -1022,9 +938,6 @@ st_draw_vbo(struct gl_context *ctx,
          max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
          num_instances = MAX2(num_instances, prims[i].num_instances);
       }
-
-      /* The base vertex offset only applies to indexed drawing */
-      max_index_plus_base = max_index;
    }
 
    /* Validate state. */
@@ -1041,8 +954,7 @@ st_draw_vbo(struct gl_context *ctx,
       st_validate_state(st);
 
       if (new_array) {
-         if (!st_validate_varrays(ctx, arrays, max_index_plus_base,
-                                  num_instances)) {
+         if (!st_validate_varrays(ctx, arrays)) {
             /* probably out of memory, no-op the draw call */
             return;
          }
@@ -1057,26 +969,6 @@ st_draw_vbo(struct gl_context *ctx,
 #endif
    }
 
-   /* Notify the driver that the content of user buffers may have been
-    * changed. */
-   assert(max_index >= min_index);
-   if (!new_array && st->num_user_attribs) {
-      for (i = 0; i < st->num_user_attribs; i++) {
-         if (st->user_attrib[i].buffer) {
-            unsigned element_size = st->user_attrib[i].element_size;
-            unsigned stride = st->user_attrib[i].stride;
-            unsigned min_offset = min_index * stride;
-            unsigned max_offset = max_index_plus_base * stride + element_size;
-
-            assert(max_offset > min_offset);
-
-            pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer,
-                                       min_offset,
-                                       max_offset - min_offset);
-         }
-      }
-   }
-
    util_draw_init_info(&info);
    if (ib) {
       setup_index_buffer(st, ib, &ibuffer);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index a559b73..ee19898 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -108,7 +108,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
    struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
    struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
    struct pipe_index_buffer ibuffer;
-   struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+   struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
    struct pipe_transfer *ib_transfer = NULL;
    GLuint attr, i;
    const GLubyte *low_addr = NULL;
@@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx,
          assert(stobj->buffer);
 
          vbuffers[attr].buffer = NULL;
+         vbuffers[attr].user_buffer = NULL;
          pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer);
          vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
          velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
+
+         /* map the attrib buffer */
+         map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
+                               PIPE_TRANSFER_READ,
+                               &vb_transfer[attr]);
+         draw_set_mapped_vertex_buffer(draw, attr, map);
       }
       else {
-         /* attribute data is in user-space memory, not a VBO */
-         uint bytes = (arrays[mesaAttr]->Size
-                       * _mesa_sizeof_type(arrays[mesaAttr]->Type)
-                       * (max_index + 1));
-
-         /* wrap user data */
-         vbuffers[attr].buffer
-            = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr,
-                                      bytes,
-				      PIPE_BIND_VERTEX_BUFFER);
+         vbuffers[attr].buffer = NULL;
+         vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr;
          vbuffers[attr].buffer_offset = 0;
          velements[attr].src_offset = 0;
+
+         draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer);
       }
 
       /* common-case setup */
@@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx,
 #if 0
       draw_set_vertex_buffer(draw, attr, &vbuffer[attr]);
 #endif
-
-      /* map the attrib buffer */
-      map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
-                            PIPE_TRANSFER_READ,
-			    &vb_transfer[attr]);
-      draw_set_mapped_vertex_buffer(draw, attr, map);
    }
 
    draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
@@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
 
  out_unref_vertex:
    for (attr = 0; attr < vp->num_inputs; attr++) {
-      pipe_buffer_unmap(pipe, vb_transfer[attr]);
+      if (vb_transfer[attr])
+         pipe_buffer_unmap(pipe, vb_transfer[attr]);
       draw_set_mapped_vertex_buffer(draw, attr, NULL);
       pipe_resource_reference(&vbuffers[attr].buffer, NULL);
    }
-- 
1.7.5.4



More information about the mesa-dev mailing list