summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c39
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c12
4 files changed, 38 insertions, 17 deletions
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index e0b2d2880b0..8afc95c9fc6 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -36,7 +36,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i;
- if (!nv50_state_validate(nv50))
+ if (!nv50_state_validate(nv50, 64))
return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 5fa39111148..ef0e99f0b12 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -229,7 +229,7 @@ extern void nv50_program_destroy(struct nv50_context *nv50,
struct nv50_program *p);
/* nv50_state_validate.c */
-extern boolean nv50_state_validate(struct nv50_context *nv50);
+extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
extern void nv50_state_flush_notify(struct nouveau_channel *chan);
extern void nv50_so_init_sifc(struct nv50_context *nv50,
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);
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 3e540013c42..ce2e479cfda 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -425,7 +425,8 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe,
if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
nv50_upload_user_vbufs(nv50);
- nv50_state_validate(nv50);
+ if (!nv50_state_validate(nv50, 0))
+ return;
nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
@@ -477,7 +478,8 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
struct nouveau_grobj *tesla = nv50->screen->tesla;
boolean ret;
- nv50_state_validate(nv50);
+ if (!nv50_state_validate(nv50, 11))
+ return;
BEGIN_RING(chan, tesla, 0x142c, 1);
OUT_RING (chan, 0);
@@ -633,7 +635,8 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
nv50_upload_user_vbufs(nv50);
- nv50_state_validate(nv50);
+ if (!nv50_state_validate(nv50, 0))
+ return;
nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
@@ -677,7 +680,8 @@ nv50_draw_elements(struct pipe_context *pipe,
struct pipe_screen *pscreen = pipe->screen;
void *map;
- nv50_state_validate(nv50);
+ if (!nv50_state_validate(nv50, 14))
+ return;
BEGIN_RING(chan, tesla, 0x142c, 1);
OUT_RING (chan, 0);