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:
parent
9a6c39bd2e
commit
5e091b573a
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue