i965: Use the batch save/reset code to avoid needing the BO validate step.
authorEric Anholt <eric@anholt.net>
Sat, 22 Oct 2011 16:37:57 +0000 (09:37 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 29 Oct 2011 19:16:05 +0000 (12:16 -0700)
We were doing the BO validate step in prepare() (brw_validate_state())
hooks of atoms so that we could check_aperture before emitting the
relocation trees during brw_upload_state() that would actually make
the batchbuffer reference too much memory to be executed.  Now that
all relocations occur in the batchbuffer, we can instead
check_aperture after emitting our state into the batchbuffer, and
easily roll back, flush, and retry if we happened to go over the
limits.

This will let us remove the whole prepare() vs emit() split in our
state atoms, which is a source of tricky dependencies and duplicated
code.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Paul Berry <stereotype441@gmail.com>
src/mesa/drivers/dri/i965/brw_draw.c

index c3755d564a514b9331f50cb6ed31c144f5e58ac4..cd1b082b8c8ed85be6191620717760281d6929c0 100644 (file)
@@ -25,6 +25,7 @@
  * 
  **************************************************************************/
 
+#include <sys/errno.h>
 
 #include "main/glheader.h"
 #include "main/context.h"
@@ -292,9 +293,9 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
 {
    struct intel_context *intel = intel_context(ctx);
    struct brw_context *brw = brw_context(ctx);
-   bool retval = false;
-   bool warn = false;
+   bool retval = true;
    GLuint i;
+   bool fail_next = false;
 
    if (ctx->NewState)
       _mesa_update_state( ctx );
@@ -344,12 +345,14 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
        * primitives.
        */
       intel_batchbuffer_require_space(intel, estimated_max_prim_size, false);
+      intel_batchbuffer_save_state(intel);
 
       if (intel->gen < 6)
         brw_set_prim(brw, &prim[i]);
       else
         gen6_set_prim(brw, &prim[i]);
 
+retry:
       /* Note that before the loop, brw->state.dirty.brw was set to != 0, and
        * that the state updated in the loop outside of this block is that in
        * *_set_prim or intel_batchbuffer_flush(), which only impacts
@@ -359,30 +362,9 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
         brw_validate_state(brw);
 
         /* Various fallback checks:  */
-        if (brw->intel.Fallback)
+        if (brw->intel.Fallback) {
+           retval = false;
            goto out;
-
-        /* Check that we can fit our state in with our existing batchbuffer, or
-         * flush otherwise.
-         */
-        if (dri_bufmgr_check_aperture_space(brw->state.validated_bos,
-                                            brw->state.validated_bo_count)) {
-           static bool warned;
-           intel_batchbuffer_flush(intel);
-
-           /* Validate the state after we flushed the batch (which would have
-            * changed the set of dirty state).  If we still fail to
-            * check_aperture, warn of what's happening, but attempt to continue
-            * on since it may succeed anyway, and the user would probably rather
-            * see a failure and a warning than a fallback.
-            */
-           brw_validate_state(brw);
-           if (!warned &&
-               dri_bufmgr_check_aperture_space(brw->state.validated_bos,
-                                               brw->state.validated_bo_count)) {
-              warn = true;
-              warned = true;
-           }
         }
 
         intel->no_batch_wrap = true;
@@ -396,7 +378,26 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
 
       intel->no_batch_wrap = false;
 
-      retval = true;
+      if (dri_bufmgr_check_aperture_space(&intel->batch.bo, 1)) {
+        if (!fail_next) {
+           intel_batchbuffer_reset_to_saved(intel);
+           intel_batchbuffer_flush(intel);
+           fail_next = true;
+           goto retry;
+        } else {
+           if (intel_batchbuffer_flush(intel) == -ENOSPC) {
+              static bool warned = false;
+
+              if (!warned) {
+                 fprintf(stderr, "i965: Single primitive emit exceeded"
+                         "available aperture space\n");
+                 warned = true;
+              }
+
+              retval = false;
+           }
+        }
+      }
    }
 
    if (intel->always_flush_batch)
@@ -405,13 +406,6 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
 
    brw_state_cache_check_size(brw);
 
-   if (warn)
-      fprintf(stderr, "i965: Single primitive emit potentially exceeded "
-             "available aperture space\n");
-
-   if (!retval)
-      DBG("%s failed\n", __FUNCTION__);
-
    return retval;
 }