summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv40
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv40')
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h26
-rw-r--r--src/gallium/drivers/nv40/nv40_fragprog.c6
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c67
-rw-r--r--src/gallium/drivers/nv40/nv40_state_scissor.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_state_stipple.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c6
6 files changed, 53 insertions, 68 deletions
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index 28a0274d771..2dd137ead0f 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -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;
-
- struct {
- unsigned enabled;
- struct nouveau_stateobj *so;
- } stipple;
+ unsigned scissor_enabled;
+ unsigned stipple_enabled;
- struct nouveau_stateobj *fragprog;
- struct nouveau_stateobj *vertprog;
+ struct nouveau_stateobj *hw[NV40_STATE_MAX];
};
struct nv40_context {
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c
index 77ac8ab2c61..db2613ef8bb 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nv40/nv40_fragprog.c
@@ -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
}
};
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index e8230111bb4..58beb72389a 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -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);
}
diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c
index 556b820e581..dc7b6d3a9d8 100644
--- a/src/gallium/drivers/nv40/nv40_state_scissor.c
+++ b/src/gallium/drivers/nv40/nv40_state_scissor.c
@@ -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
}
};
diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c
index 52462a0b502..1b0b194432e 100644
--- a/src/gallium/drivers/nv40/nv40_state_stipple.c
+++ b/src/gallium/drivers/nv40/nv40_state_stipple.c
@@ -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,
}
};
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 4a15e51eb33..8a2d2336974 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -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,
}
};