nv30, nv40: unify nv[34]0_vbo.c
authorLuca Barbieri <luca@luca-barbieri.com>
Sun, 21 Feb 2010 10:12:08 +0000 (11:12 +0100)
committerYounes Manton <younes.m@gmail.com>
Mon, 15 Mar 2010 04:03:03 +0000 (00:03 -0400)
The files are identical, except for swtnl support which is commented
out on nv30 and restart being initialized on nv30 to avoid a compiler
warning.

12 files changed:
src/gallium/drivers/nv30/Makefile
src/gallium/drivers/nv30/nv30_context.c
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_vbo.c [deleted file]
src/gallium/drivers/nv40/Makefile
src/gallium/drivers/nv40/nv40_context.c
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_vbo.c [deleted file]
src/gallium/drivers/nvfx/Makefile
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_state_emit.c
src/gallium/drivers/nvfx/nvfx_vbo.c [new file with mode: 0644]

index 791b0040bb84864d4e0aabd9df0d4203f528e08a..6ec93ee34658f0a27e095ed17e7ba6f2a9d5709a 100644 (file)
@@ -8,7 +8,6 @@ C_SOURCES = \
        nv30_fragtex.c \
        nv30_screen.c \
        nv30_state.c \
-       nv30_vbo.c \
        nv30_vertprog.c
 
 LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/nvfx
index 671a1939e8dc1de93898fc223c4b3ecd1091e208..730f4588785c395ba499f691cbff9b13636f6208 100644 (file)
@@ -60,8 +60,8 @@ nv30_create(struct pipe_screen *pscreen, void *priv)
        nvfx->pipe.screen = pscreen;
        nvfx->pipe.priv = priv;
        nvfx->pipe.destroy = nv30_destroy;
-       nvfx->pipe.draw_arrays = nv30_draw_arrays;
-       nvfx->pipe.draw_elements = nv30_draw_elements;
+       nvfx->pipe.draw_arrays = nvfx_draw_arrays;
+       nvfx->pipe.draw_elements = nvfx_draw_elements;
        nvfx->pipe.clear = nvfx_clear;
        nvfx->pipe.flush = nv30_flush;
 
index ebdd5455ca86ec4a35f032a7faae256373890937..de879d504fc13ec6701bd08945648bf07534f38d 100644 (file)
@@ -15,16 +15,6 @@ extern void nv30_fragtex_bind(struct nvfx_context *);
 /* nv30_state.c and friends */
 extern struct nvfx_state_entry nv30_state_vertprog;
 extern struct nvfx_state_entry nv30_state_fragtex;
