From ae905056d4feb5a39d956a38ab377f4d78bf4065 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 9 Feb 2008 14:08:54 +1100 Subject: [PATCH] nv40: delay all state emit until before draw --- src/mesa/pipe/nouveau/nouveau_stateobj.h | 2 +- src/mesa/pipe/nv40/nv40_context.h | 22 +++++++++++++++++++--- src/mesa/pipe/nv40/nv40_state.c | 26 +++++++++++++++++--------- src/mesa/pipe/nv40/nv40_state_emit.c | 25 +++++++++++++++++++++++++ src/mesa/pipe/nv40/nv40_vbo.c | 5 ++++- 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 8dfc0e9..58167a2 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 1a31f00..4aa3484 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 125134a..ab53b03 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 3a22cd4..a10c995 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 e2cb3fd..fd1d884 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; } -- 2.7.4