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/nv50 | |
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/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_surface.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 2 |
4 files changed, 16 insertions, 12 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 284db69e312..384ca8fb4bc 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -172,7 +172,8 @@ extern void nv50_init_state_functions(struct nv50_context *); /* nv50_state_validate.c */ /* @words: check for space before emitting relocs */ -extern boolean nv50_state_validate(struct nv50_context *, unsigned words); +extern boolean nv50_state_validate(struct nv50_context *, uint32_t state_mask, + unsigned space_words); /* nv50_surface.c */ extern void nv50_clear(struct pipe_context *, unsigned buffers, diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 44f2d25c1a7..369daf8ffa6 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -306,7 +306,11 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to) if (!ctx_to->blend) ctx_to->dirty &= ~NV50_NEW_BLEND; if (!ctx_to->rast) +#ifdef NV50_SCISSORS_CLIPPING + ctx_to->dirty &= ~(NV50_NEW_RASTERIZER | NV50_NEW_SCISSOR); +#else ctx_to->dirty &= ~NV50_NEW_RASTERIZER; +#endif if (!ctx_to->zsa) ctx_to->dirty &= ~NV50_NEW_ZSA; @@ -350,21 +354,24 @@ static struct state_validate { #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) boolean -nv50_state_validate(struct nv50_context *nv50, unsigned words) +nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words) { + uint32_t state_mask; unsigned i; if (nv50->screen->cur_ctx != nv50) nv50_switch_pipe_context(nv50); - if (nv50->dirty) { + state_mask = nv50->dirty & mask; + + if (state_mask) { for (i = 0; i < validate_list_len; ++i) { struct state_validate *validate = &validate_list[i]; - if (nv50->dirty & validate->states) + if (state_mask & validate->states) validate->func(nv50); } - nv50->dirty = 0; + nv50->dirty &= ~state_mask; } MARK_RING(nv50->screen->base.channel, words, 0); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 8bca900e1ff..57339f89a36 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -370,12 +370,10 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, struct nouveau_channel *chan = nv50->screen->base.channel; struct pipe_framebuffer_state *fb = &nv50->framebuffer; unsigned i; - const unsigned dirty = nv50->dirty; uint32_t mode = 0; /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */ - nv50->dirty &= NV50_NEW_FRAMEBUFFER; - if (!nv50_state_validate(nv50, 9 + (fb->nr_cbufs * 2))) + if (!nv50_state_validate(nv50, NV50_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2))) return; if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { @@ -408,8 +406,6 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1); OUT_RING (chan, (i << 6) | 0x3c); } - - nv50->dirty = dirty & ~NV50_NEW_FRAMEBUFFER; } @@ -851,7 +847,7 @@ nv50_resource_resolve(struct pipe_context *pipe, nv50_blitctx_prepare_state(blit); - nv50_state_validate(nv50, 36); + nv50_state_validate(nv50, ~0, 36); x_range = (float)(info->src.x1 - info->src.x0) / diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 1c8347a793a..82ac35e84ea 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -647,7 +647,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (nv50->vbo_user && !(nv50->dirty & (NV50_NEW_VERTEX | NV50_NEW_ARRAYS))) nv50_update_user_vbufs(nv50); - nv50_state_validate(nv50, 8); /* 8 as minimum, we use flush_notify here */ + nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */ chan->flush_notify = nv50_draw_vbo_flush_notify; |