aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
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_setup.c49
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c3
8 files changed, 100 insertions, 2 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 7a2f2539842..8127b16261b 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -82,6 +82,8 @@ struct llvmpipe_context {
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_shader_buffer ssbos[PIPE_SHADER_TYPES][LP_MAX_TGSI_SHADER_BUFFERS];
+
unsigned num_samplers[PIPE_SHADER_TYPES];
unsigned num_sampler_views[PIPE_SHADER_TYPES];
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index e72e119c8a1..a3c9960bcaf 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -664,6 +664,26 @@ lp_setup_set_fs_constants(struct lp_setup_context *setup,
setup->dirty |= LP_SETUP_NEW_CONSTANTS;
}
+void
+lp_setup_set_fs_ssbos(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_shader_buffer *buffers)
+{
+ unsigned i;
+
+ LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffers);
+
+ assert(num <= ARRAY_SIZE(setup->ssbos));
+
+ for (i = 0; i < num; ++i) {
+ util_copy_shader_buffer(&setup->ssbos[i].current, &buffers[i]);
+ }
+ for (; i < ARRAY_SIZE(setup->ssbos); i++) {
+ util_copy_shader_buffer(&setup->ssbos[i].current, NULL);
+ }
+ setup->dirty |= LP_SETUP_NEW_SSBOS;
+}
+
void
lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
@@ -992,6 +1012,11 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
}
}
+ for (i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
+ if (setup->ssbos[i].current.buffer == texture)
+ return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
+ }
+
return LP_UNREFERENCED;
}
@@ -1135,7 +1160,27 @@ try_update_scene_state( struct lp_setup_context *setup )
}
}
+ if (setup->dirty & LP_SETUP_NEW_SSBOS) {
+ for (i = 0; i < ARRAY_SIZE(setup->ssbos); ++i) {
+ struct pipe_resource *buffer = setup->ssbos[i].current.buffer;
+ const ubyte *current_data = NULL;
+
+ if (!buffer)
+ continue;
+ /* resource buffer */
+ current_data = (ubyte *) llvmpipe_resource_data(buffer);
+ if (current_data) {
+ current_data += setup->ssbos[i].current.buffer_offset;
+ setup->fs.current.jit_context.ssbos[i] = (const uint32_t *)current_data;
+ setup->fs.current.jit_context.num_ssbos[i] = setup->ssbos[i].current.buffer_size;
+ } else {
+ setup->fs.current.jit_context.ssbos[i] = NULL;
+ setup->fs.current.jit_context.num_ssbos[i] = 0;
+ }
+ setup->dirty |= LP_SETUP_NEW_FS;
+ }
+ }
if (setup->dirty & LP_SETUP_NEW_FS) {
if (!setup->fs.stored ||
memcmp(setup->fs.stored,
@@ -1287,6 +1332,10 @@ lp_setup_destroy( struct lp_setup_context *setup )
pipe_resource_reference(&setup->constants[i].current.buffer, NULL);
}
+ for (i = 0; i < ARRAY_SIZE(setup->ssbos); i++) {
+ pipe_resource_reference(&setup->ssbos[i].current.buffer, NULL);
+ }
+
/* free the scenes in the 'empty' queue */
for (i = 0; i < ARRAY_SIZE(setup->scenes); i++) {
struct lp_scene *scene = setup->scenes[i];
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index a42df2dc9e0..7ee50718b66 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -105,6 +105,11 @@ lp_setup_set_fs_constants(struct lp_setup_context *setup,
struct pipe_constant_buffer *buffers);
void
+lp_setup_set_fs_ssbos(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_shader_buffer *buffers);
+
+void
lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
float alpha_ref_value );
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 4b55fd922c8..9c8dde5b6ae 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -49,7 +49,7 @@
#define LP_SETUP_NEW_BLEND_COLOR 0x04
#define LP_SETUP_NEW_SCISSOR 0x08
#define LP_SETUP_NEW_VIEWPORTS 0x10
-
+#define LP_SETUP_NEW_SSBOS 0x20
struct lp_setup_variant;
@@ -143,6 +143,11 @@ struct lp_setup_context
const void *stored_data;
} constants[LP_MAX_TGSI_CONST_BUFFERS];
+ /** fragment shader buffers */
+ struct {
+ struct pipe_shader_buffer current;
+ } ssbos[LP_MAX_TGSI_SHADER_BUFFERS];
+
struct {
struct pipe_blend_color current;
uint8_t *stored;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index f15d70df7d0..1c3191b983f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -56,6 +56,7 @@
#define LP_NEW_GS 0x10000
#define LP_NEW_SO 0x20000
#define LP_NEW_SO_BUFFERS 0x40000
+#define LP_NEW_FS_SSBOS 0x80000
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 4bcca907244..f93bc434c64 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -255,6 +255,11 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]),
llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
+ if (llvmpipe->dirty & LP_NEW_FS_SSBOS)
+ lp_setup_set_fs_ssbos(llvmpipe->setup,
+ ARRAY_SIZE(llvmpipe->ssbos[PIPE_SHADER_FRAGMENT]),
+ llvmpipe->ssbos[PIPE_SHADER_FRAGMENT]);
+
if (llvmpipe->dirty & (LP_NEW_SAMPLER_VIEW))
lp_setup_set_fragment_sampler_views(llvmpipe->setup,
llvmpipe->num_sampler_views[PIPE_SHADER_FRAGMENT],
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index cf54d034fa5..6934c12c243 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -3141,6 +3141,34 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
}
}
+static void
+llvmpipe_set_shader_buffers(struct pipe_context *pipe,
+ enum pipe_shader_type shader, unsigned start_slot,
+ unsigned count, const struct pipe_shader_buffer *buffers,
+ unsigned writable_bitmask)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ unsigned i, idx;
+ for (i = start_slot, idx = 0; i < start_slot + count; i++, idx++) {
+ const struct pipe_shader_buffer *buffer = buffers ? &buffers[idx] : NULL;
+
+ util_copy_shader_buffer(&llvmpipe->ssbos[shader][i], buffer);
+
+ if (shader == PIPE_SHADER_VERTEX ||
+ shader == PIPE_SHADER_GEOMETRY) {
+ const unsigned size = buffer ? buffer->buffer_size : 0;
+ const ubyte *data = NULL;
+ if (buffer && buffer->buffer)
+ data = (ubyte *) llvmpipe_resource_data(buffer->buffer);
+ if (data)
+ data += buffer->buffer_offset;
+ draw_set_mapped_shader_buffer(llvmpipe->draw, shader,
+ i, data, size);
+ } else if (shader == PIPE_SHADER_FRAGMENT) {
+ llvmpipe->dirty |= LP_NEW_FS_SSBOS;
+ }
+ }
+}
/**
* Return the blend factor equivalent to a destination alpha of one.
@@ -3484,6 +3512,8 @@ llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe)
llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
+
+ llvmpipe->pipe.set_shader_buffers = llvmpipe_set_shader_buffers;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 89852cc95c3..4dc7eb39f8f 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -646,7 +646,8 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe,
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL |
PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_SAMPLER_VIEW)))
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_SHADER_BUFFER)))
return LP_UNREFERENCED;
return lp_setup_is_resource_referenced(llvmpipe->setup, presource);