nv40: keep track of generated context state vs current channel state
authorBen Skeggs <darktama@beleth.(none)>
Wed, 20 Feb 2008 05:21:28 +0000 (16:21 +1100)
committerBen Skeggs <darktama@beleth.(none)>
Wed, 20 Feb 2008 05:21:28 +0000 (16:21 +1100)
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_fragprog.c
src/gallium/drivers/nv40/nv40_state_emit.c
src/gallium/drivers/nv40/nv40_state_scissor.c
src/gallium/drivers/nv40/nv40_state_stipple.c
src/gallium/drivers/nv40/nv40_vertprog.c

index 28a0274d7718cc4549152c5087f0ae75329a7839..2dd137ead0f28ac84f4fb32da003b6715152e6f8 100644 (file)
 #define NOUVEAU_MSG(fmt, args...) \
        fprintf(stderr, "nouveau: "fmt, ##args);
 
+enum nv40_state_index {
+       NV40_STATE_CLIP = 1ULL,
+       NV40_STATE_SCISSOR = 2ULL,
+       NV40_STATE_STIPPLE = 3ULL,
+       NV40_STATE_FRAGPROG = 4ULL,
+       NV40_STATE_VERTPROG = 5ULL,
+       NV40_STATE_MAX = 6ULL
+};
+
 #define NV40_NEW_BLEND         (1 <<  0)
 #define NV40_NEW_RAST          (1 <<  1)
 #define NV40_NEW_ZSA           (1 <<  2)
@@ -56,6 +65,9 @@ struct nv40_channel_context {
        /* Vtxprog resources */
        struct nouveau_resource *vp_exec_heap;
        struct nouveau_resource *vp_data_heap;
+
+       /* Current 3D state of channel */
+       struct nouveau_stateobj *state[NV40_STATE_MAX];
 };
 
 struct nv40_rasterizer_state {
@@ -64,18 +76,10 @@ struct nv40_rasterizer_state {
 };
 
 struct nv40_state {
-       struct {
-               unsigned enabled;
-               struct nouveau_stateobj *so;
-       } scissor;
-
-       struct {
-               unsigned enabled;
-               struct nouveau_stateobj *so;
-       } stipple;
+       unsigned scissor_enabled;
+       unsigned stipple_enabled;
 
-       struct nouveau_stateobj *fragprog;
-       struct nouveau_stateobj *vertprog;
+       struct nouveau_stateobj *hw[NV40_STATE_MAX];
 };
 
 struct nv40_context {
index 77ac8ab2c6121fadd9741019db56e81295d9325c..db2613ef8bb76316f752fb56102d979dc16a3e09 100644 (file)
@@ -841,8 +841,8 @@ update_constants:
                        nv40_fragprog_upload(nv40, fp);
        }
 
-       if (fp->so != nv40->state.fragprog) {
-               so_ref(fp->so, &nv40->state.fragprog);
+       if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) {
+               so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]);
                return TRUE;
        }
 
@@ -861,7 +861,7 @@ struct nv40_state_entry nv40_state_fragprog = {
        .validate = nv40_fragprog_validate,
        .dirty = {
                .pipe = NV40_NEW_FRAGPROG,
-               .hw = NV40_NEW_FRAGPROG
+               .hw = NV40_STATE_FRAGPROG
        }
 };
 
index e8230111bb4893e81f15a133af60690bd77b872f..58beb72389a88efdfb098e8d60d2edc0961af1f6 100644 (file)
@@ -1,27 +1,6 @@
 #include "nv40_context.h"
 #include "nv40_state.h"
 
-/* Emit relocs for every referenced buffer.
- *
- * This is to ensure the bufmgr has an accurate idea of how
- * the buffer is used.  These relocs appear in the push buffer as
- * NOPs, and will only be turned into state changes if a buffer
- * actually moves.
- */
-static void
-nv40_state_emit_dummy_relocs(struct nv40_context *nv40)
-{
-       unsigned i;     
-       
-       so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer);
-       for (i = 0; i < 16; i++) {
-               if (!(nv40->fp_samplers & (1 << i)))
-                       continue;
-               so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]);
-       }
-       so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog);
-}
-
 static struct nv40_state_entry *render_states[] = {
        &nv40_state_clip,
        &nv40_state_scissor,
@@ -45,7 +24,7 @@ nv40_state_validate(struct nv40_context *nv40)
 
                if (nv40->dirty & e->dirty.pipe) {
                        if (e->validate(nv40))
-                               nv40->hw_dirty |= e->dirty.hw;
+                               nv40->hw_dirty |= (1 << e->dirty.hw);
                }
 
                states++;
@@ -70,6 +49,28 @@ nv40_state_validate(struct nv40_context *nv40)
        }
 }
 
