gallium: add unbind_num_trailing_slots to set_shader_images

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>
This commit is contained in:
Marek Olšák 2020-12-21 03:01:34 -05:00 committed by Marge Bot
parent 0278d1fa32
commit 72ff66c3d7
28 changed files with 145 additions and 48 deletions

View 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); ctx->pipe->set_shader_buffers(ctx->pipe, sh, 0, maxssbo, ssbos, 0);
} }
if (maximg > 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++) { for (int i = 0; i < maxcb; i++) {
ctx->pipe->set_constant_buffer(ctx->pipe, sh, i, false, NULL); ctx->pipe->set_constant_buffer(ctx->pipe, sh, i, false, NULL);

View file

@ -524,6 +524,7 @@ static void
dd_context_set_shader_images(struct pipe_context *_pipe, dd_context_set_shader_images(struct pipe_context *_pipe,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned num, unsigned start, unsigned num,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *views) const struct pipe_image_view *views)
{ {
struct dd_context *dctx = dd_context(_pipe); 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, safe_memcpy(&dctx->draw_state.shader_images[shader][start], views,
sizeof(views[0]) * num); 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 static void

View 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, static void trace_context_set_shader_images(struct pipe_context *_context,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned nr, unsigned start, unsigned nr,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct trace_context *tr_context = trace_context(_context); 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_arg_begin("images");
trace_dump_struct_array(image_view, images, nr); trace_dump_struct_array(image_view, images, nr);
trace_dump_arg_end(); trace_dump_arg_end();
trace_dump_arg(uint, unbind_num_trailing_slots);
trace_dump_call_end(); 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, static void trace_context_launch_grid(struct pipe_context *_pipe,

View 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.first_layer = 0;
image.u.tex.last_layer = (unsigned)(dst->array_size - 1); 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}; struct pipe_sampler_state sampler_state={0};
sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 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->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_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, false, NULL);
ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL); ctx->set_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 1, NULL);
pipe_sampler_view_reference(&src_view, NULL); pipe_sampler_view_reference(&src_view, NULL);

View file

@ -834,7 +834,7 @@ test_compute_clear_image(struct pipe_context *ctx)
image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE; image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE;
image.format = cb->format; 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. */ /* Dispatch compute. */
struct pipe_grid_info info = {0}; struct pipe_grid_info info = {0};

View file

@ -985,7 +985,7 @@ tc_set_sampler_views(struct pipe_context *_pipe,
struct tc_shader_images { struct tc_shader_images {
ubyte shader, start, count; ubyte shader, start, count;
bool unbind; ubyte unbind_num_trailing_slots;
struct pipe_image_view slot[0]; /* more will be allocated if needed */ 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; struct tc_shader_images *p = (struct tc_shader_images *)payload;
unsigned count = p->count; unsigned count = p->count;
if (p->unbind) { if (!p->count) {
pipe->set_shader_images(pipe, p->shader, p->start, p->count, NULL); pipe->set_shader_images(pipe, p->shader, p->start, 0,
p->unbind_num_trailing_slots, NULL);
return; 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++) for (unsigned i = 0; i < count; i++)
pipe_resource_reference(&p->slot[i].resource, NULL); pipe_resource_reference(&p->slot[i].resource, NULL);
@ -1010,9 +1012,10 @@ static void
tc_set_shader_images(struct pipe_context *_pipe, tc_set_shader_images(struct pipe_context *_pipe,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
if (!count) if (!count && !unbind_num_trailing_slots)
return; return;
struct threaded_context *tc = threaded_context(_pipe); struct threaded_context *tc = threaded_context(_pipe);
@ -1022,10 +1025,11 @@ tc_set_shader_images(struct pipe_context *_pipe,
p->shader = shader; p->shader = shader;
p->start = start; p->start = start;
p->count = count;
p->unbind = images == NULL;
if (images) { if (images) {
p->count = count;
p->unbind_num_trailing_slots = unbind_num_trailing_slots;
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
tc_set_resource_reference(&p->slot[i].resource, images[i].resource); 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])); memcpy(p->slot, images, count * sizeof(images[0]));
} else {
p->count = 0;
p->unbind_num_trailing_slots = count + unbind_num_trailing_slots;
} }
} }

View file

@ -597,7 +597,7 @@ cs_launch(struct vl_compositor *c,
image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE; image.shader_access = image.access = PIPE_IMAGE_ACCESS_READ_WRITE;
image.format = c->fb_state.cbufs[0]->texture->format; 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 */ /* Bind compute shader */
ctx->bind_compute_state(ctx, cs); ctx->bind_compute_state(ctx, cs);
@ -732,7 +732,7 @@ draw_layers(struct vl_compositor *c,
cs_launch(c, layer->cs, &(drawn.area)); cs_launch(c, layer->cs, &(drawn.area));
/* Unbind. */ /* 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_constant_buffer(c->pipe, PIPE_SHADER_COMPUTE, 0, false, NULL);
c->pipe->set_sampler_views(c->pipe, PIPE_SHADER_FRAGMENT, 0, c->pipe->set_sampler_views(c->pipe, PIPE_SHADER_FRAGMENT, 0,
num_sampler_views, NULL); num_sampler_views, NULL);

View 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, static void fd6_set_shader_images(struct pipe_context *pctx,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
struct fd_shaderimg_stateobj *so = &ctx->shaderimg[shader]; 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) if (!images)
return; return;

View file

@ -165,6 +165,7 @@ void
fd_set_shader_images(struct pipe_context *pctx, fd_set_shader_images(struct pipe_context *pctx,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct fd_context *ctx = fd_context(pctx); struct fd_context *ctx = fd_context(pctx);
@ -206,6 +207,11 @@ fd_set_shader_images(struct pipe_context *pctx,
so->enabled_mask &= ~mask; 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_shader[shader] |= FD_DIRTY_SHADER_IMAGE;
ctx->dirty |= FD_DIRTY_IMAGE; ctx->dirty |= FD_DIRTY_IMAGE;
} }

View 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, void fd_set_shader_images(struct pipe_context *pctx,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images); const struct pipe_image_view *images);
void fd_state_init(struct pipe_context *pctx); void fd_state_init(struct pipe_context *pctx);

View file

@ -2740,6 +2740,7 @@ static void
iris_set_shader_images(struct pipe_context *ctx, iris_set_shader_images(struct pipe_context *ctx,
enum pipe_shader_type p_stage, enum pipe_shader_type p_stage,
unsigned start_slot, unsigned count, unsigned start_slot, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *p_images) const struct pipe_image_view *p_images)
{ {
struct iris_context *ice = (struct iris_context *) ctx; 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; ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_VS << stage;
shs->sysvals_need_upload = true; 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);
}
} }

View file

@ -3876,7 +3876,8 @@ llvmpipe_set_shader_buffers(struct pipe_context *pipe,
static void static void
llvmpipe_set_shader_images(struct pipe_context *pipe, llvmpipe_set_shader_images(struct pipe_context *pipe,
enum pipe_shader_type shader, unsigned start_slot, 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); struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
unsigned i, idx; unsigned i, idx;
@ -3901,6 +3902,11 @@ llvmpipe_set_shader_images(struct pipe_context *pipe,
llvmpipe->cs_dirty |= LP_CSNEW_IMAGES; llvmpipe->cs_dirty |= LP_CSNEW_IMAGES;
else else
llvmpipe->dirty |= LP_NEW_FS_IMAGES; 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);
}
} }
/** /**

View file

@ -1283,9 +1283,14 @@ static void
nvc0_set_shader_images(struct pipe_context *pipe, nvc0_set_shader_images(struct pipe_context *pipe,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned nr, unsigned start, unsigned nr,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
const unsigned s = nvc0_shader_stage(shader); 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)) if (!nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images))
return; return;

View file

@ -642,14 +642,14 @@ static void
panfrost_set_shader_images( panfrost_set_shader_images(
struct pipe_context *pctx, struct pipe_context *pctx,
enum pipe_shader_type shader, 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) const struct pipe_image_view *iviews)
{ {
struct panfrost_context *ctx = pan_context(pctx); struct panfrost_context *ctx = pan_context(pctx);
/* Unbind start_slot...start_slot+count */ /* Unbind start_slot...start_slot+count */
if (!iviews) { 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); 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); 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 * static void *

View 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, static void evergreen_set_shader_images(struct pipe_context *ctx,
enum pipe_shader_type shader, unsigned start_slot, enum pipe_shader_type shader, unsigned start_slot,
unsigned count, unsigned count, unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct r600_context *rctx = (struct r600_context *)ctx; 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; unsigned old_mask;
struct r600_image_state *istate = NULL; struct r600_image_state *istate = NULL;
int idx; 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; return;
if (shader == PIPE_SHADER_FRAGMENT) if (shader == PIPE_SHADER_FRAGMENT)
@ -4307,6 +4309,16 @@ static void evergreen_set_shader_images(struct pipe_context *ctx,
istate->enabled_mask |= (1 << i); 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->atom.num_dw = util_bitcount(istate->enabled_mask) * 46;
istate->dirty_buffer_constants = TRUE; istate->dirty_buffer_constants = TRUE;
rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV; rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;

View file

@ -534,7 +534,7 @@ void si_compute_copy_image(struct si_context *sctx, struct pipe_resource *dst, u
if (is_dcc_decompress) if (is_dcc_decompress)
image[1].access |= SI_IMAGE_ACCESS_DCC_OFF; 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}; 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_launch_grid_internal(sctx, &info, saved_cs,
SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP); 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++) for (int i = 0; i < 2; i++)
pipe_resource_reference(&saved_image[i].resource, NULL); pipe_resource_reference(&saved_image[i].resource, NULL);
if (!is_dcc_decompress) { 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.offset = tex->surface.display_dcc_offset;
img[2].u.buf.size = tex->surface.u.gfx9.display_dcc_size; 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. */ /* Bind the compute shader. */
if (!sctx->cs_dcc_retile) if (!sctx->cs_dcc_retile)
@ -679,7 +679,7 @@ void si_retile_dcc(struct si_context *sctx, struct si_texture *tex)
*/ */
/* Restore states. */ /* 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++) { for (unsigned i = 0; i < 3; i++) {
pipe_resource_reference(&saved_img[i].resource, NULL); 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) if (is_array)
image.u.tex.last_layer = tex->array_size - 1; 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. */ /* Bind the shader. */
void **shader = &sctx->cs_fmask_expand[log_samples - 1][is_array]; 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); SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP);
/* Restore previous states. */ /* 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); pipe_resource_reference(&saved_image.resource, NULL);
/* Array of fully expanded FMASK values, arranged by [log2(fragments)][log2(samples)-1]. */ /* 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.first_layer = 0; /* 3D images ignore first_layer (BASE_ARRAY) */
image.u.tex.last_layer = dstsurf->u.tex.last_layer; 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}; 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 | SI_CS_WAIT_FOR_IDLE | SI_CS_IMAGE_OP |
(render_condition_enabled ? SI_CS_RENDER_COND_ENABLE : 0)); (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); ctx->set_constant_buffer(ctx, PIPE_SHADER_COMPUTE, 0, true, &saved_cb);
pipe_resource_reference(&saved_image.resource, NULL); pipe_resource_reference(&saved_image.resource, NULL);
} }

View 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, static void si_set_shader_images(struct pipe_context *pipe, 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 *views) const struct pipe_image_view *views)
{ {
struct si_context *ctx = (struct si_context *)pipe; 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); assert(shader < SI_NUM_SHADERS);
if (!count) if (!count && !unbind_num_trailing_slots)
return; return;
assert(start_slot + count <= SI_NUM_IMAGES); assert(start_slot + count + unbind_num_trailing_slots <= SI_NUM_IMAGES);
if (views) { if (views) {
for (i = 0, slot = start_slot; i < count; ++i, ++slot) 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); 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 && if (shader == PIPE_SHADER_COMPUTE &&
ctx->cs_shader_state.program && ctx->cs_shader_state.program &&
start_slot < ctx->cs_shader_state.program->sel.cs_num_images_in_user_sgprs) start_slot < ctx->cs_shader_state.program->sel.cs_num_images_in_user_sgprs)

View file

@ -30,6 +30,7 @@ static void softpipe_set_shader_images(struct pipe_context *pipe,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned start,
unsigned num, unsigned num,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct softpipe_context *softpipe = softpipe_context(pipe); 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)); 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, static void softpipe_set_shader_buffers(struct pipe_context *pipe,

View file

@ -612,12 +612,13 @@ tegra_set_shader_buffers(struct pipe_context *pcontext, unsigned int shader,
static void static void
tegra_set_shader_images(struct pipe_context *pcontext, unsigned int shader, tegra_set_shader_images(struct pipe_context *pcontext, unsigned int shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct tegra_context *context = to_tegra_context(pcontext); struct tegra_context *context = to_tegra_context(pcontext);
context->gpu->set_shader_images(context->gpu, shader, start, count, context->gpu->set_shader_images(context->gpu, shader, start, count,
images); unbind_num_trailing_slots, images);
} }
static void static void

View file

@ -1347,6 +1347,7 @@ static void
v3d_set_shader_images(struct pipe_context *pctx, v3d_set_shader_images(struct pipe_context *pctx,
enum pipe_shader_type shader, enum pipe_shader_type shader,
unsigned start, unsigned count, unsigned start, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct v3d_context *v3d = v3d_context(pctx); 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; 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 void

View 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, static void virgl_set_shader_images(struct pipe_context *ctx,
enum pipe_shader_type shader, 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 *images) const struct pipe_image_view *images)
{ {
struct virgl_context *vctx = virgl_context(ctx); 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) if (!max_shader_images)
return; return;
virgl_encode_set_shader_images(vctx, shader, start_slot, count, images); 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, static void virgl_memory_barrier(struct pipe_context *ctx,

View file

@ -621,6 +621,7 @@ static void
zink_set_shader_images(struct pipe_context *pctx, zink_set_shader_images(struct pipe_context *pctx,
enum pipe_shader_type p_stage, enum pipe_shader_type p_stage,
unsigned start_slot, unsigned count, unsigned start_slot, unsigned count,
unsigned unbind_num_trailing_slots,
const struct pipe_image_view *images) const struct pipe_image_view *images)
{ {
struct zink_context *ctx = zink_context(pctx); struct zink_context *ctx = zink_context(pctx);
@ -653,6 +654,19 @@ zink_set_shader_images(struct pipe_context *pctx,
image_view->surface = NULL; 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 static void

View file

@ -84,7 +84,7 @@ kernel::launch(command_queue &q,
q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0, q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0,
exec.sviews.size(), exec.sviews.data()); exec.sviews.size(), exec.sviews.data());
q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0, 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(), q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(),
exec.resources.data()); exec.resources.data());
q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), 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_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_compute_resources(q.pipe, 0, exec.resources.size(), NULL);
q.pipe->set_shader_images(q.pipe, PIPE_SHADER_COMPUTE, 0, 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, q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0,
exec.sviews.size(), NULL); exec.sviews.size(), NULL);
q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, 0, q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, 0,

View file

@ -136,7 +136,7 @@ static void emit_compute_state(struct rendering_state *state)
if (state->iv_dirty[PIPE_SHADER_COMPUTE]) { if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {
state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE, state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,
0, state->num_shader_images[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; 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++) { for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
if (state->iv_dirty[sh]) { if (state->iv_dirty[sh]) {
state->pctx->set_shader_images(state->pctx, 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]); 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->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); free(state.pending_clear_aspects);

View 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].shader_access = image[1].access = PIPE_IMAGE_ACCESS_WRITE;
image[2].format = PIPE_FORMAT_R8G8_UINT; 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. */ /* Set the constant buffer. */
uint32_t constants[4] = {def->nFrameHeight}; 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); pipe->memory_barrier(pipe, PIPE_BARRIER_ALL);
/* Unbind. */ /* 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->set_constant_buffer(pipe, PIPE_SHADER_COMPUTE, 0, false, NULL);
pipe->bind_compute_state(pipe, NULL); pipe->bind_compute_state(pipe, NULL);
} else { } else {

View file

@ -501,6 +501,8 @@ struct pipe_context {
* \param shader selects shader stage * \param shader selects shader stage
* \param start_slot first image slot to bind. * \param start_slot first image slot to bind.
* \param count number of consecutive images 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 * \param buffers array of 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 images will * unless it's NULL, in which case no images will
@ -509,6 +511,7 @@ struct pipe_context {
void (*set_shader_images)(struct pipe_context *, void (*set_shader_images)(struct pipe_context *,
enum pipe_shader_type shader, 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 *images); const struct pipe_image_view *images);
void (*set_vertex_buffers)( struct pipe_context *, void (*set_vertex_buffers)( struct pipe_context *,

View file

@ -175,14 +175,11 @@ st_bind_images(struct st_context *st, struct gl_program *prog,
} }
struct pipe_context *pipe = st->pipe; 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]; unsigned last_num_images = st->state.num_images[shader_type];
if (num_images < last_num_images) { unsigned unbind_slots = last_num_images > num_images ?
pipe->set_shader_images(pipe, shader_type, num_images, last_num_images - num_images : 0;
last_num_images - num_images, NULL); pipe->set_shader_images(pipe, shader_type, 0, num_images, unbind_slots,
} images);
st->state.num_images[shader_type] = num_images; st->state.num_images[shader_type] = num_images;
} }

View 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) * image.u.buf.size = (addr.last_element - addr.first_element + 1) *
addr.bytes_per_pixel; 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 */ /* Set up no-attachment framebuffer */
@ -263,7 +263,7 @@ fail:
st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], st->state.num_sampler_views[PIPE_SHADER_FRAGMENT],
null); null);
st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0; 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->dirty |= ST_NEW_FS_CONSTANTS |
ST_NEW_FS_IMAGES | ST_NEW_FS_IMAGES |