nv40: delay all state emit until before draw

This commit is contained in:
Ben Skeggs 2008-02-09 14:08:54 +11:00
parent fc65fb54ee
commit 6aad1d9bbc
5 changed files with 66 additions and 14 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}