Merge branch 'gallium-polygon-stipple'
[mesa.git] / src / gallium / drivers / nv50 / nv50_state_validate.c
index 4ae58b156b6647bf6550d4a237fb8294e23892c2..8b0b08f8e93a0650501bf7249418dd6a6b95937a 100644 (file)
@@ -8,6 +8,7 @@ nv50_validate_fb(struct nv50_context *nv50)
    struct nouveau_channel *chan = nv50->screen->base.channel;
    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
    unsigned i;
+   unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
    boolean serialize = FALSE;
 
    nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
@@ -38,6 +39,8 @@ nv50_validate_fb(struct nv50_context *nv50)
       BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
       OUT_RING  (chan, sf->depth);
 
+      ms_mode = mt->ms_mode;
+
       if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
          serialize = TRUE;
       mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
@@ -69,6 +72,8 @@ nv50_validate_fb(struct nv50_context *nv50)
       OUT_RING  (chan, sf->height);
       OUT_RING  (chan, (unk << 16) | sf->depth);
 
+      ms_mode = mt->ms_mode;
+
       if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
          serialize = TRUE;
       mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
@@ -81,6 +86,9 @@ nv50_validate_fb(struct nv50_context *nv50)
       OUT_RING  (chan, 0);
    }
 
+   BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
+   OUT_RING  (chan, ms_mode);
+
    BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
    OUT_RING  (chan, fb->width << 16);
    OUT_RING  (chan, fb->height << 16);
@@ -225,6 +233,9 @@ nv50_validate_clip(struct nv50_context *nv50)
 
    BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
    OUT_RING  (chan, (1 << nv50->clip.nr) - 1);
+
+   if (nv50->vertprog && nv50->clip.nr > nv50->vertprog->vp.clpd_nr)
+      nv50->dirty |= NV50_NEW_VERTPROG;
 }
 
 static void
@@ -254,6 +265,54 @@ nv50_validate_rasterizer(struct nv50_context *nv50)
    OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
 }
 
+static void
+nv50_validate_sample_mask(struct nv50_context *nv50)
+{
+   struct nouveau_channel *chan = nv50->screen->base.channel;
+
+   unsigned mask[4] =
+   {
+      nv50->sample_mask & 0xffff,
+      nv50->sample_mask & 0xffff,
+      nv50->sample_mask & 0xffff,
+      nv50->sample_mask & 0xffff
+   };
+
+   BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
+   OUT_RING  (chan, mask[0]);
+   OUT_RING  (chan, mask[1]);
+   OUT_RING  (chan, mask[2]);
+   OUT_RING  (chan, mask[3]);
+}
+
+static void
+nv50_switch_pipe_context(struct nv50_context *ctx_to)
+{
+   struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
+
+   if (ctx_from)
+      ctx_to->state = ctx_from->state;
+
+   ctx_to->dirty = ~0;
+
+   if (!ctx_to->vertex)
+      ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
+
+   if (!ctx_to->vertprog)
+      ctx_to->dirty &= ~NV50_NEW_VERTPROG;
+   if (!ctx_to->fragprog)
+      ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
+
+   if (!ctx_to->blend)
+      ctx_to->dirty &= ~NV50_NEW_BLEND;
+   if (!ctx_to->rast)
+      ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
+   if (!ctx_to->zsa)
+      ctx_to->dirty &= ~NV50_NEW_ZSA;
+
+   ctx_to->screen->cur_ctx = ctx_to;
+}
+
 static struct state_validate {
     void (*func)(struct nv50_context *);
     uint32_t states;
@@ -261,6 +320,7 @@ static struct state_validate {
     { nv50_validate_fb,            NV50_NEW_FRAMEBUFFER },
     { nv50_validate_blend,         NV50_NEW_BLEND },
     { nv50_validate_zsa,           NV50_NEW_ZSA },
+    { nv50_validate_sample_mask,   NV50_NEW_SAMPLE_MASK },
     { nv50_validate_rasterizer,    NV50_NEW_RASTERIZER },
     { nv50_validate_blend_colour,  NV50_NEW_BLEND_COLOUR },
     { nv50_validate_stencil_ref,   NV50_NEW_STENCIL_REF },
@@ -280,7 +340,7 @@ static struct state_validate {
     { nv50_fp_linkage_validate,    NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
                                    NV50_NEW_GMTYPROG },
     { nv50_gp_linkage_validate,    NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
-    { nv50_sprite_coords_validate, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
+    { nv50_validate_derived_rs,    NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
                                    NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
     { nv50_constbufs_validate,     NV50_NEW_CONSTBUF },
     { nv50_validate_textures,      NV50_NEW_TEXTURES },
@@ -293,11 +353,9 @@ boolean
 nv50_state_validate(struct nv50_context *nv50)
 {
    unsigned i;
-#if 0
-   if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */
-      nv50->dirty = 0xffffffff;
-#endif
-   nv50->screen->cur_ctx = nv50;
+
+   if (nv50->screen->cur_ctx != nv50)
+      nv50_switch_pipe_context(nv50);
 
    if (nv50->dirty) {
       for (i = 0; i < validate_list_len; ++i) {