-extern struct nvfx_state_entry nv30_state_vbo;
-
-/* nv30_vbo.c */
-extern void nv30_draw_arrays(struct pipe_context *, unsigned mode,
-                               unsigned start, unsigned count);
-extern void nv30_draw_elements(struct pipe_context *pipe,
-                                 struct pipe_buffer *indexBuffer,
-                                 unsigned indexSize,
-                                 unsigned mode, unsigned start,
-                                 unsigned count);
 
 /* nvfx_context.c */
 struct pipe_context *
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
deleted file mode 100644 (file)
index 2b4401e..0000000
+++ /dev/null
@@ -1,562 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-
-#include "nv30_context.h"
-#include "nvfx_state.h"
-
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_util.h"
-
-#define FORCE_SWTNL 0
-
-static INLINE int
-nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
-{
-       switch (pipe) {
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-               *fmt = NV34TCL_VTXFMT_TYPE_FLOAT;
-               break;
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R8G8B8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-               *fmt = NV34TCL_VTXFMT_TYPE_UBYTE;
-               break;
-       case PIPE_FORMAT_R16_SSCALED:
-       case PIPE_FORMAT_R16G16_SSCALED:
-       case PIPE_FORMAT_R16G16B16_SSCALED:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-               *fmt = NV34TCL_VTXFMT_TYPE_USHORT;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
-               return 1;
-       }
-
-       switch (pipe) {
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R16_SSCALED:
-               *ncomp = 1;
-               break;
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R16G16_SSCALED:
-               *ncomp = 2;
-               break;
-       case PIPE_FORMAT_R8G8B8_UNORM:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-       case PIPE_FORMAT_R16G16B16_SSCALED:
-               *ncomp = 3;
-               break;
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-               *ncomp = 4;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
-               return 1;
-       }
-
-       return 0;
-}
-
-static boolean
-nv30_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
-                   unsigned ib_size)
-{
-       struct pipe_screen *pscreen = &nvfx->screen->base.base;
-       unsigned type;
-
-       if (!ib) {
-               nvfx->idxbuf = NULL;
-               nvfx->idxbuf_format = 0xdeadbeef;
-               return FALSE;
-       }
-
-       if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1)
-               return FALSE;
-
-       switch (ib_size) {
-       case 2:
-               type = NV34TCL_IDXBUF_FORMAT_TYPE_U16;
-               break;
-       case 4:
-               type = NV34TCL_IDXBUF_FORMAT_TYPE_U32;
-               break;
-       default:
-               return FALSE;
-       }
-
-       if (ib != nvfx->idxbuf ||
-           type != nvfx->idxbuf_format) {
-               nvfx->dirty |= NVFX_NEW_ARRAYS;
-               nvfx->idxbuf = ib;
-               nvfx->idxbuf_format = type;
-       }
-
-       return TRUE;
-}
-
-static boolean
-nv30_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
-                      int attrib, struct pipe_vertex_element *ve,
-                      struct pipe_vertex_buffer *vb)
-{
-       struct pipe_screen *pscreen = nvfx->pipe.screen;
-       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
-       unsigned type, ncomp;
-       void *map;
-
-       if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp))
-               return FALSE;
-
-       map  = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
-       map += vb->buffer_offset + ve->src_offset;
-
-       switch (type) {
-       case NV34TCL_VTXFMT_TYPE_FLOAT:
-       {
-               float *v = map;
-
-               switch (ncomp) {
-               case 4:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_4F_X(attrib), 4);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       so_data  (so, fui(v[2]));
-                       so_data  (so, fui(v[3]));
-                       break;
-               case 3:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_3F_X(attrib), 3);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       so_data  (so, fui(v[2]));
-                       break;
-               case 2:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_2F_X(attrib), 2);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       break;
-               case 1:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_1F(attrib), 1);
-                       so_data  (so, fui(v[0]));
-                       break;
-               default:
-                       pipe_buffer_unmap(pscreen, vb->buffer);
-                       return FALSE;
-               }
-       }
-               break;
-       default:
-               pipe_buffer_unmap(pscreen, vb->buffer);
-               return FALSE;
-       }
-
-       pipe_buffer_unmap(pscreen, vb->buffer);
-       return TRUE;
-}
-
-void
-nv30_draw_arrays(struct pipe_context *pipe,
-                unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-       unsigned restart = 0;
-
-       nv30_vbo_set_idxbuf(nvfx, NULL, 0);
-       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
-               /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
-                                               mode, start, count);*/
-               return;
-       }
-
-       while (count) {
-               unsigned vc, nr;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
-                                       mode, start, count, &restart);
-               if (!vc) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               nr = (vc & 0xff);
-               if (nr) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, 1);
-                       OUT_RING  (chan, ((nr - 1) << 24) | start);
-                       start += nr;
-               }
-
-               nr = vc >> 8;
-               while (nr) {
-                       unsigned push = nr > 2047 ? 2047 : nr;
-
-                       nr -= push;
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, push);
-                       while (push--) {
-                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
-                               start += 0x100;
-                       }
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               count -= vc;
-               start = restart;
-       }
-
-       pipe->flush(pipe, 0, NULL);
-}
-
-static INLINE void
-nv30_draw_elements_u08(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint8_t *elts = (uint8_t *)ib + start;
-               unsigned vc, push, restart = 0;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               if (vc & 1) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
-                       OUT_RING  (chan, elts[0]);
-                       elts++; vc--;
-               }
-
-               while (vc) {
-                       unsigned i;
-
-                       push = MIN2(vc, 2047 * 2);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
-                       for (i = 0; i < push; i+=2)
-                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static INLINE void
-nv30_draw_elements_u16(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint16_t *elts = (uint16_t *)ib + start;
-               unsigned vc, push, restart = 0;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               if (vc & 1) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
-                       OUT_RING  (chan, elts[0]);
-                       elts++; vc--;
-               }
-
-               while (vc) {
-                       unsigned i;
-
-                       push = MIN2(vc, 2047 * 2);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
-                       for (i = 0; i < push; i+=2)
-                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static INLINE void
-nv30_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint32_t *elts = (uint32_t *)ib + start;
-               unsigned vc, push, restart = 0;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               while (vc) {
-                       push = MIN2(vc, 2047);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U32, push);
-                       OUT_RINGp    (chan, elts, push);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static void
-nv30_draw_elements_inline(struct pipe_context *pipe,
-                         struct pipe_buffer *ib, unsigned ib_size,
-                         unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct pipe_screen *pscreen = pipe->screen;
-       void *map;
-
-       map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
-       if (!ib) {
-               NOUVEAU_ERR("failed mapping ib\n");
-               return;
-       }
-
-       switch (ib_size) {
-       case 1:
-               nv30_draw_elements_u08(nvfx, map, mode, start, count);
-               break;
-       case 2:
-               nv30_draw_elements_u16(nvfx, map, mode, start, count);
-               break;
-       case 4:
-               nv30_draw_elements_u32(nvfx, map, mode, start, count);
-               break;
-       default:
-               NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
-               break;
-       }
-
-       pipe_buffer_unmap(pscreen, ib);
-}
-
-static void
-nv30_draw_elements_vbo(struct pipe_context *pipe,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-       unsigned restart = 0;
-
-       while (count) {
-               unsigned nr, vc;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
-                                       mode, start, count, &restart);
-               if (!vc) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               nr = (vc & 0xff);
-               if (nr) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_INDEX_BATCH, 1);
-                       OUT_RING  (chan, ((nr - 1) << 24) | start);
-                       start += nr;
-               }
-
-               nr = vc >> 8;
-               while (nr) {
-                       unsigned push = nr > 2047 ? 2047 : nr;
-
-                       nr -= push;
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_INDEX_BATCH, push);
-                       while (push--) {
-                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
-                               start += 0x100;
-                       }
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               count -= vc;
-               start = restart;
-       }
-}
-
-void
-nv30_draw_elements(struct pipe_context *pipe,
-                  struct pipe_buffer *indexBuffer, unsigned indexSize,
-                  unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       boolean idxbuf;
-
-       idxbuf = nv30_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
-       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
-               /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
-                                               mode, start, count);*/
-               return;
-       }
-
-       if (idxbuf) {
-               nv30_draw_elements_vbo(pipe, mode, start, count);
-       } else {
-               nv30_draw_elements_inline(pipe, indexBuffer, indexSize,
-                                         mode, start, count);
-       }
-
-       pipe->flush(pipe, 0, NULL);
-}
-
-static boolean
-nv30_vbo_validate(struct nvfx_context *nvfx)
-{
-       struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
-       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
-       struct pipe_buffer *ib = nvfx->idxbuf;
-       unsigned ib_format = nvfx->idxbuf_format;
-       unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-       int hw;
-
-       vtxbuf = so_new(3, 17, 18);
-       so_method(vtxbuf, eng3d, NV34TCL_VTXBUF_ADDRESS(0), nvfx->vtxelt->num_elements);
-       vtxfmt = so_new(1, 16, 0);
-       so_method(vtxfmt, eng3d, NV34TCL_VTXFMT(0), nvfx->vtxelt->num_elements);
-
-       for (hw = 0; hw < nvfx->vtxelt->num_elements; hw++) {
-               struct pipe_vertex_element *ve;
-               struct pipe_vertex_buffer *vb;
-               unsigned type, ncomp;
-
-               ve = &nvfx->vtxelt->pipe[hw];
-               vb = &nvfx->vtxbuf[ve->vertex_buffer_index];
-
-               if (!vb->stride) {
-                       if (!sattr)
-                               sattr = so_new(16, 16 * 4, 0);
-
-                       if (nv30_vbo_static_attrib(nvfx, sattr, hw, ve, vb)) {
-                               so_data(vtxbuf, 0);
-                               so_data(vtxfmt, NV34TCL_VTXFMT_TYPE_FLOAT);
-                               continue;
-                       }
-               }
-
-               if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
-                       /*nvfx->fallback_swtnl |= NVFX_NEW_ARRAYS;*/
-                       so_ref(NULL, &vtxbuf);
-                       so_ref(NULL, &vtxfmt);
-                       return FALSE;
-               }
-
-               so_reloc(vtxbuf, nouveau_bo(vb->buffer), vb->buffer_offset +
-                                ve->src_offset, vb_flags | NOUVEAU_BO_LOW |
-                                NOUVEAU_BO_OR, 0, NV34TCL_VTXBUF_ADDRESS_DMA1);
-               so_data (vtxfmt, ((vb->stride << NV34TCL_VTXFMT_STRIDE_SHIFT) |
-                                 (ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type));
-       }
-
-       if (ib) {
-               struct nouveau_bo *bo = nouveau_bo(ib);
-
-               so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
-               so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
-               so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
-                                 0, NV34TCL_IDXBUF_FORMAT_DMA1);
-       }
-
-       so_method(vtxbuf, eng3d, 0x1710, 1);
-       so_data  (vtxbuf, 0);
-
-       so_ref(vtxbuf, &nvfx->state.hw[NVFX_STATE_VTXBUF]);
-       so_ref(NULL, &vtxbuf);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXBUF);
-       so_ref(vtxfmt, &nvfx->state.hw[NVFX_STATE_VTXFMT]);
-       so_ref(NULL, &vtxfmt);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXFMT);
-       so_ref(sattr, &nvfx->state.hw[NVFX_STATE_VTXATTR]);
-       so_ref(NULL, &sattr);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXATTR);
-       return FALSE;
-}
-
-struct nvfx_state_entry nv30_state_vbo = {
-       .validate = nv30_vbo_validate,
-       .dirty = {
-               .pipe = NVFX_NEW_ARRAYS,
-               .hw = 0,
-       }
-};
index 7529e33a741d31ebc60c9649fe6589c508656207..6908506906001d62d91d8ce6750e080f431887d1 100644 (file)
@@ -8,7 +8,6 @@ C_SOURCES = \
        nv40_fragtex.c \
        nv40_screen.c \
        nv40_state.c \
