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 975b1096ccf56ed69f9651543a699f421607c4c0..0a89ae8bedefe18c6ae199ba8680fc90326938a2 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 d23cb5ee9d8efa6cbebe71e1bc773771443227e2..01bf5c3460baf1af0dfde3630a6171000f281f89 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 70abc0feba01efcb56dfe7151abf0be11698b338..a7a5fefc6d64ba453517de7fa1e9fd75a7a7c25e 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 e1a9d58525ae11dfdb5ff0c975965d6686bb636c..4c4c847c9a13a1f971d6b59a05d3fc5089e7a5ef 100644 (file)
@@ -88,6 +88,7 @@ struct nv40_fragment_program {
 
        boolean translated;
        boolean on_hw;
+       unsigned samplers;
 
        uint32_t *insn;
        int       insn_len;
index fc8a0a952afdf7fd071a80bd02579e6b1e01b0c8..080ade3827fcf8219b60f3a93447cbe2fa18d9de 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 9fb274d6274d2f8cf164b3c3d2d52e1f5d7e987f..8e8609f5c95631f54cb880e6bb1058255c0d1837 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;
 }