[Mesa-dev] [RFC] gallium: add interface for writable shader images
Ilia Mirkin
imirkin at alum.mit.edu
Sun Jul 5 06:47:05 PDT 2015
On Sun, Jul 5, 2015 at 9:25 AM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Other approaches are being considered:
>
> 1) Don't use resource wrappers (views) and pass all view parameters
> (format, layer range, level) to set_shader_images just like
> set_vertex_buffers, set_constant_buffer, or even glBindImageTexture do.
>
> 2) Use pipe_sampler_view instead of pipe_image_view,
> and maybe even use set_sampler_views instead of set_shader_images.
> set_sampler_views would have to use start_slot >= PIPE_MAX_SAMPLERS for
> all writable images to allow for OpenGL textures in the lower slots.
>
> I wouldn't like to go back to using pipe_surface, because it doesn't fit
> into the DX12 hw design.
>
> Please discuss.
> ---
> diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
> index c2eedf8..13f3938 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 imagse 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 shader stage where the images will be bound.
> + * \param start_slot first iamage 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);
On Fermi, there is only one set of 8 images that can be bound,
irrespective of stage. There are a different set of 8 bindings for 3d
and compute pipelines though. Kepler+ is all bindless so it can do
whatever.
Even though I originally advocated for the stage argument, it appears
to neither match Fermi hardware nor the GL API where I believe images
are also in a global namespace.
>
> void (*set_vertex_buffers)( struct pipe_context *,
> unsigned start_slot,
> @@ -392,6 +394,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 dc8f550..f655dda 100644
> --- a/src/gallium/include/pipe/p_state.h
> +++ b/src/gallium/include/pipe/p_state.h
> @@ -386,6 +386,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;
> +};
This is an exact copy of pipe_surface, except for the
supposedly-removable width/height and "writable" bit, which should
probably make a comeback here.
Can you remind me what was wrong with pipe_surface? I seem to recall
that you were offended by its refcountedness, but that appears to have
stayed in this version.
-ilia
More information about the mesa-dev
mailing list