diff options
Diffstat (limited to 'src/mesa/drivers/dri/r600/r700_render.c')
-rw-r--r-- | src/mesa/drivers/dri/r600/r700_render.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 9c4be37aac..e03b060fd9 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -298,28 +298,61 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim } +/* start 3d, idle, cb/db flush */ +#define PRE_EMIT_STATE_BUFSZ 10 + 5 + 14 + +static GLuint r700PredictRenderSize(GLcontext* ctx) +{ + context_t *context = R700_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct r700_vertex_program *vpc + = (struct r700_vertex_program *)ctx->VertexProgram._Current; + struct vertex_buffer *vb = &tnl->vb; + GLboolean flushed; + GLuint dwords, i; + GLuint state_size; + /* pre calculate aos count so state prediction works */ + context->radeon.tcl.aos_count = _mesa_bitcount(vpc->mesa_program.Base.InputsRead); + + dwords = PRE_EMIT_STATE_BUFSZ; + for (i = 0; i < vb->PrimitiveCount; i++) + dwords += vb->Primitive[i].count + 10; + state_size = radeonCountStateEmitSize(&context->radeon); + flushed = rcommonEnsureCmdBufSpace(&context->radeon, + dwords + state_size, __FUNCTION__); + + if (flushed) + dwords += radeonCountStateEmitSize(&context->radeon); + else + dwords += state_size; + + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: total prediction size is %d.\n", __FUNCTION__, dwords); + return dwords; +} + static GLboolean r700RunRender(GLcontext * ctx, struct tnl_pipeline_stage *stage) { context_t *context = R700_CONTEXT(ctx); radeonContextPtr radeon = &context->radeon; - unsigned int i, ind_count = 0, id = 0; + unsigned int i, id = 0; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *vb = &tnl->vb; struct radeon_renderbuffer *rrb; - for (i = 0; i < vb->PrimitiveCount; i++) - ind_count += vb->Primitive[i].count + 10; - - /* just an estimate, need to properly calculate this */ - rcommonEnsureCmdBufSpace(&context->radeon, - radeon->hw.max_state_size + ind_count, __FUNCTION__); + if (RADEON_DEBUG & DEBUG_PRIMS) + fprintf(stderr, "%s: cs begin at %d\n", + __func__, context->radeon.cmdbuf.cs->cdw); r700UpdateShaders(ctx); r700SetScissor(context); r700SetupVertexProgram(ctx); r700SetupFragmentProgram(ctx); r600UpdateTextureState(ctx); + + GLuint emit_end = r700PredictRenderSize(ctx) + + context->radeon.cmdbuf.cs->cdw; r700SetupStreams(ctx); radeonEmitState(radeon); @@ -329,7 +362,7 @@ static GLboolean r700RunRender(GLcontext * ctx, GLuint prim = _tnl_translate_prim(&vb->Primitive[i]); GLuint start = vb->Primitive[i].start; GLuint end = vb->Primitive[i].start + vb->Primitive[i].count; - r700RunRenderPrimitive(ctx, start, end, prim); + r700RunRenderPrimitive(ctx, start, end, prim); } /* Flush render op cached for last several quads. */ @@ -346,6 +379,7 @@ static GLboolean r700RunRender(GLcontext * ctx, DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit); radeonReleaseArrays(ctx, ~0); + assert(context->radeon.cmdbuf.cs->cdw <= emit_end); return GL_FALSE; } |