#include "r300_context.h"
+#define CACHE_FLUSH_BUFSZ (4*2)
+#define PRE_EMIT_STATE_BUFSZ (2+2)
+#define AOS_BUFSZ(nr) (3+(nr >>1)*3 + (nr&1)*2 + (nr*2))
+#define FIREAOS_BUFSZ (3)
+#define SCISSORS_BUFSZ (3)
+
extern void r300InitCmdBuf(r300ContextPtr r300);
void r300_emit_scissor(GLcontext *ctx);
#include "r300_render.h"
#include "r300_state.h"
#include "r300_tex.h"
+#include "r300_cmdbuf.h"
#include "radeon_buffer_objects.h"
}
}
+static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, GLuint nr_prims)
+{
+ struct r300_context *r300 = R300_CONTEXT(ctx);
+ struct r300_vertex_buffer *vbuf = &r300->vbuf;
+ int flushed;
+ GLuint dwords;
+ GLuint state_size;
+
+ dwords = 2*CACHE_FLUSH_BUFSZ;
+ dwords += PRE_EMIT_STATE_BUFSZ;
+ dwords += (AOS_BUFSZ(vbuf->num_attribs)
+ + SCISSORS_BUFSZ
+ + FIREAOS_BUFSZ )*nr_prims;
+
+ state_size= radeonCountEmitSize(&r300->radeon);
+ flushed = rcommonEnsureCmdBufSpace(&r300->radeon,
+ dwords + state_size,
+ __FUNCTION__);
+ if (flushed)
+ dwords += radeonCountEmitSize(&r300->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 r300TryDrawPrims(GLcontext *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx));
- /* ensure we have the cmd buf space in advance to cover
- * the state + DMA AOS pointers */
rcommonEnsureCmdBufSpace(&r300->radeon,
r300->radeon.hw.max_state_size + (60*sizeof(int)),
__FUNCTION__);
r300UpdateShaderStates(r300);
+ /* ensure we have the cmd buf space in advance to cover
+ * the state + DMA AOS pointers */
+ r300PredictTryDrawPrimsSize(ctx, nr_prims);
+
r300SetupIndexBuffer(ctx, ib);
r300AllocDmaRegions(ctx, arrays, max_index + 1);
#include "radeon_bocs_wrapper.h"
-void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
+int rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
void rcommonInitCmdBuf(radeonContextPtr rmesa);
*
* \param dwords The number of dwords we need to be free on the command buffer
*/
-void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
+int rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
{
if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
|| radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
/* If we try to flush empty buffer there is too big rendering operation. */
assert(rmesa->cmdbuf.cs->cdw);
rcommonFlushCmdBuf(rmesa, caller);
+ return GL_TRUE;
}
+ return GL_FALSE;
}
void rcommonInitCmdBuf(radeonContextPtr rmesa)