Could you also add comments to all the u_upload_mgr.c functions? In particular, what are the possible values for the usage/bind parameters? A follow-on patch is fine. I know that comments have been missing all along.

-Brian


On 12/29/2010 12:00 PM, Marek Olšák wrote:
- Added a parameter to specify a minimum offset that should be returned.
   r300g needs this to better implement user buffer uploads. This weird
   requirement comes from the fact that the Radeon DRM doesn't support negative
   offsets.

- Added a parameter to notify a driver that the upload flush occured.
   A driver may skip buffer validation if there was no flush, resulting
   in a better performance.

- Added a new upload function that returns a pointer to the upload buffer
   directly, so that the buffer can be filled e.g. by the translate module.
---
  src/gallium/auxiliary/util/u_upload_mgr.c     |   75 +++++++++++++++++--------
  src/gallium/auxiliary/util/u_upload_mgr.h     |   43 +++++++++++++-
  src/gallium/drivers/i965/brw_draw_upload.c    |   12 +++-
  src/gallium/drivers/r300/r300_screen_buffer.c |   10 ++-
  src/gallium/drivers/svga/svga_draw_elements.c |    5 +-
  src/gallium/drivers/svga/svga_state_vdecl.c   |    6 +-
  6 files changed, 115 insertions(+), 36 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c 
b/src/gallium/auxiliary/util/u_upload_mgr.c
index 4d97bf0..80c9b63 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -43,7 +43,7 @@ struct u_upload_mgr {

     unsigned default_size;
     unsigned alignment;
-   unsigned usage;
+   unsigned bind;

     /* The active buffer:
      */
@@ -58,7 +58,7 @@ struct u_upload_mgr {
  struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
                                        unsigned default_size,
                                        unsigned alignment,
-                                      unsigned usage )
+                                      unsigned bind )
  {
     struct u_upload_mgr *upload = CALLOC_STRUCT( u_upload_mgr );
     if (!upload)
@@ -67,7 +67,7 @@ struct u_upload_mgr *u_upload_create( struct pipe_context 
*pipe,
     upload->pipe = pipe;
     upload->default_size = default_size;
     upload->alignment = alignment;
-   upload->usage = usage;
+   upload->bind = bind;
     upload->buffer = NULL;

     return upload;
@@ -115,7 +115,7 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
     size = align(MAX2(upload->default_size, min_size), 4096);

     upload->buffer = pipe_buffer_create( upload->pipe->screen,
-                                        upload->usage,
+                                        upload->bind,
                                          size );
     if (upload->buffer == NULL)
        goto fail;
@@ -135,33 +135,61 @@ fail:
     return PIPE_ERROR_OUT_OF_MEMORY;
  }

-
-enum pipe_error u_upload_data( struct u_upload_mgr *upload,
-                               unsigned size,
-                               const void *data,
-                               unsigned *out_offset,
-                               struct pipe_resource **outbuf )
+enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
+                                unsigned min_out_offset,
+                                unsigned size,
+                                unsigned *out_offset,
+                                struct pipe_resource **outbuf,
+                                boolean *flushed,
+                                void **ptr )
  {
     unsigned alloc_size = align( size, upload->alignment );
-   enum pipe_error ret = PIPE_OK;
+   unsigned alloc_offset = align(min_out_offset, upload->alignment);
+   unsigned offset;

-   if (upload->offset + alloc_size>  upload->size) {
-      ret = u_upload_alloc_buffer( upload, alloc_size );
+   if (MAX2(upload->offset, alloc_offset) + alloc_size>  upload->size) {
+      enum pipe_error ret = u_upload_alloc_buffer(upload,
+                                                  alloc_offset + alloc_size);
        if (ret)
           return ret;
+
+      *flushed = TRUE;
+   } else {
+      *flushed = FALSE;
     }

-   assert(upload->offset<  upload->buffer->width0);
-   assert(upload->offset + size<= upload->buffer->width0);
+   offset = MAX2(upload->offset, alloc_offset);
+
+   assert(offset<  upload->buffer->width0);
+   assert(offset + size<= upload->buffer->width0);
     assert(size);

-   memcpy(upload->map + upload->offset, data, size);
+   *ptr = upload->map + offset;

     /* Emit the return values:
      */
     pipe_resource_reference( outbuf, upload->buffer );
-   *out_offset = upload->offset;
-   upload->offset += alloc_size;
+   *out_offset = offset;
+   upload->offset = offset + alloc_size;
+   return PIPE_OK;
+}
+
+enum pipe_error u_upload_data( struct u_upload_mgr *upload,
+                               unsigned min_out_offset,
+                               unsigned size,
+                               const void *data,
+                               unsigned *out_offset,
+                               struct pipe_resource **outbuf,
+                               boolean *flushed )
+{
+   uint8_t *ptr;
+   enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size,
+                                        out_offset, outbuf, flushed,
+                                        (void**)&ptr);
+   if (ret)
+      return ret;
+
+   memcpy(ptr, data, size);
     return PIPE_OK;
  }

