svga: Ensure that the wrong vdecls don't get used in swtnl path
authorJakob Bornecrantz <jakob@vmware.com>
Thu, 16 Dec 2010 03:13:21 +0000 (04:13 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 6 Jan 2011 20:09:07 +0000 (20:09 +0000)
The draw module set new state that didn't require swtnl which caused need_swtnl to
be unset. This caused the call from to svga_update_state(svga, SVGA_STATE_SWTNL_DRAW)
from the vbuf backend to overwrite the vdecls we setup there to be overwritten with
the real buffers vdecls.

src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_state_need_swtnl.c
src/gallium/drivers/svga/svga_swtnl_draw.c

index 04e281a506d5e96686b33a07aa0cebb58de9ef1b..d4970908b1e97e0a070f8e366a05d0191c199762 100644 (file)
@@ -288,6 +288,11 @@ struct svga_sw_state
    boolean need_swvfetch;
    boolean need_pipeline;
    boolean need_swtnl;
+
+   /* Flag to make sure that need sw is on while
+    * updating state within a swtnl call.
+    */
+   boolean in_swtnl_draw;
 };
 
 
index 99263d82e13147ec181c1f9882e0932b149272cd..8ba5ac8cdb4ac1b61c0430ba5c107b3d9ff59776 100644 (file)
@@ -175,6 +175,14 @@ static int update_need_swtnl( struct svga_context *svga,
       need_swtnl = 1;
    }
 
+   /*
+    * Some state changes the draw module does makes us belive we
+    * we don't need swtnl. This causes the vdecl code to pickup
+    * the wrong buffers and vertex formats. Try trivial/line-wide.
+    */
+   if (svga->state.sw.in_swtnl_draw)
+      need_swtnl = 1;
+
    if (need_swtnl != svga->state.sw.need_swtnl) {
       SVGA_DBG(DEBUG_SWTNL|DEBUG_PERF,
                "%s: need_swvfetch %s, need_pipeline %s\n",
index d9039845819f53d7ad2214eb6d89d672d5836b4e..05d86e1fb16ca85a351e46283b1f1b8e857d09d1 100644 (file)
@@ -51,6 +51,9 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
    assert(svga->state.sw.need_swtnl);
    assert(draw);
 
+   /* Make sure that the need_swtnl flag does not go away */
+   svga->state.sw.in_swtnl_draw = TRUE;
+
    ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
    if (ret) {
       svga_context_flush(svga, NULL);
@@ -119,6 +122,9 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
       pipe_buffer_unmap(&svga->pipe, cb_transfer);
    }
 
+   /* Now safe to remove the need_swtnl flag in any update_state call */
+   svga->state.sw.in_swtnl_draw = FALSE;
+
    return ret;
 }