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. --- src/mesa/drivers/dri/i965/brw_draw.c | 60 +++++++++++++++------------------ 1 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index c3755d5..cd1b082 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -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; } -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev