From d6b5464aaa93585376610ce8cace66ea3798723d Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Fri, 21 Aug 2009 18:55:34 +0300 Subject: r300: Predict emit size for next rendering operation. We do flush for cmd buffer in case there isn't enough space left for whole rendering operation. This protects dma regions from getting released in middle of state emit. Signed-off-by: Pauli Nieminen --- src/mesa/drivers/dri/r300/r300_cmdbuf.h | 6 ++++++ src/mesa/drivers/dri/r300/r300_draw.c | 35 +++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/r300') diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index 53bcc0eeb4..1b703e518a 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -38,6 +38,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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); diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 3cdb9dc2ed..03521e3fb6 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -39,6 +39,7 @@ #include "r300_render.h" #include "r300_state.h" #include "r300_tex.h" +#include "r300_cmdbuf.h" #include "radeon_buffer_objects.h" @@ -567,6 +568,34 @@ static void r300FreeData(GLcontext *ctx) } } +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, @@ -592,8 +621,6 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, 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__); @@ -607,6 +634,10 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx, 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); -- cgit v1.2.3