@@ -172,11 +200,13 @@ enum pipe_error u_upload_data( struct u_upload_mgr 
*upload,
   * renders or DrawElements calls.
   */
  enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
+                                 unsigned min_out_offset,
                                   unsigned offset,
                                   unsigned size,
                                   struct pipe_resource *inbuf,
                                   unsigned *out_offset,
-                                 struct pipe_resource **outbuf )
+                                 struct pipe_resource **outbuf,
+                                 boolean *flushed )
  {
     enum pipe_error ret = PIPE_OK;
     struct pipe_transfer *transfer = NULL;
@@ -195,13 +225,12 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr 
*upload,
     if (0)
        debug_printf("upload ptr %p ofs %d sz %d\n", map, offset, size);

-   ret = u_upload_data( upload,
+   ret = u_upload_data( upload,
+                        min_out_offset,
                          size,
                          map + offset,
                          out_offset,
-                        outbuf );
-   if (ret)
-      goto done;
+                        outbuf, flushed );

  done:
     if (map)
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h 
b/src/gallium/auxiliary/util/u_upload_mgr.h
index de016df..fc8f4d3 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -32,6 +32,8 @@
  #ifndef U_UPLOAD_MGR_H
  #define U_UPLOAD_MGR_H

+#include "pipe/p_compiler.h"
+
  struct pipe_context;
  struct pipe_resource;

@@ -39,7 +41,7 @@ struct pipe_resource;
  struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
                                        unsigned default_size,
                                        unsigned alignment,
-                                      unsigned usage );
+                                      unsigned bind );

  void u_upload_destroy( struct u_upload_mgr *upload );

@@ -53,20 +55,55 @@ void u_upload_destroy( struct u_upload_mgr *upload );
   */
  void u_upload_flush( struct u_upload_mgr *upload );

+/**
+ * Sub-allocate new memory from the upload buffer.
+ *
+ * \param upload           Upload manager
+ * \param min_out_offset   Minimum offset that should be returned in 
out_offset.
+ * \param size             Size of the allocation.
+ * \param out_offset       Pointer to where the new buffer offset will be 
returned.
+ * \param outbuf           Pointer to where the upload buffer will be returned.
+ * \param flushed          Whether the upload buffer was flushed.
+ * \param ptr              Pointer to the allocated memory that is returned.
+ */
+enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
+                                unsigned min_out_offset,
+                                unsigned size,
+                                unsigned *out_offset,
+                                struct pipe_resource **outbuf,
+                                boolean *flushed,
+                                void **ptr );
+

+/**
+ * Allocate and write data to the upload buffer.
+ *
+ * Same as u_upload_alloc, but in addition to that, it copies "data"
+ * to the pointer returned from u_upload_alloc.
+ */
  enum pipe_error u_upload_data( struct u_upload_mgr *upload,
+                               unsigned min_out_offset,
                                 unsigned size,
                                 const void *data,
                                 unsigned *out_offset,
-                               struct pipe_resource **outbuf );
+                               struct pipe_resource **outbuf,
+                               boolean *flushed );


+/**
+ * Allocate and copy an input buffer to the upload buffer.
+ *
+ * Same as u_upload_data, except that the input data comes from a buffer
+ * instead of a user pointer.
+ */
  enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
+                                 unsigned min_out_offset,
                                   unsigned offset,
                                   unsigned size,
                                   struct pipe_resource *inbuf,
                                   unsigned *out_offset,
-                                 struct pipe_resource **outbuf );
+                                 struct pipe_resource **outbuf,
+                                 boolean *flushed );