-       nv40_vbo.c \
        nv40_vertprog.c
 
 LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/nvfx
index eb8313177202b496eaafe5b624688ce438dd79a3..85c1355b4fa5dbf9018f62fb767af8555ee00144 100644 (file)
@@ -60,8 +60,8 @@ nv40_create(struct pipe_screen *pscreen, void *priv)
        nvfx->pipe.priv = priv;
        nvfx->pipe.screen = pscreen;
        nvfx->pipe.destroy = nv40_destroy;
-       nvfx->pipe.draw_arrays = nv40_draw_arrays;
-       nvfx->pipe.draw_elements = nv40_draw_elements;
+       nvfx->pipe.draw_arrays = nvfx_draw_arrays;
+       nvfx->pipe.draw_elements = nvfx_draw_elements;
        nvfx->pipe.clear = nvfx_clear;
        nvfx->pipe.flush = nv40_flush;
 
index a8aba0c0cab62a931c60ac60f5f64602c5a814d6..cebf21d00c073f35a004062454f0d3ea7b2ff218 100644 (file)
@@ -15,16 +15,6 @@ extern void nv40_fragtex_bind(struct nvfx_context *);
 /* nv40_state.c and friends */
 extern struct nvfx_state_entry nv40_state_vertprog;
 extern struct nvfx_state_entry nv40_state_fragtex;
