diff options
Diffstat (limited to 'src/mesa/pipe/nv40')
-rw-r--r-- | src/mesa/pipe/nv40/nv40_context.h | 1 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_state_emit.c | 5 | ||||
-rw-r--r-- | src/mesa/pipe/nv40/nv40_vbo.c | 176 |
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); -} |