summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/pipe/nv40/nv40_context.h1
-rw-r--r--src/mesa/pipe/nv40/nv40_state_emit.c5
-rw-r--r--src/mesa/pipe/nv40/nv40_vbo.c176
3 files changed, 95 insertions, 87 deletions
diff --git a/src/mesa/pipe/nv40/nv40_context.h b/src/mesa/pipe/nv40/nv40_context.h
index 83d3f7b676..bf1534b69b 100644
--- a/src/mesa/pipe/nv40/nv40_context.h
+++ b/src/mesa/pipe/nv40/nv40_context.h
@@ -98,7 +98,6 @@ extern boolean nv40_draw_elements(struct pipe_context *pipe,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);
-extern void nv40_vbo_arrays_update(struct nv40_context *nv40);
/* nv40_clear.c */
extern void nv40_clear(struct pipe_context *pipe, struct pipe_surface *ps,
diff --git a/src/mesa/pipe/nv40/nv40_state_emit.c b/src/mesa/pipe/nv40/nv40_state_emit.c
index fb2a3cb98e..c53b5d852a 100644
--- a/src/mesa/pipe/nv40/nv40_state_emit.c
+++ b/src/mesa/pipe/nv40/nv40_state_emit.c
@@ -25,10 +25,5 @@ nv40_emit_hw_state(struct nv40_context *nv40)
nv40_vertprog_bind(nv40, nv40->vertprog.current);
nv40->dirty &= ~NV40_NEW_VERTPROG;
}
-
- if (nv40->dirty & NV40_NEW_ARRAYS) {
- nv40_vbo_arrays_update(nv40);
- nv40->dirty &= ~NV40_NEW_ARRAYS;
- }
}
diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c
index 19ae6ca323..62c877b2dc 100644
--- a/src/mesa/pipe/nv40/nv40_vbo.c
+++ b/src/mesa/pipe/nv40/nv40_vbo.c
@@ -6,6 +6,93 @@
#include "nv40_dma.h"
#include "nv40_state.h"
+static INLINE int
+nv40_vbo_ncomp(uint format)
+{
+ int ncomp = 0;
+
+ if (pf_size_x(format)) ncomp++;
+ if (pf_size_y(format)) ncomp++;
+ if (pf_size_z(format)) ncomp++;
+ if (pf_size_w(format)) ncomp++;
+
+ return ncomp;
+}
+
+static INLINE int
+nv40_vbo_type(uint format)
+{
+ switch (pf_type(format)) {
+ case PIPE_FORMAT_TYPE_FLOAT:
+ return NV40TCL_VTXFMT_TYPE_FLOAT;
+ case PIPE_FORMAT_TYPE_UNORM:
+ return NV40TCL_VTXFMT_TYPE_UBYTE;
+ default:
+ assert(0);
+ }
+}
+
+static void
+nv40_vbo_arrays_update(struct nv40_context *nv40)
+{
+ struct nv40_vertex_program *vp = nv40->vertprog.active;
+ uint32_t inputs, vtxfmt[16];
+ int hw, num_hw;
+
+ inputs = vp->ir;
+ for (hw = 0; hw < 16 && inputs; hw++) {
+ if (inputs & (1 << hw)) {
+ num_hw = hw;
+ inputs &= ~(1 << hw);
+ }
+ }
+ num_hw++;
+
+ inputs = vp->ir;
+ BEGIN_RING(curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
+ for (hw = 0; hw < num_hw; hw++) {
+ struct pipe_vertex_element *ve;
+ struct pipe_vertex_buffer *vb;
+
+ if (!(inputs & (1 << hw))) {
+ OUT_RING(0);
+ vtxfmt[hw] = NV40TCL_VTXFMT_TYPE_FLOAT;
+ continue;
+ }
+
+ ve = &nv40->vtxelt[hw];
+ vb = &nv40->vtxbuf[ve->vertex_buffer_index];
+
+ OUT_RELOC(vb->buffer, vb->buffer_offset + ve->src_offset,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_OR | NOUVEAU_BO_RD, 0,
+ NV40TCL_VTXBUF_ADDRESS_DMA1);
+ vtxfmt[hw] = ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
+ (nv40_vbo_ncomp(ve->src_format) <<
+ NV40TCL_VTXFMT_SIZE_SHIFT) |
+ nv40_vbo_type(ve->src_format));
+ }
+
+ BEGIN_RING(curie, 0x1710, 1);
+ OUT_RING (0); /* vtx cache flush */
+ BEGIN_RING(curie, NV40TCL_VTXFMT(0), num_hw);
+ OUT_RINGp (vtxfmt, num_hw);
+}
+
+static boolean
+nv40_vbo_validate_state(struct nv40_context *nv40)
+{
+ if (nv40->dirty & ~NV40_NEW_ARRAYS)
+ nv40_emit_hw_state(nv40);
+
+ if (nv40->dirty & NV40_NEW_ARRAYS) {
+ nv40_vbo_arrays_update(nv40);
+ nv40->dirty &= ~NV40_NEW_ARRAYS;
+ }
+
+ return TRUE;
+}
+
boolean
nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
@@ -13,8 +100,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
struct nv40_context *nv40 = (struct nv40_context *)pipe;
unsigned nr;
- if (nv40->dirty)
- nv40_emit_hw_state(nv40);
+ assert(nv40_vbo_validate_state(nv40));
BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);
OUT_RING (nvgl_primitive(mode));
@@ -26,13 +112,14 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
start += nr;
}
- /*XXX: large arrays (nr>2047) will blow up */
nr = count >> 8;
- if (nr) {
- assert (nr <= 2047);
+ while (nr) {
+ unsigned push = nr > 2047 ? 2047 : nr;
+
+ nr -= push;
- BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, nr);
- while (nr--) {
+ BEGIN_RING_NI(curie, NV40TCL_VB_VERTEX_BATCH, push);
+ while (push--) {
OUT_RING(((0x100 - 1) << 24) | start);
start += 0x100;
}
@@ -121,8 +208,7 @@ nv40_draw_elements(struct pipe_context *pipe,
struct nv40_context *nv40 = (struct nv40_context *)pipe;
void *ib;
- if (nv40->dirty)
- nv40_emit_hw_state(nv40);
+ assert(nv40_vbo_validate_state(nv40));
ib = pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
PIPE_BUFFER_FLAG_READ);
@@ -157,76 +243,4 @@ nv40_draw_elements(struct pipe_context *pipe,
return TRUE;
}
-static INLINE int
-nv40_vbo_ncomp(uint format)
-{
- int ncomp = 0;
-
- if (pf_size_x(format)) ncomp++;
- if (pf_size_y(format)) ncomp++;
- if (pf_size_z(format)) ncomp++;
- if (pf_size_w(format)) ncomp++;
-
- return ncomp;
-}
-
-static INLINE int
-nv40_vbo_type(uint format)
-{
- switch (pf_type(format)) {
- case PIPE_FORMAT_TYPE_FLOAT:
- return NV40TCL_VTXFMT_TYPE_FLOAT;
- case PIPE_FORMAT_TYPE_UNORM:
- return NV40TCL_VTXFMT_TYPE_UBYTE;
- default:
- assert(0);
- }
-}
-
-void
-nv40_vbo_arrays_update(struct nv40_context *nv40)
-{
- struct nv40_vertex_program *vp = nv40->vertprog.active;
- uint32_t inputs, vtxfmt[16];
- int hw, num_hw;
-
- inputs = vp->ir;
- for (hw = 0; hw < 16 && inputs; hw++) {
- if (inputs & (1 << hw)) {
- num_hw = hw;
- inputs &= ~(1 << hw);
- }
- }
- num_hw++;
-
- inputs = vp->ir;
- BEGIN_RING(curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw);
- for (hw = 0; hw < num_hw; hw++) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
-
- if (!(inputs & (1 << hw))) {
- OUT_RING(0);
- vtxfmt[hw] = NV40TCL_VTXFMT_TYPE_FLOAT;
- continue;
- }
-
- ve = &nv40->vtxelt[hw];
- vb = &nv40->vtxbuf[ve->vertex_buffer_index];
-
- OUT_RELOC(vb->buffer, vb->buffer_offset + ve->src_offset,
- NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
- NOUVEAU_BO_OR | NOUVEAU_BO_RD, 0,
- NV40TCL_VTXBUF_ADDRESS_DMA1);
- vtxfmt[hw] = ((vb->pitch << NV40TCL_VTXFMT_STRIDE_SHIFT) |
- (nv40_vbo_ncomp(ve->src_format) <<
- NV40TCL_VTXFMT_SIZE_SHIFT) |
- nv40_vbo_type(ve->src_format));
- }
-
- BEGIN_RING(curie, 0x1710, 1);
- OUT_RING (0); /* vtx cache flush */
- BEGIN_RING(curie, NV40TCL_VTXFMT(0), num_hw);
- OUT_RINGp (vtxfmt, num_hw);
-}