gallium: add void *user_buffer to pipe_constant_buffer
authorMarek Olšák <maraeo@gmail.com>
Tue, 24 Apr 2012 20:53:05 +0000 (22:53 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 29 Apr 2012 23:18:48 +0000 (01:18 +0200)
This reduces CPU overhead when updating constants.

18 files changed:
src/gallium/drivers/i915/i915_state.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/nv30/nv30_state.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nvc0/nvc0_state.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeonsi/r600_state_common.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_state_shader.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/svga/svga_pipe_constants.c
src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_atom_constbuf.c

index 772e229ceff7d5e1201cf171de2fba7541dad64b..bd9e8bac0aeb8278c612174a355fe28943ecddaf 100644 (file)
@@ -672,6 +672,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
    unsigned new_num = 0;
    boolean diff = TRUE;
 
+   if (cb && cb->user_buffer) {
+      buf = i915_user_buffer_create(pipe->screen, cb->user_buffer,
+                                    cb->buffer_size,
+                                    PIPE_BIND_CONSTANT_BUFFER);
+   }
 
    /* XXX don't support geom shaders now */
    if (shader == PIPE_SHADER_GEOMETRY)
@@ -707,6 +712,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
 
    if (diff)
       i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&buf, NULL);
+   }
 }
 
 
index 438fc887083b90ce112f2364e4d85b459c028cb7..d4750705b435cafe40a06d6b40155049c7a8aed1 100644 (file)
@@ -155,6 +155,12 @@ extern unsigned llvmpipe_variant_count;
 struct pipe_context *
 llvmpipe_create_context( struct pipe_screen *screen, void *priv );
 
+struct pipe_resource *
+llvmpipe_user_buffer_create(struct pipe_screen *screen,
+                            void *ptr,
+                            unsigned bytes,
+                           unsigned bind_flags);
+
 
 static INLINE struct llvmpipe_context *
 llvmpipe_context( struct pipe_context *pipe )
index 7a6c1ab5bc72fe664fc09edd153c936e5fa451f6..ec94190649c36cfeb14967cabe5b8bb63f8cf5af 100644 (file)
@@ -1173,8 +1173,17 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    struct pipe_resource *constants = cb ? cb->buffer : NULL;
-   unsigned size = constants ? constants->width0 : 0;
-   const void *data = constants ? llvmpipe_resource_data(constants) : NULL;
+   unsigned size;
+   const void *data;
+
+   if (cb && cb->user_buffer) {
+      constants = llvmpipe_user_buffer_create(pipe->screen, cb->user_buffer,
+                                              cb->buffer_size,
+                                              PIPE_BIND_CONSTANT_BUFFER);
+   }
+
+   size = constants ? constants->width0 : 0;
+   data = constants ? llvmpipe_resource_data(constants) : NULL;
 
    assert(shader < PIPE_SHADER_TYPES);
    assert(index < PIPE_MAX_CONSTANT_BUFFERS);
@@ -1194,6 +1203,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
    }
 
    llvmpipe->dirty |= LP_NEW_CONSTANTS;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&constants, NULL);
+   }
 }
 
 
index f6a1ec26bc5ec47196698e9c92e152334824db86..958a8127b8995a0d485ade7a436d404d78ab1419 100644 (file)
@@ -748,7 +748,7 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe,
 /**
  * Create buffer which wraps user-space data.
  */
-static struct pipe_resource *
+struct pipe_resource *
 llvmpipe_user_buffer_create(struct pipe_screen *screen,
                             void *ptr,
                             unsigned bytes,
index 3b4cc99887721248f81bbeb4bb865894c4c33c67..f65c8b71fdde0e239bc71850b4b51cd8761e0ba9 100644 (file)
@@ -323,6 +323,12 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    struct pipe_resource *buf = cb ? cb->buffer : NULL;
    unsigned size;
 
+   if (cb && cb->user_buffer) {
+      buf = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
+                                       cb->buffer_size,
+                                       PIPE_BIND_CONSTANT_BUFFER);
+   }
+
    size = 0;
    if (buf)
       size = buf->width0 / (4 * sizeof(float));
@@ -337,6 +343,10 @@ nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
       nv30->fragprog.constbuf_nr = size;
       nv30->dirty |= NV30_NEW_FRAGCONST;
    }
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&buf, NULL);
+   }
 }
 
 static void
index afd6f2e929d122164cc42d7b0134f47686c74ce3..a17540a1492032db7e00db222043e8c089c41f20 100644 (file)
@@ -749,6 +749,12 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    struct nv50_context *nv50 = nv50_context(pipe);
    struct pipe_resource *res = cb ? cb->buffer : NULL;
 
+   if (cb && cb->user_buffer) {
+      res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
+                                       cb->buffer_size,
+                                       PIPE_BIND_CONSTANT_BUFFER);
+   }
+
    pipe_resource_reference(&nv50->constbuf[shader][index], res);
 
    nv50->constbuf_dirty[shader] |= 1 << index;
