summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2016-07-29 17:48:28 +0200
committerMarek Olšák <marek.olsak@amd.com>2016-08-06 13:56:14 +0200
commitc3efdeb8ddbc4033c63e22571a22466bd12135ae (patch)
tree7d82005b03afd61f07457273be260519aadf067f /src/gallium
parentd82cfab84c6b202e09180961959306acd50bd786 (diff)
radeonsi: flush if sampler views and images use too much memory
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/radeon/r600_cs.h34
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c48
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);
}
}
}