diff options
author | Marek Olšák <[email protected]> | 2016-07-29 17:48:28 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-08-06 13:56:14 +0200 |
commit | c3efdeb8ddbc4033c63e22571a22466bd12135ae (patch) | |
tree | 7d82005b03afd61f07457273be260519aadf067f /src/gallium | |
parent | d82cfab84c6b202e09180961959306acd50bd786 (diff) |
radeonsi: flush if sampler views and images use too much memory
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeon/r600_cs.h | 34 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 48 |
2 files changed, 63 insertions, 19 deletions
diff --git a/src/gallium/drivers/radeon/r600_cs.h b/src/gallium/drivers/radeon/r600_cs.h index 72a91bf56aa..988774aac8f 100644 --- a/src/gallium/drivers/radeon/r600_cs.h +++ b/src/gallium/drivers/radeon/r600_cs.h @@ -54,6 +54,40 @@ static inline unsigned radeon_add_to_buffer_list(struct r600_common_context *rct rbo->domains, priority) * 4; } +/** + * Same as above, but also checks memory usage and flushes the context + * accordingly. + * + * When this SHOULD NOT be used: + * + * - if r600_context_add_resource_size has been called for the buffer + * followed by *_need_cs_space for checking the memory usage + * + * - if r600_need_dma_space has been called for the buffer + * + * - when emitting state packets and draw packets (because preceding packets + * can't be re-emitted at that point) + * + * - if shader resource "enabled_mask" is not up-to-date or there is + * a different constraint disallowing a context flush + */ +static inline unsigned +radeon_add_to_buffer_list_check_mem(struct r600_common_context *rctx, + struct r600_ring *ring, + struct r600_resource *rbo, + enum radeon_bo_usage usage, + enum radeon_bo_priority priority, + bool check_mem) +{ + if (check_mem && + !rctx->ws->cs_memory_below_limit(ring->cs, + rctx->vram + rbo->vram_usage, + rctx->gtt + rbo->gart_usage)) + ring->flush(rctx, RADEON_FLUSH_ASYNC, NULL); + + return radeon_add_to_buffer_list(rctx, ring, rbo, usage, priority); +} + static inline void r600_emit_reloc(struct r600_common_context *rctx, struct r600_ring *ring, struct r600_resource *rbo, enum radeon_bo_usage usage, diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 1cbb86a4b1e..ea585845435 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -296,9 +296,12 @@ static void si_release_sampler_views(struct si_sampler_views *views) static void si_sampler_view_add_buffer(struct si_context *sctx, struct pipe_resource *resource, enum radeon_bo_usage usage, - bool is_stencil_sampler) + bool is_stencil_sampler, + bool check_mem) { struct r600_resource *rres; + struct r600_texture *rtex; + enum radeon_bo_priority priority; if (!resource) return; @@ -311,17 +314,23 @@ static void si_sampler_view_add_buffer(struct si_context *sctx, } rres = (struct r600_resource*)resource; - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, rres, usage, - r600_get_sampler_view_priority(rres)); + priority = r600_get_sampler_view_priority(rres); - if (resource->target != PIPE_BUFFER) { - struct r600_texture *rtex = (struct r600_texture*)resource; + radeon_add_to_buffer_list_check_mem(&sctx->b, &sctx->b.gfx, + rres, usage, priority, + check_mem); - if (rtex->dcc_separate_buffer) - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - rtex->dcc_separate_buffer, usage, - RADEON_PRIO_DCC); - } + if (resource->target == PIPE_BUFFER) + return; + + /* Now add separate DCC if it's present. */ + rtex = (struct r600_texture*)resource; + if (!rtex->dcc_separate_buffer) + return; + + radeon_add_to_buffer_list_check_mem(&sctx->b, &sctx->b.gfx, + rtex->dcc_separate_buffer, usage, + RADEON_PRIO_DCC, check_mem); } static void si_sampler_views_begin_new_cs(struct si_context *sctx, @@ -336,7 +345,7 @@ static void si_sampler_views_begin_new_cs(struct si_context *sctx, si_sampler_view_add_buffer(sctx, sview->base.texture, RADEON_USAGE_READ, - sview->is_stencil_sampler); + sview->is_stencil_sampler, false); } } @@ -403,7 +412,7 @@ static void si_set_sampler_view(struct si_context *sctx, si_sampler_view_add_buffer(sctx, view->texture, RADEON_USAGE_READ, - rview->is_stencil_sampler); + rview->is_stencil_sampler, true); pipe_sampler_view_reference(&views->views[slot], view); memcpy(desc, rview->state, 8*4); @@ -565,7 +574,7 @@ si_image_views_begin_new_cs(struct si_context *sctx, struct si_images_info *imag assert(view->resource); si_sampler_view_add_buffer(sctx, view->resource, - RADEON_USAGE_READWRITE, false); + RADEON_USAGE_READWRITE, false, false); } } @@ -624,7 +633,7 @@ static void si_set_shader_image(struct si_context *ctx, util_copy_image_view(&images->views[slot], view); si_sampler_view_add_buffer(ctx, &res->b.b, - RADEON_USAGE_READWRITE, false); + RADEON_USAGE_READWRITE, false, true); if (res->b.b.target == PIPE_BUFFER) { if (view->access & PIPE_IMAGE_ACCESS_WRITE) @@ -1506,9 +1515,10 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource sctx->descriptors_dirty |= 1u << si_sampler_descriptors_idx(shader); - radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, - rbuffer, RADEON_USAGE_READ, - RADEON_PRIO_SAMPLER_BUFFER); + radeon_add_to_buffer_list_check_mem(&sctx->b, &sctx->b.gfx, + rbuffer, RADEON_USAGE_READ, + RADEON_PRIO_SAMPLER_BUFFER, + true); } } } @@ -1534,10 +1544,10 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource sctx->descriptors_dirty |= 1u << si_image_descriptors_idx(shader); - radeon_add_to_buffer_list( + radeon_add_to_buffer_list_check_mem( &sctx->b, &sctx->b.gfx, rbuffer, RADEON_USAGE_READWRITE, - RADEON_PRIO_SAMPLER_BUFFER); + RADEON_PRIO_SAMPLER_BUFFER, true); } } } |