From 05a12c53a308965aba1c00f0caf36d8e0f32e035 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sun, 5 Jul 2015 14:48:33 +0200 Subject: gallium: add interface for writable shader images PIPE_CAPs will be added some other time. Reviewed-by: Ilia Mirkin --- src/gallium/auxiliary/util/u_debug_describe.c | 9 +++++++ src/gallium/auxiliary/util/u_debug_describe.h | 2 ++ src/gallium/auxiliary/util/u_dump.h | 3 +++ src/gallium/auxiliary/util/u_dump_state.c | 27 +++++++++++++++++++++ src/gallium/auxiliary/util/u_inlines.h | 10 ++++++++ src/gallium/docs/source/context.rst | 16 ++++++------ src/gallium/drivers/ilo/ilo_state.c | 10 +++++--- src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 10 +++++--- src/gallium/include/pipe/p_context.h | 35 ++++++++++++++++++--------- src/gallium/include/pipe/p_state.h | 25 +++++++++++++++++++ 10 files changed, 120 insertions(+), 27 deletions(-) (limited to 'src/gallium') 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 @@ -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) 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 @@ -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); 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 @@ -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) { 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, @@ -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. * 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 @@ -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. */ -- cgit v1.2.3