nv40: bind textures based on fragprog usage.
authorBen Skeggs <skeggsb@gmail.com>
Sun, 6 Jan 2008 10:52:24 +0000 (21:52 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Sun, 6 Jan 2008 10:52:24 +0000 (21:52 +1100)
src/mesa/pipe/nv40/nv40_context.h
src/mesa/pipe/nv40/nv40_fragprog.c
src/mesa/pipe/nv40/nv40_state.c
src/mesa/pipe/nv40/nv40_state.h
src/mesa/pipe/nv40/nv40_state_emit.c
src/mesa/pipe/nv40/nv40_state_tex.c

index 975b109..0a89ae8 100644 (file)
@@ -17,7 +17,6 @@
 #define NOUVEAU_MSG(fmt, args...) \
        fprintf(stderr, "nouveau: "fmt, ##args);
 
-#define NV40_NEW_TEXTURE       (1 << 0)
 #define NV40_NEW_VERTPROG      (1 << 1)
 #define NV40_NEW_FRAGPROG      (1 << 2)
 #define NV40_NEW_ARRAYS                (1 << 3)
@@ -39,8 +38,10 @@ struct nv40_context {
        uint32_t dirty;
 
        struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
-       struct pipe_texture       *tex_miptree[PIPE_MAX_SAMPLERS];
-       uint32_t                   tex_dirty;
+       struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
+       unsigned dirty_samplers;
+       unsigned fp_samplers;
+       unsigned vp_samplers;
 
        uint32_t rt_enable;
        struct pipe_buffer_handle *rt[4];
index d23cb5e..01bf5c3 100644 (file)
@@ -223,8 +223,12 @@ nv40_fp_tex(struct nv40_fpc *fpc, int sat, int op, int unit,
            struct nv40_sreg dst, int mask,
            struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2)
 {
+       struct nv40_fragment_program *fp = fpc->fp;
+
        nv40_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2);
-       fpc->fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT);
+
+       fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT);
+       fp->samplers |= (1 << unit);
 }
 
 static INLINE struct nv40_sreg
index 70abc0f..a7a5fef 100644 (file)
@@ -238,10 +238,8 @@ nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit,
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
        struct nv40_sampler_state *ps = hwcso;
 
-       nv40->tex_sampler[unit]  = ps;
-       nv40->tex_dirty         |= (1 << unit);
-
-       nv40->dirty |= NV40_NEW_TEXTURE;
+       nv40->tex_sampler[unit] = ps;
+       nv40->dirty_samplers |= (1 << unit);
 }
 
 static void
@@ -256,10 +254,8 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned unit,
 {
        struct nv40_context *nv40 = (struct nv40_context *)pipe;
 
-       nv40->tex_miptree[unit]  = miptree;
-       nv40->tex_dirty         |= (1 << unit);
-
-       nv40->dirty |= NV40_NEW_TEXTURE;
+       nv40->tex_miptree[unit] = (struct nv40_miptree *)miptree;
+       nv40->dirty_samplers |= (1 << unit);
 }
 
 static void *
index e1a9d58..4c4c847 100644 (file)
@@ -88,6 +88,7 @@ struct nv40_fragment_program {
 
        boolean translated;
        boolean on_hw;
+       unsigned samplers;
 
        uint32_t *insn;
        int       insn_len;
index fc8a0a9..080ade3 100644 (file)
@@ -9,18 +9,17 @@ nv40_emit_hw_state(struct nv40_context *nv40)
 
        if (nv40->dirty & NV40_NEW_FRAGPROG) {
                nv40_fragprog_bind(nv40, nv40->fragprog.current);
-               /*XXX: clear NV40_NEW_FRAGPROG if no now program uploaded */
+               /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */
        }
 
-       if (nv40->dirty & NV40_NEW_TEXTURE)
+       if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) {
                nv40_state_tex_update(nv40);
 
-       if (nv40->dirty & (NV40_NEW_TEXTURE | NV40_NEW_FRAGPROG)) {
                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_TEXTURE | NV40_NEW_FRAGPROG);
+               nv40->dirty &= ~NV40_NEW_FRAGPROG;
        }
 
        if (nv40->dirty & NV40_NEW_VERTPROG) {
@@ -28,6 +27,8 @@ nv40_emit_hw_state(struct nv40_context *nv40)
                nv40->dirty &= ~NV40_NEW_VERTPROG;
        }
 
+       nv40->dirty_samplers = 0;
+
        /* Emit relocs for every referenced buffer.
         * This is to ensure the bufmgr has an accurate idea of how
         * the buffer is used.  This isn't very efficient, but we don't
@@ -73,7 +74,7 @@ nv40_emit_hw_state(struct nv40_context *nv40)
 
        /* Texture images */
        for (i = 0; i < 16; i++) {
-               if (!nv40->tex[i].buffer)
+               if (!(nv40->fp_samplers & (1 << i)))
                        continue;
                BEGIN_RING(curie, NV40TCL_TEX_OFFSET(i), 2);
                OUT_RELOCl(nv40->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
index 9fb274d..8e8609f 100644 (file)
@@ -60,8 +60,8 @@ static void
 nv40_tex_unit_enable(struct nv40_context *nv40, int unit)
 {
        struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
-       struct pipe_texture *pt = nv40->tex_miptree[unit];
-       struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt;
+       struct nv40_miptree *nv40mt = nv40->tex_miptree[unit];
+       struct pipe_texture *pt = &nv40mt->base;
        struct nv40_texture_format *tf;
        uint32_t txf, txs, txp;
        int swizzled = 0; /*XXX: implement in region code? */
@@ -127,18 +127,26 @@ nv40_tex_unit_enable(struct nv40_context *nv40, int unit)
 void
 nv40_state_tex_update(struct nv40_context *nv40)
 {
-       while (nv40->tex_dirty) {
-               int unit = ffs(nv40->tex_dirty) - 1;
-
-               if (nv40->tex_miptree[unit]) {
-                       nv40_tex_unit_enable(nv40, unit);
-               } else {
-                       nv40->tex[unit].buffer = NULL;
-                       BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1);
-                       OUT_RING  (0);
-               }
-
-               nv40->tex_dirty &= ~(1 << unit);
+       struct nv40_fragment_program *fp = nv40->fragprog.active;
+       unsigned samplers, unit;
+
+       samplers = nv40->fp_samplers & ~fp->samplers;
+       while (samplers) {
+               unit = ffs(samplers) - 1;
+               samplers &= ~(1 << unit);
+
+               BEGIN_RING(curie, NV40TCL_TEX_ENABLE(unit), 1);
+               OUT_RING  (0);
+       }
+
+       samplers = nv40->dirty_samplers & fp->samplers;
+       while (samplers) {
+               unit = ffs(samplers) - 1;
+               samplers &= ~(1 << unit);
+
+               nv40_tex_unit_enable(nv40, unit);
        }
+
+       nv40->fp_samplers = fp->samplers;
 }