2 #include "nv50_context.h"
3 #include "os/os_time.h"
6 nv50_validate_fb(struct nv50_context *nv50)
8 struct nouveau_channel *chan = nv50->screen->base.channel;
9 struct pipe_framebuffer_state *fb = &nv50->framebuffer;
11 boolean serialize = FALSE;
13 nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
15 BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
16 OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs);
17 BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
18 OUT_RING (chan, fb->width << 16);
19 OUT_RING (chan, fb->height << 16);
21 MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
23 for (i = 0; i < fb->nr_cbufs; ++i) {
24 struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
25 struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
26 struct nouveau_bo *bo = mt->base.bo;
27 uint32_t offset = sf->offset;
29 BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
30 OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
31 OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
32 OUT_RING (chan, nv50_format_table[sf->base.format].rt);
33 OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
34 OUT_RING (chan, mt->layer_stride >> 2);
35 BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
36 OUT_RING (chan, sf->width);
37 OUT_RING (chan, sf->height);
38 BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
39 OUT_RING (chan, sf->depth);
41 if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
43 mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
44 mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
46 /* only register for writing, otherwise we'd always serialize here */
47 nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
48 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
52 struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
53 struct nv50_surface *sf = nv50_surface(fb->zsbuf);
54 struct nouveau_bo *bo = mt->base.bo;
55 int unk = mt->base.base.target == PIPE_TEXTURE_2D;
56 uint32_t offset = sf->offset;
58 MARK_RING (chan, 12, 2);
59 BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
60 OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
61 OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
62 OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt);
63 OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
64 OUT_RING (chan, mt->layer_stride >> 2);
65 BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
67 BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
68 OUT_RING (chan, sf->width);
69 OUT_RING (chan, sf->height);
70 OUT_RING (chan, (unk << 16) | sf->depth);
72 if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
74 mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
75 mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
77 nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
78 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
80 BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
84 BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
85 OUT_RING (chan, fb->width << 16);
86 OUT_RING (chan, fb->height << 16);
89 BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
95 nv50_validate_blend_colour(struct nv50_context *nv50)
97 struct nouveau_channel *chan = nv50->screen->base.channel;
99 BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
100 OUT_RINGf (chan, nv50->blend_colour.color[0]);
101 OUT_RINGf (chan, nv50->blend_colour.color[1]);
102 OUT_RINGf (chan, nv50->blend_colour.color[2]);
103 OUT_RINGf (chan, nv50->blend_colour.color[3]);
107 nv50_validate_stencil_ref(struct nv50_context *nv50)
109 struct nouveau_channel *chan = nv50->screen->base.channel;
111 BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
112 OUT_RING (chan, nv50->stencil_ref.ref_value[0]);
113 BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
114 OUT_RING (chan, nv50->stencil_ref.ref_value[1]);
118 nv50_validate_stipple(struct nv50_context *nv50)
120 struct nouveau_channel *chan = nv50->screen->base.channel;
123 BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
124 for (i = 0; i < 32; ++i)
125 OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
129 nv50_validate_scissor(struct nv50_context *nv50)
131 struct nouveau_channel *chan = nv50->screen->base.channel;
132 struct pipe_scissor_state *s = &nv50->scissor;
133 #ifdef NV50_SCISSORS_CLIPPING
134 struct pipe_viewport_state *vp = &nv50->viewport;
135 int minx, maxx, miny, maxy;
138 (NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT | NV50_NEW_FRAMEBUFFER)) &&
139 nv50->state.scissor == nv50->rast->pipe.scissor)
141 nv50->state.scissor = nv50->rast->pipe.scissor;
143 if (nv50->state.scissor) {
150 maxx = nv50->framebuffer.width;
152 maxy = nv50->framebuffer.height;
155 minx = MAX2(minx, (int)(vp->translate[0] - fabsf(vp->scale[0])));
156 maxx = MIN2(maxx, (int)(vp->translate[0] + fabsf(vp->scale[0])));
157 miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
158 maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
160 BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
161 OUT_RING (chan, (maxx << 16) | minx);
162 OUT_RING (chan, (maxy << 16) | miny);
164 BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
165 OUT_RING (chan, (s->maxx << 16) | s->minx);
166 OUT_RING (chan, (s->maxy << 16) | s->miny);
171 nv50_validate_viewport(struct nv50_context *nv50)
173 struct nouveau_channel *chan = nv50->screen->base.channel;
176 BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
177 OUT_RINGf (chan, nv50->viewport.translate[0]);
178 OUT_RINGf (chan, nv50->viewport.translate[1]);
179 OUT_RINGf (chan, nv50->viewport.translate[2]);
180 BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
181 OUT_RINGf (chan, nv50->viewport.scale[0]);
182 OUT_RINGf (chan, nv50->viewport.scale[1]);
183 OUT_RINGf (chan, nv50->viewport.scale[2]);
185 zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
186 zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
188 #ifdef NV50_SCISSORS_CLIPPING
189 BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
190 OUT_RINGf (chan, zmin);
191 OUT_RINGf (chan, zmax);
196 nv50_validate_clip(struct nv50_context *nv50)
198 struct nouveau_channel *chan = nv50->screen->base.channel;
201 if (nv50->clip.depth_clamp) {
203 NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |
204 NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |
205 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
210 #ifndef NV50_SCISSORS_CLIPPING
212 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 |
213 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;
216 BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
217 OUT_RING (chan, clip);
220 BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
221 OUT_RING (chan, (0 << 8) | NV50_CB_AUX);
222 BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nv50->clip.nr * 4);
223 OUT_RINGp (chan, &nv50->clip.ucp[0][0], nv50->clip.nr * 4);
226 BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
227 OUT_RING (chan, (1 << nv50->clip.nr) - 1);
229 if (nv50->vertprog && nv50->clip.nr > nv50->vertprog->vp.clpd_nr)
230 nv50->dirty |= NV50_NEW_VERTPROG;
234 nv50_validate_blend(struct nv50_context *nv50)
236 struct nouveau_channel *chan = nv50->screen->base.channel;
238 WAIT_RING(chan, nv50->blend->size);
239 OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
243 nv50_validate_zsa(struct nv50_context *nv50)
245 struct nouveau_channel *chan = nv50->screen->base.channel;
247 WAIT_RING(chan, nv50->zsa->size);
248 OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
252 nv50_validate_rasterizer(struct nv50_context *nv50)
254 struct nouveau_channel *chan = nv50->screen->base.channel;
256 WAIT_RING(chan, nv50->rast->size);
257 OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
261 nv50_switch_pipe_context(struct nv50_context *ctx_to)
263 struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
266 ctx_to->state = ctx_from->state;
271 ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
273 if (!ctx_to->vertprog)
274 ctx_to->dirty &= ~NV50_NEW_VERTPROG;
275 if (!ctx_to->fragprog)
276 ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
279 ctx_to->dirty &= ~NV50_NEW_BLEND;
281 ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
283 ctx_to->dirty &= ~NV50_NEW_ZSA;
285 ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
289 static struct state_validate {
290 void (*func)(struct nv50_context *);
292 } validate_list[] = {
293 { nv50_validate_fb, NV50_NEW_FRAMEBUFFER },
294 { nv50_validate_blend, NV50_NEW_BLEND },
295 { nv50_validate_zsa, NV50_NEW_ZSA },
296 { nv50_validate_rasterizer, NV50_NEW_RASTERIZER },
297 { nv50_validate_blend_colour, NV50_NEW_BLEND_COLOUR },
298 { nv50_validate_stencil_ref, NV50_NEW_STENCIL_REF },
299 { nv50_validate_stipple, NV50_NEW_STIPPLE },
300 #ifdef NV50_SCISSORS_CLIPPING
301 { nv50_validate_scissor, NV50_NEW_SCISSOR | NV50_NEW_VIEWPORT |
302 NV50_NEW_RASTERIZER |
303 NV50_NEW_FRAMEBUFFER },
305 { nv50_validate_scissor, NV50_NEW_SCISSOR },
307 { nv50_validate_viewport, NV50_NEW_VIEWPORT },
308 { nv50_validate_clip, NV50_NEW_CLIP },
309 { nv50_vertprog_validate, NV50_NEW_VERTPROG },
310 { nv50_gmtyprog_validate, NV50_NEW_GMTYPROG },
311 { nv50_fragprog_validate, NV50_NEW_FRAGPROG },
312 { nv50_fp_linkage_validate, NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
314 { nv50_gp_linkage_validate, NV50_NEW_GMTYPROG | NV50_NEW_VERTPROG },
315 { nv50_validate_derived_rs, NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER |
316 NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
317 { nv50_constbufs_validate, NV50_NEW_CONSTBUF },
318 { nv50_validate_textures, NV50_NEW_TEXTURES },
319 { nv50_validate_samplers, NV50_NEW_SAMPLERS },
320 { nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS }
322 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
325 nv50_state_validate(struct nv50_context *nv50)
329 if (nv50->screen->cur_ctx != nv50)
330 nv50_switch_pipe_context(nv50);
333 for (i = 0; i < validate_list_len; ++i) {
334 struct state_validate *validate = &validate_list[i];
336 if (nv50->dirty & validate->states)
337 validate->func(nv50);
342 nv50_bufctx_emit_relocs(nv50);