summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-10-18 11:57:43 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-10-18 11:57:43 +0100
commit2e3580d994e2caf6d81763803c8525a7ed42b8fd (patch)
tree64ccfa6ba7bc221d689c50357527fe6bf733bd14
parent0177c6e66cfddeb62feca86e7bd5ae763b9b5244 (diff)
llvmpipe: Maintain a copy of the shader constants to prevent clobbering.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c64
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h13
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 a74756de7c..08dac459db 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 c15a59e4d1..82ec71f100 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]);