summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/pipe/nv40/nv40_vbo.c113
1 files changed, 93 insertions, 20 deletions
diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c
index fda32cdb49..7562781fcf 100644
--- a/src/mesa/pipe/nv40/nv40_vbo.c
+++ b/src/mesa/pipe/nv40/nv40_vbo.c
@@ -149,7 +149,8 @@ nv40_vbo_arrays_update(struct nv40_context *nv40)
}
static boolean
-nv40_vbo_validate_state(struct nv40_context *nv40)
+nv40_vbo_validate_state(struct nv40_context *nv40,
+ struct pipe_buffer_handle *ib, unsigned ib_format)
{
unsigned inputs;
@@ -173,6 +174,14 @@ nv40_vbo_validate_state(struct nv40_context *nv40)
NV40TCL_VTXBUF_ADDRESS_DMA1);
}
+ if (ib) {
+ BEGIN_RING(curie, 0x181c, 2);
+ OUT_RELOCl(ib, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
+ NOUVEAU_BO_RD);
+ OUT_RELOCd(ib, ib_format, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
+ NOUVEAU_BO_RD | NOUVEAU_BO_OR, 0, 1);
+ }
+
BEGIN_RING(curie, 0x1710, 1);
OUT_RING (0); /* vtx cache flush */
@@ -186,7 +195,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
struct nv40_context *nv40 = (struct nv40_context *)pipe;
unsigned nr;
- assert(nv40_vbo_validate_state(nv40));
+ assert(nv40_vbo_validate_state(nv40, NULL, 0));
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (nvgl_primitive(mode));
@@ -286,45 +295,109 @@ nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
}
}
-boolean
-nv40_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer_handle *indexBuffer, unsigned indexSize,
- unsigned mode, unsigned start, unsigned count)
+static boolean
+nv40_draw_elements_inline(struct pipe_context *pipe,
+ struct pipe_buffer_handle *ib, unsigned ib_size,
+ unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = (struct nv40_context *)pipe;
- void *ib;
+ struct pipe_winsys *ws = pipe->winsys;
+ void *map;
- assert(nv40_vbo_validate_state(nv40));
+ assert(nv40_vbo_validate_state(nv40, NULL, 0));
- ib = pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
- PIPE_BUFFER_FLAG_READ);
- if (!ib) {
- NOUVEAU_ERR("Couldn't map index buffer!!\n");
- return FALSE;
- }
+ map = ws->buffer_map(ws, ib, PIPE_BUFFER_FLAG_READ);
+ if (!ib)
+ assert(0);
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (nvgl_primitive(mode));
- switch (indexSize) {
+ switch (ib_size) {
case 1:
- nv40_draw_elements_u08(nv40, ib, start, count);
+ nv40_draw_elements_u08(nv40, map, start, count);
break;
case 2:
- nv40_draw_elements_u16(nv40, ib, start, count);
+ nv40_draw_elements_u16(nv40, map, start, count);
break;
case 4:
- nv40_draw_elements_u32(nv40, ib, start, count);
+ nv40_draw_elements_u32(nv40, map, start, count);
break;
default:
- NOUVEAU_ERR("unsupported elt size %d\n", indexSize);
+ assert(0);
+ break;
+ }
+
+ BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+ OUT_RING (0);
+
+ ws->buffer_unmap(ws, ib);
+
+ return TRUE;
+}
+
+static boolean
+nv40_draw_elements_vbo(struct pipe_context *pipe,
+ struct pipe_buffer_handle *ib, unsigned ib_size,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct nv40_context *nv40 = (struct nv40_context *)pipe;
+ unsigned nr;
+
+ switch (ib_size) {
+ case 2:
+ assert(nv40_vbo_validate_state(nv40, ib, 0x00000010));
break;
+ case 4:
+ assert(nv40_vbo_validate_state(nv40, ib, 0x00000000));
+ break;
+ default:
+ assert(0);
+ }
+
+
+ BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
+ OUT_RING (nvgl_primitive(mode));
+
+ nr = (count & 0xff);
+ if (nr) {
+ BEGIN_RING(curie, 0x1824, 1);
+ OUT_RING (((nr - 1) << 24) | start);
+ start += nr;
+ }
+
+ nr = count >> 8;
+ while (nr) {
+ unsigned push = nr > 2047 ? 2047 : nr;
+
+ nr -= push;
+
+ BEGIN_RING_NI(curie, 0x1824, push);
+ while (push--) {
+ OUT_RING(((0x100 - 1) << 24) | start);
+ start += 0x100;
+ }
}
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (0);
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
+ return TRUE;
+}
+
+boolean
+nv40_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer_handle *indexBuffer, unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count)
+{
+ if (indexSize != 1) {
+ nv40_draw_elements_vbo(pipe, indexBuffer, indexSize,
+ mode, start, count);
+ } else {
+ nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
+ mode, start, count);
+ }
+
pipe->flush(pipe, 0);
return TRUE;
}