nv40: keep track of generated context state vs current channel state

This commit is contained in:
Ben Skeggs 2008-02-20 16:21:28 +11:00
parent c0f9cab905
commit 46c3d0918d
6 changed files with 53 additions and 68 deletions

View File

@ -22,6 +22,15 @@
#define NOUVEAU_MSG(fmt, args...) \
fprintf(stderr, "nouveau: "fmt, ##args);
enum nv40_state_index {
NV40_STATE_CLIP = 1ULL,
NV40_STATE_SCISSOR = 2ULL,
NV40_STATE_STIPPLE = 3ULL,
NV40_STATE_FRAGPROG = 4ULL,
NV40_STATE_VERTPROG = 5ULL,
NV40_STATE_MAX = 6ULL
};
#define NV40_NEW_BLEND (1 << 0)
#define NV40_NEW_RAST (1 << 1)
#define NV40_NEW_ZSA (1 << 2)
@ -56,6 +65,9 @@ struct nv40_channel_context {
/* Vtxprog resources */
struct nouveau_resource *vp_exec_heap;
struct nouveau_resource *vp_data_heap;
/* Current 3D state of channel */
struct nouveau_stateobj *state[NV40_STATE_MAX];
};
struct nv40_rasterizer_state {
@ -64,18 +76,10 @@ struct nv40_rasterizer_state {
};
struct nv40_state {
struct {
unsigned enabled;
struct nouveau_stateobj *so;
} scissor;
unsigned scissor_enabled;
unsigned stipple_enabled;
struct {
unsigned enabled;
struct nouveau_stateobj *so;
} stipple;
struct nouveau_stateobj *fragprog;
struct nouveau_stateobj *vertprog;
struct nouveau_stateobj *hw[NV40_STATE_MAX];
};
struct nv40_context {

View File

@ -841,8 +841,8 @@ update_constants:
nv40_fragprog_upload(nv40, fp);
}
if (fp->so != nv40->state.fragprog) {
so_ref(fp->so, &nv40->state.fragprog);
if (fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) {
so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]);
return TRUE;
}
@ -861,7 +861,7 @@ struct nv40_state_entry nv40_state_fragprog = {
.validate = nv40_fragprog_validate,
.dirty = {
.pipe = NV40_NEW_FRAGPROG,
.hw = NV40_NEW_FRAGPROG
.hw = NV40_STATE_FRAGPROG
}
};

View File

@ -1,27 +1,6 @@
#include "nv40_context.h"
#include "nv40_state.h"
/* Emit relocs for every referenced buffer.
*
* This is to ensure the bufmgr has an accurate idea of how
* the buffer is used. These relocs appear in the push buffer as
* NOPs, and will only be turned into state changes if a buffer
* actually moves.
*/
static void
nv40_state_emit_dummy_relocs(struct nv40_context *nv40)
{
unsigned i;
so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer);
for (i = 0; i < 16; i++) {
if (!(nv40->fp_samplers & (1 << i)))
continue;
so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]);
}
so_emit_reloc_markers(nv40->nvws, nv40->state.fragprog);
}
static struct nv40_state_entry *render_states[] = {
&nv40_state_clip,
&nv40_state_scissor,
@ -45,7 +24,7 @@ nv40_state_validate(struct nv40_context *nv40)
if (nv40->dirty & e->dirty.pipe) {
if (e->validate(nv40))
nv40->hw_dirty |= e->dirty.hw;
nv40->hw_dirty |= (1 << e->dirty.hw);
}
states++;
@ -70,6 +49,28 @@ nv40_state_validate(struct nv40_context *nv40)
}
}
static void
nv40_state_emit(struct nv40_context *nv40)
{
unsigned i;
while (nv40->hw_dirty) {
unsigned idx = ffs(nv40->hw_dirty) - 1;
nv40->hw_dirty &= ~(1 << idx);
so_ref (nv40->state.hw[idx], &nv40->hw->state[idx]);
so_emit(nv40->nvws, nv40->hw->state[idx]);
}
so_emit_reloc_markers(nv40->nvws, nv40->so_framebuffer);
for (i = 0; i < 16; i++) {
if (!(nv40->fp_samplers & (1 << i)))
continue;
so_emit_reloc_markers(nv40->nvws, nv40->so_fragtex[i]);
}
so_emit_reloc_markers(nv40->nvws, nv40->state.hw[NV40_STATE_FRAGPROG]);
}
void
nv40_emit_hw_state(struct nv40_context *nv40)
{
@ -90,24 +91,9 @@ nv40_emit_hw_state(struct nv40_context *nv40)
if (nv40->dirty & NV40_NEW_BCOL)
so_emit(nv40->nvws, nv40->so_bcol);
if (nv40->hw_dirty & NV40_NEW_SCISSOR) {
so_emit(nv40->nvws, nv40->state.scissor.so);
nv40->hw_dirty &= ~NV40_NEW_SCISSOR;
}
if (nv40->dirty & NV40_NEW_VIEWPORT)
so_emit(nv40->nvws, nv40->so_viewport);
if (nv40->hw_dirty & NV40_NEW_STIPPLE) {
so_emit(nv40->nvws, nv40->state.stipple.so);
nv40->hw_dirty &= ~NV40_NEW_STIPPLE;
}
if (nv40->hw_dirty & NV40_NEW_FRAGPROG) {
so_emit(nv40->nvws, nv40->state.fragprog);
nv40->hw_dirty &= ~NV40_NEW_FRAGPROG;
}
if (nv40->dirty_samplers || (nv40->dirty & NV40_NEW_FRAGPROG)) {
nv40_fragtex_bind(nv40);
@ -118,14 +104,9 @@ nv40_emit_hw_state(struct nv40_context *nv40)
nv40->dirty &= ~NV40_NEW_FRAGPROG;
}
if (nv40->hw_dirty & NV40_NEW_VERTPROG) {
so_emit(nv40->nvws, nv40->state.vertprog);
nv40->hw_dirty &= ~NV40_NEW_VERTPROG;
}
nv40_state_emit(nv40);
nv40->dirty_samplers = 0;
nv40->dirty = 0;
nv40_state_emit_dummy_relocs(nv40);
}

