nv50: draw_elements() - inline only for the moment
authorBen Skeggs <skeggsb@gmail.com>
Thu, 12 Jun 2008 04:15:38 +0000 (14:15 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 29 Jun 2008 05:46:17 +0000 (15:46 +1000)
src/gallium/drivers/nv50/nv50_vbo.c

index 7451948..586a6c4 100644 (file)
@@ -52,16 +52,110 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
        return TRUE;
 }
 
+static INLINE void
+nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
+                             unsigned start, unsigned count)
+{
+       map += start;
+
+       if (count & 1) {
+               BEGIN_RING(tesla, 0x15e8, 1);
+               OUT_RING  (map[0]);
+               map++;
+               count--;
+       }
+
+       while (count) {
+               unsigned nr = count > 2046 ? 2046 : count;
+               int i;
+
+               BEGIN_RING(tesla, 0x400015f0, nr >> 1);
+               for (i = 0; i < nr; i += 2)
+                       OUT_RING  ((map[1] << 16) | map[0]);
+
+               count -= nr;
+               map += nr;
+       }
+}
+
+static INLINE void
+nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
+                             unsigned start, unsigned count)
+{
+       map += start;
+
+       if (count & 1) {
+               BEGIN_RING(tesla, 0x15e8, 1);
+               OUT_RING  (map[0]);
+               map++;
+               count--;
+       }
+
+       while (count) {
+               unsigned nr = count > 2046 ? 2046 : count;
+               int i;
+
+               BEGIN_RING(tesla, 0x400015f0, nr >> 1);
+               for (i = 0; i < nr; i += 2)
+                       OUT_RING  ((map[1] << 16) | map[0]);
+
+               count -= nr;
+               map += nr;
+       }
+}
+
+static INLINE void
+nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map,
+                             unsigned start, unsigned count)
+{
+       map += start;
+
+       while (count) {
+               unsigned nr = count > 2047 ? 2047 : count;
+
+               BEGIN_RING(tesla, 0x400015e8, nr);
+               OUT_RINGp (map, nr);
+
+               count -= nr;
+               map += nr;
+       }
+}
+
 boolean
 nv50_draw_elements(struct pipe_context *pipe,
                   struct pipe_buffer *indexBuffer, unsigned indexSize,
                   unsigned mode, unsigned start, unsigned count)
 {
        struct nv50_context *nv50 = nv50_context(pipe);
+       struct pipe_winsys *ws = pipe->winsys;
+       void *map = ws->buffer_map(ws, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
 
        nv50_state_validate(nv50);
 
-       NOUVEAU_ERR("unimplemented\n");
+       BEGIN_RING(tesla, 0x142c, 1);
+       OUT_RING  (0);
+       BEGIN_RING(tesla, 0x142c, 1);
+       OUT_RING  (0);
+
+       BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1);
+       OUT_RING  (nv50_prim(mode));
+       switch (indexSize) {
+       case 1:
+               nv50_draw_elements_inline_u08(nv50, map, start, count);
+               break;
+       case 2:
+               nv50_draw_elements_inline_u16(nv50, map, start, count);
+               break;
+       case 4:
+               nv50_draw_elements_inline_u32(nv50, map, start, count);
+               break;
+       default:
+               assert(0);
+       }
+       BEGIN_RING(tesla, NV50TCL_VERTEX_END, 1);
+       OUT_RING  (0);
+
+       pipe->flush(pipe, 0, NULL);
        return TRUE;
 }