summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r600/r700_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r600/r700_render.c')
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index cdf3220a7f..d64e921bda 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);
@@ -298,22 +300,52 @@ 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);
/* always emit CB base to prevent
* lock ups on some chips.
@@ -327,6 +359,9 @@ static GLboolean r700RunRender(GLcontext * ctx,
r700SetupVertexProgram(ctx);
r700SetupFragmentProgram(ctx);
r600UpdateTextureState(ctx);
+
+ GLuint emit_end = r700PredictRenderSize(ctx)
+ + context->radeon.cmdbuf.cs->cdw;
r700SetupStreams(ctx);
radeonEmitState(radeon);
@@ -336,7 +371,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. */
@@ -354,6 +389,14 @@ static GLboolean r700RunRender(GLcontext * ctx,
radeonReleaseArrays(ctx, ~0);
+ if (RADEON_DEBUG & DEBUG_PRIMS)
+ fprintf(stderr, "%s: cs end at %d\n",
+ __func__, context->radeon.cmdbuf.cs->cdw);
+
+ 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;
}