summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2015-07-05 14:48:33 +0200
committerMarek Olšák <[email protected]>2015-07-16 16:52:20 +0200
commit05a12c53a308965aba1c00f0caf36d8e0f32e035 (patch)
tree7914bcae5a16fff973d438326b3cc9749de8d22b
parentb73bec0ecd43861337daf9663e242d2b44f36dbd (diff)
gallium: add interface for writable shader images
PIPE_CAPs will be added some other time. Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/auxiliary/util/u_debug_describe.c9
-rw-r--r--src/gallium/auxiliary/util/u_debug_describe.h2
-rw-r--r--src/gallium/auxiliary/util/u_dump.h3
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c27
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h10
-rw-r--r--src/gallium/docs/source/context.rst16
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c10
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c10
-rw-r--r--src/gallium/include/pipe/p_context.h35
-rw-r--r--src/gallium/include/pipe/p_state.h25
10 files changed, 120 insertions, 27 deletions
diff --git a/src/gallium/auxiliary/util/u_debug_describe.c b/src/gallium/auxiliary/util/u_debug_describe.c
index df73ed83ef6..f428d22d205 100644
--- a/src/gallium/auxiliary/util/u_debug_describe.c
+++ b/src/gallium/auxiliary/util/u_debug_describe.c
@@ -81,6 +81,15 @@ debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr)
}
void
+debug_describe_image_view(char* buf, const struct pipe_image_view *ptr)
+{
+ char res[128];
+ debug_describe_resource(res, ptr->resource);
+ util_sprintf(buf, "pipe_image_view<%s,%s>", res,
+ util_format_short_name(ptr->format));
+}
+
+void
debug_describe_so_target(char* buf,
const struct pipe_stream_output_target *ptr)
{
diff --git a/src/gallium/auxiliary/util/u_debug_describe.h b/src/gallium/auxiliary/util/u_debug_describe.h
index 4f7882b0b37..2172ecb4395 100644
--- a/src/gallium/auxiliary/util/u_debug_describe.h
+++ b/src/gallium/auxiliary/util/u_debug_describe.h
@@ -35,12 +35,14 @@ struct pipe_reference;
struct pipe_resource;
struct pipe_surface;
struct pipe_sampler_view;
+struct pipe_image_view;
/* a 256-byte buffer is necessary and sufficient */
void debug_describe_reference(char* buf, const struct pipe_reference*ptr);
void debug_describe_resource(char* buf, const struct pipe_resource *ptr);
void debug_describe_surface(char* buf, const struct pipe_surface *ptr);
void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr);
+void debug_describe_image_view(char* buf, const struct pipe_image_view *ptr);
void debug_describe_so_target(char* buf,
const struct pipe_stream_output_target *ptr);
diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h
index 58e7dfd8244..3ddf518fa2b 100644
--- a/src/gallium/auxiliary/util/u_dump.h
+++ b/src/gallium/auxiliary/util/u_dump.h
@@ -154,6 +154,9 @@ util_dump_surface(FILE *stream,
const struct pipe_surface *state);
void
+util_dump_image_view(FILE *stream, const struct pipe_image_view *state);
+
+void
util_dump_transfer(FILE *stream,
const struct pipe_transfer *state);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index 7f620b50cf0..88027cbbc79 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -672,6 +672,33 @@ util_dump_surface(FILE *stream, const struct pipe_surface *state)
void
+util_dump_image_view(FILE *stream, const struct pipe_image_view *state)
+{
+ if (!state) {
+ util_dump_null(stream);
+ return;
+ }
+
+ util_dump_struct_begin(stream, "pipe_image_view");
+
+ util_dump_member(stream, ptr, state, resource);
+ util_dump_member(stream, format, state, format);
+
+ if (state->resource->target == PIPE_BUFFER) {
+ util_dump_member(stream, uint, state, u.buf.first_element);
+ util_dump_member(stream, uint, state, u.buf.last_element);
+ }
+ else {
+ util_dump_member(stream, uint, state, u.tex.first_layer);
+ util_dump_member(stream, uint, state, u.tex.last_layer);
+ util_dump_member(stream, uint, state, u.tex.level);
+ }
+
+ util_dump_struct_end(stream);
+}
+
+
+void
util_dump_transfer(FILE *stream, const struct pipe_transfer *state)
{
if(!state) {
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 95401621ec3..661a949a4b1 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -173,6 +173,16 @@ pipe_sampler_view_release(struct pipe_context *ctx,
*ptr = NULL;
}
+static INLINE void
+pipe_image_view_reference(struct pipe_image_view **ptr, struct pipe_image_view *view)
+{
+ struct pipe_image_view *old_view = *ptr;
+
+ if (pipe_reference_described(&(*ptr)->reference, &view->reference,
+ (debug_reference_descriptor)debug_describe_image_view))
+ old_view->context->image_view_destroy(old_view->context, old_view);
+ *ptr = view;
+}
static INLINE void
pipe_so_target_reference(struct pipe_stream_output_target **ptr,
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 0908ee7e058..a7d08d2c7f9 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -131,14 +131,14 @@ from a shader without an associated sampler. This means that they
have no support for floating point coordinates, address wrap modes or
filtering.
-Shader resources are specified for all the shader stages at once using
-the ``set_shader_resources`` method. When binding texture resources,
-the ``level``, ``first_layer`` and ``last_layer`` pipe_surface fields
-specify the mipmap level and the range of layers the texture will be
-constrained to. In the case of buffers, ``first_element`` and
-``last_element`` specify the range within the buffer that will be used
-by the shader resource. Writes to a shader resource are only allowed
-when the ``writable`` flag is set.
+There are 2 types of shader resources: buffers and images.
+
+Buffers are specified using the ``set_shader_buffers`` method.
+
+Images are specified using the ``set_shader_images`` method. When binding
+images, the ``level``, ``first_layer`` and ``last_layer`` pipe_image_view
+fields specify the mipmap level and the range of layers the image will be
+constrained to.
Surfaces
^^^^^^^^
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index c13fa9c2e18..d89765a9d23 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -1849,10 +1849,11 @@ ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
}
static void
-ilo_set_shader_resources(struct pipe_context *pipe,
- unsigned start, unsigned count,
- struct pipe_surface **surfaces)
+ilo_set_shader_images(struct pipe_context *pipe, unsigned shader,
+ unsigned start, unsigned count,
+ struct pipe_image_view **views)
{
+#if 0
struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
struct ilo_resource_state *dst = &vec->resource;
unsigned i;
@@ -1881,6 +1882,7 @@ ilo_set_shader_resources(struct pipe_context *pipe,
}
vec->dirty |= ILO_DIRTY_RESOURCE;
+#endif
}
static void
@@ -2345,7 +2347,7 @@ ilo_init_state_functions(struct ilo_context *ilo)
ilo->base.set_scissor_states = ilo_set_scissor_states;
ilo->base.set_viewport_states = ilo_set_viewport_states;
ilo->base.set_sampler_views = ilo_set_sampler_views;
- ilo->base.set_shader_resources = ilo_set_shader_resources;
+ ilo->base.set_shader_images = ilo_set_shader_images;
ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
ilo->base.set_index_buffer = ilo_set_index_buffer;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 6b7a211e71b..337559c3be8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -1125,13 +1125,15 @@ nvc0_set_compute_resources(struct pipe_context *pipe,
}
static void
-nvc0_set_shader_resources(struct pipe_context *pipe,
+nvc0_set_shader_images(struct pipe_context *pipe,
unsigned start, unsigned nr,
- struct pipe_surface **resources)
+ struct pipe_image_view **views)
{
- nvc0_bind_surfaces_range(nvc0_context(pipe), 0, start, nr, resources);
+#if 0
+ nvc0_bind_surfaces_range(nvc0_context(pipe), 0, start, nr, views);
nvc0_context(pipe)->dirty |= NVC0_NEW_SURFACES;
+#endif
}
static INLINE void
@@ -1253,7 +1255,7 @@ nvc0_init_state_functions(struct nvc0_context *nvc0)
pipe->set_global_binding = nvc0_set_global_bindings;
pipe->set_compute_resources = nvc0_set_compute_resources;
- pipe->set_shader_resources = nvc0_set_shader_resources;
+ pipe->set_shader_images = nvc0_set_shader_images;
nvc0->sample_mask = ~0;
nvc0->min_samples = 1;
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index d2c2e4c8d14..76873956cc0 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -48,6 +48,7 @@ struct pipe_depth_stencil_alpha_state;
struct pipe_draw_info;
struct pipe_fence_handle;
struct pipe_framebuffer_state;
+struct pipe_image_view;
struct pipe_index_buffer;
struct pipe_query;
struct pipe_poly_stipple;
@@ -236,20 +237,21 @@ struct pipe_context {
const float default_inner_level[2]);
/**
- * Bind an array of shader resources that will be used by the
- * graphics pipeline. Any resources that were previously bound to
- * the specified range will be unbound after this call.
+ * Bind an array of images that will be used by a shader.
+ * Any images that were previously bound to the specified range
+ * will be unbound.
*
- * \param start first resource to bind.
- * \param count number of consecutive resources to bind.
- * \param resources array of pointers to the resources to bind, it
+ * \param shader selects shader stage
+ * \param start_slot first image slot to bind.
+ * \param count number of consecutive images to bind.
+ * \param buffers array of pointers to the images to bind, it
* should contain at least \a count elements
- * unless it's NULL, in which case no new
- * resources will be bound.
+ * unless it's NULL, in which case no images will
+ * be bound.
*/
- void (*set_shader_resources)(struct pipe_context *,
- unsigned start, unsigned count,
- struct pipe_surface **resources);
+ void (*set_shader_images)(struct pipe_context *, unsigned shader,
+ unsigned start_slot, unsigned count,
+ struct pipe_image_view **images);
void (*set_vertex_buffers)( struct pipe_context *,
unsigned start_slot,
@@ -398,6 +400,17 @@ struct pipe_context {
struct pipe_surface *);
/**
+ * Create an image view into a buffer or texture to be used with load,
+ * store, and atomic instructions by a shader stage.
+ */
+ struct pipe_image_view * (*create_image_view)(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ const struct pipe_image_view *templat);
+
+ void (*image_view_destroy)(struct pipe_context *ctx,
+ struct pipe_image_view *view);
+
+ /**
* Map a resource.
*
* Transfers are (by default) context-private and allow uploads to be
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 1c529f7d078..78dc5785332 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -389,6 +389,31 @@ struct pipe_sampler_view
/**
+ * A view into a writable buffer or texture that can be bound to a shader
+ * stage.
+ */
+struct pipe_image_view
+{
+ struct pipe_reference reference;
+ struct pipe_resource *resource; /**< resource into which this is a view */
+ struct pipe_context *context; /**< context this view belongs to */
+ enum pipe_format format; /**< typed PIPE_FORMAT_x */
+
+ union {
+ struct {
+ unsigned first_layer:16; /**< first layer to use for array textures */
+ unsigned last_layer:16; /**< last layer to use for array textures */
+ unsigned level:8; /**< mipmap level to use */
+ } tex;
+ struct {
+ unsigned first_element;
+ unsigned last_element;
+ } buf;
+ } u;
+};
+
+
+/**
* Subregion of 1D/2D/3D image resource.
*/
struct pipe_box