gallium: add interface for writable shader images
authorMarek Olšák <marek.olsak@amd.com>
Sun, 5 Jul 2015 12:48:33 +0000 (14:48 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 16 Jul 2015 14:52:20 +0000 (16:52 +0200)
PIPE_CAPs will be added some other time.

Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/auxiliary/util/u_debug_describe.c
src/gallium/auxiliary/util/u_debug_describe.h
src/gallium/auxiliary/util/u_dump.h
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_inlines.h
src/gallium/docs/source/context.rst
src/gallium/drivers/ilo/ilo_state.c
src/gallium/drivers/nouveau/nvc0/nvc0_state.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_state.h

index df73ed83ef612b52b6b48bc037d6c1959969478d..f428d22d20556564134b1f6bf3dc5c40b963302f 100644 (file)
@@ -80,6 +80,15 @@ debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr)
    util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format));
 }
 
+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)
index 4f7882b0b377bd79c2d41fec7fcdbdf19447f825..2172ecb43959d37104ac1e70e48a4f4b6ec659be 100644 (file)
@@ -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);
 
index 58e7dfd8244e4b9e125be52cb115668db3cdd08f..3ddf518fa2b319cd9b146d877322affbae7ae8ae 100644 (file)
@@ -153,6 +153,9 @@ void
 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);
index 7f620b50cf056b33befa1b9c0ce00e65e163c15c..88027cbbc79be59334627aa3dab3c7f191373ae7 100644 (file)
@@ -671,6 +671,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)
 {
index 95401621ec36e19ec598e0d541b12975e1863e8e..661a949a4b1a5ffac8d87d1889d9c19e4420d5de 100644 (file)
@@ -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,
index 0908ee7e0583f1d958fe0b55e172fb53250686d9..a7d08d2c7f9e59d6e8c16f4aa4472788655d92dc 100644 (file)
@@ -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
 ^^^^^^^^
index c13fa9c2e18f670877faf4dfe2dc39b38fa5805a..d89765a9d23fc516a2993d463c5ab20fb8f57875 100644 (file)
@@ -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;
 
index 6b7a211e71bd0ac7c5b9210fcc512ed672f88680..337559c3be82f119f365aa09d72785f351823998 100644 (file)
@@ -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;
index d2c2e4c8d144681f7b9b65ad6d4123f8e9b55746..76873956cc02b1fe564623171f2cf2e297b27710 100644 (file)
@@ -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,
@@ -397,6 +399,17 @@ struct pipe_context {
    void (*surface_destroy)(struct pipe_context *ctx,
                            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.
     *
index 1c529f7d0783393127fd4980aa303f9a5870b14a..78dc5785332a0c50c5381c89e45200336fc4d65f 100644 (file)
@@ -388,6 +388,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.
  */