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:
Ilia Mirkin 2015-03-05 12:10:15 -05:00
parent 207ae2b0ef
commit aba3392541
5 changed files with 11 additions and 9 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;