gallium: add unbind_num_trailing_slots to set_shader_images
authorMarek Olšák <marek.olsak@amd.com>
Mon, 21 Dec 2020 08:01:34 +0000 (03:01 -0500)
committerMarge Bot <eric+marge@anholt.net>
Wed, 27 Jan 2021 23:53:34 +0000 (23:53 +0000)
Instead of calling this function again to unbind trailing slots,
extend it to do it when images are being set. This reduces CPU overhead.
Only st/mesa benefits.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8298>

28 files changed:
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/driver_ddebug/dd_context.c
src/gallium/auxiliary/driver_trace/tr_context.c
src/gallium/auxiliary/util/u_compute.c
src/gallium/auxiliary/util/u_tests.c
src/gallium/auxiliary/util/u_threaded_context.c
src/gallium/auxiliary/vl/vl_compositor_cs.c
src/gallium/drivers/freedreno/a6xx/fd6_image.c
src/gallium/drivers/freedreno/freedreno_state.c
src/gallium/drivers/freedreno/freedreno_state.h
src/gallium/drivers/iris/iris_state.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/nouveau/nvc0/nvc0_state.c
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/radeonsi/si_compute_blit.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/softpipe/sp_state_image.c
src/gallium/drivers/tegra/tegra_context.c
src/gallium/drivers/v3d/v3dx_state.c
src/gallium/drivers/virgl/virgl_context.c
src/gallium/drivers/zink/zink_context.c
src/gallium/frontends/clover/core/kernel.cpp
src/gallium/frontends/lavapipe/lvp_execute.c
src/gallium/frontends/omx/vid_enc_common.c
src/gallium/include/pipe/p_context.h
src/mesa/state_tracker/st_atom_image.c
src/mesa/state_tracker/st_cb_readpixels.c

index f2bb4dd..5ba9d59 100644 (file)
@@ -343,7 +343,7 @@ void cso_destroy_context( struct cso_context *ctx )
                ctx->pipe->set_shader_buffers(ctx->pipe, sh, 0, maxssbo, ssbos, 0);
             }
             if (maximg > 0) {
-               ctx->pipe->set_shader_images(ctx->pipe, sh, 0, maximg, NULL);
+               ctx->pipe->set_shader_images(ctx->pipe, sh, 0, 0, maximg, NULL);
             }
             for (int i = 0; i < maxcb; i++) {
                ctx->pipe->set_constant_buffer(ctx->pipe, sh, i, false, NULL);
index f96fe14..211133f 100644 (file)
@@ -524,6 +524,7 @@ static void
 dd_context_set_shader_images(struct pipe_context *_pipe,
                              enum pipe_shader_type shader,
                              unsigned start, unsigned num,
+                             unsigned unbind_num_trailing_slots,
                              const struct pipe_image_view *views)
 {
    struct dd_context *dctx = dd_context(_pipe);
@@ -531,7 +532,10 @@ dd_context_set_shader_images(struct pipe_context *_pipe,
 
    safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
                sizeof(views[0]) * num);
-   pipe->set_shader_images(pipe, shader, start, num, views);
+   safe_memcpy(&dctx->draw_state.shader_images[shader][start + num], NULL,
+               sizeof(views[0]) * unbind_num_trailing_slots);
+   pipe->set_shader_images(pipe, shader, start, num,
+                           unbind_num_trailing_slots, views);
 }
 
 static void
index a31da2c..3b81b70 100644 (file)
@@ -1772,6 +1772,7 @@ static void trace_context_set_shader_buffers(struct pipe_context *_context,
 static void trace_context_set_shader_images(struct pipe_context *_context,
                                             enum pipe_shader_type shader,
                                             unsigned start, unsigned nr,
+                                            unsigned unbind_num_trailing_slots,
                                             const struct pipe_image_view *images)
 {
    struct trace_context *tr_context = trace_context(_context);
@@ -1784,9 +1785,11 @@ static void trace_context_set_shader_images(struct pipe_context *_context,
    trace_dump_arg_begin("images");
    trace_dump_struct_array(image_view, images, nr);
    trace_dump_arg_end();
+   trace_dump_arg(uint, unbind_num_trailing_slots);
    trace_dump_call_end();
 
-   context->set_shader_images(context, shader, start, nr, images);
+   context->set_shader_images(context, shader, start, nr,
+                              unbind_num_trailing_slots, images);
 }
 
 static void trace_context_launch_grid(struct pipe_context *_pipe,
index 3da98ee..dcfc266 100644 (file)
@@ -118,7 +118,7 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf
    image.u.tex.first_layer = 0;
    image.u.tex.last_layer = (unsigned)(dst->array_size - 1);
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &image);
 
    struct pipe_sampler_state sampler_state={0};
    sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -157,7 +157,7 @@ void util_compute_blit(struct pipe_context *ctx, struct pipe_blit_info *blit_inf
 
    ctx->memory_barrier(ctx, PIPE_BARRIER_ALL);
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 0, 1, NULL);
    ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, NULL);
    ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL);
    pipe_sampler_view_reference(&src_view, NULL);
index 52f1ab4..f73123b 100644 (file)
@@ -834,7 +834,7 @@ test_compute_clear_image(struct pipe_context *ctx)
    image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE;
    image.format = cb->format;
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &image);
 
    /* Dispatch compute. */
    struct pipe_grid_info info = {0};
