diff options
author | Christoph Bumiller <[email protected]> | 2011-08-27 20:49:36 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-08-30 13:55:07 +0200 |
commit | 222b3ea653e5525a4afa57e6a2353335953012d4 (patch) | |
tree | a0a296f28409108acfdd6830fbc8aefb0e1f55bb /src/gallium/drivers/nvc0 | |
parent | 9f4998639c3c47f0b7ee3e2a29b7f3609d3f7796 (diff) |
nv50,nvc0: add states mask to state validation function
This prevents null dereferences in validation of interdependent
state after a switch to a pipe context where we mark all state
as dirty but where not all state is valid / set yet.
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_surface.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_vbo.c | 3 |
4 files changed, 15 insertions, 12 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index bf891649a57..aa50df076b1 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -179,7 +179,8 @@ void nvc0_tfb_validate(struct nvc0_context *); extern void nvc0_init_state_functions(struct nvc0_context *); /* nvc0_state_validate.c */ -extern boolean nvc0_state_validate(struct nvc0_context *); +extern boolean nvc0_state_validate(struct nvc0_context *, uint32_t state_mask, + unsigned space_words); /* nvc0_surface.c */ extern void nvc0_clear(struct pipe_context *, unsigned buffers, diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 968d7a7bd49..2fca2919ce6 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -453,7 +453,7 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to) if (!ctx_to->blend) ctx_to->dirty &= ~NVC0_NEW_BLEND; if (!ctx_to->rast) - ctx_to->dirty &= ~NVC0_NEW_RASTERIZER; + ctx_to->dirty &= ~(NVC0_NEW_RASTERIZER | NVC0_NEW_SCISSOR); if (!ctx_to->zsa) ctx_to->dirty &= ~NVC0_NEW_ZSA; @@ -490,23 +490,28 @@ static struct state_validate { #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) boolean -nvc0_state_validate(struct nvc0_context *nvc0) +nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words) { + uint32_t state_mask; unsigned i; if (nvc0->screen->cur_ctx != nvc0) nvc0_switch_pipe_context(nvc0); - if (nvc0->dirty) { + state_mask = nvc0->dirty & mask; + + if (state_mask) { for (i = 0; i < validate_list_len; ++i) { struct state_validate *validate = &validate_list[i]; - if (nvc0->dirty & validate->states) + if (state_mask & validate->states) validate->func(nvc0); } - nvc0->dirty = 0; + nvc0->dirty &= ~state_mask; } + MARK_RING(nvc0->screen->base.channel, words, 0); + nvc0_bufctx_emit_relocs(nvc0); return TRUE; diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index a4fd17e5324..385e2f0268b 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -383,12 +383,10 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, struct nouveau_channel *chan = nvc0->screen->base.channel; struct pipe_framebuffer_state *fb = &nvc0->framebuffer; unsigned i; - const unsigned dirty = nvc0->dirty; uint32_t mode = 0; /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ - nvc0->dirty &= NVC0_NEW_FRAMEBUFFER; - if (!nvc0_state_validate(nvc0)) + if (!nvc0_state_validate(nvc0, NVC0_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2))) return; if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { @@ -421,8 +419,6 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); OUT_RING (chan, (i << 6) | 0x3c); } - - nvc0->dirty = dirty & ~NVC0_NEW_FRAMEBUFFER; } void diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 8a5bf8dc582..41b45521d8a 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -584,7 +584,8 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (nvc0->vbo_user && !(nvc0->dirty & (NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS))) nvc0_update_user_vbufs(nvc0); - nvc0_state_validate(nvc0); + /* 8 as minimum to avoid immediate double validation of new buffers */ + nvc0_state_validate(nvc0, ~0, 8); chan->flush_notify = nvc0_draw_vbo_flush_notify; |