summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/pipe/nv40/nv40_context.h7
-rw-r--r--src/mesa/pipe/nv40/nv40_fragprog.c6
-rw-r--r--src/mesa/pipe/nv40/nv40_state.c12
-rw-r--r--src/mesa/pipe/nv40/nv40_state.h1
-rw-r--r--src/mesa/pipe/nv40/nv40_state_emit.c11
-rw-r--r--src/mesa/pipe/nv40/nv40_state_tex.c36
6 files changed, 42 insertions, 31 deletions
diff --git a/src/mesa/pipe/nv40/nv40_context.h b/src/mesa/pipe/nv40/nv40_context.h
index 975b1096cc..0a89ae8bed 100644
--- a/src/mesa/pipe/nv40/nv40_context.h
+++ b/src/mesa/pipe/nv40/nv40_context.h
@@ -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];
diff --git a/src/mesa/pipe/nv40/nv40_fragprog.c b/src/mesa/pipe/nv40/nv40_fragprog.c
index d23cb5ee9d..01bf5c3460 100644
--- a/src/mesa/pipe/nv40/nv40_fragprog.c
+++ b/src/mesa/pipe/nv40/nv40_fragprog.c
@@ -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
diff --git a/src/mesa/pipe/nv40/nv40_state.c b/src/mesa/pipe/nv40/nv40_state.c
index 70abc0feba..a7a5fefc6d 100644
--- a/src/mesa/pipe/nv40/nv40_state.c
+++ b/src/mesa/pipe/nv40/nv40_state.c
@@ -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 *
diff --git a/src/mesa/pipe/nv40/nv40_state.h b/src/mesa/pipe/nv40/nv40_state.h
index e1a9d58525..4c4c847c9a 100644
--- a/src/mesa/pipe/nv40/nv40_state.h
+++ b/src/mesa/pipe/nv40/nv40_state.h
@@ -88,6 +88,7 @@ struct nv40_fragment_program {
boolean translated;
boolean on_hw;
+ unsigned samplers;
uint32_t *insn;
int insn_len;
diff --git a/src/mesa/pipe/nv40/nv40_state_emit.c b/src/mesa/pipe/nv40/nv40_state_emit.c
index fc8a0a952a..080ade3827 100644
--- a/src/mesa/pipe/nv40/nv40_state_emit.c
+++ b/src/mesa/pipe/nv40/nv40_state_emit.c
@@ -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 |
diff --git a/src/mesa/pipe/nv40/nv40_state_tex.c b/src/mesa/pipe/nv40/nv40_state_tex.c
index 9fb274d627..8e8609f5c9 100644
--- a/src/mesa/pipe/nv40/nv40_state_tex.c
+++ b/src/mesa/pipe/nv40/nv40_state_tex.c
@@ -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;
}