nvfx: add NOUVEAU_VTXIDX_IN_VRAM variable to put vertex/index buffers in VRAM
authorLuca Barbieri <luca@luca-barbieri.com>
Mon, 11 Jan 2010 02:13:42 +0000 (03:13 +0100)
committerLuca Barbieri <luca@luca-barbieri.com>
Tue, 23 Mar 2010 17:11:25 +0000 (18:11 +0100)
On some systems, putting vertex and index buffers in VRAM instead of GART
memory eliminates massive graphics corruption which is otherwise present,
due to unclear causes.

This patch adds an environment variable that does that, along with helpful
messages.

It turns it on by default on G7x, as it is what I am seeing corruption
on and some other reports also seemed to pinpoint these cards.

src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_screen.h
src/gallium/drivers/nvfx/nvfx_vbo.c

index 6cbd8b23e1f033f59443788c29faa2aec4795f18..f7f39218944b7dbd87d9fb8cf4c67ac1d1a5f1b4 100644 (file)
@@ -293,6 +293,36 @@ static void nv40_screen_init(struct nvfx_screen *screen, struct nouveau_stateobj
        so_data  (so, 0x00000001);
 }
 
+static void
+nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+{
+       int vram_hack_default = 0;
+       int vram_hack;
+       // TODO: this is a bit of a guess; also add other cards that may need this hack.
+       // It may also depend on the specific card or the AGP/PCIe chipset.
+       if(screen->base.device->chipset == 0x47 /* G70 */
+               || screen->base.device->chipset == 0x49 /* G71 */
+               || screen->base.device->chipset == 0x46 /* G72 */
+               )
+               vram_hack_default = 1;
+       vram_hack = debug_get_bool_option("NOUVEAU_VTXIDX_IN_VRAM", vram_hack_default);
+
+#ifdef DEBUG
+       if(!vram_hack)
+       {
+               fprintf(stderr, "Some systems may experience graphics corruption due to randomly misplaced vertices.\n"
+                       "If this is happening, export NOUVEAU_VTXIDX_IN_VRAM=1 may reduce or eliminate the problem\n");
+       }
+       else
+       {
+               fprintf(stderr, "A performance reducing hack is being used to help avoid graphics corruption.\n"
+                       "You can try export NOUVEAU_VTXIDX_IN_VRAM=0 to disable it.\n");
+       }
+#endif
+
+       screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+}
+
 struct pipe_screen *
 nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
 {
@@ -350,6 +380,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
                return NULL;
        }
 
+       nvfx_screen_init_buffer_functions(screen);
        nvfx_screen_init_miptree_functions(pscreen);
 
        ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
index c0b4b9899dd501b3a69c3e4ca44abd8f41b51128..baa848c47aaedf6dd3a9db95dd5c5ea0807fea83 100644 (file)
@@ -12,6 +12,7 @@ struct nvfx_screen {
        struct nvfx_context *cur_ctx;
 
        unsigned is_nv4x; /* either 0 or ~0 */
+       int vertex_buffer_flags;
 
        /* HW graphics objects */
        struct nv04_surface_2d *eng2d;
index db47acb9502f0e7f8b449f244fda12d19c2a8b39..c26536b0e77ca7ed824491068834d6c0599077ef 100644 (file)
@@ -495,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
        struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
        struct pipe_buffer *ib = nvfx->idxbuf;
        unsigned ib_format = nvfx->idxbuf_format;
-       unsigned vb_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+       unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
        int hw;
 
        vtxbuf = so_new(3, 17, 18);