diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 462aca31246..2708565aecb 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -609,6 +609,44 @@ zink_set_shader_buffers(struct pipe_context *pctx, } } +static void +zink_set_shader_images(struct pipe_context *pctx, + enum pipe_shader_type p_stage, + unsigned start_slot, unsigned count, + const struct pipe_image_view *images) +{ + struct zink_context *ctx = zink_context(pctx); + + for (unsigned i = 0; i < count; i++) { + struct zink_image_view *image_view = &ctx->image_views[p_stage][start_slot + i]; + if (images && images[i].resource) { + struct zink_resource *res = zink_resource(images[i].resource); + util_copy_image_view(&image_view->base, images + i); + if (images[i].resource->target == PIPE_BUFFER) { + image_view->buffer_view = create_buffer_view(zink_screen(pctx->screen), res, images[i].format, images[i].u.buf.offset, images[i].u.buf.size); + assert(image_view->buffer_view); + } else { + struct pipe_surface tmpl = {}; + tmpl.format = images[i].format; + tmpl.nr_samples = 1; + tmpl.u.tex.level = images[i].u.tex.level; + tmpl.u.tex.first_layer = images[i].u.tex.first_layer; + tmpl.u.tex.last_layer = images[i].u.tex.last_layer; + image_view->surface = zink_surface(pctx->create_surface(pctx, &res->base, &tmpl)); + assert(image_view->surface); + } + } else if (image_view->base.resource) { + if (image_view->base.resource->target == PIPE_BUFFER) + vkDestroyBufferView(zink_screen(pctx->screen)->dev, image_view->buffer_view, NULL); + else + pipe_surface_reference((struct pipe_surface**)&image_view->surface, NULL); + pipe_resource_reference(&image_view->base.resource, NULL); + image_view->base.resource = NULL; + image_view->surface = NULL; + } + } +} + static void zink_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader_type, @@ -1414,6 +1452,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.set_scissor_states = zink_set_scissor_states; ctx->base.set_constant_buffer = zink_set_constant_buffer; ctx->base.set_shader_buffers = zink_set_shader_buffers; + ctx->base.set_shader_images = zink_set_shader_images; ctx->base.set_framebuffer_state = zink_set_framebuffer_state; ctx->base.set_stencil_ref = zink_set_stencil_ref; ctx->base.set_clip_state = zink_set_clip_state; diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index a29232f4fe6..7f6d85858f5 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -44,6 +44,7 @@ struct zink_depth_stencil_alpha_state; struct zink_gfx_program; struct zink_rasterizer_state; struct zink_resource; +struct zink_surface; struct zink_vertex_elements_state; enum zink_blit_flags { @@ -60,6 +61,14 @@ struct zink_sampler_view { }; }; +struct zink_image_view { + struct pipe_image_view base; + union { + struct zink_surface *surface; + VkBufferView buffer_view; + }; +}; + static inline struct zink_sampler_view * zink_sampler_view(struct pipe_sampler_view *pview) { @@ -99,6 +108,7 @@ struct zink_context { struct pipe_constant_buffer ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_shader_buffer ssbos[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS]; uint32_t writable_ssbos; + struct zink_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES]; struct pipe_framebuffer_state fb_state; struct zink_vertex_elements_state *element_state;