index 3e8d0b8..9c07888 100644 (file)
@@ -985,7 +985,7 @@ tc_set_sampler_views(struct pipe_context *_pipe,
 
 struct tc_shader_images {
    ubyte shader, start, count;
-   bool unbind;
+   ubyte unbind_num_trailing_slots;
    struct pipe_image_view slot[0]; /* more will be allocated if needed */
 };
 
@@ -995,12 +995,14 @@ tc_call_set_shader_images(struct pipe_context *pipe, union tc_payload *payload)
    struct tc_shader_images *p = (struct tc_shader_images *)payload;
    unsigned count = p->count;
 
-   if (p->unbind) {
-      pipe->set_shader_images(pipe, p->shader, p->start, p->count, NULL);
+   if (!p->count) {
+      pipe->set_shader_images(pipe, p->shader, p->start, 0,
+                              p->unbind_num_trailing_slots, NULL);
       return;
    }
 
-   pipe->set_shader_images(pipe, p->shader, p->start, p->count, p->slot);
+   pipe->set_shader_images(pipe, p->shader, p->start, p->count,
+                           p->unbind_num_trailing_slots, p->slot);
 
    for (unsigned i = 0; i < count; i++)
       pipe_resource_reference(&p->slot[i].resource, NULL);
@@ -1010,9 +1012,10 @@ static void
 tc_set_shader_images(struct pipe_context *_pipe,
                      enum pipe_shader_type shader,
                      unsigned start, unsigned count,
+                     unsigned unbind_num_trailing_slots,
                      const struct pipe_image_view *images)
 {
-   if (!count)
+   if (!count && !unbind_num_trailing_slots)
       return;
 
    struct threaded_context *tc = threaded_context(_pipe);
@@ -1022,10 +1025,11 @@ tc_set_shader_images(struct pipe_context *_pipe,
 
    p->shader = shader;
    p->start = start;
-   p->count = count;
-   p->unbind = images == NULL;
 
    if (images) {
+      p->count = count;
+      p->unbind_num_trailing_slots = unbind_num_trailing_slots;
+
       for (unsigned i = 0; i < count; i++) {
          tc_set_resource_reference(&p->slot[i].resource, images[i].resource);
 
@@ -1041,6 +1045,9 @@ tc_set_shader_images(struct pipe_context *_pipe,
          }
       }
       memcpy(p->slot, images, count * sizeof(images[0]));
+   } else {
+      p->count = 0;
+      p->unbind_num_trailing_slots = count + unbind_num_trailing_slots;
    }
 }
 
index 111cf4f..c8a375c 100644 (file)
@@ -597,7 +597,7 @@ cs_launch(struct vl_compositor *c,
    image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE;
    image.format = c->fb_state.cbufs[0]->texture->format;
 
-   ctx->set_shader_images(c->pipe, PIPE_SHADER_COMPUTE, 0, 1, &image);
+   ctx->set_shader_images(c->pipe, PIPE_SHADER_COMPUTE, 0, 1, 0, &image);
 
    /* Bind compute shader */
    ctx->bind_compute_state(ctx, cs);
@@ -732,7 +732,7 @@ draw_layers(struct vl_compositor       *c,
          cs_launch(c, layer->cs, &(drawn.area));
 
          /* Unbind. */
-         c->pipe->set_shader_images(c->pipe, PIPE_SHADER_COMPUTE, 0, 1, NULL);
+         c->pipe->set_shader_images(c->pipe, PIPE_SHADER_COMPUTE, 0, 0, 1, NULL);
          c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_COMPUTE, 0, false, NULL);
          c->pipe->set_sampler_views(c->pipe, PIPE_SHADER_FRAGMENT, 0,
                         num_sampler_views, NULL);
index 56824b3..1fa6bd0 100644 (file)
@@ -316,12 +316,14 @@ fd6_build_ibo_state(struct fd_context *ctx, const struct ir3_shader_variant *v,
 static void fd6_set_shader_images(struct pipe_context *pctx,
                enum pipe_shader_type shader,
                unsigned start, unsigned count,
+               unsigned unbind_num_trailing_slots,
                const struct pipe_image_view *images)
 {
        struct fd_context *ctx = fd_context(pctx);
        struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader];
 
-       fd_set_shader_images(pctx, shader, start, count, images);
+       fd_set_shader_images(pctx, shader, start, count,
+                            unbind_num_trailing_slots, images);
 
        if (!images)
                return;
index cc7fb18..edbc861 100644 (file)
@@ -165,6 +165,7 @@ void
 fd_set_shader_images(struct pipe_context *pctx,
                enum pipe_shader_type shader,
                unsigned start, unsigned count,
+               unsigned unbind_num_trailing_slots,
                const struct pipe_image_view *images)
 {
        struct fd_context *ctx = fd_context(pctx);
@@ -206,6 +207,11 @@ fd_set_shader_images(struct pipe_context *pctx,
                so->enabled_mask &= ~mask;
        }
 
+       for (unsigned i = 0; i < unbind_num_trailing_slots; i++)
+               pipe_resource_reference(&so->si[i + start + count].resource, NULL);
+
+       so->enabled_mask &= ~(BITFIELD_MASK(unbind_num_trailing_slots) << (start + count));
+
        ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_IMAGE;
        ctx->dirty |= FD_DIRTY_IMAGE;
 }
index b45a2da..dfa4a94 100644 (file)
@@ -53,6 +53,7 @@ static inline bool fd_depth_clamp_enabled(struct fd_context *ctx)
 void fd_set_shader_images(struct pipe_context *pctx,
                enum pipe_shader_type shader,
                unsigned start, unsigned count,
+               unsigned unbind_num_trailing_slots,
                const struct pipe_image_view *images);
 
 void fd_state_init(struct pipe_context *pctx);
index 26bb12d..be9862a 100644 (file)
@@ -2740,6 +2740,7 @@ static void
 iris_set_shader_images(struct pipe_context *ctx,
                        enum pipe_shader_type p_stage,
                        unsigned start_slot, unsigned count,
+                       unsigned unbind_num_trailing_slots,
                        const struct pipe_image_view *p_images)
 {
    struct iris_context *ice = (struct iris_context *) ctx;
@@ -2840,6 +2841,11 @@ iris_set_shader_images(struct pipe_context *ctx,
       ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS << stage;
       shs->sysvals_need_upload = true;
    }
+
+   if (unbind_num_trailing_slots) {
+      iris_set_shader_images(ctx, p_stage, start_slot + count,
+                             unbind_num_trailing_slots, 0, NULL);
+   }
 }
 
 
index b3673b4..b151efc 100644 (file)
@@ -3876,7 +3876,8 @@ llvmpipe_set_shader_buffers(struct pipe_context *pipe,
 static void
 llvmpipe_set_shader_images(struct pipe_context *pipe,
                             enum pipe_shader_type shader, unsigned start_slot,
-                           unsigned count, const struct pipe_image_view *images)
+                           unsigned count, unsigned unbind_num_trailing_slots,
+                           const struct pipe_image_view *images)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    unsigned i, idx;
@@ -3901,6 +3902,11 @@ llvmpipe_set_shader_images(struct pipe_context *pipe,
       llvmpipe->cs_dirty |= LP_CSNEW_IMAGES;
    else
       llvmpipe->dirty |= LP_NEW_FS_IMAGES;
+
+   if (unbind_num_trailing_slots) {
+      llvmpipe_set_shader_images(pipe, shader, start_slot + count,
+                                 unbind_num_trailing_slots, 0, NULL);
+   }
 }
 
 /**
index e8afe65..02942d5 100644 (file)
@@ -1283,9 +1283,14 @@ static void
 nvc0_set_shader_images(struct pipe_context *pipe,
                        enum pipe_shader_type shader,
                        unsigned start, unsigned nr,
+                       unsigned unbind_num_trailing_slots,
                        const struct pipe_image_view *images)
 {
    const unsigned s = nvc0_shader_stage(shader);
+
+   nvc0_bind_images_range(nvc0_context(pipe), s, start + nr,
+                          unbind_num_trailing_slots, NULL);
+
    if (!nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images))
       return;
 
index d8cba2d..1600e26 100644 (file)
@@ -642,14 +642,14 @@ static void
 panfrost_set_shader_images(
         struct pipe_context *pctx,
         enum pipe_shader_type shader,
-        unsigned start_slot, unsigned count,
+        unsigned start_slot, unsigned count, unsigned unbind_num_trailing_slots,
         const struct pipe_image_view *iviews)
 {
         struct panfrost_context *ctx = pan_context(pctx);
 
         /* Unbind start_slot...start_slot+count */
         if (!iviews) {
-                for (int i = start_slot; i < start_slot + count; i++) {
+                for (int i = start_slot; i < start_slot + count + unbind_num_trailing_slots; i++) {
                         pipe_resource_reference(&ctx->images[shader][i].resource, NULL);
                 }
 
@@ -677,6 +677,12 @@ panfrost_set_shader_images(
 
                 util_copy_image_view(&ctx->images[shader][start_slot+i], image);
         }
+
+        /* Unbind start_slot+count...start_slot+count+unbind_num_trailing_slots */
+        for (int i = 0; i < unbind_num_trailing_slots; i++) {
+                SET_BIT(ctx->image_mask[shader], 1 << (start_slot + count + i), NULL);
+                util_copy_image_view(&ctx->images[shader][start_slot+count+i], NULL);
+        }
 }
 
 static void *
index c14052c..e7e9139 100644 (file)
@@ -4150,7 +4150,7 @@ static void evergreen_set_shader_buffers(struct pipe_context *ctx,
 
 static void evergreen_set_shader_images(struct pipe_context *ctx,
                                        enum pipe_shader_type shader, unsigned start_slot,
-                                       unsigned count,
+                                       unsigned count, unsigned unbind_num_trailing_slots,
                                        const struct pipe_image_view *images)
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
@@ -4164,7 +4164,9 @@ static void evergreen_set_shader_images(struct pipe_context *ctx,
        unsigned old_mask;
        struct r600_image_state *istate = NULL;
        int idx;
-       if (shader != PIPE_SHADER_FRAGMENT && shader != PIPE_SHADER_COMPUTE && count == 0)
+       if (shader != PIPE_SHADER_FRAGMENT && shader != PIPE_SHADER_COMPUTE)
+               return;
+       if (!count && !unbind_num_trailing_slots)
                return;
 
        if (shader == PIPE_SHADER_FRAGMENT)
@@ -4307,6 +4309,16 @@ static void evergreen_set_shader_images(struct pipe_context *ctx,
                istate->enabled_mask |= (1 << i);
        }
 
+       for (i = start_slot + count, idx = 0;
+            i < start_slot + count + unbind_num_trailing_slots; i++, idx++) {
+               rview = &istate->views[i];
+
+               pipe_resource_reference((struct pipe_resource **)&rview->base.resource, NULL);
+               istate->enabled_mask &= ~(1 << i);
+               istate->compressed_colortex_mask &= ~(1 << i);
+               istate->compressed_depthtex_mask &= ~(1 << i);
+       }
+
        istate->atom.num_dw = util_bitcount(istate->enabled_mask) * 46;
        istate->dirty_buffer_constants = TRUE;
        rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;
index 9bc74b2..ca5fd53 100644 (file)
@@ -534,7 +534,7 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u
    if (is_dcc_decompress)
       image[1].access |= SI_IMAGE_ACCESS_DCC_OFF;
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 2, image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 2, 0, image);
 
    struct pipe_grid_info info = {0};
 
@@ -603,7 +603,7 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u
    si_launch_grid_internal(sctx, &info, saved_cs,
                            SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP);
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 2, saved_image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 2, 0, saved_image);
    for (int i = 0; i < 2; i++)
       pipe_resource_reference(&saved_image[i].resource, NULL);
    if (!is_dcc_decompress) {
@@ -652,7 +652,7 @@ void si_retile_dcc(struct si_context *sctx, struct si_texture *tex)
    img[2].u.buf.offset = tex->surface.display_dcc_offset;
    img[2].u.buf.size = tex->surface.u.gfx9.display_dcc_size;
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 3, img);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 3, 0, img);
 
    /* Bind the compute shader. */
    if (!sctx->cs_dcc_retile)
@@ -679,7 +679,7 @@ void si_retile_dcc(struct si_context *sctx, struct si_texture *tex)
     */
 
    /* Restore states. */
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 3, saved_img);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 3, 0, saved_img);
 
    for (unsigned i = 0; i < 3; i++) {
       pipe_resource_reference(&saved_img[i].resource, NULL);
@@ -717,7 +717,7 @@ void si_compute_expand_fmask(struct pipe_context *ctx, struct pipe_resource *tex
    if (is_array)
       image.u.tex.last_layer = tex->array_size - 1;
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &image);
 
    /* Bind the shader. */
    void **shader = &sctx->cs_fmask_expand[log_samples - 1][is_array];
@@ -740,7 +740,7 @@ void si_compute_expand_fmask(struct pipe_context *ctx, struct pipe_resource *tex
                            SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP);
 
    /* Restore previous states. */
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &saved_image);
    pipe_resource_reference(&saved_image.resource, NULL);
 
    /* Array of fully expanded FMASK values, arranged by [log2(fragments)][log2(samples)-1]. */
@@ -819,7 +819,7 @@ void si_compute_clear_render_target(struct pipe_context *ctx, struct pipe_surfac
    image.u.tex.first_layer = 0; /* 3D images ignore first_layer (BASE_ARRAY) */
    image.u.tex.last_layer = dstsurf->u.tex.last_layer;
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &image);
 
    struct pipe_grid_info info = {0};
 
@@ -852,7 +852,7 @@ void si_compute_clear_render_target(struct pipe_context *ctx, struct pipe_surfac
                            SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP |
                            (render_condition_enabled ? SI_CS_RENDER_COND_ENABLE : 0));
 
-   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, &saved_image);
+   ctx->set_shader_images(ctx, PIPE_SHADER_COMPUTE, 0, 1, 0, &saved_image);
    ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, true, &saved_cb);
    pipe_resource_reference(&saved_image.resource, NULL);
 }
