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);
#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;
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;
{
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
{
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
{
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
(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
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
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
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
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
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 */
}
nv40->dirty_samplers = 0;
+ nv40->dirty = 0;
nv40_state_emit_dummy_relocs(nv40);
}
so_emit(nv40->nvws, vtxfmt);
so_emit(nv40->nvws, vtxbuf);
so_ref (vtxbuf, &nv40->so_vtxbuf);
+ so_ref (NULL, &vtxbuf);
so_ref (NULL, &vtxfmt);
}
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;
}