nv40: rework fragment texture state
authorBen Skeggs <darktama@beleth.(none)>
Fri, 22 Feb 2008 02:32:51 +0000 (13:32 +1100)
committerBen Skeggs <darktama@beleth.(none)>
Fri, 22 Feb 2008 02:32:51 +0000 (13:32 +1100)
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_fragtex.c
src/gallium/drivers/nv40/nv40_state.c
src/gallium/drivers/nv40/nv40_state_emit.c

index 69062a8..cbc798f 100644 (file)
@@ -155,7 +155,6 @@ struct nv40_context {
        struct nv40_state state;
        unsigned fallback;
 
-       struct nouveau_stateobj *so_fragtex[16];
        struct nouveau_stateobj *so_vtxbuf;
 
        struct pipe_vertex_buffer  vtxbuf[PIPE_ATTRIB_MAX];
@@ -209,6 +208,7 @@ extern struct nv40_state_entry nv40_state_blend_colour;
 extern struct nv40_state_entry nv40_state_zsa;
 extern struct nv40_state_entry nv40_state_viewport;
 extern struct nv40_state_entry nv40_state_framebuffer;
+extern struct nv40_state_entry nv40_state_fragtex;
 
 /* nv40_vbo.c */
 extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode,
index 811f309..826d4a9 100644 (file)
@@ -52,7 +52,7 @@ nv40_fragtex_format(uint pipe_format)
 }
 
 
-static void
+static struct nouveau_stateobj *
 nv40_fragtex_build(struct nv40_context *nv40, int unit)
 {
        struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
@@ -90,7 +90,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
                break;
        default:
                NOUVEAU_ERR("Unknown target %d\n", pt->target);
-               return;
+               return NULL;
        }
 
        if (swizzled) {
@@ -117,15 +117,14 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
        so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1);
        so_data  (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
 
-       so_emit(nv40->nvws, so);
-       so_ref (so, &nv40->so_fragtex[unit]);
-       so_ref (NULL, &so);
+       return so;
 }
 
-void
-nv40_fragtex_bind(struct nv40_context *nv40)
+static boolean
+nv40_fragtex_validate(struct nv40_context *nv40)
 {
        struct nv40_fragment_program *fp = nv40->pipe_state.fragprog;
+       struct nouveau_stateobj *so;
        unsigned samplers, unit;
 
        samplers = nv40->fp_samplers & ~fp->samplers;
@@ -133,9 +132,12 @@ nv40_fragtex_bind(struct nv40_context *nv40)
                unit = ffs(samplers) - 1;
                samplers &= ~(1 << unit);
 
-               so_ref(NULL, &nv40->so_fragtex[unit]);
-               BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1);
-               OUT_RING  (0);
+               so = so_new(2, 0);
+               so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1);
+               so_data  (so, 0);
+               so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
+               so_ref(NULL, &so);
+               nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit));
        }
 
        samplers = nv40->dirty_samplers & fp->samplers;
@@ -143,9 +145,21 @@ nv40_fragtex_bind(struct nv40_context *nv40)
                unit = ffs(samplers) - 1;
                samplers &= ~(1 << unit);
 
-               nv40_fragtex_build(nv40, unit);
+               so = nv40_fragtex_build(nv40, unit);
+               so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
+               so_ref(NULL, &so);
+               nv40->hw_dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit));
        }
 
        nv40->fp_samplers = fp->samplers;
+       return FALSE;
 }
 
+struct nv40_state_entry nv40_state_fragtex = {
+       .validate = nv40_fragtex_validate,
+       .dirty = {
+               .pipe = NV40_NEW_SAMPLER | NV40_NEW_FRAGPROG,
+               .hw = 0
+       }
+};
+
index 84818d6..74cbabb 100644 (file)
@@ -259,6 +259,7 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit,
 
        nv40->tex_sampler[unit] = ps;
        nv40->dirty_samplers |= (1 << unit);
+       nv40->dirty |= NV40_NEW_SAMPLER;
 }
 
 static void
@@ -275,6 +276,7 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit,
 
        nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree;
        nv40->dirty_samplers |= (1 << unit);
+       nv40->dirty |= NV40_NEW_SAMPLER;
 }
 
 static void *
index a9ca71c..6d87b7b 100644 (file)
@@ -8,6 +8,7 @@ static struct nv40_state_entry *render_states[] = {
        &nv40_state_scissor,
        &nv40_state_stipple,
        &nv40_state_fragprog,
+       &nv40_state_fragtex,
        &nv40_state_vertprog,
        &nv40_state_blend,
        &nv40_state_blend_colour,
@@ -35,6 +36,7 @@ nv40_state_validate(struct nv40_context *nv40)
 
                states++;
        }
+       nv40->dirty = 0;
 
        if (nv40->fallback & NV40_FALLBACK_TNL &&
            !(last_fallback & NV40_FALLBACK_TNL)) {
@@ -72,7 +74,8 @@ nv40_state_emit(struct nv40_context *nv40)
        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_FRAGTEX0+i]);
        }
        so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]);
 }
@@ -81,20 +84,11 @@ void
 nv40_emit_hw_state(struct nv40_context *nv40)
 {
        nv40_state_validate(nv40);
-
-       if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) {
-               nv40_fragtex_bind(nv40);
-
-               BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
-               OUT_RING  (2);
-               BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
-               OUT_RING  (1);
-               nv40->dirty &= ~NV40_NEW_FRAGPROG;
-       }
-
        nv40_state_emit(nv40);
 
-       nv40->dirty_samplers = 0;
-       nv40->dirty = 0;
+       BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
+       OUT_RING  (2);
+       BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
+       OUT_RING  (1);
 }