From: Ben Skeggs Date: Mon, 18 Feb 2008 03:12:58 +0000 (+1100) Subject: nv40: similar changes to polygon stipple as were done for scissor X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=12e0aa7b1d587b7c30897762d2f8f368a4a7d453;p=mesa.git nv40: similar changes to polygon stipple as were done for scissor --- diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index c4523112dbc..7d5806f5f73 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -59,6 +59,18 @@ struct nv40_rasterizer_state { struct nouveau_stateobj *so; }; +struct nv40_state { + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } scissor; + + struct { + unsigned enabled; + struct nouveau_stateobj *so; + } stipple; +}; + struct nv40_context { struct pipe_context pipe; struct nouveau_winsys *nvws; @@ -79,12 +91,10 @@ struct nv40_context { struct { struct pipe_scissor_state scissor; + unsigned stipple[32]; } pipe_state; - struct { - unsigned scissor_enabled; - struct nouveau_stateobj *scissor; - } state; + struct nv40_state state; struct nouveau_stateobj *so_framebuffer; struct nouveau_stateobj *so_fragtex[16]; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index bb9b6b139f0..a36efd37f6a 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -711,15 +711,8 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, const struct pipe_poly_stipple *stipple) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_stateobj *so = so_new(33, 0); - unsigned i; - so_method(so, nv40->hw->curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); - for (i = 0; i < 32; i++) - so_data(so, stipple->stipple[i]); - - so_ref(so, &nv40->so_stipple); - so_ref(NULL, &so); + memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 74306fe22b3..244c6838f34 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -29,8 +29,8 @@ nv40_state_scissor_validate(struct nv40_context *nv40) struct pipe_scissor_state *s = &nv40->pipe_state.scissor; struct nouveau_stateobj *so; - if (nv40->state.scissor && - (rast->scissor == 0 && nv40->state.scissor_enabled == 0)) + if (nv40->state.scissor.so && + (rast->scissor == 0 && nv40->state.scissor.enabled == 0)) return FALSE; so = so_new(3, 0); @@ -43,7 +43,38 @@ nv40_state_scissor_validate(struct nv40_context *nv40) so_data (so, 4096 << 16); } - so_ref(so, &nv40->state.scissor); + so_ref(so, &nv40->state.scissor.so); + so_ref(NULL, &so); + return TRUE; +} + +static boolean +nv40_state_stipple_validate(struct nv40_context *nv40) +{ + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_stateobj *so; + + if (nv40->state.stipple.so && (rast->poly_stipple_enable == 0 && + nv40->state.stipple.enabled == 0)) + return FALSE; + + if (rast->poly_stipple_enable) { + unsigned i; + + so = so_new(35, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 1); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); + for (i = 0; i < 32; i++) + so_data(so, nv40->pipe_state.stipple[i]); + } else { + so = so_new(2, 0); + so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); + so_data (so, 0); + } + + so_ref(so, &nv40->state.stipple.so); so_ref(NULL, &so); return TRUE; } @@ -63,6 +94,13 @@ static struct nv40_state_atom states[] = { .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST, .hw = NV40_NEW_SCISSOR, } + }, + { + .validate = nv40_state_stipple_validate, + .dirty = { + .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST, + .hw = NV40_NEW_STIPPLE, + } } }; @@ -100,15 +138,17 @@ nv40_emit_hw_state(struct nv40_context *nv40) so_emit(nv40->nvws, nv40->so_bcol); if (nv40->hw_dirty & NV40_NEW_SCISSOR) { - so_emit(nv40->nvws, nv40->state.scissor); + so_emit(nv40->nvws, nv40->state.scissor.so); nv40->hw_dirty &= ~NV40_NEW_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->hw_dirty & NV40_NEW_STIPPLE) { + so_emit(nv40->nvws, nv40->state.stipple.so); + nv40->hw_dirty &= ~NV40_NEW_STIPPLE; + } if (nv40->dirty & NV40_NEW_FRAGPROG) { nv40_fragprog_bind(nv40, nv40->fragprog.current);