Mesa (lp-binning): llvmpipe: Maintain a copy of the shader constants to prevent clobbering.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sun Oct 18 10:58:25 UTC 2009


Module: Mesa
Branch: lp-binning
Commit: 2e3580d994e2caf6d81763803c8525a7ed42b8fd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2e3580d994e2caf6d81763803c8525a7ed42b8fd

Author: José Fonseca <jfonseca at vmware.com>
Date:   Sun Oct 18 11:57:43 2009 +0100

llvmpipe: Maintain a copy of the shader constants to prevent clobbering.

---

 src/gallium/drivers/llvmpipe/lp_setup.c         |   64 +++++++++++++++++-----
 src/gallium/drivers/llvmpipe/lp_setup_context.h |   13 ++++-
 2 files changed, 61 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index a74756d..08dac45 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -101,6 +101,11 @@ static void reset_context( struct setup_context *setup )
 
    SETUP_DEBUG("%s\n", __FUNCTION__);
 
+   /* Reset derived data */
+   pipe_buffer_reference(&setup->constants.current, NULL);
+   setup->constants.stored_size = 0;
+   setup->constants.stored_data = NULL;
+
    /* Free all but last binner command lists:
     */
    for (i = 0; i < setup->tiles_x; i++) {
@@ -424,18 +429,11 @@ void
 lp_setup_set_fs_constants(struct setup_context *setup,
                           struct pipe_buffer *buffer)
 {
-   const void *data = buffer ? llvmpipe_buffer(buffer)->data : NULL;
-   struct pipe_buffer *dummy;
-
    SETUP_DEBUG("%s\n", __FUNCTION__);
 
-   /* FIXME: hold on to the reference */
-   dummy = NULL;
-   pipe_buffer_reference(&dummy, buffer);
+   pipe_buffer_reference(&setup->constants.current, buffer);
 
-   setup->fs.current.jit_context.constants = data;
-
-   setup->fs.dirty = TRUE;
+   setup->dirty |= LP_SETUP_NEW_CONSTANTS;
 }
 
 
@@ -447,7 +445,7 @@ lp_setup_set_alpha_ref_value( struct setup_context *setup,
 
    if(setup->fs.current.jit_context.alpha_ref_value != alpha_ref_value) {
       setup->fs.current.jit_context.alpha_ref_value = alpha_ref_value;
-      setup->fs.dirty = TRUE;
+      setup->dirty |= LP_SETUP_NEW_FS;
    }
 }
 
@@ -468,7 +466,7 @@ lp_setup_set_blend_color( struct setup_context *setup,
          setup->fs.current.jit_context.blend_color[i*4 + j] = c;
    }
 
-   setup->fs.dirty = TRUE;
+   setup->dirty |= LP_SETUP_NEW_FS;
 }
 
 void
@@ -505,7 +503,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
       }
    }
 
-   setup->fs.dirty = TRUE;
+   setup->dirty |= LP_SETUP_NEW_FS;
 }
 
 boolean
@@ -524,7 +522,43 @@ lp_setup_update_shader_state( struct setup_context *setup )
 
    assert(setup->fs.current.jit_function);
 
-   if(setup->fs.dirty) {
+   if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
+      struct pipe_buffer *buffer = setup->constants.current;
+
+      if(buffer) {
+         unsigned current_size = buffer->size;
+         const void *current_data = llvmpipe_buffer(buffer)->data;
+
+         /* TODO: copy only the actually used constants? */
+
+         if(setup->constants.stored_size != current_size ||
+            !setup->constants.stored_data ||
+            memcmp(setup->constants.stored_data,
+                   current_data,
+                   current_size) != 0) {
+            void *stored;
+
+            stored = get_data(&setup->data, current_size);
+            if(stored) {
+               memcpy(stored,
+                      current_data,
+                      current_size);
+               setup->constants.stored_size = current_size;
+               setup->constants.stored_data = stored;
+            }
+         }
+      }
+      else {
+         setup->constants.stored_size = 0;
+         setup->constants.stored_data = NULL;
+      }
+
+      setup->fs.current.jit_context.constants = setup->constants.stored_data;
+      setup->dirty |= LP_SETUP_NEW_FS;
+   }
+
+
+   if(setup->dirty & LP_SETUP_NEW_FS) {
       if(!setup->fs.stored ||
          memcmp(setup->fs.stored,
                 &setup->fs.current,
@@ -539,10 +573,10 @@ lp_setup_update_shader_state( struct setup_context *setup )
             setup->fs.stored = stored;
          }
       }
-
-      setup->fs.dirty = FALSE;
    }
 
+   setup->dirty = 0;
+
    assert(setup->fs.stored);
 }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index c15a59e..82ec71f 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -43,6 +43,10 @@
 #define DATA_BLOCK_SIZE (16 * 1024 - sizeof(unsigned) - sizeof(void *))
    
 
+#define LP_SETUP_NEW_FS        0x01
+#define LP_SETUP_NEW_CONSTANTS 0x02
+
+
 /* switch to a non-pointer value for this:
  */
 typedef void (*lp_rast_cmd)( struct lp_rasterizer *, const union lp_rast_cmd_arg );
@@ -112,9 +116,16 @@ struct setup_context {
 
       const struct lp_rast_state *stored;
       struct lp_rast_state current;
-      boolean dirty;
    } fs;
 
+   struct {
+      struct pipe_buffer *current;
+      unsigned stored_size;
+      const void *stored_data;
+   } constants;
+
+   unsigned dirty;
+
    void (*point)( struct setup_context *,
                   const float (*v0)[4]);
 




More information about the mesa-commit mailing list