index ccaa280..6139769 100644 (file)
@@ -803,6 +803,7 @@ static void si_set_shader_image(struct si_context *ctx, unsigned shader, unsigne
 
 static void si_set_shader_images(struct pipe_context *pipe, enum pipe_shader_type shader,
                                  unsigned start_slot, unsigned count,
+                                 unsigned unbind_num_trailing_slots,
                                  const struct pipe_image_view *views)
 {
    struct si_context *ctx = (struct si_context *)pipe;
@@ -810,10 +811,10 @@ static void si_set_shader_images(struct pipe_context *pipe, enum pipe_shader_typ
 
    assert(shader < SI_NUM_SHADERS);
 
-   if (!count)
+   if (!count && !unbind_num_trailing_slots)
       return;
 
-   assert(start_slot + count <= SI_NUM_IMAGES);
+   assert(start_slot + count + unbind_num_trailing_slots <= SI_NUM_IMAGES);
 
    if (views) {
       for (i = 0, slot = start_slot; i < count; ++i, ++slot)
@@ -823,6 +824,9 @@ static void si_set_shader_images(struct pipe_context *pipe, enum pipe_shader_typ
          si_set_shader_image(ctx, shader, slot, NULL, false);
    }
 
+   for (i = 0; i < unbind_num_trailing_slots; ++i, ++slot)
+      si_set_shader_image(ctx, shader, slot, NULL, false);
+
    if (shader == PIPE_SHADER_COMPUTE &&
        ctx->cs_shader_state.program &&
        start_slot < ctx->cs_shader_state.program->sel.cs_num_images_in_user_sgprs)
index 8e67571..bb2fb21 100644 (file)
@@ -30,6 +30,7 @@ static void softpipe_set_shader_images(struct pipe_context *pipe,
                                        enum pipe_shader_type shader,
                                        unsigned start,
                                        unsigned num,
+                                       unsigned unbind_num_trailing_slots,
                                        const struct pipe_image_view *images)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -50,6 +51,13 @@ static void softpipe_set_shader_images(struct pipe_context *pipe,
          memset(&softpipe->tgsi.image[shader]->sp_iview[idx], 0, sizeof(struct pipe_image_view));
       }
    }
+
+   for (i = 0; i < unbind_num_trailing_slots; i++) {
+      int idx = start + num + i;
+
+      pipe_resource_reference(&softpipe->tgsi.image[shader]->sp_iview[idx].resource, NULL);
+      memset(&softpipe->tgsi.image[shader]->sp_iview[idx], 0, sizeof(struct pipe_image_view));
+   }
 }
 
 static void softpipe_set_shader_buffers(struct pipe_context *pipe,
index 98e84a5..aca2568 100644 (file)
@@ -612,12 +612,13 @@ tegra_set_shader_buffers(struct pipe_context *pcontext, unsigned int shader,
 static void
 tegra_set_shader_images(struct pipe_context *pcontext, unsigned int shader,
                         unsigned start, unsigned count,
+                        unsigned unbind_num_trailing_slots,
                         const struct pipe_image_view *images)
 {
    struct tegra_context *context = to_tegra_context(pcontext);
 
    context->gpu->set_shader_images(context->gpu, shader, start, count,
-                                   images);
+                                   unbind_num_trailing_slots, images);
 }
 
 static void
index aa03156..86fe97d 100644 (file)
@@ -1347,6 +1347,7 @@ static void
 v3d_set_shader_images(struct pipe_context *pctx,
                       enum pipe_shader_type shader,
                       unsigned start, unsigned count,
+                      unsigned unbind_num_trailing_slots,
                       const struct pipe_image_view *images)
 {
         struct v3d_context *v3d = v3d_context(pctx);
@@ -1392,6 +1393,11 @@ v3d_set_shader_images(struct pipe_context *pctx,
         }
 
         v3d->dirty |= VC5_DIRTY_SHADER_IMAGE;
+
+        if (unbind_num_trailing_slots) {
+                v3d_set_shader_images(pctx, shader, start + count,
+                                      unbind_num_trailing_slots, 0, NULL);
+        }
 }
 
 void
index 72c4a41..2e42f1b 100644 (file)
@@ -1282,6 +1282,7 @@ static void virgl_fence_server_sync(struct pipe_context *ctx,
 static void virgl_set_shader_images(struct pipe_context *ctx,
                                     enum pipe_shader_type shader,
                                     unsigned start_slot, unsigned count,
+                                    unsigned unbind_num_trailing_slots,
                                     const struct pipe_image_view *images)
 {
    struct virgl_context *vctx = virgl_context(ctx);
@@ -1311,6 +1312,11 @@ static void virgl_set_shader_images(struct pipe_context *ctx,
    if (!max_shader_images)
       return;
    virgl_encode_set_shader_images(vctx, shader, start_slot, count, images);
+
+   if (unbind_num_trailing_slots) {
+      virgl_set_shader_images(ctx, shader, start_slot + count,
+                              unbind_num_trailing_slots, 0, NULL);
+   }
 }
 
 static void virgl_memory_barrier(struct pipe_context *ctx,
index 4ef0451..eec6f16 100644 (file)
@@ -621,6 +621,7 @@ static void
 zink_set_shader_images(struct pipe_context *pctx,
                        enum pipe_shader_type p_stage,
                        unsigned start_slot, unsigned count,
+                       unsigned unbind_num_trailing_slots,
                        const struct pipe_image_view *images)
 {
    struct zink_context *ctx = zink_context(pctx);
@@ -653,6 +654,19 @@ zink_set_shader_images(struct pipe_context *pctx,
          image_view->surface = NULL;
       }
    }
+
+   for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
+      struct zink_image_view *image_view = &ctx->image_views[p_stage][start_slot + count + i];
+      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
index 9187357..fad6b75 100644 (file)
@@ -84,7 +84,7 @@ kernel::launch(command_queue &q,
    q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0,
                              exec.sviews.size(), exec.sviews.data());
    q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0,
-                             exec.iviews.size(), exec.iviews.data());
+                             exec.iviews.size(), 0, exec.iviews.data());
    q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(),
                                  exec.resources.data());
    q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(),
@@ -102,7 +102,7 @@ kernel::launch(command_queue &q,
    q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), NULL, NULL);
    q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(), NULL);
    q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0,
-                             exec.iviews.size(), NULL);
+                             0, exec.iviews.size(), NULL);
    q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0,
                              exec.sviews.size(), NULL);
    q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, 0,
