nv40: convert the inline idxbuf paths also
authorBen Skeggs <skeggsb@gmail.com>
Fri, 28 Mar 2008 13:30:04 +0000 (00:30 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 4 Apr 2008 01:17:27 +0000 (11:17 +1000)
src/gallium/drivers/nv40/nv40_vbo.c

index 33d3efb58d06dca85ba51a210949a8488c9dd06c..8cc977a19a1286ea5e0131d2e3e45b33f6a80610 100644 (file)
@@ -232,69 +232,139 @@ nv40_draw_arrays(struct pipe_context *pipe,
 
 static INLINE void
 nv40_draw_elements_u08(struct nv40_context *nv40, void *ib,
-                      unsigned start, unsigned count)
+                      unsigned mode, unsigned start, unsigned count)
 {
-       uint8_t *elts = (uint8_t *)ib + start;
-       int push, i;
-
-       if (count & 1) {
-               BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
-               OUT_RING  (elts[0]);
-               elts++; count--;
-       }
+       struct nouveau_channel *chan = nv40->nvws->channel;
 
        while (count) {
-               push = MIN2(count, 2047 * 2);
+               uint8_t *elts = (uint8_t *)ib + start;
+               unsigned vc, push, restart;
+
+               nv40_state_emit(nv40);
+
+               vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(NULL);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (nvgl_primitive(mode));
+
+               if (vc & 1) {
+                       BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
+                       OUT_RING  (elts[0]);
+                       elts++; vc--;
+               }
+
+               while (vc) {
+                       unsigned i;
+
+                       push = MIN2(vc, 2047 * 2);
 
-               BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
-               for (i = 0; i < push; i+=2)
-                       OUT_RING((elts[i+1] << 16) | elts[i]);
+                       BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
+                       for (i = 0; i < push; i+=2)
+                               OUT_RING((elts[i+1] << 16) | elts[i]);
 
-               count -= push;
-               elts  += push;
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (0);
+
+               start = restart;
        }
 }
 
 static INLINE void
 nv40_draw_elements_u16(struct nv40_context *nv40, void *ib,
-                      unsigned start, unsigned count)
+                      unsigned mode, unsigned start, unsigned count)
 {
-       uint16_t *elts = (uint16_t *)ib + start;
-       int push, i;
-
-       if (count & 1) {
-               BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
-               OUT_RING  (elts[0]);
-               elts++; count--;
-       }
+       struct nouveau_channel *chan = nv40->nvws->channel;
 
        while (count) {
-               push = MIN2(count, 2047 * 2);
+               uint16_t *elts = (uint16_t *)ib + start;
+               unsigned vc, push, restart;
 
-               BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
-               for (i = 0; i < push; i+=2)
-                       OUT_RING((elts[i+1] << 16) | elts[i]);
+               nv40_state_emit(nv40);
 
-               count -= push;
-               elts  += push;
+               vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(NULL);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (nvgl_primitive(mode));
+
+               if (vc & 1) {
+                       BEGIN_RING(curie, NV40TCL_VB_ELEMENT_U32, 1);
+                       OUT_RING  (elts[0]);
+                       elts++; vc--;
+               }
+
+               while (vc) {
+                       unsigned i;
+
+                       push = MIN2(vc, 2047 * 2);
+
+                       BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
+                       for (i = 0; i < push; i+=2)
+                               OUT_RING((elts[i+1] << 16) | elts[i]);
+
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (0);
+
+               start = restart;
        }
 }
 
 static INLINE void
 nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
-                      unsigned start, unsigned count)
+                      unsigned mode, unsigned start, unsigned count)
 {
-       uint32_t *elts = (uint32_t *)ib + start;
-       int push;
+       struct nouveau_channel *chan = nv40->nvws->channel;
 
        while (count) {
-               push = MIN2(count, 2047);
+               uint32_t *elts = (uint32_t *)ib + start;
+               unsigned vc, push, restart;
+
+               nv40_state_emit(nv40);
+
+               vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(NULL);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (nvgl_primitive(mode));
+
+               while (vc) {
+                       push = MIN2(vc, 2047);
 
-               BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push);
-               OUT_RINGp    (elts, push);
+                       BEGIN_RING_NI(curie, NV40TCL_VB_ELEMENT_U32, push);
+                       OUT_RINGp    (elts, push);
 
-               count -= push;
-               elts  += push;
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+               OUT_RING  (0);
+
+               start = restart;
        }
 }
 
@@ -315,29 +385,22 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
                return FALSE;
        }
 
-       BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-       OUT_RING  (nvgl_primitive(mode));
-
        switch (ib_size) {
        case 1:
-               nv40_draw_elements_u08(nv40, map, start, count);
+               nv40_draw_elements_u08(nv40, map, mode, start, count);
                break;
        case 2:
-               nv40_draw_elements_u16(nv40, map, start, count);
+               nv40_draw_elements_u16(nv40, map, mode, start, count);
                break;
        case 4:
-               nv40_draw_elements_u32(nv40, map, start, count);
+               nv40_draw_elements_u32(nv40, map, mode, start, count);
                break;
        default:
                NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
                break;
        }
 
-       BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
-       OUT_RING  (0);
-
        ws->buffer_unmap(ws, ib);
-
        return TRUE;
 }