diff --git a/src/gallium/drivers/i965/brw_draw_upload.c 
b/src/gallium/drivers/i965/brw_draw_upload.c
index ebeb1e1..cf94054 100644
--- a/src/gallium/drivers/i965/brw_draw_upload.c
+++ b/src/gallium/drivers/i965/brw_draw_upload.c
@@ -89,13 +89,16 @@ static int brw_prepare_vertices(struct brw_context *brw)
                           vb->buffer->width0 - vb->buffer_offset :
                           MAX2(vb->buffer->width0 - vb->buffer_offset,
                                vb->stride * (max_index + 1 - min_index)));
+        boolean flushed;

-        ret = u_upload_buffer( brw->vb.upload_vertex,
+        ret = u_upload_buffer( brw->vb.upload_vertex,
+                               0,
                                 vb->buffer_offset + min_index * vb->stride,
                                 size,
                                 vb->buffer,
                                 &offset,
-&upload_buf );
+&upload_buf,
+&flushed );
          if (ret)
             return ret;

@@ -251,13 +254,16 @@ static int brw_prepare_indices(struct brw_context *brw)
     /* Turn userbuffer into a proper hardware buffer?
      */
     if (brw_buffer_is_user_buffer(index_buffer)) {
+      boolean flushed;

        ret = u_upload_buffer( brw->vb.upload_index,
+                             0,
                              index_offset,
                              ib_size,
                              index_buffer,
                              &offset,
-&upload_buf );
+&upload_buf,
+&flushed );
        if (ret)
          return ret;

diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c 
b/src/gallium/drivers/r300/r300_screen_buffer.c
index f969981..11ad87e 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -62,15 +62,16 @@ void r300_upload_index_buffer(struct r300_context *r300,
                               unsigned count)
  {
      unsigned index_offset;
+    boolean flushed;
      uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer;

      *index_buffer = NULL;

      u_upload_data(r300->upload_ib,
-                  count * index_size,
+                  0, count * index_size,
                    ptr + (*start * index_size),
                    &index_offset,
-                  index_buffer);
+                  index_buffer,&flushed);

      *start = index_offset / index_size;
  }
@@ -78,6 +79,7 @@ void r300_upload_index_buffer(struct r300_context *r300,
  void r300_upload_user_buffers(struct r300_context *r300)
  {
      int i, nr = r300->velems->count;
+    boolean flushed;

      for (i = 0; i<  nr; i++) {
          struct pipe_vertex_buffer *vb =
@@ -85,9 +87,9 @@ void r300_upload_user_buffers(struct r300_context *r300)

          if (r300_buffer_is_user_buffer(vb->buffer)) {
              u_upload_data(r300->upload_vb,
-                          vb->buffer->width0,
+                          0, vb->buffer->width0,
                            r300_buffer(vb->buffer)->user_buffer,
-&vb->buffer_offset,&vb->buffer);
+&vb->buffer_offset,&vb->buffer,&flushed);

              r300->validate_buffers = TRUE;
              r300->vertex_arrays_dirty = TRUE;
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c 
b/src/gallium/drivers/svga/svga_draw_elements.c
index c7ea014..83527c6 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -120,14 +120,17 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl 
*hwtnl,
     if (index_buffer&&
         svga_buffer_is_user_buffer(index_buffer))
     {
+      boolean flushed;
        assert( index_buffer->width0>= index_offset + count * index_size );

        ret = u_upload_buffer( hwtnl->upload_ib,
+                             0,
                               index_offset,
                               count * index_size,
                               index_buffer,
                               &index_offset,
-&upload_buffer );
+&upload_buffer,
+&flushed );
        if (ret)
           goto done;

diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c 
b/src/gallium/drivers/svga/svga_state_vdecl.c
index 3af7bf2..958d003 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -57,12 +57,14 @@ upload_user_buffers( struct svga_context *svga )
           struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);

           if (!buffer->uploaded.buffer) {
+            boolean flushed;
              ret = u_upload_buffer( svga->upload_vb,
-                                   0,
+                                   0, 0,
                                     buffer->b.b.width0,
                                     &buffer->b.b,
                                     &buffer->uploaded.offset,
-&buffer->uploaded.buffer );
+&buffer->uploaded.buffer,
+&flushed);
              if (ret)
                 return ret;

--
1.7.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
.


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to