View File

@ -7,8 +7,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40)
struct pipe_scissor_state *s = &nv40->pipe_state.scissor;
struct nouveau_stateobj *so;
if (nv40->state.scissor.so &&
(rast->scissor == 0 && nv40->state.scissor.enabled == 0))
if (nv40->state.hw[NV40_STATE_SCISSOR] &&
(rast->scissor == 0 && nv40->state.scissor_enabled == 0))
return FALSE;
so = so_new(3, 0);
@ -21,7 +21,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40)
so_data (so, 4096 << 16);
}
so_ref(so, &nv40->state.scissor.so);
so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]);
so_ref(NULL, &so);
return TRUE;
}
@ -30,6 +30,6 @@ struct nv40_state_entry nv40_state_scissor = {
.validate = nv40_state_scissor_validate,
.dirty = {
.pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST,
.hw = NV40_NEW_SCISSOR
.hw = NV40_STATE_SCISSOR
}
};

View File

@ -7,8 +7,8 @@ nv40_state_stipple_validate(struct nv40_context *nv40)
struct nouveau_grobj *curie = nv40->hw->curie;
struct nouveau_stateobj *so;
if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 &&
nv40->state.stipple.enabled == 0))
if (nv40->state.hw[NV40_STATE_STIPPLE] &&
(rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0))
return FALSE;
if (rast->poly_stipple_enable) {
@ -26,7 +26,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40)
so_data (so, 0);
}
so_ref(so, &nv40->state.stipple.so);
so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]);
so_ref(NULL, &so);
return TRUE;
}
@ -35,6 +35,6 @@ struct nv40_state_entry nv40_state_stipple = {
.validate = nv40_state_stipple_validate,
.dirty = {
.pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST,
.hw = NV40_NEW_STIPPLE
.hw = NV40_STATE_STIPPLE,
}
};

View File

@ -786,8 +786,8 @@ check_gpu_resources:
}
}
if (vp->so != nv40->state.vertprog) {
so_ref(vp->so, &nv40->state.vertprog);
if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) {
so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]);
return TRUE;
}
@ -807,7 +807,7 @@ struct nv40_state_entry nv40_state_vertprog = {
.validate = nv40_vertprog_validate,
.dirty = {
.pipe = NV40_NEW_VERTPROG,
.hw = NV40_NEW_VERTPROG
.hw = NV40_STATE_VERTPROG,
}
};