index 75a10c2..be624c9 100644 (file)
@@ -136,7 +136,7 @@ static void emit_compute_state(struct rendering_state *state)
    if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
       state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
                                      0, state->num_shader_images[PIPE_SHADER_COMPUTE],
-                                     state->iv[PIPE_SHADER_COMPUTE]);
+                                     0, state->iv[PIPE_SHADER_COMPUTE]);
       state->iv_dirty[PIPE_SHADER_COMPUTE] = false;
    }
 
@@ -281,7 +281,7 @@ static void emit_state(struct rendering_state *state)
    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
       if (state->iv_dirty[sh]) {
          state->pctx->set_shader_images(state->pctx, sh,
-                                        0, state->num_shader_images[sh],
+                                        0, state->num_shader_images[sh], 0,
                                         state->iv[sh]);
       }
    }
@@ -2792,7 +2792,7 @@ VkResult lvp_execute_cmds(struct lvp_device *device,
       }
       state.pctx->bind_sampler_states(state.pctx, s, 0, PIPE_MAX_SAMPLERS, state.ss_cso[s]);
 
-      state.pctx->set_shader_images(state.pctx, s, 0, device->physical_device->max_images, NULL);
+      state.pctx->set_shader_images(state.pctx, s, 0, 0, device->physical_device->max_images, NULL);
    }
 
    free(state.pending_clear_aspects);