-extern struct nvfx_state_entry nv40_state_vbo;
-
-/* nv40_vbo.c */
-extern void nv40_draw_arrays(struct pipe_context *, unsigned mode,
-                               unsigned start, unsigned count);
-extern void nv40_draw_elements(struct pipe_context *pipe,
-                                 struct pipe_buffer *indexBuffer,
-                                 unsigned indexSize,
-                                 unsigned mode, unsigned start,
-                                 unsigned count);
 
 /* nvfx_context.c */
 struct pipe_context *
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
deleted file mode 100644 (file)
index 196a12b..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-
-#include "nv40_context.h"
-#include "nvfx_state.h"
-
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_util.h"
-
-#define FORCE_SWTNL 0
-
-static INLINE int
-nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
-{
-       switch (pipe) {
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-               *fmt = NV34TCL_VTXFMT_TYPE_FLOAT;
-               break;
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R8G8B8_UNORM:
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-               *fmt = NV34TCL_VTXFMT_TYPE_UBYTE;
-               break;
-       case PIPE_FORMAT_R16_SSCALED:
-       case PIPE_FORMAT_R16G16_SSCALED:
-       case PIPE_FORMAT_R16G16B16_SSCALED:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-               *fmt = NV34TCL_VTXFMT_TYPE_USHORT;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
-               return 1;
-       }
-
-       switch (pipe) {
-       case PIPE_FORMAT_R8_UNORM:
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R16_SSCALED:
-               *ncomp = 1;
-               break;
-       case PIPE_FORMAT_R8G8_UNORM:
-       case PIPE_FORMAT_R32G32_FLOAT:
-       case PIPE_FORMAT_R16G16_SSCALED:
-               *ncomp = 2;
-               break;
-       case PIPE_FORMAT_R8G8B8_UNORM:
-       case PIPE_FORMAT_R32G32B32_FLOAT:
-       case PIPE_FORMAT_R16G16B16_SSCALED:
-               *ncomp = 3;
-               break;
-       case PIPE_FORMAT_R8G8B8A8_UNORM:
-       case PIPE_FORMAT_R32G32B32A32_FLOAT:
-       case PIPE_FORMAT_R16G16B16A16_SSCALED:
-               *ncomp = 4;
-               break;
-       default:
-               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
-               return 1;
-       }
-
-       return 0;
-}
-
-static boolean
-nv40_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
-                   unsigned ib_size)
-{
-       struct pipe_screen *pscreen = &nvfx->screen->base.base;
-       unsigned type;
-
-       if (!ib) {
-               nvfx->idxbuf = NULL;
-               nvfx->idxbuf_format = 0xdeadbeef;
-               return FALSE;
-       }
-
-       if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1)
-               return FALSE;
-
-       switch (ib_size) {
-       case 2:
-               type = NV34TCL_IDXBUF_FORMAT_TYPE_U16;
-               break;
-       case 4:
-               type = NV34TCL_IDXBUF_FORMAT_TYPE_U32;
-               break;
-       default:
-               return FALSE;
-       }
-
-       if (ib != nvfx->idxbuf ||
-           type != nvfx->idxbuf_format) {
-               nvfx->dirty |= NVFX_NEW_ARRAYS;
-               nvfx->idxbuf = ib;
-               nvfx->idxbuf_format = type;
-       }
-
-       return TRUE;
-}
-
-static boolean
-nv40_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
-                      int attrib, struct pipe_vertex_element *ve,
-                      struct pipe_vertex_buffer *vb)
-{
-       struct pipe_screen *pscreen = nvfx->pipe.screen;
-       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
-       unsigned type, ncomp;
-       void *map;
-
-       if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp))
-               return FALSE;
-
-       map  = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
-       map += vb->buffer_offset + ve->src_offset;
-
-       switch (type) {
-       case NV34TCL_VTXFMT_TYPE_FLOAT:
-       {
-               float *v = map;
-
-               switch (ncomp) {
-               case 4:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_4F_X(attrib), 4);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       so_data  (so, fui(v[2]));
-                       so_data  (so, fui(v[3]));
-                       break;
-               case 3:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_3F_X(attrib), 3);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       so_data  (so, fui(v[2]));
-                       break;
-               case 2:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_2F_X(attrib), 2);
-                       so_data  (so, fui(v[0]));
-                       so_data  (so, fui(v[1]));
-                       break;
-               case 1:
-                       so_method(so, eng3d, NV34TCL_VTX_ATTR_1F(attrib), 1);
-                       so_data  (so, fui(v[0]));
-                       break;
-               default:
-                       pipe_buffer_unmap(pscreen, vb->buffer);
-                       return FALSE;
-               }
-       }
-               break;
-       default:
-               pipe_buffer_unmap(pscreen, vb->buffer);
-               return FALSE;
-       }
-
-       pipe_buffer_unmap(pscreen, vb->buffer);
-
-       return TRUE;
-}
-
-void
-nv40_draw_arrays(struct pipe_context *pipe,
-                unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-       unsigned restart;
-
-       nv40_vbo_set_idxbuf(nvfx, NULL, 0);
-       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
-               nvfx_draw_elements_swtnl(pipe, NULL, 0,
-                                         mode, start, count);
-                return;
-       }
-
-       while (count) {
-               unsigned vc, nr;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
-                                       mode, start, count, &restart);
-               if (!vc) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               nr = (vc & 0xff);
-               if (nr) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, 1);
-                       OUT_RING  (chan, ((nr - 1) << 24) | start);
-                       start += nr;
-               }
-
-               nr = vc >> 8;
-               while (nr) {
-                       unsigned push = nr > 2047 ? 2047 : nr;
-
-                       nr -= push;
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, push);
-                       while (push--) {
-                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
-                               start += 0x100;
-                       }
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               count -= vc;
-               start = restart;
-       }
-
-       pipe->flush(pipe, 0, NULL);
-}
-
-static INLINE void
-nv40_draw_elements_u08(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint8_t *elts = (uint8_t *)ib + start;
-               unsigned vc, push, restart;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               if (vc & 1) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
-                       OUT_RING  (chan, elts[0]);
-                       elts++; vc--;
-               }
-
-               while (vc) {
-                       unsigned i;
-
-                       push = MIN2(vc, 2047 * 2);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
-                       for (i = 0; i < push; i+=2)
-                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static INLINE void
-nv40_draw_elements_u16(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint16_t *elts = (uint16_t *)ib + start;
-               unsigned vc, push, restart;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               if (vc & 1) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
-                       OUT_RING  (chan, elts[0]);
-                       elts++; vc--;
-               }
-
-               while (vc) {
-                       unsigned i;
-
-                       push = MIN2(vc, 2047 * 2);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
-                       for (i = 0; i < push; i+=2)
-                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static INLINE void
-nv40_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-
-       while (count) {
-               uint32_t *elts = (uint32_t *)ib + start;
-               unsigned vc, push, restart;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
-                                       mode, start, count, &restart);
-               if (vc == 0) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-               count -= vc;
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               while (vc) {
-                       push = MIN2(vc, 2047);
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U32, push);
-                       OUT_RINGp    (chan, elts, push);
-
-                       vc -= push;
-                       elts += push;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               start = restart;
-       }
-}
-
-static void
-nv40_draw_elements_inline(struct pipe_context *pipe,
-                         struct pipe_buffer *ib, unsigned ib_size,
-                         unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct pipe_screen *pscreen = pipe->screen;
-       void *map;
-
-       map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
-       if (!ib) {
-               NOUVEAU_ERR("failed mapping ib\n");
-               return;
-       }
-
-       switch (ib_size) {
-       case 1:
-               nv40_draw_elements_u08(nvfx, map, mode, start, count);
-               break;
-       case 2:
-               nv40_draw_elements_u16(nvfx, map, mode, start, count);
-               break;
-       case 4:
-               nv40_draw_elements_u32(nvfx, map, mode, start, count);
-               break;
-       default:
-               NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
-               break;
-       }
-
-       pipe_buffer_unmap(pscreen, ib);
-}
-
-static void
-nv40_draw_elements_vbo(struct pipe_context *pipe,
-                      unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       struct nvfx_screen *screen = nvfx->screen;
-       struct nouveau_channel *chan = screen->base.channel;
-       struct nouveau_grobj *eng3d = screen->eng3d;
-       unsigned restart;
-
-       while (count) {
-               unsigned nr, vc;
-
-               nvfx_state_emit(nvfx);
-
-               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
-                                       mode, start, count, &restart);
-               if (!vc) {
-                       FIRE_RING(chan);
-                       continue;
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, nvgl_primitive(mode));
-
-               nr = (vc & 0xff);
-               if (nr) {
-                       BEGIN_RING(chan, eng3d, NV34TCL_VB_INDEX_BATCH, 1);
-                       OUT_RING  (chan, ((nr - 1) << 24) | start);
-                       start += nr;
-               }
-
-               nr = vc >> 8;
-               while (nr) {
-                       unsigned push = nr > 2047 ? 2047 : nr;
-
-                       nr -= push;
-
-                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_INDEX_BATCH, push);
-                       while (push--) {
-                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
-                               start += 0x100;
-                       }
-               }
-
-               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
-               OUT_RING  (chan, 0);
-
-               count -= vc;
-               start = restart;
-       }
-}
-
-void
-nv40_draw_elements(struct pipe_context *pipe,
-                  struct pipe_buffer *indexBuffer, unsigned indexSize,
-                  unsigned mode, unsigned start, unsigned count)
-{
-       struct nvfx_context *nvfx = nvfx_context(pipe);
-       boolean idxbuf;
-
-       idxbuf = nv40_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
-       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
-               nvfx_draw_elements_swtnl(pipe, NULL, 0,
-                                         mode, start, count);
-                return;
-       }
-
-       if (idxbuf) {
-               nv40_draw_elements_vbo(pipe, mode, start, count);
-       } else {
-               nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
-                                         mode, start, count);
-       }
-
-       pipe->flush(pipe, 0, NULL);
-}
-
-static boolean
-nv40_vbo_validate(struct nvfx_context *nvfx)
-{
-       struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
-       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
-       struct pipe_buffer *ib = nvfx->idxbuf;
-       unsigned ib_format = nvfx->idxbuf_format;
-       unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-       int hw;
-
-       vtxbuf = so_new(3, 17, 18);
-       so_method(vtxbuf, eng3d, NV34TCL_VTXBUF_ADDRESS(0), nvfx->vtxelt->num_elements);
-       vtxfmt = so_new(1, 16, 0);
-       so_method(vtxfmt, eng3d, NV34TCL_VTXFMT(0), nvfx->vtxelt->num_elements);
-
-       for (hw = 0; hw < nvfx->vtxelt->num_elements; hw++) {
-               struct pipe_vertex_element *ve;
-               struct pipe_vertex_buffer *vb;
-               unsigned type, ncomp;
-
-               ve = &nvfx->vtxelt->pipe[hw];
-               vb = &nvfx->vtxbuf[ve->vertex_buffer_index];
-
-               if (!vb->stride) {
-                       if (!sattr)
-                               sattr = so_new(16, 16 * 4, 0);
-
-                       if (nv40_vbo_static_attrib(nvfx, sattr, hw, ve, vb)) {
-                               so_data(vtxbuf, 0);
-                               so_data(vtxfmt, NV34TCL_VTXFMT_TYPE_FLOAT);
-                               continue;
-                       }
-               }
-
-               if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
-                       nvfx->fallback_swtnl |= NVFX_NEW_ARRAYS;
-                       so_ref(NULL, &vtxbuf);
-                       so_ref(NULL, &vtxfmt);
-                       return FALSE;
-               }
-
-               so_reloc(vtxbuf, nouveau_bo(vb->buffer),
-                                vb->buffer_offset + ve->src_offset,
-                                vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
-                                0, NV34TCL_VTXBUF_ADDRESS_DMA1);
-               so_data (vtxfmt, ((vb->stride << NV34TCL_VTXFMT_STRIDE_SHIFT) |
-                                 (ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type));
-       }
-
-       if (ib) {
-               struct nouveau_bo *bo = nouveau_bo(ib);
-
-               so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
-               so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
-               so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
-                         0, NV34TCL_IDXBUF_FORMAT_DMA1);
-       }
-
-       so_method(vtxbuf, eng3d, 0x1710, 1);
-       so_data  (vtxbuf, 0);
-
-       so_ref(vtxbuf, &nvfx->state.hw[NVFX_STATE_VTXBUF]);
-       so_ref(NULL, &vtxbuf);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXBUF);
-       so_ref(vtxfmt, &nvfx->state.hw[NVFX_STATE_VTXFMT]);
-       so_ref(NULL, &vtxfmt);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXFMT);
-       so_ref(sattr, &nvfx->state.hw[NVFX_STATE_VTXATTR]);
-       so_ref(NULL, &sattr);
-       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXATTR);
-       return FALSE;
-}
-
-struct nvfx_state_entry nv40_state_vbo = {
-       .validate = nv40_vbo_validate,
-       .dirty = {
-               .pipe = NVFX_NEW_ARRAYS,
-               .hw = 0,
-       }
-};
-
index a23d024f118fd5739bce5a34db4f75450db9ab9b..d1304ccea0dd530590f9d3e27e319bb250cf7b84 100644 (file)
@@ -18,6 +18,7 @@ C_SOURCES = \
        nvfx_state_viewport.c \
        nvfx_state_zsa.c \
        nvfx_surface.c \
