nv40: until gallium is fixed we'll need a fallback for user clip planes
authorBen Skeggs <skeggsb@gmail.com>
Mon, 18 Feb 2008 05:26:33 +0000 (16:26 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Mon, 18 Feb 2008 05:26:33 +0000 (16:26 +1100)
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_state.c
src/gallium/drivers/nv40/nv40_state_emit.c

index 7d5806f5f734d0ca7a823c40d68955e021f563fe..e9ed7ea3fb482ca4a08a3d45c573fed534c48e58 100644 (file)
@@ -34,6 +34,9 @@
 #define NV40_NEW_VERTPROG      (1 <<  9)
 #define NV40_NEW_FRAGPROG      (1 << 10)
 #define NV40_NEW_ARRAYS                (1 << 11)
+#define NV40_NEW_UCP           (1 << 12)
+
+#define NV40_FALLBACK_TNL (1 << 0)
 
 struct nv40_channel_context {
        struct nouveau_winsys *nvws;
@@ -92,9 +95,11 @@ struct nv40_context {
        struct {
                struct pipe_scissor_state scissor;
                unsigned stipple[32];
+               struct pipe_clip_state clip;
        } pipe_state;
 
        struct nv40_state state;
+       unsigned fallback;
 
        struct nouveau_stateobj *so_framebuffer;
        struct nouveau_stateobj *so_fragtex[16];
@@ -131,6 +136,14 @@ nv40_context(struct pipe_context *pipe)
        return (struct nv40_context *)pipe;
 }
 
+struct nv40_state_entry {
+       boolean (*validate)(struct nv40_context *nv40);
+       struct {
+               unsigned pipe;
+               unsigned hw;
+       } dirty;
+};
+
 extern void nv40_init_state_functions(struct nv40_context *nv40);
 extern void nv40_init_surface_functions(struct nv40_context *nv40);
 extern void nv40_init_miptree_functions(struct nv40_context *nv40);
index d7379e909053d2650fbde76a0c02a302546e8712..c203b00240314bdd48842ab90976a2959c8535ab 100644 (file)
@@ -561,6 +561,10 @@ static void
 nv40_set_clip_state(struct pipe_context *pipe,
                    const struct pipe_clip_state *clip)
 {
+       struct nv40_context *nv40 = nv40_context(pipe);
+
+       nv40->pipe_state.clip = *clip;
+       nv40->dirty |= NV40_NEW_UCP;
 }
 
 static void
index 244c6838f34a441476d0fa1203ba44fdf249663c..ce52a3863e7ff869c07d92c7af9e4d2e51910f76 100644 (file)
@@ -79,15 +79,15 @@ nv40_state_stipple_validate(struct nv40_context *nv40)
        return TRUE;
 }
 
-struct nv40_state_atom {
-       boolean (*validate)(struct nv40_context *nv40);
-       struct {
-               unsigned pipe;
-               unsigned hw;
-       } dirty;
-};
+static boolean
+nv40_state_clip_validate(struct nv40_context *nv40)
+{
+       if (nv40->pipe_state.clip.nr)
+               nv40->fallback |= NV40_FALLBACK_TNL;
+       return FALSE;
+}
 
-static struct nv40_state_atom states[] = {
+static struct nv40_state_entry states[] = {
        {
                .validate = nv40_state_scissor_validate,
                .dirty = {
@@ -101,13 +101,23 @@ static struct nv40_state_atom states[] = {
                        .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST,
                        .hw = NV40_NEW_STIPPLE,
                }
+       },
+       {
+               .validate = nv40_state_clip_validate,
+               .dirty = {
+                       .pipe = NV40_NEW_UCP,
+                       .hw = 0,
+               }
        }
 };
 
 static void
 nv40_state_validate(struct nv40_context *nv40)
 {
-       unsigned i;
+       unsigned i, last_fallback;
+
+       last_fallback = nv40->fallback;
+       nv40->fallback = 0;
 
        for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) {
                if (nv40->dirty & states[i].dirty.pipe) {
@@ -115,6 +125,15 @@ nv40_state_validate(struct nv40_context *nv40)
                                nv40->hw_dirty |= states[i].dirty.hw;
                }
        }
+
+       if (nv40->fallback & NV40_FALLBACK_TNL &&
+           !(last_fallback & NV40_FALLBACK_TNL)) {
+               NOUVEAU_ERR("XXX: hwtnl->swtnl\n");
+       } else
+       if (last_fallback & NV40_FALLBACK_TNL &&
+           !(nv40->fallback & NV40_FALLBACK_TNL)) {
+               NOUVEAU_ERR("XXX: swtnl->hwtnl\n");
+       }
 }
 
 void