summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-03-05 12:10:15 -0500
committerEmil Velikov <[email protected]>2015-06-03 12:28:58 +0100
commit07aa6d78bbc9639dd7bbc86bbb375aae1103ddfd (patch)
treebf497503c9cf094ea510885a62963725690694d8
parent70816a66d5431db37cb6207efe6439b895746d16 (diff)
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 <[email protected]> Reviewed-by: Tobias Klausmann <[email protected]> (cherry picked from commit aba3392541f38f82e3ebde251fdcca78e90adbf3)
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_clear.c2
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_context.h2
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_draw.c4
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_state_validate.c10
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_vbo.c2
5 files changed, 11 insertions, 9 deletions
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
index 1ab8929cc38..83fd1fa38dd 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
@@ -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) {
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.h b/src/gallium/drivers/nouveau/nv30/nv30_context.h
index 7b32aaee936..592cdbe24f9 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.h
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.h
@@ -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);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
index 4ef94c78490..c1665b7ad2f 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
@@ -134,7 +134,7 @@ nv30_render_draw_elements(struct vbuf_render *render,
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, FALSE))
+ if (!nv30_state_validate(nv30, ~0, FALSE))
return;
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
@@ -179,7 +179,7 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, FALSE))
+ if (!nv30_state_validate(nv30, ~0, FALSE))
return;
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
index 704c24b624e..a954dcce562 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
@@ -454,7 +454,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;
@@ -479,14 +479,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);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
index 67ab8295218..d4e384b21d2 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
@@ -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;