-       nvfx_transfer.c
+       nvfx_transfer.c \
+       nvfx_vbo.c
 
 include ../../Makefile.template
index 75008f8dddcda696ac2ae28c29c354f63bed4b00..8f121fe3af2d9f86525bead542eef94f76663254 100644 (file)
@@ -189,6 +189,7 @@ extern struct nvfx_state_entry nvfx_state_rasterizer;
 extern struct nvfx_state_entry nvfx_state_scissor;
 extern struct nvfx_state_entry nvfx_state_sr;
 extern struct nvfx_state_entry nvfx_state_stipple;
+extern struct nvfx_state_entry nvfx_state_vbo;
 extern struct nvfx_state_entry nvfx_state_viewport;
 extern struct nvfx_state_entry nvfx_state_vtxfmt;
 extern struct nvfx_state_entry nvfx_state_zsa;
@@ -220,4 +221,13 @@ extern void nvfx_state_emit(struct nvfx_context *nvfx);
 /* nvfx_transfer.c */
 extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx);
 
+/* nvfx_vbo.c */
+extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode,
+                               unsigned start, unsigned count);
+extern void nvfx_draw_elements(struct pipe_context *pipe,
+                                 struct pipe_buffer *indexBuffer,
+                                 unsigned indexSize,
+                                 unsigned mode, unsigned start,
+                                 unsigned count);
+
 #endif
