summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-02-18 14:12:58 +1100
committerBen Skeggs <skeggsb@gmail.com>2008-02-18 14:12:58 +1100
commit12e0aa7b1d587b7c30897762d2f8f368a4a7d453 (patch)
treeef7d190bd51fe495b7fdf860ec0dbdc04406428d /src/gallium
parent5e091b573aa0a0c45f8ff34429f2a9d4198bb80a (diff)
nv40: similar changes to polygon stipple as were done for scissor
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h18
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c9
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c52
3 files changed, 61 insertions, 18 deletions
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index c4523112db..7d5806f5f7 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 bb9b6b139f..a36efd37f6 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 74306fe22b..244c6838f3 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);