#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)
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];
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
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
{
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 *
boolean translated;
boolean on_hw;
+ unsigned samplers;
uint32_t *insn;
int insn_len;
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) {
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
/* 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 |
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? */
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;
}