nv40: ensure scissor gets disabled where necessary

Fixes progs/demos/lodbias.

Makes a complete mess of things, but now there's a motivation to finish
this off :)
This commit is contained in:
Ben Skeggs 2008-02-16 21:27:53 +11:00
parent 9a6c39bd2e
commit 5e091b573a
3 changed files with 91 additions and 16 deletions

View File

@ -54,6 +54,11 @@ struct nv40_channel_context {
struct nouveau_resource *vp_data_heap;
};
struct nv40_rasterizer_state {
struct pipe_rasterizer_state pipe;
struct nouveau_stateobj *so;
};
struct nv40_context {
struct pipe_context pipe;
struct nouveau_winsys *nvws;
@ -63,7 +68,8 @@ struct nv40_context {
int chipset;
uint32_t dirty;
unsigned dirty;
unsigned hw_dirty;
struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
@ -71,14 +77,23 @@ struct nv40_context {
unsigned fp_samplers;
unsigned vp_samplers;
struct {
struct pipe_scissor_state scissor;
} pipe_state;
struct {
unsigned scissor_enabled;
struct nouveau_stateobj *scissor;
} state;
struct nouveau_stateobj *so_framebuffer;
struct nouveau_stateobj *so_fragtex[16];
struct nouveau_stateobj *so_vtxbuf;
struct nouveau_stateobj *so_blend;
struct nv40_rasterizer_state *rasterizer;
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;

View File

@ -278,12 +278,12 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso));
struct nouveau_stateobj *so = so_new(32, 0);
/*XXX: ignored:
* light_twoside
* offset_cw/ccw -nohw
* scissor
* point_smooth -nohw
* multisample
* offset_units / offset_scale
@ -362,24 +362,29 @@ nv40_rasterizer_state_create(struct pipe_context *pipe,
so_data(so, 0);
}
return (void *)so;
rsso->so = so;
rsso->pipe = *cso;
return (void *)rsso;
}
static void
nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_rasterizer_state *rsso = hwcso;
so_ref(hwcso, &nv40->so_rast);
so_ref(rsso->so, &nv40->so_rast);
nv40->rasterizer = rsso;
nv40->dirty |= NV40_NEW_RAST;
}
static void
nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nouveau_stateobj *so = hwcso;
struct nv40_rasterizer_state *rsso = hwcso;
so_ref(NULL, &so);
so_ref(NULL, &rsso->so);
free(rsso);
}
static void *
@ -723,14 +728,8 @@ nv40_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *s)
{
struct nv40_context *nv40 = nv40_context(pipe);
struct nouveau_stateobj *so = so_new(3, 0);
so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2);
so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
so_ref(so, &nv40->so_scissor);
so_ref(NULL, &so);
nv40->pipe_state.scissor = *s;
nv40->dirty |= NV40_NEW_SCISSOR;
}

View File

@ -22,9 +22,68 @@ nv40_state_emit_dummy_relocs(struct nv40_context *nv40)
so_emit_reloc_markers(nv40->nvws, nv40->fragprog.active->so);
}
static boolean
nv40_state_scissor_validate(struct nv40_context *nv40)
{
struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe;
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))
return FALSE;
so = so_new(3, 0);
so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2);
if (rast->scissor) {
so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
} else {
so_data (so, 4096 << 16);
so_data (so, 4096 << 16);
}
so_ref(so, &nv40->state.scissor);
so_ref(NULL, &so);
return TRUE;
}
struct nv40_state_atom {
boolean (*validate)(struct nv40_context *nv40);
struct {
unsigned pipe;
unsigned hw;
} dirty;
};
static struct nv40_state_atom states[] = {
{
.validate = nv40_state_scissor_validate,
.dirty = {
.pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST,
.hw = NV40_NEW_SCISSOR,
}
}
};
static void
nv40_state_validate(struct nv40_context *nv40)
{
unsigned i;
for (i = 0; i < sizeof(states) / sizeof(states[0]); i++) {
if (nv40->dirty & states[i].dirty.pipe) {
if (states[i].validate(nv40))
nv40->hw_dirty |= states[i].dirty.hw;
}
}
}
void
nv40_emit_hw_state(struct nv40_context *nv40)
{
nv40_state_validate(nv40);
if (nv40->dirty & NV40_NEW_FB)
so_emit(nv40->nvws, nv40->so_framebuffer);
@ -40,8 +99,10 @@ nv40_emit_hw_state(struct nv40_context *nv40)
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->hw_dirty & NV40_NEW_SCISSOR) {
so_emit(nv40->nvws, nv40->state.scissor);
nv40->hw_dirty &= ~NV40_NEW_SCISSOR;
}
if (nv40->dirty & NV40_NEW_VIEWPORT)
so_emit(nv40->nvws, nv40->so_viewport);