summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2015-05-08 00:15:22 -0400
committerIlia Mirkin <[email protected]>2015-05-09 13:36:23 -0400
commitf617029db3f8786d94c64f1a73c42b89b6d261fa (patch)
treee5bc89c2d03d0850b51f403526ab27060392e8a2
parentd6fb155f30ac2bd7853da32ddf99e9f7840a8f01 (diff)
nv50: keep track of PGRAPH state in nv50_screen
Normally this is kept in nv50_context, and on switching the active context, the state is copied from the previous context. However when the last context is destroyed, this is lost, and a new context might later be created. When the currently-active context is destroyed, save its state in the screen, and restore it when setting the current context. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90363 Reported-by: Matteo Bruni <[email protected]> Signed-off-by: Ilia Mirkin <[email protected]> Tested-by: Matteo Bruni <[email protected]> Cc: [email protected]
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.c11
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.h29
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_screen.h24
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_state_validate.c2
4 files changed, 36 insertions, 30 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 2cfd5db5ea0..5b5d3912c20 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -138,8 +138,11 @@ nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (nv50_context_screen(nv50)->cur_ctx == nv50)
- nv50_context_screen(nv50)->cur_ctx = NULL;
+ if (nv50->screen->cur_ctx == nv50) {
+ nv50->screen->cur_ctx = NULL;
+ /* Save off the state in case another context gets created */
+ nv50->screen->save_state = nv50->state;
+ }
nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
@@ -290,6 +293,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
pipe->get_sample_position = nv50_context_get_sample_position;
if (!screen->cur_ctx) {
+ /* Restore the last context's state here, normally handled during
+ * context switch
+ */
+ nv50->state = screen->save_state;
screen->cur_ctx = nv50;
nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index 45eb554eb4f..1f123ef7e92 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -104,28 +104,7 @@ struct nv50_context {
uint32_t dirty;
boolean cb_dirty;
- struct {
- uint32_t instance_elts; /* bitmask of per-instance elements */
- uint32_t instance_base;
- uint32_t interpolant_ctrl;
- uint32_t semantic_color;
- uint32_t semantic_psize;
- int32_t index_bias;
- boolean uniform_buffer_bound[3];
- boolean prim_restart;
- boolean point_sprite;
- boolean rt_serialize;
- boolean flushed;
- boolean rasterizer_discard;
- uint8_t tls_required;
- boolean new_tls_space;
- uint8_t num_vtxbufs;
- uint8_t num_vtxelts;
- uint8_t num_textures[3];
- uint8_t num_samplers[3];
- uint8_t prim_size;
- uint16_t scissor;
- } state;
+ struct nv50_graph_state state;
struct nv50_blend_stateobj *blend;
struct nv50_rasterizer_stateobj *rast;
@@ -191,12 +170,6 @@ nv50_context(struct pipe_context *pipe)
return (struct nv50_context *)pipe;
}
-static INLINE struct nv50_screen *
-nv50_context_screen(struct nv50_context *nv50)
-{
- return nv50_screen(&nv50->base.screen->base);
-}
-
/* return index used in nv50_context arrays for a specific shader type */
static INLINE unsigned
nv50_context_shader_stage(unsigned pipe)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
index f8ce365135a..881051b1862 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
@@ -25,10 +25,34 @@ struct nv50_context;
struct nv50_blitter;
+struct nv50_graph_state {
+ uint32_t instance_elts; /* bitmask of per-instance elements */
+ uint32_t instance_base;
+ uint32_t interpolant_ctrl;
+ uint32_t semantic_color;
+ uint32_t semantic_psize;
+ int32_t index_bias;
+ boolean uniform_buffer_bound[3];
+ boolean prim_restart;
+ boolean point_sprite;
+ boolean rt_serialize;
+ boolean flushed;
+ boolean rasterizer_discard;
+ uint8_t tls_required;
+ boolean new_tls_space;
+ uint8_t num_vtxbufs;
+ uint8_t num_vtxelts;
+ uint8_t num_textures[3];
+ uint8_t num_samplers[3];
+ uint8_t prim_size;
+ uint16_t scissor;
+};
+
struct nv50_screen {
struct nouveau_screen base;
struct nv50_context *cur_ctx;
+ struct nv50_graph_state save_state;
struct nouveau_bo *code;
struct nouveau_bo *uniforms;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index 85e19b4c623..116bf4bba7c 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -394,6 +394,8 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to)
if (ctx_from)
ctx_to->state = ctx_from->state;
+ else
+ ctx_to->state = ctx_to->screen->save_state;
ctx_to->dirty = ~0;
ctx_to->viewports_dirty = ~0;