diff options
author | Ben Skeggs <[email protected]> | 2010-03-03 14:43:21 +1000 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2010-03-10 16:29:58 +1000 |
commit | e1d015fe222a3f6f942426c39fb1a17188df8d57 (patch) | |
tree | 393856ee4899e39b1e0b27f5dbd3582c516c8b0f /src/gallium/drivers/nv50/nv50_state_validate.c | |
parent | 62ab89785b55e60b978dc2b32995676859299c80 (diff) |
nv50: ensure enough room for state changes in current pushbuf
Also allows the nv50_state_validate() caller to request a minimum amount
of space that itself requires, not all callers accurately use this yet
but the simple cases are now accounted for.
Rendering will also be dropped on the floor if validate fails now.
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_state_validate.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index abdb9a55c85..b01a3d87de6 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -405,19 +405,11 @@ nv50_state_flush_notify(struct nouveau_channel *chan) } boolean -nv50_state_validate(struct nv50_context *nv50) +nv50_state_validate(struct nv50_context *nv50, unsigned nr_dwords) { struct nouveau_channel *chan = nv50->screen->base.channel; - int i; - - if (nv50->screen->cur_ctx != nv50) { - for (i = 0; i < validate_list_len; i++) { - if (nv50->state.hw[i]) - nv50->state.hw_dirty |= (1 << i); - } - - nv50->screen->cur_ctx = nv50; - } + unsigned nr_relocs = 0; + int ret, i; for (i = 0; i < validate_list_len; i++) { struct state_validate *validate = &validate_list[i]; @@ -430,12 +422,37 @@ nv50_state_validate(struct nv50_context *nv50) if (!so) continue; + nr_dwords += (so->total + so->cur); + nr_relocs += so->cur_reloc; + so_ref(so, &nv50->state.hw[i]); so_ref(NULL, &so); nv50->state.hw_dirty |= (1 << i); } nv50->dirty = 0; + if (nv50->screen->cur_ctx != nv50) { + for (i = 0; i < validate_list_len; i++) { + if (!nv50->state.hw[i] || + (nv50->state.hw_dirty & (1 << i))) + continue; + + nr_dwords += (nv50->state.hw[i]->total + + nv50->state.hw[i]->cur); + nr_relocs += nv50->state.hw[i]->cur_reloc; + nv50->state.hw_dirty |= (1 << i); + } + + nv50->screen->cur_ctx = nv50; + } + + ret = MARK_RING(chan, nr_dwords, nr_relocs); + if (ret) { + debug_printf("MARK_RING(%d, %d) failed: %d\n", + nr_dwords, nr_relocs, ret); + return FALSE; + } + while (nv50->state.hw_dirty) { i = ffs(nv50->state.hw_dirty) - 1; nv50->state.hw_dirty &= ~(1 << i); |