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];
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,
}
}
+ 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;
}
}
}
+ 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,
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];
unsigned num,
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 );
#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;
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;
#define LP_NEW_GS 0x10000
#define LP_NEW_SO 0x20000
#define LP_NEW_SO_BUFFERS 0x40000
+#define LP_NEW_FS_SSBOS 0x80000
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],
}
}
+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.
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;
}
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);