diff options
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 53 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_draw.c | 9 |
4 files changed, 64 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 084e3fb1240..615a6809588 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -368,6 +368,12 @@ struct r600_common_screen { */ unsigned compressed_colortex_counter; + /* Atomically increment this counter when an existing texture's + * backing buffer or tile mode parameters have changed that requires + * recomputation of shader descriptors. + */ + unsigned dirty_tex_descriptor_counter; + void (*query_opaque_metadata)(struct r600_common_screen *rscreen, struct r600_texture *rtex, struct radeon_bo_metadata *md); @@ -460,6 +466,7 @@ struct r600_common_context { unsigned gpu_reset_counter; unsigned last_dirty_fb_counter; unsigned last_compressed_colortex_counter; + unsigned last_dirty_tex_descriptor_counter; struct u_upload_mgr *uploader; struct u_suballocator *allocator_so_filled_size; diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index a251fe94b6d..6dcce3cdb08 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -324,11 +324,12 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex, static void si_set_sampler_view(struct si_context *sctx, struct si_sampler_views *views, - unsigned slot, struct pipe_sampler_view *view) + unsigned slot, struct pipe_sampler_view *view, + bool disallow_early_out) { struct si_sampler_view *rview = (struct si_sampler_view*)view; - if (views->views[slot] == view) + if (views->views[slot] == view && !disallow_early_out) return; if (view) { @@ -398,11 +399,11 @@ static void si_set_sampler_views(struct pipe_context *ctx, if (!views || !views[i]) { samplers->depth_texture_mask &= ~(1u << slot); samplers->compressed_colortex_mask &= ~(1u << slot); - si_set_sampler_view(sctx, &samplers->views, slot, NULL); + si_set_sampler_view(sctx, &samplers->views, slot, NULL, false); continue; } - si_set_sampler_view(sctx, &samplers->views, slot, views[i]); + si_set_sampler_view(sctx, &samplers->views, slot, views[i], false); if (views[i]->texture && views[i]->texture->target != PIPE_BUFFER) { struct r600_texture *rtex = @@ -518,7 +519,9 @@ static void si_set_shader_image(struct si_context *ctx, } res = (struct r600_resource *)view->resource; - util_copy_image_view(&images->views[slot], view); + + if (&images->views[slot] != view) + util_copy_image_view(&images->views[slot], view); si_sampler_view_add_buffer(ctx, &res->b.b, RADEON_USAGE_READWRITE); @@ -1366,6 +1369,46 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource } } +/* Update mutable image descriptor fields of all bound textures. */ +void si_update_all_texture_descriptors(struct si_context *sctx) +{ + unsigned shader; + + for (shader = 0; shader < SI_NUM_SHADERS; shader++) { + struct si_sampler_views *samplers = &sctx->samplers[shader].views; + struct si_images_info *images = &sctx->images[shader]; + unsigned mask; + + /* Images. */ + mask = images->desc.enabled_mask; + while (mask) { + unsigned i = u_bit_scan(&mask); + struct pipe_image_view *view = &images->views[i]; + + if (!view->resource || + view->resource->target == PIPE_BUFFER) + continue; + + si_set_shader_image(sctx, images, i, view); + } + + /* Sampler views. */ + mask = samplers->desc.enabled_mask; + while (mask) { + unsigned i = u_bit_scan(&mask); + struct pipe_sampler_view *view = samplers->views[i]; + + if (!view || + !view->texture || + view->texture->target == PIPE_BUFFER) + continue; + + si_set_sampler_view(sctx, samplers, i, + samplers->views[i], true); + } + } +} + /* SHADER USER DATA */ static void si_mark_shader_pointers_dirty(struct si_context *sctx, diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 4d069934b18..e5795eb6968 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -267,6 +267,7 @@ void si_release_all_descriptors(struct si_context *sctx); void si_all_descriptors_begin_new_cs(struct si_context *sctx); void si_upload_const_buffer(struct si_context *sctx, struct r600_resource **rbuffer, const uint8_t *ptr, unsigned size, uint32_t *const_offset); +void si_update_all_texture_descriptors(struct si_context *sctx); void si_shader_change_notify(struct si_context *sctx); void si_update_compressed_colortex_masks(struct si_context *sctx); void si_emit_graphics_shader_userdata(struct si_context *sctx, diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 788869e5a91..c7590cb1458 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -808,7 +808,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) struct si_context *sctx = (struct si_context *)ctx; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; struct pipe_index_buffer ib = {}; - unsigned mask, dirty_fb_counter; + unsigned mask, dirty_fb_counter, dirty_tex_counter; if (!info->count && !info->indirect && (info->indexed || !info->count_from_stream_output)) @@ -837,6 +837,13 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) si_mark_atom_dirty(sctx, &sctx->framebuffer.atom); } + /* Invalidate & recompute texture descriptors if needed. */ + dirty_tex_counter = p_atomic_read(&sctx->b.screen->dirty_tex_descriptor_counter); + if (dirty_tex_counter != sctx->b.last_dirty_tex_descriptor_counter) { + sctx->b.last_dirty_tex_descriptor_counter = dirty_tex_counter; + si_update_all_texture_descriptors(sctx); + } + si_decompress_graphics_textures(sctx); /* Set the rasterization primitive type. |