Merge branch 'xa_branch'
[mesa.git] / src / mesa / drivers / dri / r600 / r700_render.c
index 316a0943f4ec0eb36f51811d9933d467c9a9e874..0f7a7a46b714eed05526a200b6634fe2dc63ff91 100644 (file)
@@ -244,7 +244,8 @@ static int r700NumVerts(int num_verts, int prim)
        return num_verts - verts_off;
 }
 
-static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
+static void r700RunRenderPrimitive(struct gl_context * ctx, int start, int end,
+                                  int prim, GLint basevertex)
 {
     context_t *context = R700_CONTEXT(ctx);
     BATCH_LOCALS(&context->radeon);
@@ -275,6 +276,16 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
             SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
     }
 
+       /* 16-bit indexes are packed in a 32-bit value */
+       SETfield(vgt_index_type,
+#if MESA_BIG_ENDIAN
+                       VGT_DMA_SWAP_32_BIT,
+#else
+                       VGT_DMA_SWAP_NONE,
+#endif
+                       SWAP_MODE_shift, SWAP_MODE_mask);
+
+
     vgt_num_indices = num_indices;
     SETfield(vgt_draw_initiator, DI_SRC_SEL_DMA, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
     SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
@@ -282,6 +293,7 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
     total_emit =   3  /* VGT_PRIMITIVE_TYPE */
                 + 2  /* VGT_INDEX_TYPE */
                 + 2  /* NUM_INSTANCES */
+                + 4  /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */
                 + 5 + 2; /* DRAW_INDEX */
 
     BEGIN_BATCH_NO_AUTOSTATE(total_emit);
@@ -294,6 +306,11 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
     // num instances
     R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
     R600_OUT_BATCH(1);
+    /* offset */
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2));
+    R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
+    R600_OUT_BATCH(basevertex); //VTX_BASE_VTX_LOC
+    R600_OUT_BATCH(0);          //VTX_START_INST_LOC
     // draw packet
     R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3));
     R600_OUT_BATCH(context->ind_buf.bo_offset);
@@ -308,11 +325,11 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
     COMMIT_BATCH();
 }
 
-static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, int prim)
+static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start, int end, int prim)
 {
     context_t *context = R700_CONTEXT(ctx);
     BATCH_LOCALS(&context->radeon);
-    int type, i;
+    int type;
     uint32_t num_indices, total_emit = 0;
     uint32_t vgt_draw_initiator = 0;
     uint32_t vgt_index_type     = 0;
@@ -341,29 +358,24 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end,
             SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
     }
 
+       /* 16-bit indexes are packed in a 32-bit value */
+       SETfield(vgt_index_type,
+#if MESA_BIG_ENDIAN
+                       VGT_DMA_SWAP_32_BIT,
+#else
+                       VGT_DMA_SWAP_NONE,
+#endif
+                       SWAP_MODE_shift, SWAP_MODE_mask);
+
     vgt_num_indices = num_indices;
     SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
 
-    if (start == 0)
-    {
-       SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
-    }
-    else
-    {
-       if (num_indices > 0xffff)
-       {
-               total_emit += num_indices;
-       }
-       else
-       {
-               total_emit += (num_indices + 1) / 2;
-       }
-       SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
-    }
+    SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
 
     total_emit +=   3 /* VGT_PRIMITIVE_TYPE */
                  + 2 /* VGT_INDEX_TYPE */
                  + 2 /* NUM_INSTANCES */
+                 + 4 /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */
                  + 3; /* DRAW */
 
     BEGIN_BATCH_NO_AUTOSTATE(total_emit);
@@ -376,43 +388,16 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end,
     // num instances
     R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
     R600_OUT_BATCH(1);
+    /* offset */
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2));
+    R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
+    R600_OUT_BATCH(start); //VTX_BASE_VTX_LOC
+    R600_OUT_BATCH(0); //VTX_START_INST_LOC
     // draw packet
-    if(start == 0)
-    {
-        R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
-        R600_OUT_BATCH(vgt_num_indices);
-        R600_OUT_BATCH(vgt_draw_initiator);
-    }
-    else
-    {
-       if (num_indices > 0xffff)
-        {
-           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);
-           for (i = start; i < (start + num_indices); i++)
-           {
-               R600_OUT_BATCH(i);
-           }
-       }
-       else
-        {
-           R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (((num_indices + 1) / 2) + 1)));
-           R600_OUT_BATCH(vgt_num_indices);
-           R600_OUT_BATCH(vgt_draw_initiator);
-           for (i = start; i < (start + num_indices); i += 2)
-           {
-               if ((i + 1) == (start + num_indices))
-               {
-                   R600_OUT_BATCH(i);
-               }
-               else
-               {
-                   R600_OUT_BATCH(((i + 1) << 16) | (i));
-               }
-           }
-       }
-    }
+    
+    R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
+    R600_OUT_BATCH(vgt_num_indices);
+    R600_OUT_BATCH(vgt_draw_initiator);
 
     END_BATCH();
     COMMIT_BATCH();
@@ -421,7 +406,7 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end,
 /* start 3d, idle, cb/db flush */
 #define PRE_EMIT_STATE_BUFSZ 5 + 5 + 14
 
