r600: fix r700PredictRenderSize for draw prims path
[mesa.git] / src / mesa / drivers / dri / r600 / r700_render.c
index daa05f653dc8149eed4c5a7bd7bf2b35012d790b..bdf0bfc0e43ebaedbb95b88a6d71ac54af359e76 100644 (file)
@@ -262,6 +262,16 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
        TNLcontext *tnl = TNL_CONTEXT(ctx);
        struct vertex_buffer *vb = &tnl->vb;
 
+    GLboolean bUseDrawIndex;
+    if( (NULL != context->ind_buf.bo) && (GL_TRUE != context->ind_buf.bHostIb) )
+    {
+        bUseDrawIndex = GL_TRUE;
+    }
+    else
+    {
+        bUseDrawIndex = GL_FALSE;
+    }
+
        type = r700PrimitiveType(prim);
        num_indices = r700NumVerts(end - start, prim);
 
@@ -272,10 +282,20 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
        if (type < 0 || num_indices <= 0)
                return;
 
-    total_emit =   3 /* VGT_PRIMITIVE_TYPE */
-            + 2 /* VGT_INDEX_TYPE */
-            + 2 /* NUM_INSTANCES */
+    if(GL_TRUE == bUseDrawIndex)
+    {
+        total_emit =   3  /* VGT_PRIMITIVE_TYPE */
+                        + 2  /* VGT_INDEX_TYPE */
+                        + 2  /* NUM_INSTANCES */
+                     + 5+2; /* DRAW_INDEX */
+    }
+    else
+    {
+        total_emit =   3 /* VGT_PRIMITIVE_TYPE */
+                + 2 /* VGT_INDEX_TYPE */
+                + 2 /* NUM_INSTANCES */
                  + num_indices + 3; /* DRAW_INDEX_IMMD */
+    }
 
     BEGIN_BATCH_NO_AUTOSTATE(total_emit);
        // prim
@@ -287,6 +307,15 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
 
        // index type
     SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+
+    if(GL_TRUE == bUseDrawIndex)
+    {
+        if(GL_TRUE != context->ind_buf.is_32bit)
+        {
+            SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+        }
+    }
+
     R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
     R600_OUT_BATCH(vgt_index_type);
 
@@ -296,12 +325,36 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
 
        // draw packet
     vgt_num_indices = num_indices;
-    SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+
+    if(GL_TRUE == bUseDrawIndex)
+    {
+        SETfield(vgt_draw_initiator, DI_SRC_SEL_DMA, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+    }
+    else
+    {
+        SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+    }
+
        SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
 
-    R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
-    R600_OUT_BATCH(vgt_num_indices);
-    R600_OUT_BATCH(vgt_draw_initiator);
+    if(GL_TRUE == bUseDrawIndex)
+    {
+        R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3));
+        R600_OUT_BATCH(context->ind_buf.bo_offset);
+        R600_OUT_BATCH(0);
+        R600_OUT_BATCH(vgt_num_indices);
+        R600_OUT_BATCH(vgt_draw_initiator);
+        R600_OUT_BATCH_RELOC(context->ind_buf.bo_offset,
+                             context->ind_buf.bo,
+                             context->ind_buf.bo_offset,
+                             RADEON_GEM_DOMAIN_GTT, 0, 0);
+    }
+    else
+    {
+        R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
+        R600_OUT_BATCH(vgt_num_indices);
+        R600_OUT_BATCH(vgt_draw_initiator);
+    }
 
     if(NULL == context->ind_buf.bo)
     {
@@ -340,10 +393,6 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
                 }
             }
         }
-        else
-        {
-            /* TODO : hw ib draw */
-        }
     }
 
     END_BATCH();
@@ -353,12 +402,10 @@ 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)
+static GLuint r700PredictRenderSize(GLcontext* ctx, GLuint nr_prims)
 {
     context_t *context = R700_CONTEXT(ctx);
-    TNLcontext *tnl = TNL_CONTEXT(ctx);
     struct r700_vertex_program *vp = context->selected_vp;
-    struct vertex_buffer *vb = &tnl->vb;
     GLboolean flushed;
     GLuint dwords, i;
     GLuint state_size;
@@ -366,8 +413,15 @@ static GLuint r700PredictRenderSize(GLcontext* ctx)
     context->radeon.tcl.aos_count = _mesa_bitcount(vp->mesa_program->Base.InputsRead);
 
     dwords = PRE_EMIT_STATE_BUFSZ;
-    for (i = 0; i < vb->PrimitiveCount; i++)
-        dwords += vb->Primitive[i].count + 10;
+    if (nr_prims)
+           dwords += nr_prims * 14;
+    else {
+           TNLcontext *tnl = TNL_CONTEXT(ctx);
+           struct vertex_buffer *vb = &tnl->vb;
+
+           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__);
@@ -407,7 +461,7 @@ static GLboolean r700RunRender(GLcontext * ctx,
     r700SetupFragmentProgram(ctx);
     r600UpdateTextureState(ctx);
 
-    GLuint emit_end = r700PredictRenderSize(ctx
+    GLuint emit_end = r700PredictRenderSize(ctx, 0)
         + context->radeon.cmdbuf.cs->cdw;
     r700SetupStreams(ctx);
 
@@ -899,7 +953,7 @@ static void r700SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
         return;
     }
 
-    context->ind_buf.bHostIb = GL_TRUE;
+    context->ind_buf.bHostIb = GL_FALSE;
 
 #if MESA_BIG_ENDIAN
     if (mesa_ind_buf->type == GL_UNSIGNED_INT) 
@@ -995,7 +1049,7 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx,
 
     r600UpdateTextureState(ctx);
 
-    GLuint emit_end = r700PredictRenderSize(ctx
+    GLuint emit_end = r700PredictRenderSize(ctx, nr_prims)
                     + context->radeon.cmdbuf.cs->cdw;
 
     r700SetupIndexBuffer(ctx, ib);