r300: Predict emit size for next rendering operation.
authorPauli Nieminen <suokkos@gmail.com>
Fri, 21 Aug 2009 15:55:34 +0000 (18:55 +0300)
committerPauli Nieminen <suokkos@gmail.com>
Fri, 21 Aug 2009 16:12:31 +0000 (19:12 +0300)
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 <suokkos@gmail.com>
src/mesa/drivers/dri/r300/r300_cmdbuf.h
src/mesa/drivers/dri/r300/r300_draw.c
src/mesa/drivers/dri/radeon/radeon_cmdbuf.h
src/mesa/drivers/dri/radeon/radeon_common.c

index 53bcc0eeb49d6db0373487d32f2a01c6d82ad0c5..1b703e518a0c403196553c27de42e7bf7d5c8201 100644 (file)
@@ -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);
 
index 3cdb9dc2edb256e7a155c3a5a89605eb4ce5b1b2..03521e3fb6d5e836fa250c74f5e621d4c928eb79 100644 (file)
@@ -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);
index 7d025fcac6fb2c4aa0ec4a92843aff32d6223590..da748515addcc4e299dddb47f228e16052bd13f8 100644 (file)
@@ -3,7 +3,7 @@
 
 #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);
index f0cf31c55f04be32ff0b336ce531fa0feda34a02..6c3f7a57e504b205dcfa52afd3d3622dc1104ce6 100644 (file)
@@ -1189,14 +1189,16 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
  *
  * \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)