-static GLuint r700PredictRenderSize(GLcontext* ctx,
+static GLuint r700PredictRenderSize(struct gl_context* ctx,
                                    const struct _mesa_prim *prim,
                                    const struct _mesa_index_buffer *ib,
                                    GLuint nr_prims)
@@ -433,16 +418,11 @@ static GLuint r700PredictRenderSize(GLcontext* ctx,
 
     dwords = PRE_EMIT_STATE_BUFSZ;
     if (ib)
-           dwords += nr_prims * 14;
+           dwords += nr_prims * 18;
     else {
            for (i = 0; i < nr_prims; ++i)
            {
-                   if (prim[i].start == 0)
-                           dwords += 10;
-                   else if (prim[i].count > 0xffff)
-                           dwords += prim[i].count + 10;
-                   else
-                           dwords += ((prim[i].count + 1) / 2) + 10;
+               dwords += 14;
            }
     }
 
@@ -488,7 +468,7 @@ static GLuint r700PredictRenderSize(GLcontext* ctx,
  * Convert attribute data type to float
  * If the attribute uses named buffer object replace the bo with newly allocated bo
  */
-static void r700ConvertAttrib(GLcontext *ctx, int count, 
+static void r700ConvertAttrib(struct gl_context *ctx, int count, 
                               const struct gl_client_array *input, 
                               struct StreamDesc *attr)
 {
@@ -567,7 +547,8 @@ static void r700ConvertAttrib(GLcontext *ctx, int count,
     }
 }
 
-static void r700AlignDataToDword(GLcontext *ctx, 
+#if 0 /* unused */
+static void r700AlignDataToDword(struct gl_context *ctx, 
                                  const struct gl_client_array *input, 
                                  int count, 
                                  struct StreamDesc *attr)
@@ -608,8 +589,9 @@ static void r700AlignDataToDword(GLcontext *ctx,
 
     attr->stride = dst_stride;
 }
+#endif
 
-static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input[], int count)
+static void r700SetupStreams(struct gl_context *ctx, const struct gl_client_array *input[], int count)
 {
        context_t *context = R700_CONTEXT(ctx);
     GLuint stride;
@@ -625,31 +607,23 @@ static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input
 
         stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB;
 
-        if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT ||
+        if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT
 #if MESA_BIG_ENDIAN
-            getTypeSize(input[i]->Type) != 4 || 
+            || getTypeSize(input[i]->Type) != 4
 #endif
-            stride < 4
+            ) 
         {
+            assert(count);
             r700ConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
         } 
         else 
         {
             if (input[i]->BufferObj->Name) 
             {
-                if (stride % 4 != 0) 
-                {
-                    assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
-                    r700AlignDataToDword(ctx, input[i], count, &context->stream_desc[index]);
-                    context->stream_desc[index].is_named_bo = GL_FALSE;
-                } 
-                else 
-                {
-                    context->stream_desc[index].stride = input[i]->StrideB;
-                    context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
-                    context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
-                    context->stream_desc[index].is_named_bo = GL_TRUE;
-                }
+                context->stream_desc[index].stride = input[i]->StrideB;
+                context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
+                context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
+                context->stream_desc[index].is_named_bo = GL_TRUE;
             } 
             else 
             {
@@ -718,7 +692,7 @@ static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input
                                         RADEON_GEM_DOMAIN_GTT, 0);    
 }
 
-static void r700FreeData(GLcontext *ctx)
+static void r700FreeData(struct gl_context *ctx)
 {
     /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
      * to prevent double unref in radeonReleaseArrays
@@ -743,7 +717,7 @@ static void r700FreeData(GLcontext *ctx)
     }
 }
 
-static void r700FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+static void r700FixupIndexBuffer(struct gl_context *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
 {
     context_t *context = R700_CONTEXT(ctx);
     GLvoid *src_ptr;
@@ -818,7 +792,7 @@ static void r700FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
     }
 }
 
-static void r700SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+static void r700SetupIndexBuffer(struct gl_context *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
 {
     context_t *context = R700_CONTEXT(ctx);
 
@@ -871,7 +845,7 @@ static void r700SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
     }
 }
 
-static GLboolean check_fallbacks(GLcontext *ctx)
+static GLboolean check_fallbacks(struct gl_context *ctx)
 {
        if (ctx->RenderMode != GL_RENDER)
                return GL_TRUE;
@@ -879,7 +853,7 @@ static GLboolean check_fallbacks(GLcontext *ctx)
        return GL_FALSE;
 }
 
-static GLboolean r700TryDrawPrims(GLcontext *ctx,
+static GLboolean r700TryDrawPrims(struct gl_context *ctx,
                                  const struct gl_client_array *arrays[],
                                  const struct _mesa_prim *prim,
                                  GLuint nr_prims,
@@ -932,7 +906,8 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx,
                    r700RunRenderPrimitive(ctx,
                                           prim[i].start,
                                           prim[i].start + prim[i].count,
-                                          prim[i].mode);
+                                          prim[i].mode,
+                                          prim[i].basevertex);
            else
                    r700RunRenderPrimitiveImmediate(ctx,
                                                    prim[i].start,
@@ -966,7 +941,7 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx,
     return GL_TRUE;
 }
 
-static void r700DrawPrims(GLcontext *ctx,
+static void r700DrawPrims(struct gl_context *ctx,
                          const struct gl_client_array *arrays[],
                          const struct _mesa_prim *prim,
                          GLuint nr_prims,
@@ -984,15 +959,17 @@ static void r700DrawPrims(GLcontext *ctx,
        /* This check should get folded into just the places that
         * min/max index are really needed.
         */
-       if (!index_bounds_valid) {
-               vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
-       }
 
-       if (min_index) {
+       if (!vbo_all_varyings_in_vbos(arrays)) {
+           if (!index_bounds_valid)
+               vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+           /* do we want to rebase, minimizes the 
+            * amount of data to upload? */
+           if (min_index) {
                vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r700DrawPrims );
                return;
+           }
        }
-
        /* Make an attempt at drawing */
        retval = r700TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
 
@@ -1003,7 +980,7 @@ static void r700DrawPrims(GLcontext *ctx,
        }
 }
 
-void r700InitDraw(GLcontext *ctx)
+void r700InitDraw(struct gl_context *ctx)
 {
        struct vbo_context *vbo = vbo_context(ctx);