@@ -760,6 +766,10 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
 
    nv50->dirty |= NV50_NEW_CONSTBUF;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&res, NULL);
+   }
 }
 
 /* =============================================================================
index 9b1ae550fff9613804ab1ab7345af608b0348e52..40161252a3daa25cb47313cb2bbff31f8ec92e79 100644 (file)
@@ -621,6 +621,12 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct pipe_resource *res = cb ? cb->buffer : NULL;
 
+   if (cb && cb->user_buffer) {
+      res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
+                                       cb->buffer_size,
+                                       PIPE_BIND_CONSTANT_BUFFER);
+   }
+
    switch (shader) {
    case PIPE_SHADER_VERTEX: shader = 0; break;
       /*
@@ -642,6 +648,10 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
    nvc0->constbuf_dirty[shader] |= 1 << index;
 
    nvc0->dirty |= NVC0_NEW_CONSTBUF;
+
+   if (cb->user_buffer) {
+      pipe_resource_reference(&res, NULL);
+   }
 }
 
 /* =============================================================================
index 3822f2fd5d1e878f7b5db55b22bf40b6703ded01..566bc443807a3b8534156a85292ac4eece1abd1f 100644 (file)
@@ -1841,8 +1841,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     if (buf == NULL || buf->width0 == 0)
         return;
 
-    if (rbuf->b.b.user_ptr)
-        mapped = (uint32_t*)rbuf->b.b.user_ptr;
+    if (cb->user_buffer)
+        mapped = (uint32_t*)cb->user_buffer;
     else if (rbuf->constant_buffer)
         mapped = (uint32_t*)rbuf->constant_buffer;
     else
index 4b9338d3464ecbb952a1fbe6cb4bbfe917077e17..517121dc28808baf420dc569ca0a0b7913162bab 100644 (file)
@@ -1203,10 +1203,8 @@ static void evergreen_set_clip_state(struct pipe_context *ctx,
        rctx->states[R600_PIPE_STATE_CLIP] = rstate;
        r600_context_pipe_state_set(rctx, rstate);
 
-       cb.buffer = pipe_user_buffer_create(ctx->screen,
-                                           state->ucp,
-                                           4*4*8, /* 8*4 floats */
-                                           PIPE_BIND_CONSTANT_BUFFER);
+       cb.buffer = NULL;
+       cb.user_buffer = state->ucp;
        cb.buffer_offset = 0;
        cb.buffer_size = 4*4*8;
        r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
index 81ffaa8bfd9346b1a16a47bc0ac72288c1027794..3a83b613e587889b18f3ac31d04ad06c73fca178 100644 (file)
@@ -1286,10 +1286,8 @@ static void r600_set_clip_state(struct pipe_context *ctx,
        rctx->states[R600_PIPE_STATE_CLIP] = rstate;
        r600_context_pipe_state_set(rctx, rstate);
 
-       cb.buffer = pipe_user_buffer_create(ctx->screen,
-                                           state->ucp,
-                                           4*4*8, /* 8*4 floats */
-                                           PIPE_BIND_CONSTANT_BUFFER);
+       cb.buffer = NULL;
+       cb.user_buffer = state->ucp;
        cb.buffer_offset = 0;
        cb.buffer_size = 4*4*8;
        r600_set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
index 9e1f016f2946e04c0ee1fe5f7d9c0da39bdf52a9..ccae7d91d43863075b963830f9fa6cee65633e01 100644 (file)
@@ -535,7 +535,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct r600_constbuf_state *state;
        struct pipe_constant_buffer *cb;
-       uint8_t *ptr;
+       const uint8_t *ptr;
 
        switch (shader) {
        case PIPE_SHADER_VERTEX:
@@ -561,7 +561,7 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
        cb = &state->cb[index];
        cb->buffer_size = input->buffer_size;
 
-       ptr = input->buffer->user_ptr;
+       ptr = input->user_buffer;
 
        if (ptr) {
                /* Upload the user buffer. */
index 05a201ce3bc44746a00fdb3aee74e8ed298e0894..63c07420915f2191b55e0763c14deae8f8126151 100644 (file)
@@ -439,6 +439,12 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
                return;
        }
 
+        if (cb->user_buffer) {
+           rbuffer = pipe_user_buffer_create(ctx->screen, cb->user_buffer,
+                                         cb->buffer_size,
+                                         PIPE_BIND_CONSTANT_BUFFER);
+        }
+
        r600_inval_shader_cache(rctx);
 
        r600_upload_const_buffer(rctx, &rbuffer, &offset);
index c657bd61fcffe7ffd54e9d9e6163585cdae2f5c3..7634254104b9bc18d5f00ea4bd7b304239de1da3 100644 (file)
@@ -206,6 +206,11 @@ softpipe_reset_sampler_variants(struct softpipe_context *softpipe);
 struct pipe_context *
 softpipe_create_context( struct pipe_screen *, void *priv );
 
+struct pipe_resource *
+softpipe_user_buffer_create(struct pipe_screen *screen,
+                            void *ptr,
+                            unsigned bytes,
+                           unsigned bind_flags);
 
 #define SP_UNREFERENCED         0
 #define SP_REFERENCED_FOR_READ  (1 << 0)
index af05d0d5d686a6bd9cfa4bc46f141968451478d5..4056d2d44445057547b78b0abe0dc7543a3ab9b1 100644 (file)
@@ -346,8 +346,17 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
    struct pipe_resource *constants = cb ? cb->buffer : NULL;
-   unsigned size = constants ? constants->width0 : 0;
-   const void *data = constants ? softpipe_resource(constants)->data : NULL;
+   unsigned size;
+   const void *data;
+
+   if (cb && cb->user_buffer) {
+      constants = softpipe_user_buffer_create(pipe->screen, cb->user_buffer,
+                                              cb->buffer_size,
+                                              PIPE_BIND_CONSTANT_BUFFER);
+   }
+
+   size = constants ? constants->width0 : 0;
+   data = constants ? softpipe_resource(constants)->data : NULL;
 
    assert(shader < PIPE_SHADER_TYPES);
 
@@ -364,6 +373,10 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
    softpipe->const_buffer_size[shader][index] = size;
 
    softpipe->dirty |= SP_NEW_CONSTANTS;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&constants, NULL);
+   }
 }
 
 
