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