nv30: avoid doing extra work on clear and hitting unexpected states
Clearing can happen at a time when various state objects are incoherent and not ready for a draw. Some of the validation functions don't handle this well, so only flush the framebuffer state. This has the advantage of also not doing extra work. This works around some crashes that can happen when clearing. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
This commit is contained in:
parent
207ae2b0ef
commit
aba3392541
|
@ -58,7 +58,7 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers,
|
|||
struct pipe_framebuffer_state *fb = &nv30->framebuffer;
|
||||
uint32_t colr = 0, zeta = 0, mode = 0;
|
||||
|
||||
if (!nv30_state_validate(nv30, TRUE))
|
||||
if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, TRUE))
|
||||
return;
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
|
||||
|
|
|
@ -204,7 +204,7 @@ void
|
|||
nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info);
|
||||
|
||||
boolean
|
||||
nv30_state_validate(struct nv30_context *nv30, boolean hwtnl);
|
||||
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, boolean hwtnl);
|
||||
|
||||
void
|
||||
nv30_state_release(struct nv30_context *nv30);
|
||||
|
|
|
@ -130,7 +130,7 @@ nv30_render_draw_elements(struct vbuf_render *render,
|
|||
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
|
||||
}
|
||||
|
||||
if (!nv30_state_validate(nv30, FALSE))
|
||||
if (!nv30_state_validate(nv30, ~0, FALSE))
|
||||
return;
|
||||
|
||||
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
|
||||
|
@ -175,7 +175,7 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
|
|||
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 0);
|
||||
}
|
||||
|
||||
if (!nv30_state_validate(nv30, FALSE))
|
||||
if (!nv30_state_validate(nv30, ~0, FALSE))
|
||||
return;
|
||||
|
||||
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
|
||||
|
|
|
@ -456,7 +456,7 @@ nv30_state_context_switch(struct nv30_context *nv30)
|
|||
}
|
||||
|
||||
boolean
|
||||
nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
|
||||
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, boolean hwtnl)
|
||||
{
|
||||
struct nouveau_screen *screen = &nv30->screen->base;
|
||||
struct nouveau_pushbuf *push = nv30->base.pushbuf;
|
||||
|
@ -481,14 +481,16 @@ nv30_state_validate(struct nv30_context *nv30, boolean hwtnl)
|
|||
else
|
||||
validate = swtnl_validate_list;
|
||||
|
||||
if (nv30->dirty) {
|
||||
mask &= nv30->dirty;
|
||||
|
||||
if (mask) {
|
||||
while (validate->func) {
|
||||
if (nv30->dirty & validate->mask)
|
||||
if (mask & validate->mask)
|
||||
validate->func(nv30);
|
||||
validate++;
|
||||
}
|
||||
|
||||
nv30->dirty = 0;
|
||||
nv30->dirty &= ~mask;
|
||||
}
|
||||
|
||||
nouveau_pushbuf_bufctx(push, bctx);
|
||||
|
|
|
@ -564,7 +564,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
|
||||
nv30_update_user_vbufs(nv30);
|
||||
|
||||
nv30_state_validate(nv30, TRUE);
|
||||
nv30_state_validate(nv30, ~0, TRUE);
|
||||
if (nv30->draw_flags) {
|
||||
nv30_render_vbo(pipe, info);
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue