gallium: add interface for writable shader images

PIPE_CAPs will be added some other time.

Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Marek Olšák
2015-07-05 14:48:33 +02:00
parent b73bec0ecd
commit 05a12c53a3
10 changed files with 120 additions and 27 deletions

View 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)); 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 void
debug_describe_so_target(char* buf, debug_describe_so_target(char* buf,
const struct pipe_stream_output_target *ptr) const struct pipe_stream_output_target *ptr)

View File

@@ -35,12 +35,14 @@ struct pipe_reference;
struct pipe_resource; struct pipe_resource;
struct pipe_surface; struct pipe_surface;
struct pipe_sampler_view; struct pipe_sampler_view;
struct pipe_image_view;
/* a 256-byte buffer is necessary and sufficient */ /* a 256-byte buffer is necessary and sufficient */
void debug_describe_reference(char* buf, const struct pipe_reference*ptr); 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_resource(char* buf, const struct pipe_resource *ptr);
void debug_describe_surface(char* buf, const struct pipe_surface *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_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, void debug_describe_so_target(char* buf,
const struct pipe_stream_output_target *ptr); const struct pipe_stream_output_target *ptr);

View File

@@ -153,6 +153,9 @@ void
util_dump_surface(FILE *stream, util_dump_surface(FILE *stream,
const struct pipe_surface *state); const struct pipe_surface *state);
void
util_dump_image_view(FILE *stream, const struct pipe_image_view *state);
void void
util_dump_transfer(FILE *stream, util_dump_transfer(FILE *stream,
const struct pipe_transfer *state); const struct pipe_transfer *state);

View 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 void
util_dump_transfer(FILE *stream, const struct pipe_transfer *state) util_dump_transfer(FILE *stream, const struct pipe_transfer *state)
{ {

View File

@@ -173,6 +173,16 @@ pipe_sampler_view_release(struct pipe_context *ctx,
*ptr = NULL; *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 static INLINE void
pipe_so_target_reference(struct pipe_stream_output_target **ptr, pipe_so_target_reference(struct pipe_stream_output_target **ptr,

View 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 have no support for floating point coordinates, address wrap modes or
filtering. filtering.
Shader resources are specified for all the shader stages at once using There are 2 types of shader resources: buffers and images.
the ``set_shader_resources`` method. When binding texture resources,
the ``level``, ``first_layer`` and ``last_layer`` pipe_surface fields Buffers are specified using the ``set_shader_buffers`` method.
specify the mipmap level and the range of layers the texture will be
constrained to. In the case of buffers, ``first_element`` and Images are specified using the ``set_shader_images`` method. When binding
``last_element`` specify the range within the buffer that will be used images, the ``level``, ``first_layer`` and ``last_layer`` pipe_image_view
by the shader resource. Writes to a shader resource are only allowed fields specify the mipmap level and the range of layers the image will be
when the ``writable`` flag is set. constrained to.
Surfaces Surfaces
^^^^^^^^ ^^^^^^^^

View File

@@ -1849,10 +1849,11 @@ ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
} }
static void static void
ilo_set_shader_resources(struct pipe_context *pipe, ilo_set_shader_images(struct pipe_context *pipe, unsigned shader,
unsigned start, unsigned count, unsigned start, unsigned count,
struct pipe_surface **surfaces) struct pipe_image_view **views)
{ {
#if 0
struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
struct ilo_resource_state *dst = &vec->resource; struct ilo_resource_state *dst = &vec->resource;
unsigned i; unsigned i;
@@ -1881,6 +1882,7 @@ ilo_set_shader_resources(struct pipe_context *pipe,
} }
vec->dirty |= ILO_DIRTY_RESOURCE; vec->dirty |= ILO_DIRTY_RESOURCE;
#endif
} }
static void 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_scissor_states = ilo_set_scissor_states;
ilo->base.set_viewport_states = ilo_set_viewport_states; ilo->base.set_viewport_states = ilo_set_viewport_states;
ilo->base.set_sampler_views = ilo_set_sampler_views; 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_vertex_buffers = ilo_set_vertex_buffers;
ilo->base.set_index_buffer = ilo_set_index_buffer; ilo->base.set_index_buffer = ilo_set_index_buffer;

View File

@@ -1125,13 +1125,15 @@ nvc0_set_compute_resources(struct pipe_context *pipe,
} }
static void static void
nvc0_set_shader_resources(struct pipe_context *pipe, nvc0_set_shader_images(struct pipe_context *pipe,
unsigned start, unsigned nr, 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; nvc0_context(pipe)->dirty |= NVC0_NEW_SURFACES;
#endif
} }
static INLINE void 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_global_binding = nvc0_set_global_bindings;
pipe->set_compute_resources = nvc0_set_compute_resources; 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->sample_mask = ~0;
nvc0->min_samples = 1; nvc0->min_samples = 1;

View File

@@ -48,6 +48,7 @@ struct pipe_depth_stencil_alpha_state;
struct pipe_draw_info; struct pipe_draw_info;
struct pipe_fence_handle; struct pipe_fence_handle;
struct pipe_framebuffer_state; struct pipe_framebuffer_state;
struct pipe_image_view;
struct pipe_index_buffer; struct pipe_index_buffer;
struct pipe_query; struct pipe_query;
struct pipe_poly_stipple; struct pipe_poly_stipple;
@@ -236,20 +237,21 @@ struct pipe_context {
const float default_inner_level[2]); const float default_inner_level[2]);
/** /**
* Bind an array of shader resources that will be used by the * Bind an array of images that will be used by a shader.
* graphics pipeline. Any resources that were previously bound to * Any images that were previously bound to the specified range
* the specified range will be unbound after this call. * will be unbound.
* *
* \param start first resource to bind. * \param shader selects shader stage
* \param count number of consecutive resources to bind. * \param start_slot first image slot to bind.
* \param resources array of pointers to the resources to bind, it * \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 * should contain at least \a count elements
* unless it's NULL, in which case no new * unless it's NULL, in which case no images will
* resources will be bound. * be bound.
*/ */
void (*set_shader_resources)(struct pipe_context *, void (*set_shader_images)(struct pipe_context *, unsigned shader,
unsigned start, unsigned count, unsigned start_slot, unsigned count,
struct pipe_surface **resources); struct pipe_image_view **images);
void (*set_vertex_buffers)( struct pipe_context *, void (*set_vertex_buffers)( struct pipe_context *,
unsigned start_slot, unsigned start_slot,
@@ -397,6 +399,17 @@ struct pipe_context {
void (*surface_destroy)(struct pipe_context *ctx, void (*surface_destroy)(struct pipe_context *ctx,
struct pipe_surface *); 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. * Map a resource.
* *

View 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. * Subregion of 1D/2D/3D image resource.
*/ */