summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-06-16 22:24:16 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-06-29 15:46:19 +1000
commitbb9efb5534a652878161e28bd73039eff5b11014 (patch)
tree298c27678a56fa1ef0d9b520cd0e1107f046e3c8 /src/gallium/drivers/nv50
parent94999d39d43d24a702f4cb55b515906d03a57277 (diff)
nv50: separate state validation and upload, similar to nv40
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h21
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c80
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c6
4 files changed, 86 insertions, 27 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index cbb473410a..3e0e523ee3 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -74,6 +74,25 @@ nv50_miptree(struct pipe_texture *pt)
return (struct nv50_miptree *)pt;
}
+struct nv50_state {
+ unsigned dirty;
+
+ struct nouveau_stateobj *fb;
+ struct nouveau_stateobj *blend;
+ struct nouveau_stateobj *blend_colour;
+ struct nouveau_stateobj *zsa;
+ struct nouveau_stateobj *rast;
+ struct nouveau_stateobj *stipple;
+ struct nouveau_stateobj *scissor;
+ struct nouveau_stateobj *viewport;
+ struct nouveau_stateobj *tsc_upload;
+ struct nouveau_stateobj *tic_upload;
+ struct nouveau_stateobj *vertprog;
+ struct nouveau_stateobj *fragprog;
+ struct nouveau_stateobj *vtxfmt;
+ struct nouveau_stateobj *vtxbuf;
+};
+
struct nv50_context {
struct pipe_context pipe;
@@ -82,6 +101,8 @@ struct nv50_context {
struct draw_context *draw;
+ struct nv50_state state;
+
unsigned dirty;
struct nv50_blend_stateobj *blend;
struct nv50_zsa_stateobj *zsa;
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 21945410b1..7bb2f454bb 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -1615,8 +1615,7 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp);
so_method(so, tesla, 0x140c, 1);
so_data (so, 0); /* program start offset */
- so_emit(nv50->screen->nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.vertprog);
}
void
@@ -1655,8 +1654,7 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp);
so_method(so, tesla, 0x1414, 1);
so_data (so, 0); /* program start offset */
- so_emit(nv50->screen->nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.fragprog);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index 9d93c04da7..566f95f682 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -103,14 +103,59 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, 0);
so_data (so, h);
- so_emit(nv50->screen->nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.fb);
+}
+
+static void
+nv50_state_emit(struct nv50_context *nv50)
+{
+ struct nv50_screen *screen = nv50->screen;
+ struct nouveau_winsys *nvws = screen->nvws;
+
+ if (nv50->pctx_id != screen->cur_pctx) {
+ nv50->state.dirty |= 0xffffffff;
+ screen->cur_pctx = nv50->pctx_id;
+ }
+
+ if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
+ so_emit(nvws, nv50->state.fb);
+ if (nv50->state.dirty & NV50_NEW_BLEND)
+ so_emit(nvws, nv50->state.blend);
+ if (nv50->state.dirty & NV50_NEW_ZSA)
+ so_emit(nvws, nv50->state.zsa);
+ if (nv50->state.dirty & NV50_NEW_VERTPROG)
+ so_emit(nvws, nv50->state.vertprog);
+ if (nv50->state.dirty & NV50_NEW_FRAGPROG)
+ so_emit(nvws, nv50->state.fragprog);
+ if (nv50->state.dirty & NV50_NEW_RASTERIZER)
+ so_emit(nvws, nv50->state.rast);
+ if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
+ so_emit(nvws, nv50->state.blend_colour);
+ if (nv50->state.dirty & NV50_NEW_STIPPLE)
+ so_emit(nvws, nv50->state.stipple);
+ if (nv50->state.dirty & NV50_NEW_SCISSOR)
+ so_emit(nvws, nv50->state.scissor);
+ if (nv50->state.dirty & NV50_NEW_VIEWPORT)
+ so_emit(nvws, nv50->state.viewport);
+ if (nv50->state.dirty & NV50_NEW_SAMPLER)
+ so_emit(nvws, nv50->state.tsc_upload);
+ if (nv50->state.dirty & NV50_NEW_TEXTURE)
+ so_emit(nvws, nv50->state.tic_upload);
+ if (nv50->state.dirty & NV50_NEW_ARRAYS) {
+ so_emit(nvws, nv50->state.vtxfmt);
+ so_emit(nvws, nv50->state.vtxbuf);
+ }
+ nv50->state.dirty = 0;
+
+ so_emit_reloc_markers(nvws, nv50->state.fb);
+ so_emit_reloc_markers(nvws, nv50->state.vertprog);
+ so_emit_reloc_markers(nvws, nv50->state.fragprog);
+ so_emit_reloc_markers(nvws, nv50->state.vtxbuf);
}
boolean
nv50_state_validate(struct nv50_context *nv50)
{
- struct nouveau_winsys *nvws = nv50->screen->nvws;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so;
unsigned i;
@@ -119,10 +164,10 @@ nv50_state_validate(struct nv50_context *nv50)
nv50_state_validate_fb(nv50);
if (nv50->dirty & NV50_NEW_BLEND)
- so_emit(nvws, nv50->blend->so);
+ so_ref(nv50->blend->so, &nv50->state.blend);
if (nv50->dirty & NV50_NEW_ZSA)
- so_emit(nvws, nv50->zsa->so);
+ so_ref(nv50->zsa->so, &nv50->state.zsa);
if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
nv50_vertprog_validate(nv50);
@@ -131,7 +176,7 @@ nv50_state_validate(struct nv50_context *nv50)
nv50_fragprog_validate(nv50);
if (nv50->dirty & NV50_NEW_RASTERIZER)
- so_emit(nvws, nv50->rasterizer->so);
+ so_ref(nv50->rasterizer->so, &nv50->state.rast);
if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
so = so_new(5, 0);
@@ -140,8 +185,7 @@ nv50_state_validate(struct nv50_context *nv50)
so_data (so, fui(nv50->blend_colour.color[1]));
so_data (so, fui(nv50->blend_colour.color[2]));
so_data (so, fui(nv50->blend_colour.color[3]));
- so_emit(nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.blend_colour);
}
if (nv50->dirty & NV50_NEW_STIPPLE) {
@@ -149,8 +193,7 @@ nv50_state_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
for (i = 0; i < 32; i++)
so_data(so, nv50->stipple.stipple[i]);
- so_emit(nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.stipple);
}
if (nv50->dirty & NV50_NEW_SCISSOR) {
@@ -160,8 +203,7 @@ nv50_state_validate(struct nv50_context *nv50)
nv50->scissor.minx);
so_data (so, (nv50->scissor.maxy << 16) |
nv50->scissor.miny);
- so_emit(nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.scissor);
}
if (nv50->dirty & NV50_NEW_VIEWPORT) {
@@ -174,8 +216,7 @@ nv50_state_validate(struct nv50_context *nv50)
so_data (so, fui(nv50->viewport.scale[0]));
so_data (so, fui(-nv50->viewport.scale[1]));
so_data (so, fui(nv50->viewport.scale[2]));
- so_emit(nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.viewport);
}
if (nv50->dirty & NV50_NEW_SAMPLER) {
@@ -187,8 +228,7 @@ nv50_state_validate(struct nv50_context *nv50)
so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
for (i = 0; i < nv50->sampler_nr; i++)
so_datap (so, nv50->sampler[i], 8);
- so_emit(nvws, so);
- so_ref(NULL, &so);
+ so_ref(so, &nv50->state.tsc_upload);
}
if (nv50->dirty & NV50_NEW_TEXTURE) {
@@ -213,15 +253,17 @@ nv50_state_validate(struct nv50_context *nv50)
so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_HIGH, 0, 0);
}
-
- so_emit(nvws, so);
- so_ref(NULL, &so);
+
+ so_ref(so, &nv50->state.tic_upload);
}
if (nv50->dirty & NV50_NEW_ARRAYS)
nv50_vbo_validate(nv50);
+ nv50->state.dirty |= nv50->dirty;
nv50->dirty = 0;
+ nv50_state_emit(nv50);
+
return TRUE;
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 7a1c2f24ef..3f0b66ae36 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -208,9 +208,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
NOUVEAU_BO_LOW, 0, 0);
}
- so_emit(nv50->screen->nvws, vtxfmt);
- so_ref (NULL, &vtxfmt);
- so_emit(nv50->screen->nvws, vtxbuf);
- so_ref (NULL, &vtxbuf);
+ so_ref (vtxfmt, &nv50->state.vtxfmt);
+ so_ref (vtxbuf, &nv50->state.vtxbuf);
}