summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-02-09 14:08:54 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-02-15 13:50:33 +1100
commit6aad1d9bbc2dd77b600c60e471da3f6e392c09ab (patch)
treee9f3d17e1fad42d88c5e1cef18840552091fd564 /src
parentfc65fb54eec6562b158e38f9fc426b49174ba912 (diff)
nv40: delay all state emit until before draw
Diffstat (limited to 'src')
-rw-r--r--src/mesa/pipe/nouveau/nouveau_stateobj.h2
-rw-r--r--src/mesa/pipe/nv40/nv40_context.h22
-rw-r--r--src/mesa/pipe/nv40/nv40_state.c26
-rw-r--r--src/mesa/pipe/nv40/nv40_state_emit.c25
-rw-r--r--src/mesa/pipe/nv40/nv40_vbo.c5
5 files changed, 66 insertions, 14 deletions
diff --git a/src/mesa/pipe/nouveau/nouveau_stateobj.h b/src/mesa/pipe/nouveau/nouveau_stateobj.h
index 8dfc0e9e9a..58167a24de 100644
--- a/src/mesa/pipe/nouveau/nouveau_stateobj.h
+++ b/src/mesa/pipe/nouveau/nouveau_stateobj.h
@@ -30,7 +30,7 @@ so_new(unsigned push, unsigned reloc)
struct nouveau_stateobj *so;
so = malloc(sizeof(struct nouveau_stateobj));
- so->refcount = 0;
+ so->refcount = 1;
so->push = malloc(sizeof(unsigned) * push);
so->reloc = malloc(sizeof(struct nouveau_stateobj_reloc) * reloc);
diff --git a/src/mesa/pipe/nv40/nv40_context.h b/src/mesa/pipe/nv40/nv40_context.h
index 1a31f00ad6..4aa34847e8 100644
--- a/src/mesa/pipe/nv40/nv40_context.h
+++ b/src/mesa/pipe/nv40/nv40_context.h
@@ -22,9 +22,18 @@
#define NOUVEAU_MSG(fmt, args...) \
fprintf(stderr, "nouveau: "fmt, ##args);
-#define NV40_NEW_VERTPROG (1 << 1)
-#define NV40_NEW_FRAGPROG (1 << 2)
-#define NV40_NEW_ARRAYS (1 << 3)
+#define NV40_NEW_BLEND (1 << 0)
+#define NV40_NEW_RAST (1 << 1)
+#define NV40_NEW_ZSA (1 << 2)
+#define NV40_NEW_SAMPLER (1 << 3)
+#define NV40_NEW_FB (1 << 4)
+#define NV40_NEW_STIPPLE (1 << 5)
+#define NV40_NEW_SCISSOR (1 << 6)
+#define NV40_NEW_VIEWPORT (1 << 7)
+#define NV40_NEW_BCOL (1 << 8)
+#define NV40_NEW_VERTPROG (1 << 9)
+#define NV40_NEW_FRAGPROG (1 << 10)
+#define NV40_NEW_ARRAYS (1 << 11)
struct nv40_context {
struct pipe_context pipe;
@@ -51,6 +60,13 @@ struct nv40_context {
struct nouveau_stateobj *so_framebuffer;
struct nouveau_stateobj *so_fragtex[16];
struct nouveau_stateobj *so_vtxbuf;
+ struct nouveau_stateobj *so_blend;
+ struct nouveau_stateobj *so_rast;
+ struct nouveau_stateobj *so_zsa;
+ struct nouveau_stateobj *so_bcol;
+ struct nouveau_stateobj *so_scissor;
+ struct nouveau_stateobj *so_viewport;
+ struct nouveau_stateobj *so_stipple;
struct {
struct nouveau_resource *exec_heap;
diff --git a/src/mesa/pipe/nv40/nv40_state.c b/src/mesa/pipe/nv40/nv40_state.c
index 125134afdc..ab53b03cb0 100644
--- a/src/mesa/pipe/nv40/nv40_state.c
+++ b/src/mesa/pipe/nv40/nv40_state.c
@@ -53,7 +53,8 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_emit(nv40->nvws, hwcso);
+ so_ref(hwcso, &nv40->so_blend);
+ nv40->dirty |= NV40_NEW_BLEND;
}
static void
@@ -354,7 +355,8 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_emit(nv40->nvws, hwcso);
+ so_ref(hwcso, &nv40->so_rast);
+ nv40->dirty |= NV40_NEW_RAST;
}
static void
@@ -420,7 +422,8 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
- so_emit(nv40->nvws, hwcso);
+ so_ref(hwcso, &nv40->so_zsa);
+ nv40->dirty |= NV40_NEW_ZSA;
}
static void
@@ -508,8 +511,9 @@ nv40_set_blend_color(struct pipe_context *pipe,
(float_to_ubyte(bcol->color[1]) << 8) |
(float_to_ubyte(bcol->color[2]) << 0)));
- so_emit(nv40->nvws, so);
+ so_ref(so, &nv40->so_bcol);
so_ref(NULL, &so);
+ nv40->dirty |= NV40_NEW_BCOL;
}
static void
@@ -677,8 +681,9 @@ nv40_set_framebuffer_state(struct pipe_context *pipe,
so_data (so, ((w - 1) << 16) | 0);
so_data (so, ((h - 1) << 16) | 0);
- so_emit(nv40->nvws, so);
- so_ref (so, &nv40->so_framebuffer);
+ so_ref(so, &nv40->so_framebuffer);
+ so_ref(NULL, &so);
+ nv40->dirty |= NV40_NEW_FB;
}
static void
@@ -693,8 +698,9 @@ nv40_set_polygon_stipple(struct pipe_context *pipe,
for (i = 0; i < 32; i++)
so_data(so, stipple->stipple[i]);
- so_emit(nv40->nvws, so);
+ so_ref(so, &nv40->so_stipple);
so_ref(NULL, &so);
+ nv40->dirty |= NV40_NEW_STIPPLE;
}
static void
@@ -708,8 +714,9 @@ nv40_set_scissor_state(struct pipe_context *pipe,
so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
- so_emit(nv40->nvws, so);
+ so_ref(so, &nv40->so_scissor);
so_ref(NULL, &so);
+ nv40->dirty |= NV40_NEW_SCISSOR;
}
static void
@@ -729,8 +736,9 @@ nv40_set_viewport_state(struct pipe_context *pipe,
so_data (so, fui(vpt->scale[2]));
so_data (so, fui(vpt->scale[3]));
- so_emit(nv40->nvws, so);
+ so_ref(so, &nv40->so_viewport);
so_ref(NULL, &so);
+ nv40->dirty |= NV40_NEW_VIEWPORT;
}
static void
diff --git a/src/mesa/pipe/nv40/nv40_state_emit.c b/src/mesa/pipe/nv40/nv40_state_emit.c
index 3a22cd4bd5..a10c995548 100644
--- a/src/mesa/pipe/nv40/nv40_state_emit.c
+++ b/src/mesa/pipe/nv40/nv40_state_emit.c
@@ -25,6 +25,30 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40)
void
nv40_emit_hw_state(struct nv40_context *nv40)
{
+ if (nv40->dirty & NV40_NEW_FB)
+ so_emit(nv40->nvws, nv40->so_framebuffer);
+
+ if (nv40->dirty & NV40_NEW_BLEND)
+ so_emit(nv40->nvws, nv40->so_blend);
+
+ if (nv40->dirty & NV40_NEW_RAST)
+ so_emit(nv40->nvws, nv40->so_rast);
+
+ if (nv40->dirty & NV40_NEW_ZSA)
+ so_emit(nv40->nvws, nv40->so_zsa);
+
+ if (nv40->dirty & NV40_NEW_BCOL)
+ so_emit(nv40->nvws, nv40->so_bcol);
+
+ if (nv40->dirty & NV40_NEW_SCISSOR)
+ so_emit(nv40->nvws, nv40->so_scissor);
+
+ if (nv40->dirty & NV40_NEW_VIEWPORT)
+ so_emit(nv40->nvws, nv40->so_viewport);
+
+ if (nv40->dirty & NV40_NEW_STIPPLE)
+ so_emit(nv40->nvws, nv40->so_stipple);
+
if (nv40->dirty & NV40_NEW_FRAGPROG) {
nv40_fragprog_bind(nv40, nv40->fragprog.current);
/*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */
@@ -46,6 +70,7 @@ nv40_emit_hw_state(struct nv40_context *nv40)
}
nv40->dirty_samplers = 0;
+ nv40->dirty = 0;
nv40_state_emit_dummy_relocs(nv40);
}
diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c
index e2cb3fda8f..fd1d884193 100644
--- a/src/mesa/pipe/nv40/nv40_vbo.c
+++ b/src/mesa/pipe/nv40/nv40_vbo.c
@@ -158,6 +158,7 @@ nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib,
so_emit(nv40->nvws, vtxfmt);
so_emit(nv40->nvws, vtxbuf);
so_ref (vtxbuf, &nv40->so_vtxbuf);
+ so_ref (NULL, &vtxbuf);
so_ref (NULL, &vtxfmt);
}
@@ -165,8 +166,10 @@ static boolean
nv40_vbo_validate_state(struct nv40_context *nv40,
struct pipe_buffer *ib, unsigned ib_format)
{
+ unsigned vdn = nv40->dirty & NV40_NEW_ARRAYS;
+
nv40_emit_hw_state(nv40);
- if (nv40->dirty & NV40_NEW_ARRAYS || ib) {
+ if (vdn || ib) {
nv40_vbo_arrays_update(nv40, ib, ib_format);
nv40->dirty &= ~NV40_NEW_ARRAYS;
}