1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50_context.h"
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_time.h"
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_fb(struct nv50_context *nv50)
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_framebuffer_state *fb = &nv50->framebuffer;
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, fb->width << 16);
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, fb->height << 16);
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < fb->nr_cbufs; ++i) {
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nouveau_bo *bo = mt->base.bo;
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, bo->offset + sf->offset);
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, bo->offset + sf->offset);
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (likely(nouveau_bo_memtype(bo))) {
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, mt->layer_stride >> 2);
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, sf->width);
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, sf->height);
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, sf->depth);
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0);
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0);
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, sf->height);
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, 0);
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(!fb->zsbuf);
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(!mt->ms_mode);
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ms_mode = mt->ms_mode;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nv50->state.rt_serialize = TRUE;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* only register for writing, otherwise we'd always serialize here */
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (fb->zsbuf) {
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nv50_surface *sf = nv50_surface(fb->zsbuf);
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct nouveau_bo *bo = mt->base.bo;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int unk = mt->base.base.target == PIPE_TEXTURE_2D;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, bo->offset + sf->offset);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, bo->offset + sf->offset);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, mt->layer_stride >> 2);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 1);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, sf->width);
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, sf->height);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, (unk << 16) | sf->depth);
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ms_mode = mt->ms_mode;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nv50->state.rt_serialize = TRUE;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 0);
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, ms_mode);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, fb->width << 16);
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, fb->height << 16);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_blend_colour(struct nv50_context *nv50)
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(BLEND_COLOR(0)), 4);
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->blend_colour.color[0]);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->blend_colour.color[1]);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->blend_colour.color[2]);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->blend_colour.color[3]);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_stencil_ref(struct nv50_context *nv50)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(STENCIL_FRONT_FUNC_REF), 1);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, nv50->stencil_ref.ref_value[0]);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1);
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, nv50->stencil_ref.ref_value[1]);
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_stipple(struct nv50_context *nv50)
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < 32; ++i)
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i]));
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_scissor(struct nv50_context *nv50)
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_scissor_state *s = &nv50->scissor;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NV50_SCISSORS_CLIPPING
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_viewport_state *vp = &nv50->viewport;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int minx, maxx, miny, maxy;
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!(nv50->dirty &
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) &&
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       nv50->state.scissor == nv50->rast->pipe.scissor)
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50->state.scissor = nv50->rast->pipe.scissor;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nv50->state.scissor) {
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      minx = s->minx;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      maxx = s->maxx;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      miny = s->miny;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      maxy = s->maxy;
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      minx = 0;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      maxx = nv50->framebuffer.width;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      miny = 0;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      maxy = nv50->framebuffer.height;
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0])));
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (maxx << 16) | minx);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (maxy << 16) | miny);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (s->maxx << 16) | s->minx);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (s->maxy << 16) | s->miny);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_viewport(struct nv50_context *nv50)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float zmin, zmax;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3);
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.translate[0]);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.translate[1]);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.translate[2]);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3);
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.scale[0]);
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.scale[1]);
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, nv50->viewport.scale[2]);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NV50_SCISSORS_CLIPPING
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, zmin);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAf(push, zmax);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_check_program_ucps(struct nv50_context *nv50,
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        struct nv50_program *vp, uint8_t mask)
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned n = util_logbase2(mask) + 1;
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vp->vp.clpd_nr >= n)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_program_destroy(nv50, vp);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vp->vp.clpd_nr = n;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (likely(vp == nv50->vertprog)) {
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->dirty |= NV50_NEW_VERTPROG;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_vertprog_validate(nv50);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->dirty |= NV50_NEW_GMTYPROG;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_gmtyprog_validate(nv50);
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_fp_linkage_validate(nv50);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_clip(struct nv50_context *nv50)
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_program *vp;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint8_t clip_enable;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nv50->dirty & NV50_NEW_CLIP) {
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, (0 << 8) | NV50_CB_AUX);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vp = nv50->gmtyprog;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (likely(!vp))
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vp = nv50->vertprog;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   clip_enable = nv50->rast->pipe.clip_plane_enable;
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, clip_enable);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (clip_enable)
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_check_program_ucps(nv50, vp, clip_enable);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_blend(struct nv50_context *nv50)
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_SPACE(push, nv50->blend->size);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAp(push, nv50->blend->state, nv50->blend->size);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_zsa(struct nv50_context *nv50)
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_SPACE(push, nv50->zsa->size);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_rasterizer(struct nv50_context *nv50)
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_SPACE(push, nv50->rast->size);
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAp(push, nv50->rast->state, nv50->rast->size);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_validate_sample_mask(struct nv50_context *nv50)
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv50->base.pushbuf;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned mask[4] =
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->sample_mask & 0xffff,
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->sample_mask & 0xffff,
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->sample_mask & 0xffff,
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->sample_mask & 0xffff
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   };
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, mask[0]);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, mask[1]);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, mask[2]);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, mask[3]);
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_switch_pipe_context(struct nv50_context *ctx_to)
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ctx_from)
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->state = ctx_from->state;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_to->dirty = ~0;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->vertex)
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->vertprog)
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~NV50_NEW_VERTPROG;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->fragprog)
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->blend)
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~NV50_NEW_BLEND;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->rast)
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NV50_SCISSORS_CLIPPING
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~(NV50_NEW_RASTERIZER | NV50_NEW_SCISSOR);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!ctx_to->zsa)
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ctx_to->dirty &= ~NV50_NEW_ZSA;
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ctx_to->screen->cur_ctx = ctx_to;
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct state_validate {
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    void (*func)(struct nv50_context *);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint32_t states;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} validate_list[] = {
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_fb,            NV50_NEW_FRAMEBUFFER },
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_blend,         NV50_NEW_BLEND },
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_zsa,           NV50_NEW_ZSA },
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_sample_mask,   NV50_NEW_SAMPLE_MASK },
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_rasterizer,    NV50_NEW_RASTERIZER },
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_blend_colour,  NV50_NEW_BLEND_COLOUR },
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_stencil_ref,   NV50_NEW_STENCIL_REF },
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_stipple,       NV50_NEW_STIPPLE },
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef NV50_SCISSORS_CLIPPING
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_scissor,       NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT |
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_RASTERIZER |
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_FRAMEBUFFER },
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_scissor,       NV50_NEW_SCISSOR },
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_viewport,      NV50_NEW_VIEWPORT },
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_vertprog_validate,      NV50_NEW_VERTPROG },
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_gmtyprog_validate,      NV50_NEW_GMTYPROG },
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_fragprog_validate,      NV50_NEW_FRAGPROG },
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_fp_linkage_validate,    NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_GMTYPROG | NV50_NEW_RASTERIZER },
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_gp_linkage_validate,    NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_derived_rs,    NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_clip,          NV50_NEW_CLIP | NV50_NEW_RASTERIZER |
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_constbufs_validate,     NV50_NEW_CONSTBUF },
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_textures,      NV50_NEW_TEXTURES },
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_validate_samplers,      NV50_NEW_SAMPLERS },
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_stream_output_validate, NV50_NEW_STRMOUT |
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t state_mask;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nv50->screen->cur_ctx != nv50)
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_switch_pipe_context(nv50);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   state_mask = nv50->dirty & mask;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (state_mask) {
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < validate_list_len; ++i) {
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         struct state_validate *validate = &validate_list[i];
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (state_mask & validate->states)
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            validate->func(nv50);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->dirty &= ~state_mask;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (nv50->state.rt_serialize) {
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nv50->state.rt_serialize = FALSE;
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (nv50->base.pushbuf, 0);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_bufctx_fence(nv50->bufctx_3d, FALSE);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (unlikely(nv50->state.flushed)) {
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50->state.flushed = FALSE;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nv50_bufctx_fence(nv50->bufctx_3d, TRUE);
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return !ret;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
407