summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2012-12-04 14:52:44 +0000
committerJosé Fonseca <[email protected]>2012-12-07 15:03:07 +0000
commit1d35f77228ad540a551a8e09e062b764a6e31f5e (patch)
treea9128d5c57a248616077b3977ef88b5e45e33b6d /src/gallium/drivers/llvmpipe
parent35840ab189595b817fa8b1a1df8cc92474a7c38d (diff)
gallivm,llvmpipe,draw: Support multiple constant buffers.
Support 16 (defined in LP_MAX_TGSI_CONST_BUFFERS) as opposed to 32 (as defined by PIPE_MAX_CONSTANT_BUFFERS) because that would make the jit context become unnecessarily large. v2: Bump limit from 4 to 16 to cover ARB_uniform_buffer_object needs, per Dave Airlie. Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c90
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c2
8 files changed, 66 insertions, 46 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 25cdff998c4..5afa4360aae 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -72,7 +72,7 @@ struct llvmpipe_context {
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
struct pipe_clip_state clip;
- struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
+ struct pipe_resource *constants[PIPE_SHADER_TYPES][LP_MAX_TGSI_CONST_BUFFERS];
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 2667aeb24e6..ea7c8054bfa 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -124,7 +124,8 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
LLVMTypeRef context_type;
- elem_types[LP_JIT_CTX_CONSTANTS] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0);
+ elem_types[LP_JIT_CTX_CONSTANTS] =
+ LLVMArrayType(LLVMPointerType(LLVMFloatTypeInContext(lc), 0), LP_MAX_TGSI_CONST_BUFFERS);
elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc);
elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] =
elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index b4699074656..5dc5bc4c4bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -37,6 +37,7 @@
#include "gallivm/lp_bld_struct.h"
+#include "gallivm/lp_bld_limits.h"
#include "pipe/p_state.h"
#include "lp_texture.h"
@@ -97,7 +98,7 @@ enum {
*/
struct lp_jit_context
{
- const float *constants;
+ const float *constants[LP_MAX_TGSI_CONST_BUFFERS];
float alpha_ref_value;
@@ -127,7 +128,7 @@ enum {
#define lp_jit_context_constants(_gallivm, _ptr) \
- lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
+ lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
#define lp_jit_context_alpha_ref_value(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_ALPHA_REF, "alpha_ref_value")
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 0f497afac53..7d40d8cf661 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -120,11 +120,15 @@ first_point( struct lp_setup_context *setup,
void lp_setup_reset( struct lp_setup_context *setup )
{
+ unsigned i;
+
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
/* Reset derived state */
- setup->constants.stored_size = 0;
- setup->constants.stored_data = NULL;
+ for (i = 0; i < Elements(setup->constants); ++i) {
+ setup->constants[i].stored_size = 0;
+ setup->constants[i].stored_data = NULL;
+ }
setup->fs.stored = NULL;
setup->dirty = ~0;
@@ -549,13 +553,21 @@ lp_setup_set_fs_variant( struct lp_setup_context *setup,
void
lp_setup_set_fs_constants(struct lp_setup_context *setup,
- struct pipe_resource *buffer)
+ unsigned num,
+ struct pipe_resource **buffers)
{
- LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer);
+ unsigned i;
+
+ LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffers);
- pipe_resource_reference(&setup->constants.current, buffer);
+ assert(num <= Elements(setup->constants));
- setup->dirty |= LP_SETUP_NEW_CONSTANTS;
+ for (i = 0; i < num; ++i) {
+ if (setup->constants[i].current != buffers[i]) {
+ pipe_resource_reference(&setup->constants[i].current, buffers[i]);
+ setup->dirty |= LP_SETUP_NEW_CONSTANTS;
+ }
+ }
}
@@ -820,6 +832,7 @@ try_update_scene_state( struct lp_setup_context *setup )
{
boolean new_scene = (setup->fs.stored == NULL);
struct lp_scene *scene = setup->scene;
+ unsigned i;
assert(scene);
@@ -858,42 +871,44 @@ try_update_scene_state( struct lp_setup_context *setup )
setup->dirty |= LP_SETUP_NEW_FS;
}
- if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
- struct pipe_resource *buffer = setup->constants.current;
+ if (setup->dirty & LP_SETUP_NEW_CONSTANTS) {
+ for (i = 0; i < Elements(setup->constants); ++i) {
+ struct pipe_resource *buffer = setup->constants[i].current;
- if(buffer) {
- unsigned current_size = buffer->width0;
- const void *current_data = llvmpipe_resource_data(buffer);
+ if (buffer) {
+ unsigned current_size = buffer->width0;
+ const void *current_data = llvmpipe_resource_data(buffer);
- /* TODO: copy only the actually used constants? */
+ /* 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;
+ if (setup->constants[i].stored_size != current_size ||
+ !setup->constants[i].stored_data ||
+ memcmp(setup->constants[i].stored_data,
+ current_data,
+ current_size) != 0) {
+ void *stored;
- stored = lp_scene_alloc(scene, current_size);
- if (!stored) {
- assert(!new_scene);
- return FALSE;
- }
+ stored = lp_scene_alloc(scene, current_size);
+ if (!stored) {
+ assert(!new_scene);
+ return FALSE;
+ }
- memcpy(stored,
- current_data,
- current_size);
- setup->constants.stored_size = current_size;
- setup->constants.stored_data = stored;
+ memcpy(stored,
+ current_data,
+ current_size);
+ setup->constants[i].stored_size = current_size;
+ setup->constants[i].stored_data = stored;
+ }
+ }
+ else {
+ setup->constants[i].stored_size = 0;
+ setup->constants[i].stored_data = NULL;
}
- }
- 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;
+ setup->fs.current.jit_context.constants[i] = setup->constants[i].stored_data;
+ setup->dirty |= LP_SETUP_NEW_FS;
+ }
}
@@ -904,7 +919,6 @@ try_update_scene_state( struct lp_setup_context *setup )
sizeof setup->fs.current) != 0)
{
struct lp_rast_state *stored;
- uint i;
/* The fs state that's been stored in the scene is different from
* the new, current state. So allocate a new lp_rast_state object
@@ -1039,7 +1053,9 @@ lp_setup_destroy( struct lp_setup_context *setup )
pipe_resource_reference(&setup->fs.current_tex[i], NULL);
}
- pipe_resource_reference(&setup->constants.current, NULL);
+ for (i = 0; i < Elements(setup->constants); i++) {
+ pipe_resource_reference(&setup->constants[i].current, NULL);
+ }
/* free the scenes in the 'empty' queue */
for (i = 0; i < Elements(setup->scenes); i++) {
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index c3dde804002..55fbd9be8b8 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -100,7 +100,8 @@ lp_setup_set_fs_variant( struct lp_setup_context *setup,
void
lp_setup_set_fs_constants(struct lp_setup_context *setup,
- struct pipe_resource *buffer);
+ unsigned num,
+ struct pipe_resource **buffers);
void
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index f810700ef29..60809db50a2 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -131,7 +131,7 @@ struct lp_setup_context
struct pipe_resource *current;
unsigned stored_size;
const void *stored_data;
- } constants;
+ } constants[LP_MAX_TGSI_CONST_BUFFERS];
struct {
struct pipe_blend_color current;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 3b826de80c9..aef222d20f6 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -174,8 +174,9 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
}
if (llvmpipe->dirty & LP_NEW_CONSTANTS)
- lp_setup_set_fs_constants(llvmpipe->setup,
- llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
+ lp_setup_set_fs_constants(llvmpipe->setup,
+ Elements(llvmpipe->constants[PIPE_SHADER_FRAGMENT]),
+ llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW))
lp_setup_set_fragment_sampler_views(llvmpipe->setup,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index f89f9525eee..dced5d25a7f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -2422,7 +2422,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
data = constants ? llvmpipe_resource_data(constants) : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+ assert(index < Elements(llvmpipe->constants[shader]));
if(llvmpipe->constants[shader][index] == constants)
return;