nouveau: replace vtxbuf/idxbuf caps with BO_ flags in nouveau_screen and fix uncached...
authorLuca Barbieri <luca@luca-barbieri.com>
Thu, 15 Apr 2010 04:57:20 +0000 (06:57 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Thu, 15 Apr 2010 06:13:12 +0000 (08:13 +0200)
Faster, simpler and more flexible.

Also, we set those flags properly on nv3x so that we don't allocate buffers in GART.

Since on AGP GART is uncached, OpenGL doesn't distinguish between vertex and index buffers, and we don't support hardware index buffers for now, this caused uncached reads.

Also check bind and not usage for PIPE_BIND_* flags, got broken in the gallium-resources transition.

src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/drivers/nouveau/nouveau_screen.h
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_screen.h
src/gallium/drivers/nvfx/nvfx_vbo.c

index a0bbc3e38d73c2bd3b6b55c92d9764be74c9b627..233a91a2ffd9106f09d878c0752a7b46da00e5e9 100644 (file)
@@ -44,14 +44,10 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
        uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
        int ret;
 
-       if (bind & PIPE_BIND_VERTEX_BUFFER) {
-               if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
-                       flags |= NOUVEAU_BO_GART;
-       } else
-       if (usage & PIPE_BIND_INDEX_BUFFER) {
-               if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
-                       flags |= NOUVEAU_BO_GART;
-       }
+       if (bind & PIPE_BIND_VERTEX_BUFFER)
+               flags |= nouveau_screen(pscreen)->vertex_buffer_flags;
+       else if (bind & PIPE_BIND_INDEX_BUFFER)
+               flags |= nouveau_screen(pscreen)->index_buffer_flags;
 
        if (bind & (PIPE_BIND_RENDER_TARGET |
                        PIPE_BIND_DEPTH_STENCIL |
index f32ecd0b69bc3593a769752c7758a9ee821f8186..747fd15acdd0d23918cb2f6ea86a04538b490691 100644 (file)
@@ -5,6 +5,11 @@ struct nouveau_screen {
        struct pipe_screen base;
        struct nouveau_device *device;
        struct nouveau_channel *channel;
+
+       /* note that OpenGL doesn't distinguish between these, so
+        * these almost always should be set to the same value */
+       unsigned vertex_buffer_flags;
+       unsigned index_buffer_flags;
 };
 
 static inline struct nouveau_screen *
index b144bef5e619d70954eb44c3119c217a8cb3f01b..cd7da9977d8e0eaea6b56688272f0848df181518 100644 (file)
@@ -13,9 +13,6 @@
 #include "nouveau/nouveau_resource.h"
 #include "nouveau/nouveau_pushbuf.h"
 
-#define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000)
-#define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001)
-
 static inline uint32_t
 nouveau_screen_transfer_flags(unsigned pipe)
 {
index 425786f00f2e8482f2281a3f9b3a166ab3f913e6..7a831143f0f9b3ac9260d8b35918f7eda242426f 100644 (file)
@@ -134,10 +134,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
                return 1;
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
                return 1;
-       case NOUVEAU_CAP_HW_VTXBUF:
-               return screen->force_push ? 0 : 1;
-       case NOUVEAU_CAP_HW_IDXBUF:
-               return screen->force_push ? 0 : 1;
        case PIPE_CAP_INDEP_BLEND_ENABLE:
                return 1;
        case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -501,6 +497,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        FIRE_RING (chan);
 
        screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
+       if(!screen->force_push)
+               screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART;
        return pscreen;
 }
 
index 6742759490819229d44473a96fc0ea86e448eae9..04b456d4087908bb24d3b21094f29b8371827c76 100644 (file)
@@ -69,10 +69,6 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
                return 0;
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
                return !!screen->is_nv4x;
-       case NOUVEAU_CAP_HW_VTXBUF:
-               return !screen->force_swtnl;
-       case NOUVEAU_CAP_HW_IDXBUF:
-               return !screen->force_swtnl && screen->eng3d->grclass == NV40TCL;
        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
                return 16;
        case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -287,8 +283,8 @@ static void nv40_screen_init(struct nvfx_screen *screen)
        OUT_RING(chan, 0x00000001);
 }
 
-static void
-nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+static unsigned
+nvfx_screen_get_vertex_buffer_flags(struct nvfx_screen* screen)
 {
        int vram_hack_default = 0;
        int vram_hack;
@@ -314,7 +310,7 @@ nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
        }
 #endif
 
-       screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+       return vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
 }
 
 struct pipe_screen *
@@ -375,8 +371,16 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 
        screen->force_swtnl = debug_get_bool_option("NOUVEAU_SWTNL", FALSE);
 
+       screen->vertex_buffer_reloc_flags = nvfx_screen_get_vertex_buffer_flags(screen);
+
+       /* surely both nv3x and nv44 support index buffers too: find out how and test that */
+       if(eng3d_class == NV40TCL)
+               screen->index_buffer_reloc_flags = screen->vertex_buffer_reloc_flags;
+
+       if(!screen->force_swtnl && screen->vertex_buffer_reloc_flags == screen->index_buffer_reloc_flags)
+               screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = screen->vertex_buffer_reloc_flags;
+
        nvfx_screen_init_resource_functions(pscreen);
-       nvfx_screen_init_buffer_functions(screen);
 
        ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
        if (ret) {
index aa1b0e1108580ddac904e7db98f4962fe313db56..127d8919af4fedd2f8700d5494d0ebb04d5c8b3b 100644 (file)
@@ -14,8 +14,9 @@ struct nvfx_screen {
        struct nvfx_context *cur_ctx;
 
        unsigned is_nv4x; /* either 0 or ~0 */
-       int vertex_buffer_flags;
        boolean force_swtnl;
+       unsigned vertex_buffer_reloc_flags;
+       unsigned index_buffer_reloc_flags;
 
        /* HW graphics objects */
        struct nv04_surface_2d *eng2d;
index 8b9b5d0203cda4ebd52253b05a3db8f748f6007d..bc87fe275c0c20b4c9e32b6358efc0b2fc2ac2cf 100644 (file)
@@ -90,7 +90,7 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
                return FALSE;
        }
 
-       if (nvfx->screen->eng3d->grclass != NV40TCL || ib_size == 1)
+       if (!nvfx->screen->index_buffer_reloc_flags || ib_size == 1)
                return FALSE;
 
        switch (ib_size) {
@@ -493,7 +493,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
        int i;
        int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr);
        uint32_t vtxfmt[16];
-       unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
+       unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD;
 
        if (!elements)
                return TRUE;
@@ -567,11 +567,14 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
        OUT_RING(chan, 0);
 
        if (ib) {
+               unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD;
                struct nouveau_bo* bo = nvfx_resource(ib)->bo;
 
+               assert(nvfx->screen->index_buffer_reloc_flags);
+
                OUT_RING(chan, RING_3D(NV34TCL_IDXBUF_ADDRESS, 2));
-               OUT_RELOC(chan, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
-               OUT_RELOC(chan, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
+               OUT_RELOC(chan, bo, 0, ib_flags | NOUVEAU_BO_LOW, 0, 0);
+               OUT_RELOC(chan, bo, ib_format, ib_flags | NOUVEAU_BO_OR,
                                  0, NV34TCL_IDXBUF_FORMAT_DMA1);
        }
 
@@ -583,7 +586,7 @@ void
 nvfx_vbo_relocate(struct nvfx_context *nvfx)
 {
        struct nouveau_channel* chan = nvfx->screen->base.channel;
-       unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
+       unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
        int i;
 
        MARK_RING(chan, 2 * 16 + 3, 2 * 16 + 3);
@@ -602,14 +605,17 @@ nvfx_vbo_relocate(struct nvfx_context *nvfx)
 
        if(nvfx->idxbuf)
        {
+               unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
                struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo;
 
+               assert(nvfx->screen->index_buffer_reloc_flags);
+
                OUT_RELOC(chan, bo, RING_3D(NV34TCL_IDXBUF_ADDRESS, 2),
-                               vb_flags, 0, 0);
+                               ib_flags, 0, 0);
                OUT_RELOC(chan, bo, 0,
-                               vb_flags | NOUVEAU_BO_LOW, 0, 0);
+                               ib_flags | NOUVEAU_BO_LOW, 0, 0);
                OUT_RELOC(chan, bo, nvfx->idxbuf_format,
-                               vb_flags | NOUVEAU_BO_OR,
+                               ib_flags | NOUVEAU_BO_OR,
                                0, NV34TCL_IDXBUF_FORMAT_DMA1);
        }
 }