index 9961dacce4c25a2ab90483408f3c6aaa70d58f88..88b86f9fb5015cf13a9c088fad62391be349f944 100644 (file)
@@ -3,10 +3,6 @@
 #include "nvfx_state.h"
 #include "draw/draw_context.h"
 
-/* temporary, will be removed in next patch */
-#define nv30_state_vtxfmt nvfx_state_vtxfmt
-#define nv40_state_vtxfmt nvfx_state_vtxfmt
-
 #define RENDER_STATES(name, nvxx, vbo) \
 static struct nvfx_state_entry *name##_render_states[] = { \
        &nvfx_state_framebuffer, \
@@ -21,7 +17,7 @@ static struct nvfx_state_entry *name##_render_states[] = { \
        &nvfx_state_zsa, \
        &nvfx_state_sr, \
        &nvfx_state_viewport, \
-       &nvxx##_state_##vbo, \
+       &nvfx_state_##vbo, \
        NULL \
 }
 
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
new file mode 100644 (file)
index 0000000..9d501ef
--- /dev/null
@@ -0,0 +1,563 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
+#include "nvfx_context.h"
+#include "nvfx_state.h"
+
+#include "nouveau/nouveau_channel.h"
+#include "nouveau/nouveau_pushbuf.h"
+#include "nouveau/nouveau_util.h"
+
+#define FORCE_SWTNL 0
+
+static INLINE int
+nvfx_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
+{
+       switch (pipe) {
+       case PIPE_FORMAT_R32_FLOAT:
+       case PIPE_FORMAT_R32G32_FLOAT:
+       case PIPE_FORMAT_R32G32B32_FLOAT:
+       case PIPE_FORMAT_R32G32B32A32_FLOAT:
+               *fmt = NV34TCL_VTXFMT_TYPE_FLOAT;
+               break;
+       case PIPE_FORMAT_R8_UNORM:
+       case PIPE_FORMAT_R8G8_UNORM:
+       case PIPE_FORMAT_R8G8B8_UNORM:
+       case PIPE_FORMAT_R8G8B8A8_UNORM:
+               *fmt = NV34TCL_VTXFMT_TYPE_UBYTE;
+               break;
+       case PIPE_FORMAT_R16_SSCALED:
+       case PIPE_FORMAT_R16G16_SSCALED:
+       case PIPE_FORMAT_R16G16B16_SSCALED:
+       case PIPE_FORMAT_R16G16B16A16_SSCALED:
+               *fmt = NV34TCL_VTXFMT_TYPE_USHORT;
+               break;
+       default:
+               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
+               return 1;
+       }
+
+       switch (pipe) {
+       case PIPE_FORMAT_R8_UNORM:
+       case PIPE_FORMAT_R32_FLOAT:
+       case PIPE_FORMAT_R16_SSCALED:
+               *ncomp = 1;
+               break;
+       case PIPE_FORMAT_R8G8_UNORM:
+       case PIPE_FORMAT_R32G32_FLOAT:
+       case PIPE_FORMAT_R16G16_SSCALED:
+               *ncomp = 2;
+               break;
+       case PIPE_FORMAT_R8G8B8_UNORM:
+       case PIPE_FORMAT_R32G32B32_FLOAT:
+       case PIPE_FORMAT_R16G16B16_SSCALED:
+               *ncomp = 3;
+               break;
+       case PIPE_FORMAT_R8G8B8A8_UNORM:
+       case PIPE_FORMAT_R32G32B32A32_FLOAT:
+       case PIPE_FORMAT_R16G16B16A16_SSCALED:
+               *ncomp = 4;
+               break;
+       default:
+               NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
+               return 1;
+       }
+
+       return 0;
+}
+
+static boolean
+nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
+                   unsigned ib_size)
+{
+       struct pipe_screen *pscreen = &nvfx->screen->base.base;
+       unsigned type;
+
+       if (!ib) {
+               nvfx->idxbuf = NULL;
+               nvfx->idxbuf_format = 0xdeadbeef;
+               return FALSE;
+       }
+
+       if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1)
+               return FALSE;
+
+       switch (ib_size) {
+       case 2:
+               type = NV34TCL_IDXBUF_FORMAT_TYPE_U16;
+               break;
+       case 4:
+               type = NV34TCL_IDXBUF_FORMAT_TYPE_U32;
+               break;
+       default:
+               return FALSE;
+       }
+
+       if (ib != nvfx->idxbuf ||
+           type != nvfx->idxbuf_format) {
+               nvfx->dirty |= NVFX_NEW_ARRAYS;
+               nvfx->idxbuf = ib;
+               nvfx->idxbuf_format = type;
+       }
+
+       return TRUE;
+}
+
+static boolean
+nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
+                      int attrib, struct pipe_vertex_element *ve,
+                      struct pipe_vertex_buffer *vb)
+{
+       struct pipe_screen *pscreen = nvfx->pipe.screen;
+       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+       unsigned type, ncomp;
+       void *map;
+
+       if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp))
+               return FALSE;
+
+       map  = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+       map += vb->buffer_offset + ve->src_offset;
+
+       switch (type) {
+       case NV34TCL_VTXFMT_TYPE_FLOAT:
+       {
+               float *v = map;
+
+               switch (ncomp) {
+               case 4:
+                       so_method(so, eng3d, NV34TCL_VTX_ATTR_4F_X(attrib), 4);
+                       so_data  (so, fui(v[0]));
+                       so_data  (so, fui(v[1]));
+                       so_data  (so, fui(v[2]));
+                       so_data  (so, fui(v[3]));
+                       break;
+               case 3:
+                       so_method(so, eng3d, NV34TCL_VTX_ATTR_3F_X(attrib), 3);
+                       so_data  (so, fui(v[0]));
+                       so_data  (so, fui(v[1]));
+                       so_data  (so, fui(v[2]));
+                       break;
+               case 2:
+                       so_method(so, eng3d, NV34TCL_VTX_ATTR_2F_X(attrib), 2);
+                       so_data  (so, fui(v[0]));
+                       so_data  (so, fui(v[1]));
+                       break;
+               case 1:
+                       so_method(so, eng3d, NV34TCL_VTX_ATTR_1F(attrib), 1);
+                       so_data  (so, fui(v[0]));
+                       break;
+               default:
+                       pipe_buffer_unmap(pscreen, vb->buffer);
+                       return FALSE;
+               }
+       }
+               break;
+       default:
+               pipe_buffer_unmap(pscreen, vb->buffer);
+               return FALSE;
+       }
+
+       pipe_buffer_unmap(pscreen, vb->buffer);
+       return TRUE;
+}
+
+void
+nvfx_draw_arrays(struct pipe_context *pipe,
+                unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       struct nvfx_screen *screen = nvfx->screen;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *eng3d = screen->eng3d;
+       unsigned restart = 0;
+
+       nvfx_vbo_set_idxbuf(nvfx, NULL, 0);
+       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
+               nvfx_draw_elements_swtnl(pipe, NULL, 0,
+                                           mode, start, count);
+                return;
+       }
+
+       while (count) {
+               unsigned vc, nr;
+
+               nvfx_state_emit(nvfx);
+
+               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
+                                       mode, start, count, &restart);
+               if (!vc) {
+                       FIRE_RING(chan);
+                       continue;
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, nvgl_primitive(mode));
+
+               nr = (vc & 0xff);
+               if (nr) {
+                       BEGIN_RING(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, 1);
+                       OUT_RING  (chan, ((nr - 1) << 24) | start);
+                       start += nr;
+               }
+
+               nr = vc >> 8;
+               while (nr) {
+                       unsigned push = nr > 2047 ? 2047 : nr;
+
+                       nr -= push;
+
+                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, push);
+                       while (push--) {
+                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
+                               start += 0x100;
+                       }
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, 0);
+
+               count -= vc;
+               start = restart;
+       }
+
+       pipe->flush(pipe, 0, NULL);
+}
+
+static INLINE void
+nvfx_draw_elements_u08(struct nvfx_context *nvfx, void *ib,
+                      unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_screen *screen = nvfx->screen;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *eng3d = screen->eng3d;
+
+       while (count) {
+               uint8_t *elts = (uint8_t *)ib + start;
+               unsigned vc, push, restart = 0;
+
+               nvfx_state_emit(nvfx);
+
+               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(chan);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, nvgl_primitive(mode));
+
+               if (vc & 1) {
+                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
+                       OUT_RING  (chan, elts[0]);
+                       elts++; vc--;
+               }
+
+               while (vc) {
+                       unsigned i;
+
+                       push = MIN2(vc, 2047 * 2);
+
+                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
+                       for (i = 0; i < push; i+=2)
+                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
+
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, 0);
+
+               start = restart;
+       }
+}
+
+static INLINE void
+nvfx_draw_elements_u16(struct nvfx_context *nvfx, void *ib,
+                      unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_screen *screen = nvfx->screen;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *eng3d = screen->eng3d;
+
+       while (count) {
+               uint16_t *elts = (uint16_t *)ib + start;
+               unsigned vc, push, restart = 0;
+
+               nvfx_state_emit(nvfx);
+
+               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(chan);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, nvgl_primitive(mode));
+
+               if (vc & 1) {
+                       BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
+                       OUT_RING  (chan, elts[0]);
+                       elts++; vc--;
+               }
+
+               while (vc) {
+                       unsigned i;
+
+                       push = MIN2(vc, 2047 * 2);
+
+                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
+                       for (i = 0; i < push; i+=2)
+                               OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
+
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, 0);
+
+               start = restart;
+       }
+}
+
+static INLINE void
+nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
+                      unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_screen *screen = nvfx->screen;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *eng3d = screen->eng3d;
+
+       while (count) {
+               uint32_t *elts = (uint32_t *)ib + start;
+               unsigned vc, push, restart = 0;
+
+               nvfx_state_emit(nvfx);
+
+               vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
+                                       mode, start, count, &restart);
+               if (vc == 0) {
+                       FIRE_RING(chan);
+                       continue;
+               }
+               count -= vc;
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, nvgl_primitive(mode));
+
+               while (vc) {
+                       push = MIN2(vc, 2047);
+
+                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U32, push);
+                       OUT_RINGp    (chan, elts, push);
+
+                       vc -= push;
+                       elts += push;
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, 0);
+
+               start = restart;
+       }
+}
+
+static void
+nvfx_draw_elements_inline(struct pipe_context *pipe,
+                         struct pipe_buffer *ib, unsigned ib_size,
+                         unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       struct pipe_screen *pscreen = pipe->screen;
+       void *map;
+
+       map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
+       if (!ib) {
+               NOUVEAU_ERR("failed mapping ib\n");
+               return;
+       }
+
+       switch (ib_size) {
+       case 1:
+               nvfx_draw_elements_u08(nvfx, map, mode, start, count);
+               break;
+       case 2:
+               nvfx_draw_elements_u16(nvfx, map, mode, start, count);
+               break;
+       case 4:
+               nvfx_draw_elements_u32(nvfx, map, mode, start, count);
+               break;
+       default:
+               NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
+               break;
+       }
+
+       pipe_buffer_unmap(pscreen, ib);
+}
+
+static void
+nvfx_draw_elements_vbo(struct pipe_context *pipe,
+                      unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       struct nvfx_screen *screen = nvfx->screen;
+       struct nouveau_channel *chan = screen->base.channel;
+       struct nouveau_grobj *eng3d = screen->eng3d;
+       unsigned restart = 0;
+
+       while (count) {
+               unsigned nr, vc;
+
+               nvfx_state_emit(nvfx);
+
+               vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
+                                       mode, start, count, &restart);
+               if (!vc) {
+                       FIRE_RING(chan);
+                       continue;
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, nvgl_primitive(mode));
+
+               nr = (vc & 0xff);
+               if (nr) {
+                       BEGIN_RING(chan, eng3d, NV34TCL_VB_INDEX_BATCH, 1);
+                       OUT_RING  (chan, ((nr - 1) << 24) | start);
+                       start += nr;
+               }
+
+               nr = vc >> 8;
+               while (nr) {
+                       unsigned push = nr > 2047 ? 2047 : nr;
+
+                       nr -= push;
+
+                       BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_INDEX_BATCH, push);
+                       while (push--) {
+                               OUT_RING(chan, ((0x100 - 1) << 24) | start);
+                               start += 0x100;
+                       }
+               }
+
+               BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+               OUT_RING  (chan, 0);
+
+               count -= vc;
+               start = restart;
+       }
+}
+
+void
+nvfx_draw_elements(struct pipe_context *pipe,
+                  struct pipe_buffer *indexBuffer, unsigned indexSize,
+                  unsigned mode, unsigned start, unsigned count)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+       boolean idxbuf;
+
+       idxbuf = nvfx_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
+       if (FORCE_SWTNL || !nvfx_state_validate(nvfx)) {
+               nvfx_draw_elements_swtnl(pipe, NULL, 0,
+                                           mode, start, count);
+               return;
+       }
+
+       if (idxbuf) {
+               nvfx_draw_elements_vbo(pipe, mode, start, count);
+       } else {
+               nvfx_draw_elements_inline(pipe, indexBuffer, indexSize,
+                                         mode, start, count);
+       }
+
+       pipe->flush(pipe, 0, NULL);
+}
+
+static boolean
+nvfx_vbo_validate(struct nvfx_context *nvfx)
+{
+       struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
+       struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+       struct pipe_buffer *ib = nvfx->idxbuf;
+       unsigned ib_format = nvfx->idxbuf_format;
+       unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+       int hw;
+
+       vtxbuf = so_new(3, 17, 18);
+       so_method(vtxbuf, eng3d, NV34TCL_VTXBUF_ADDRESS(0), nvfx->vtxelt->num_elements);
+       vtxfmt = so_new(1, 16, 0);
+       so_method(vtxfmt, eng3d, NV34TCL_VTXFMT(0), nvfx->vtxelt->num_elements);
+
+       for (hw = 0; hw < nvfx->vtxelt->num_elements; hw++) {
+               struct pipe_vertex_element *ve;
+               struct pipe_vertex_buffer *vb;
+               unsigned type, ncomp;
+
+               ve = &nvfx->vtxelt->pipe[hw];
+               vb = &nvfx->vtxbuf[ve->vertex_buffer_index];
+
+               if (!vb->stride) {
+                       if (!sattr)
+                               sattr = so_new(16, 16 * 4, 0);
+
+                       if (nvfx_vbo_static_attrib(nvfx, sattr, hw, ve, vb)) {
+                               so_data(vtxbuf, 0);
+                               so_data(vtxfmt, NV34TCL_VTXFMT_TYPE_FLOAT);
+                               continue;
+                       }
+               }
+
+               if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
+                       nvfx->fallback_swtnl |= NVFX_NEW_ARRAYS;
+                       so_ref(NULL, &vtxbuf);
+                       so_ref(NULL, &vtxfmt);
+                       return FALSE;
+               }
+
+               so_reloc(vtxbuf, nouveau_bo(vb->buffer),
+                                vb->buffer_offset + ve->src_offset,
+                                vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+                                0, NV34TCL_VTXBUF_ADDRESS_DMA1);
+               so_data (vtxfmt, ((vb->stride << NV34TCL_VTXFMT_STRIDE_SHIFT) |
+                                 (ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type));
+       }
+
+       if (ib) {
+               struct nouveau_bo *bo = nouveau_bo(ib);
+
+               so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
+               so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
+               so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
+                                 0, NV34TCL_IDXBUF_FORMAT_DMA1);
+       }
+
+       so_method(vtxbuf, eng3d, 0x1710, 1);
+       so_data  (vtxbuf, 0);
+
+       so_ref(vtxbuf, &nvfx->state.hw[NVFX_STATE_VTXBUF]);
+       so_ref(NULL, &vtxbuf);
+       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXBUF);
+       so_ref(vtxfmt, &nvfx->state.hw[NVFX_STATE_VTXFMT]);
+       so_ref(NULL, &vtxfmt);
+       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXFMT);
+       so_ref(sattr, &nvfx->state.hw[NVFX_STATE_VTXATTR]);
+       so_ref(NULL, &sattr);
+       nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXATTR);
+       return FALSE;
+}
+
+struct nvfx_state_entry nvfx_state_vbo = {
+       .validate = nvfx_vbo_validate,
+       .dirty = {
+               .pipe = NVFX_NEW_ARRAYS,
+               .hw = 0,
+       }
+};