radeonsi: flush if sampler views and images use too much memory
authorMarek Olšák <marek.olsak@amd.com>
Fri, 29 Jul 2016 15:48:28 +0000 (17:48 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 6 Aug 2016 11:56:14 +0000 (13:56 +0200)
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_cs.h
src/gallium/drivers/radeonsi/si_descriptors.c

index 72a91bf..988774a 100644 (file)
@@ -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,
index 1cbb86a..ea58584 100644 (file)
@@ -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);
                        }
                }
        }