nv40: keep track of generated context state vs current channel state
This commit is contained in:
parent
c0f9cab905
commit
46c3d0918d
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue