mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-31 20:00:24 +01:00
nv40: bind textures based on fragprog usage.
This commit is contained in:
parent
732540f997
commit
df34b6b2bc
6 changed files with 40 additions and 29 deletions
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ struct nv40_fragment_program {
|
|||
|
||||
boolean translated;
|
||||
boolean on_hw;
|
||||
unsigned samplers;
|
||||
|
||||
uint32_t *insn;
|
||||
int insn_len;
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
struct nv40_fragment_program *fp = nv40->fragprog.active;
|
||||
unsigned samplers, unit;
|
||||
|
||||
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);
|
||||
}
|
||||
samplers = nv40->fp_samplers & ~fp->samplers;
|
||||
while (samplers) {
|
||||
unit = ffs(samplers) - 1;
|
||||
samplers &= ~(1 << unit);
|
||||
|
||||
nv40->tex_dirty &= ~(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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue