nv50: use hw idx buffers where we can
authorBen Skeggs <bskeggs@redhat.com>
Tue, 16 Feb 2010 05:43:51 +0000 (15:43 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 16 Feb 2010 05:57:59 +0000 (15:57 +1000)
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_vbo.c

index 8c4478e483b6fa1a60e7b97a723e5c7857eb3d86..2232461b9b66a3daa29014f15840cc919a9bcb2d 100644 (file)
@@ -134,7 +134,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
        case NOUVEAU_CAP_HW_VTXBUF:
                return 1;
        case NOUVEAU_CAP_HW_IDXBUF:
-               return 0;
+               return 1;
        case PIPE_CAP_INDEP_BLEND_ENABLE:
                return 1;
        case PIPE_CAP_INDEP_BLEND_FUNC:
index 7a2618d2a3a16964deb97885ca1f311fc7ea9e5e..1c8ee0b9adf83364c5720ef7f3a4c8d293c3e91f 100644 (file)
@@ -673,8 +673,6 @@ nv50_draw_elements(struct pipe_context *pipe,
        struct pipe_screen *pscreen = pipe->screen;
        void *map;
        
-       map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
-
        nv50_state_validate(nv50);
 
        BEGIN_RING(chan, tesla, 0x142c, 1);
@@ -685,14 +683,35 @@ nv50_draw_elements(struct pipe_context *pipe,
        BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
        OUT_RING  (chan, nv50_prim(mode));
 
-       nv50_draw_elements_inline(nv50, map, indexSize, start, count);
+       if (!nv50->vbo_fifo && indexSize == 4) {
+               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
+               OUT_RING  (chan, count);
+               nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+                                      start << 2, count << 2);
+       } else
+       if (!nv50->vbo_fifo && indexSize == 2) {
+               unsigned vb_start = (start & ~1);
+               unsigned vb_end = (start + count + 1) & ~1;
+               unsigned dwords = (vb_end - vb_start) >> 1;
+
+               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+               OUT_RING  (chan, ((start & 1) << 31) | count);
+               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
+               OUT_RING  (chan, dwords);
+               nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+                                      vb_start << 1, dwords << 2);
+               BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+               OUT_RING  (chan, 0);
+       } else {
+               map = pipe_buffer_map(pscreen, indexBuffer,
+                                     PIPE_BUFFER_USAGE_CPU_READ);
+               nv50_draw_elements_inline(nv50, map, indexSize, start, count);
+               nv50_unmap_vbufs(nv50);
+               pipe_buffer_unmap(pscreen, indexBuffer);
+       }
 
        BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
        OUT_RING  (chan, 0);
-
-       nv50_unmap_vbufs(nv50);
-
-       pipe_buffer_unmap(pscreen, indexBuffer);
 }
 
 static INLINE boolean