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;
}
}
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;
}