index f5c6f565f217127ebfe706fc124e39358b6726cb..292010638f9e595ba21a2899c61442b21e3609e9 100644 (file)
@@ -454,7 +454,7 @@ softpipe_transfer_unmap(struct pipe_context *pipe,
 /**
  * Create buffer which wraps user-space data.
  */
-static struct pipe_resource *
+struct pipe_resource *
 softpipe_user_buffer_create(struct pipe_screen *screen,
                             void *ptr,
                             unsigned bytes,
index 5de547bc08a619a7f983ddaf13fbc606d6c47344..46dc45b9ed087737cd7ea1cb8b210d908be18ed7 100644 (file)
@@ -29,6 +29,7 @@
 #include "tgsi/tgsi_parse.h"
 
 #include "svga_context.h"
+#include "svga_resource_buffer.h"
 
 /***********************************************************************
  * Constant buffers 
@@ -50,6 +51,12 @@ static void svga_set_constant_buffer(struct pipe_context *pipe,
    struct svga_context *svga = svga_context(pipe);
    struct pipe_resource *buf = cb ? cb->buffer : NULL;
 
+   if (cb && cb->user_buffer) {
+      buf = svga_user_buffer_create(pipe->screen, cb->user_buffer,
+                                    cb->buffer_size,
+                                    PIPE_BIND_CONSTANT_BUFFER);
+   }
+
    assert(shader < PIPE_SHADER_TYPES);
    assert(index == 0);
 
@@ -60,6 +67,10 @@ static void svga_set_constant_buffer(struct pipe_context *pipe,
       svga->dirty |= SVGA_NEW_FS_CONST_BUFFER;
    else
       svga->dirty |= SVGA_NEW_VS_CONST_BUFFER;
+
+   if (cb && cb->user_buffer) {
+      pipe_resource_reference(&buf, NULL);
+   }
 }
 
 
index ceb6c6b7ef19bffbcbc5ffaec5bb548f0ca85905..e969b74eff67f9f92d52c79589d6c15c8e2f78dc 100644 (file)
@@ -459,6 +459,7 @@ struct pipe_constant_buffer {
    struct pipe_resource *buffer; /**< the actual buffer */
    unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
    unsigned buffer_size;   /**< how much data can be read in shader */
+   const void *user_buffer;  /**< pointer to a user buffer if buffer == NULL */
 };
 
 
index eb98161dbd0fd2ed322676f4a3d1f2072f9451a3..c9018b3bd77d3083ffbac99b51f79858ffeff559 100644 (file)
@@ -56,8 +56,6 @@ void st_upload_constants( struct st_context *st,
                           struct gl_program_parameter_list *params,
                           unsigned shader_type)
 {
-   struct pipe_context *pipe = st->pipe;
-
    assert(shader_type == PIPE_SHADER_VERTEX ||
           shader_type == PIPE_SHADER_FRAGMENT ||
           shader_type == PIPE_SHADER_GEOMETRY);
@@ -80,13 +78,12 @@ void st_upload_constants( struct st_context *st,
        */
       if (st->constbuf_uploader) {
          cb.buffer = NULL;
+         cb.user_buffer = NULL;
          u_upload_data(st->constbuf_uploader, 0, paramBytes,
                        params->ParameterValues, &cb.buffer_offset, &cb.buffer);
       } else {
-         cb.buffer = pipe_user_buffer_create(pipe->screen,
-                                             params->ParameterValues,
-                                             paramBytes,
-                                             PIPE_BIND_CONSTANT_BUFFER);
+         cb.buffer = NULL;
+         cb.user_buffer = params->ParameterValues;
          cb.buffer_offset = 0;
       }
       cb.buffer_size = paramBytes;