index aec0170..6777bd5 100644 (file)
@@ -459,7 +459,7 @@ OMX_ERRORTYPE enc_LoadImage_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEF
          image[2].shader_access = image[1].access = PIPE_IMAGE_ACCESS_WRITE;
          image[2].format = PIPE_FORMAT_R8G8_UINT;
 
-         pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 3, image);
+         pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 3, 0, image);
 
          /* Set the constant buffer. */
          uint32_t constants[4] = {def->nFrameHeight};
@@ -496,7 +496,7 @@ OMX_ERRORTYPE enc_LoadImage_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEF
          pipe->memory_barrier(pipe, PIPE_BARRIER_ALL);
 
          /* Unbind. */
-         pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 3, NULL);
+         pipe->set_shader_images(pipe, PIPE_SHADER_COMPUTE, 0, 0, 3, NULL);
          pipe->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, false, NULL);
          pipe->bind_compute_state(pipe, NULL);
       } else {
index bea258b..1f653e1 100644 (file)
@@ -501,6 +501,8 @@ struct pipe_context {
     * \param shader     selects shader stage
     * \param start_slot first image slot to bind.
     * \param count      number of consecutive images to bind.
+    * \param unbind_num_trailing_slots  number of images to unbind after
+    *                                   the bound slot
     * \param buffers    array of the images to bind, it
     *                   should contain at least \a count elements
     *                   unless it's NULL, in which case no images will
@@ -509,6 +511,7 @@ struct pipe_context {
    void (*set_shader_images)(struct pipe_context *,
                              enum pipe_shader_type shader,
                              unsigned start_slot, unsigned count,
+                             unsigned unbind_num_trailing_slots,
                              const struct pipe_image_view *images);
 
    void (*set_vertex_buffers)( struct pipe_context *,
index 37f12cf..0cf63db 100644 (file)
@@ -175,14 +175,11 @@ st_bind_images(struct st_context *st, struct gl_program *prog,
    }
 
    struct pipe_context *pipe = st->pipe;
-   pipe->set_shader_images(pipe, shader_type, 0, num_images, images);
-
-   /* clear out any stale shader images */
    unsigned last_num_images = st->state.num_images[shader_type];
-   if (num_images < last_num_images) {
-      pipe->set_shader_images(pipe, shader_type, num_images,
-                              last_num_images - num_images, NULL);
-   }
+   unsigned unbind_slots = last_num_images > num_images ?
+                              last_num_images - num_images : 0;
+   pipe->set_shader_images(pipe, shader_type, 0, num_images, unbind_slots,
+                           images);
    st->state.num_images[shader_type] = num_images;
 }
 
index cc34611..44bc91f 100644 (file)
@@ -211,7 +211,7 @@ try_pbo_readpixels(struct st_context *st, struct st_renderbuffer *strb,
       image.u.buf.size = (addr.last_element - addr.first_element + 1) *
                          addr.bytes_per_pixel;
 
-      pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &image);
+      pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, &image);
    }
 
    /* Set up no-attachment framebuffer */
@@ -263,7 +263,7 @@ fail:
                            st->state.num_sampler_views[PIPE_SHADER_FRAGMENT],
                            null);
    st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
-   pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 1, NULL);
+   pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 0, 1, NULL);
 
    st->dirty |= ST_NEW_FS_CONSTANTS |
                 ST_NEW_FS_IMAGES |