diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 74519489f7..586a6c49de 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -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; } |