Mesa (7.11): winsys/radeon: fix space checking

Marek Olšák mareko at kemper.freedesktop.org
Sun Aug 7 09:37:07 PDT 2011


Module: Mesa
Branch: 7.11
Commit: d8a0c1b4bc2c06fa26ed648e0b3be7f5d0dba8f9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d8a0c1b4bc2c06fa26ed648e0b3be7f5d0dba8f9

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Aug  7 18:35:06 2011 +0200

winsys/radeon: fix space checking

We should remove the relocations which caused a validation failure
from the list, so that the kernel receives only the validated ones.

NOTE: This is a candidate for the 7.11 branch.
(cherry picked from commit 64ab39b035f755510a644643b96451431bbe5f27)

Conflicts:

	src/gallium/winsys/radeon/drm/radeon_drm_cs.c

---

 src/gallium/drivers/r300/r300_emit.c          |    3 +-
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c |   33 +++++++++++++++++++++++-
 src/gallium/winsys/radeon/drm/radeon_drm_cs.h |    1 +
 src/gallium/winsys/radeon/drm/radeon_winsys.h |    4 ++-
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d214af4..09ce470 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1237,13 +1237,12 @@ validate:
         r300->rws->cs_add_reloc(r300->cs, r300_resource(index_buffer)->cs_buf,
                                 r300_resource(index_buffer)->domain, 0);
 
-    /* Now do the validation. */
+    /* Now do the validation (flush is called inside cs_validate on failure). */
     if (!r300->rws->cs_validate(r300->cs)) {
         /* Ooops, an infinite loop, give up. */
         if (flushed)
             return FALSE;
 
-        r300_flush(&r300->context, RADEON_FLUSH_ASYNC, NULL);
         flushed = TRUE;
         goto validate;
     }
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 0139de1..1dcc7e1 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -115,6 +115,7 @@ static void radeon_cs_context_cleanup(struct radeon_cs_context *csc)
     }
 
     csc->crelocs = 0;
+    csc->validated_crelocs = 0;
     csc->chunks[0].length_dw = 0;
     csc->chunks[1].length_dw = 0;
     csc->used_gart = 0;
@@ -307,9 +308,37 @@ static void radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs,
 static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
+    boolean status =
+        cs->csc->used_gart < cs->ws->gart_size * 0.8 &&
+        cs->csc->used_vram < cs->ws->vram_size * 0.8;
 
-    return cs->csc->used_gart < cs->ws->gart_size * 0.8 &&
-           cs->csc->used_vram < cs->ws->vram_size * 0.8;
+    if (status) {
+        cs->csc->validated_crelocs = cs->csc->crelocs;
+    } else {
+        /* Remove lately-added relocations. The validation failed with them
+         * and the CS is about to be flushed because of that. Keep only
+         * the already-validated relocations. */
+        unsigned i;
+
+        for (i = cs->csc->validated_crelocs; i < cs->csc->crelocs; i++) {
+            p_atomic_dec(&cs->csc->relocs_bo[i]->num_cs_references);
+            radeon_bo_reference(&cs->csc->relocs_bo[i], NULL);
+        }
+        cs->csc->crelocs = cs->csc->validated_crelocs;
+
+        /* Flush if there are any relocs. Clean up otherwise. */
+        if (cs->csc->crelocs) {
+            cs->flush_cs(cs->flush_data, RADEON_FLUSH_ASYNC);
+        } else {
+            radeon_cs_context_cleanup(cs->csc);
+
+            assert(cs->base.cdw == 0);
+            if (cs->base.cdw != 0) {
+                fprintf(stderr, "radeon: Unexpected error in %s.\n", __func__);
+            }
+        }
+    }
+    return status;
 }
 
 static void radeon_drm_cs_write_reloc(struct radeon_winsys_cs *rcs,
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index 339beed..fc51f45 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -41,6 +41,7 @@ struct radeon_cs_context {
     /* Relocs. */
     unsigned                    nrelocs;
     unsigned                    crelocs;
+    unsigned			validated_crelocs;
     struct radeon_bo            **relocs_bo;
     struct drm_radeon_cs_reloc  *relocs;
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 3a64e4a..41c26c6 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -271,7 +271,9 @@ struct radeon_winsys {
 
     /**
      * Return TRUE if there is enough memory in VRAM and GTT for the relocs
-     * added so far.
+     * added so far. If the validation fails, all the relocations which have
+     * been added since the last call of cs_validate will be removed and
+     * the CS will be flushed (provided there are still any relocations).
      *
      * \param cs        A command stream to validate.
      */



More information about the mesa-commit mailing list