+static void
+nv40_state_emit(struct nv40_context *nv40)
+{
+       unsigned i;
+
+       while (nv40->hw_dirty) {
+               unsigned idx = ffs(nv40->hw_dirty) - 1;
+               nv40->hw_dirty &= ~(1 << idx);
+
+               so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]);
+               so_emit(nv40->nvws, nv40->hw->state[idx]);
+       }
+
+       so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer);
+       for (i = 0; i < 16; i++) {
+               if (!(nv40->fp_samplers & (1 << i)))
+                       continue;
+               so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]);
+       }
+       so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]);
+}
+
 void
 nv40_emit_hw_state(struct nv40_context *nv40)
 {
@@ -90,24 +91,9 @@ nv40_emit_hw_state(struct nv40_context *nv40)
        if (nv40->dirty & NV40_NEW_BCOL)
                so_emit(nv40->nvws, nv40->so_bcol);
 
-       if (nv40->hw_dirty & NV40_NEW_SCISSOR) {
-               so_emit(nv40->nvws, nv40->state.scissor.so);
-               nv40->hw_dirty &= ~NV40_NEW_SCISSOR;
-       }
-
        if (nv40->dirty & NV40_NEW_VIEWPORT)
                so_emit(nv40->nvws, nv40->so_viewport);
 
-       if (nv40->hw_dirty & NV40_NEW_STIPPLE) {
-               so_emit(nv40->nvws, nv40->state.stipple.so);
-               nv40->hw_dirty &= ~NV40_NEW_STIPPLE;
-       }
-
-       if (nv40->hw_dirty & NV40_NEW_FRAGPROG) {
-               so_emit(nv40->nvws, nv40->state.fragprog);
-               nv40->hw_dirty &= ~NV40_NEW_FRAGPROG;
-       }
-
        if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) {
                nv40_fragtex_bind(nv40);
 
@@ -118,14 +104,9 @@ nv40_emit_hw_state(struct nv40_context *nv40)
                nv40->dirty &= ~NV40_NEW_FRAGPROG;
        }
 
-       if (nv40->hw_dirty & NV40_NEW_VERTPROG) {
-               so_emit(nv40->nvws, nv40->state.vertprog);
-               nv40->hw_dirty &= ~NV40_NEW_VERTPROG;
-       }
+       nv40_state_emit(nv40);
 
        nv40->dirty_samplers = 0;
        nv40->dirty = 0;
-
-       nv40_state_emit_dummy_relocs(nv40);
 }
 
index 556b820e58182ca747ecc374177667b4317f9539..dc7b6d3a9d88f52249be3c637e4935447261c5b6 100644 (file)
@@ -7,8 +7,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40)
        struct pipe_scissor_state *s = &nv40->pipe_state.scissor;
        struct nouveau_stateobj *so;
 
-       if (nv40->state.scissor.so &&
-           (rast->scissor == 0 && nv40->state.scissor.enabled == 0))
+       if (nv40->state.hw[NV40_STATE_SCISSOR] &&
+           (rast->scissor == 0 && nv40->state.scissor_enabled == 0))
                return FALSE;
 
        so = so_new(3, 0);
@@ -21,7 +21,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40)
                so_data  (so, 4096 << 16);
        }
 
-       so_ref(so, &nv40->state.scissor.so);
+       so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]);
        so_ref(NULL, &so);
        return TRUE;
 }
@@ -30,6 +30,6 @@ struct nv40_state_entry nv40_state_scissor = {
        .validate = nv40_state_scissor_validate,
        .dirty = {
                .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST,
-               .hw = NV40_NEW_SCISSOR
+               .hw = NV40_STATE_SCISSOR
        }
 };
index 52462a0b5024453690c625b9846c43be2a9aa65b..1b0b194432ea40b1a41eba0da1d3c0ed89f901c4 100644 (file)
@@ -7,8 +7,8 @@ nv40_state_stipple_validate(struct nv40_context *nv40)
        struct nouveau_grobj *curie = nv40->hw->curie;
        struct nouveau_stateobj *so;
 
-       if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 &&
-                                      nv40->state.stipple.enabled == 0))
+       if (nv40->state.hw[NV40_STATE_STIPPLE] &&
+          (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0))
                return FALSE;
 
        if (rast->poly_stipple_enable) {
@@ -26,7 +26,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40)
                so_data  (so, 0);
        }
 
-       so_ref(so, &nv40->state.stipple.so);
+       so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]);
        so_ref(NULL, &so);
        return TRUE;
 }
@@ -35,6 +35,6 @@ struct nv40_state_entry nv40_state_stipple = {
        .validate = nv40_state_stipple_validate,
        .dirty = {
                .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST,
-               .hw = NV40_NEW_STIPPLE
+               .hw = NV40_STATE_STIPPLE,
        }
 };
index 4a15e51eb33ae6218d8f600a459aa8cafcff31c4..8a2d2336974f69e97b3edb92de641edddced9b66 100644 (file)
@@ -786,8 +786,8 @@ check_gpu_resources:
                }
        }
 
-       if (vp->so != nv40->state.vertprog) {
-               so_ref(vp->so, &nv40->state.vertprog);
+       if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) {
+               so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]);
                return TRUE;
        }
 
@@ -807,7 +807,7 @@ struct nv40_state_entry nv40_state_vertprog = {
        .validate = nv40_vertprog_validate,
        .dirty = {
                .pipe = NV40_NEW_VERTPROG,
-               .hw = NV40_NEW_VERTPROG
+               .hw = NV40_STATE_VERTPROG,
        }
 };