diff options
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_tcl.c | 21 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_draw.c | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r700_render.c | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tcl.c | 21 |
4 files changed, 44 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 0f5e501c1a6..7b3a9fc859d 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -51,6 +51,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_swtcl.h" #include "r200_maos.h" +#include "radeon_common_context.h" + #define HAVE_POINTS 1 @@ -368,12 +370,13 @@ r200ComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord ) * Predict total emit size for next rendering operation so there is no flush in middle of rendering * Prediction has to aim towards the best possible value that is worse than worst case scenario */ -static void r200EnsureEmitSize( GLcontext * ctx , GLubyte* vimap_rev ) +static GLuint r200EnsureEmitSize( GLcontext * ctx , GLubyte* vimap_rev ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint space_required; + GLuint state_size; GLuint nr_aos = 0; int i; /* predict number of aos to emit */ @@ -387,10 +390,11 @@ static void r200EnsureEmitSize( GLcontext * ctx , GLubyte* vimap_rev ) { /* count the prediction for state size */ - space_required = radeonCountStateEmitSize( &rmesa->radeon ); + space_required = 0; + state_size = radeonCountStateEmitSize( &rmesa->radeon ); /* vtx may be changed in r200EmitArrays so account for it if not dirty */ if (!rmesa->hw.vtx.dirty) - space_required += rmesa->hw.vtx.check(rmesa->radeon.glCtx, &rmesa->hw.vtx); + state_size += rmesa->hw.vtx.check(rmesa->radeon.glCtx, &rmesa->hw.vtx); /* predict size for elements */ for (i = 0; i < VB->PrimitiveCount; ++i) { @@ -413,7 +417,10 @@ static void r200EnsureEmitSize( GLcontext * ctx , GLubyte* vimap_rev ) space_required += SCISSOR_BUFSZ; } /* flush the buffer in case we need more than is left. */ - rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required, __FUNCTION__); + if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required + state_size, __FUNCTION__)) + return space_required + radeonCountStateEmitSize( &rmesa->radeon ); + else + return space_required + state_size; } @@ -530,7 +537,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, /* Do the actual work: */ radeonReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); - r200EnsureEmitSize( ctx, vimap_rev ); + GLuint emit_end = r200EnsureEmitSize( ctx, vimap_rev ) + + rmesa->radeon.cmdbuf.cs->cdw; r200EmitArrays( ctx, vimap_rev ); for (i = 0 ; i < VB->PrimitiveCount ; i++) @@ -547,6 +555,9 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, else r200EmitPrimitive( ctx, start, start+length, prim ); } + if ( emit_end < rmesa->radeon.cmdbuf.cs->cdw ) + WARN_ONCE("Rendering was %d commands larger than predicted size." + " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end); return GL_FALSE; /* finished the pipe */ } diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 2ac898bd59d..56680516c83 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -42,6 +42,7 @@ #include "r300_cmdbuf.h" #include "radeon_buffer_objects.h" +#include "radeon_common_context.h" #include "tnl/tnl.h" #include "tnl/t_vp_build.h" @@ -632,7 +633,8 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, /* ensure we have the cmd buf space in advance to cover * the state + DMA AOS pointers */ - r300PredictTryDrawPrimsSize(ctx, nr_prims); + GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims) + + r300->radeon.cmdbuf.cs->cdw; r300SetupIndexBuffer(ctx, ib); @@ -656,6 +658,10 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, fprintf(stderr, "%s: %u (%d-%d) cs ending at %d\n", __FUNCTION__, nr_prims, min_index, max_index, r300->radeon.cmdbuf.cs->cdw ); + if (emit_end < r300->radeon.cmdbuf.cs->cdw) + WARN_ONCE("Rendering was %d commands larger than predicted size." + " We might overflow command buffer.\n", r300->radeon.cmdbuf.cs->cdw - emit_end); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 899c2cf05c3..9b0b5443d6a 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -53,6 +53,8 @@ #include "r700_fragprog.h" #include "r700_state.h" +#include "radeon_common_context.h" + void r700WaitForIdle(context_t *context); void r700WaitForIdleClean(context_t *context); GLboolean r700SendTextureState(context_t *context); @@ -384,7 +386,9 @@ static GLboolean r700RunRender(GLcontext * ctx, fprintf(stderr, "%s: cs end at %d\n", __func__, context->radeon.cmdbuf.cs->cdw); - assert(context->radeon.cmdbuf.cs->cdw <= emit_end); + if ( emit_end < context->radeon.cmdbuf.cs->cdw ) + WARN_ONCE("Rendering was %d commands larger than predicted size." + " We might overflow command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end); return GL_FALSE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index 908b3c9f061..2404f284505 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -50,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_swtcl.h" #include "radeon_maos.h" +#include "radeon_common_context.h" @@ -359,12 +360,13 @@ radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord ) * Predict total emit size for next rendering operation so there is no flush in middle of rendering * Prediction has to aim towards the best possible value that is worse than worst case scenario */ -static void radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) +static GLuint radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint space_required; + GLuint state_size; GLuint nr_aos = 1; /* radeonEmitArrays does always emit one */ int i; /* list of flags that are allocating aos object */ @@ -388,10 +390,11 @@ static void radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) { /* count the prediction for state size */ - space_required = radeonCountStateEmitSize( &rmesa->radeon ); + space_required = 0; + state_size = radeonCountStateEmitSize( &rmesa->radeon ); /* tcl may be changed in radeonEmitArrays so account for it if not dirty */ if (!rmesa->hw.tcl.dirty) - space_required += rmesa->hw.tcl.check( rmesa->radeon.glCtx, &rmesa->hw.tcl ); + state_size += rmesa->hw.tcl.check( rmesa->radeon.glCtx, &rmesa->hw.tcl ); /* predict size for elements */ for (i = 0; i < VB->PrimitiveCount; ++i) { @@ -414,7 +417,10 @@ static void radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) space_required += SCISSOR_BUFSZ; } /* flush the buffer in case we need more than is left. */ - rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required, __FUNCTION__); + if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required, __FUNCTION__)) + return space_required + radeonCountStateEmitSize( &rmesa->radeon ); + else + return space_required + state_size; } /**********************************************************************/ @@ -467,7 +473,8 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx, } radeonReleaseArrays( ctx, ~0 ); - radeonEnsureEmitSize( ctx, inputs ); + GLuint emit_end = radeonEnsureEmitSize( ctx, inputs ) + + rmesa->radeon.cmdbuf.cs->cdw; radeonEmitArrays( ctx, inputs ); rmesa->tcl.Elts = VB->Elts; @@ -487,6 +494,10 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx, radeonEmitPrimitive( ctx, start, start+length, prim ); } + if (emit_end < rmesa->radeon.cmdbuf.cs->cdw) + WARN_ONCE("Rendering was %d commands larger than predicted size." + " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end); + return GL_FALSE; /* finished the pipe */ } |