Use write posting in the kickoff function too.
[mesa.git] / src / mesa / pipe / nv40 / nv40_state.c
1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4
5 #include "nv40_context.h"
6 #include "nv40_dma.h"
7 #include "nv40_state.h"
8
9 #include "nvgl_pipe.h"
10
11 static void *
12 nv40_alpha_test_state_create(struct pipe_context *pipe,
13 const struct pipe_alpha_test_state *cso)
14 {
15 struct nv40_alpha_test_state *at;
16
17 at = malloc(sizeof(struct nv40_alpha_test_state));
18
19 at->enabled = cso->enabled ? 1 : 0;
20 if (at->enabled) {
21 at->func = nvgl_comparison_op(cso->func);
22 at->ref = float_to_ubyte(cso->ref);
23 }
24
25 return (void *)at;
26 }
27
28 static void
29 nv40_alpha_test_state_bind(struct pipe_context *pipe, void *hwcso)
30 {
31 struct nv40_context *nv40 = (struct nv40_context *)pipe;
32 struct nv40_alpha_test_state *at = hwcso;
33
34 if (at->enabled) {
35 BEGIN_RING(curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
36 OUT_RING (at->enabled);
37 OUT_RING (at->func);
38 OUT_RING (at->ref);
39 } else {
40 BEGIN_RING(curie, NV40TCL_ALPHA_TEST_ENABLE, 1);
41 OUT_RING (0);
42 }
43 }
44
45 static void
46 nv40_alpha_test_state_delete(struct pipe_context *pipe, void *hwcso)
47 {
48 free(hwcso);
49 }
50
51 static void *
52 nv40_blend_state_create(struct pipe_context *pipe,
53 const struct pipe_blend_state *cso)
54 {
55 struct nv40_blend_state *cb;
56
57 cb = malloc(sizeof(struct nv40_blend_state));
58
59 cb->b_enable = cso->blend_enable ? 1 : 0;
60 if (cb->b_enable) {
61 cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
62 (nvgl_blend_func(cso->rgb_src_factor)));
63 cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
64 (nvgl_blend_func(cso->rgb_dst_factor)));
65 cb->b_eqn = ((nvgl_blend_eqn(cso->alpha_func) << 16) |
66 (nvgl_blend_eqn(cso->rgb_func)));
67 }
68
69 cb->l_enable = cso->logicop_enable ? 1 : 0;
70 if (cb->l_enable) {
71 cb->l_op = nvgl_logicop_func(cso->logicop_func);
72 }
73
74 cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
75 ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
76 ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
77 ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
78
79 cb->d_enable = cso->dither ? 1 : 0;
80
81 return (void *)cb;
82 }
83
84 static void
85 nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso)
86 {
87 struct nv40_context *nv40 = (struct nv40_context *)pipe;
88 struct nv40_blend_state *cb = hwcso;
89
90 BEGIN_RING(curie, NV40TCL_DITHER_ENABLE, 1);
91 OUT_RING (cb->d_enable);
92
93 if (cb->b_enable) {
94 BEGIN_RING(curie, NV40TCL_BLEND_ENABLE, 3);
95 OUT_RING (cb->b_enable);
96 OUT_RING (cb->b_srcfunc);
97 OUT_RING (cb->b_dstfunc);
98 BEGIN_RING(curie, NV40TCL_BLEND_EQUATION, 2);
99 OUT_RING (cb->b_eqn);
100 OUT_RING (cb->c_mask);
101 } else {
102 BEGIN_RING(curie, NV40TCL_BLEND_ENABLE, 1);
103 OUT_RING (0);
104 }
105
106 if (cb->l_enable) {
107 BEGIN_RING(curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2);
108 OUT_RING (cb->l_enable);
109 OUT_RING (cb->l_op);
110 } else {
111 BEGIN_RING(curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 1);
112 OUT_RING (0);
113 }
114 }
115
116 static void
117 nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso)
118 {
119 free(hwcso);
120 }
121
122
123 static INLINE unsigned
124 wrap_mode(unsigned wrap) {
125 unsigned ret;
126
127 switch (wrap) {
128 case PIPE_TEX_WRAP_REPEAT:
129 ret = NV40TCL_TEX_WRAP_S_REPEAT;
130 break;
131 case PIPE_TEX_WRAP_MIRROR_REPEAT:
132 ret = NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT;
133 break;
134 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
135 ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE;
136 break;
137 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
138 ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER;
139 break;
140 case PIPE_TEX_WRAP_CLAMP:
141 ret = NV40TCL_TEX_WRAP_S_CLAMP;
142 break;
143 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
144 ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
145 break;
146 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
147 ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
148 break;
149 case PIPE_TEX_WRAP_MIRROR_CLAMP:
150 ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
151 break;
152 default:
153 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
154 ret = NV40TCL_TEX_WRAP_S_REPEAT;
155 break;
156 }
157
158 return ret >> NV40TCL_TEX_WRAP_S_SHIFT;
159 }
160
161 static void *
162 nv40_sampler_state_create(struct pipe_context *pipe,
163 const struct pipe_sampler_state *cso)
164 {
165 struct nv40_sampler_state *ps;
166 uint32_t filter = 0;
167
168 ps = malloc(sizeof(struct nv40_sampler_state));
169
170 ps->fmt = 0;
171 if (!cso->normalized_coords)
172 ps->fmt |= NV40TCL_TEX_FORMAT_RECT;
173
174 ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) |
175 (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) |
176 (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT));
177
178 ps->en = 0;
179 if (cso->max_anisotropy >= 2.0) {
180 /* no idea, binary driver sets it, works without it.. meh.. */
181 ps->wrap |= (1 << 5);
182
183 if (cso->max_anisotropy >= 16.0) {
184 ps->en |= (7 << 4);
185 } else
186 if (cso->max_anisotropy >= 12.0) {
187 ps->en |= (6 << 4);
188 } else
189 if (cso->max_anisotropy >= 10.0) {
190 ps->en |= (5 << 4);
191 } else
192 if (cso->max_anisotropy >= 8.0) {
193 ps->en |= (4 << 4);
194 } else
195 if (cso->max_anisotropy >= 6.0) {
196 ps->en |= (3 << 4);
197 } else
198 if (cso->max_anisotropy >= 4.0) {
199 ps->en |= (2 << 4);
200 } else {
201 ps->en |= (1 << 4); /* 2.0 */
202 }
203 }
204
205 switch (cso->mag_img_filter) {
206 case PIPE_TEX_FILTER_LINEAR:
207 filter |= NV40TCL_TEX_FILTER_MAG_LINEAR;
208 break;
209 case PIPE_TEX_FILTER_NEAREST:
210 default:
211 filter |= NV40TCL_TEX_FILTER_MAG_NEAREST;
212 break;
213 }
214
215 switch (cso->min_img_filter) {
216 case PIPE_TEX_FILTER_LINEAR:
217 switch (cso->min_mip_filter) {
218 case PIPE_TEX_MIPFILTER_NEAREST:
219 filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST;
220 break;
221 case PIPE_TEX_MIPFILTER_LINEAR:
222 filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR;
223 break;
224 case PIPE_TEX_MIPFILTER_NONE:
225 default:
226 filter |= NV40TCL_TEX_FILTER_MIN_LINEAR;
227 break;
228 }
229 break;
230 case PIPE_TEX_FILTER_NEAREST:
231 default:
232 switch (cso->min_mip_filter) {
233 case PIPE_TEX_MIPFILTER_NEAREST:
234 filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST;
235 break;
236 case PIPE_TEX_MIPFILTER_LINEAR:
237 filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR;
238 break;
239 case PIPE_TEX_MIPFILTER_NONE:
240 default:
241 filter |= NV40TCL_TEX_FILTER_MIN_NEAREST;
242 break;
243 }
244 break;
245 }
246
247 ps->filt = filter;
248
249 ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
250 (float_to_ubyte(cso->border_color[0]) << 16) |
251 (float_to_ubyte(cso->border_color[1]) << 8) |
252 (float_to_ubyte(cso->border_color[2]) << 0));
253
254 return (void *)ps;
255 }
256
257 static void
258 nv40_sampler_state_bind(struct pipe_context *pipe, unsigned unit,
259 void *hwcso)
260 {
261 struct nv40_context *nv40 = (struct nv40_context *)pipe;
262 struct nv40_sampler_state *ps = hwcso;
263
264 nv40->tex_sampler[unit] = ps;
265 nv40->tex_dirty |= (1 << unit);
266
267 nv40->dirty |= NV40_NEW_TEXTURE;
268 }
269
270 static void
271 nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
272 {
273 free(hwcso);
274 }
275
276 static void *
277 nv40_rasterizer_state_create(struct pipe_context *pipe,
278 const struct pipe_rasterizer_state *cso)
279 {
280 struct nv40_rasterizer_state *rs;
281 int i;
282
283 /*XXX: ignored:
284 * light_twoside
285 * offset_cw/ccw -nohw
286 * scissor
287 * point_smooth -nohw
288 * multisample
289 * offset_units / offset_scale
290 */
291 rs = malloc(sizeof(struct nv40_rasterizer_state));
292
293 rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;
294
295 rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
296 rs->line_smooth_en = cso->line_smooth ? 1 : 0;
297 rs->line_stipple_en = cso->line_stipple_enable ? 1 : 0;
298 rs->line_stipple = (cso->line_stipple_pattern << 16) |
299 cso->line_stipple_factor;
300
301 rs->point_size = *(uint32_t*)&cso->point_size;
302
303 rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
304 rs->poly_stipple_en = cso->poly_stipple_enable ? 1 : 0;
305
306 if (cso->front_winding == PIPE_WINDING_CCW) {
307 rs->front_face = 0x0901;
308 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
309 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
310 } else {
311 rs->front_face = 0x0900;
312 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
313 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
314 }
315
316 rs->cull_face_en = 0;
317 rs->cull_face = 0x0900;
318 switch (cso->cull_mode) {
319 case PIPE_WINDING_CCW:
320 rs->cull_face = 0x0901;
321 /* fall-through */
322 case PIPE_WINDING_CW:
323 rs->cull_face_en = 1;
324 break;
325 case PIPE_WINDING_NONE:
326 default:
327 break;
328 }
329
330 if (cso->point_sprite) {
331 rs->point_sprite = (1 << 0);
332 for (i = 0; i < 8; i++) {
333 if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
334 rs->point_sprite |= (1 << (8 + i));
335 }
336 } else {
337 rs->point_sprite = 0;
338 }
339
340 return (void *)rs;
341 }
342
343 static void
344 nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
345 {
346 struct nv40_context *nv40 = (struct nv40_context *)pipe;
347 struct nv40_rasterizer_state *rs = hwcso;
348
349 BEGIN_RING(curie, NV40TCL_SHADE_MODEL, 1);
350 OUT_RING (rs->shade_model);
351
352 BEGIN_RING(curie, NV40TCL_LINE_WIDTH, 2);
353 OUT_RING (rs->line_width);
354 OUT_RING (rs->line_smooth_en);
355 BEGIN_RING(curie, NV40TCL_LINE_STIPPLE_ENABLE, 2);
356 OUT_RING (rs->line_stipple_en);
357 OUT_RING (rs->line_stipple);
358
359 BEGIN_RING(curie, NV40TCL_POINT_SIZE, 1);
360 OUT_RING (rs->point_size);
361
362 BEGIN_RING(curie, NV40TCL_POLYGON_MODE_FRONT, 6);
363 OUT_RING (rs->poly_mode_front);
364 OUT_RING (rs->poly_mode_back);
365 OUT_RING (rs->cull_face);
366 OUT_RING (rs->front_face);
367 OUT_RING (rs->poly_smooth_en);
368 OUT_RING (rs->cull_face_en);
369
370 BEGIN_RING(curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
371 OUT_RING (rs->poly_stipple_en);
372
373 BEGIN_RING(curie, NV40TCL_POINT_SPRITE, 1);
374 OUT_RING (rs->point_sprite);
375 }
376
377 static void
378 nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
379 {
380 free(hwcso);
381 }
382
383 static void *
384 nv40_depth_stencil_state_create(struct pipe_context *pipe,
385 const struct pipe_depth_stencil_state *cso)
386 {
387 struct nv40_depth_stencil_state *zs;
388
389 /*XXX: ignored:
390 * depth.occlusion_count
391 * depth.clear
392 * stencil.clear_value
393 */
394 zs = malloc(sizeof(struct nv40_depth_stencil_state));
395
396 zs->depth.func = nvgl_comparison_op(cso->depth.func);
397 zs->depth.write_enable = cso->depth.writemask ? 1 : 0;
398 zs->depth.test_enable = cso->depth.enabled ? 1 : 0;
399
400 zs->stencil.back.enable = cso->stencil.back_enabled ? 1 : 0;
401 zs->stencil.back.wmask = cso->stencil.write_mask[1];
402 zs->stencil.back.func =
403 nvgl_comparison_op(cso->stencil.back_func);
404 zs->stencil.back.ref = cso->stencil.ref_value[1];
405 zs->stencil.back.vmask = cso->stencil.value_mask[1];
406 zs->stencil.back.fail = nvgl_stencil_op(cso->stencil.back_fail_op);
407 zs->stencil.back.zfail = nvgl_stencil_op(cso->stencil.back_zfail_op);
408 zs->stencil.back.zpass = nvgl_stencil_op(cso->stencil.back_zpass_op);
409
410 zs->stencil.front.enable= cso->stencil.front_enabled ? 1 : 0;
411 zs->stencil.front.wmask = cso->stencil.write_mask[0];
412 zs->stencil.front.func =
413 nvgl_comparison_op(cso->stencil.front_func);
414 zs->stencil.front.ref = cso->stencil.ref_value[0];
415 zs->stencil.front.vmask = cso->stencil.value_mask[0];
416 zs->stencil.front.fail = nvgl_stencil_op(cso->stencil.front_fail_op);
417 zs->stencil.front.zfail = nvgl_stencil_op(cso->stencil.front_zfail_op);
418 zs->stencil.front.zpass = nvgl_stencil_op(cso->stencil.front_zpass_op);
419
420 return (void *)zs;
421 }
422
423 static void
424 nv40_depth_stencil_state_bind(struct pipe_context *pipe, void *hwcso)
425 {
426 struct nv40_context *nv40 = (struct nv40_context *)pipe;
427 struct nv40_depth_stencil_state *zs = hwcso;
428
429 BEGIN_RING(curie, NV40TCL_DEPTH_FUNC, 3);
430 OUT_RINGp ((uint32_t *)&zs->depth, 3);
431 BEGIN_RING(curie, NV40TCL_STENCIL_BACK_ENABLE, 16);
432 OUT_RINGp ((uint32_t *)&zs->stencil.back, 8);
433 OUT_RINGp ((uint32_t *)&zs->stencil.front, 8);
434 }
435
436 static void
437 nv40_depth_stencil_state_delete(struct pipe_context *pipe, void *hwcso)
438 {
439 free(hwcso);
440 }
441
442 static void *
443 nv40_vp_state_create(struct pipe_context *pipe,
444 const struct pipe_shader_state *cso)
445 {
446 struct nv40_vertex_program *vp;
447
448 vp = calloc(1, sizeof(struct nv40_vertex_program));
449 vp->pipe = cso;
450
451 return (void *)vp;
452 }
453
454 static void
455 nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
456 {
457 struct nv40_context *nv40 = (struct nv40_context *)pipe;
458 struct nv40_vertex_program *vp = hwcso;
459
460 nv40->vertprog.current = vp;
461 nv40->dirty |= NV40_NEW_VERTPROG;
462 }
463
464 static void
465 nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso)
466 {
467 free(hwcso);
468 }
469
470 static void *
471 nv40_fp_state_create(struct pipe_context *pipe,
472 const struct pipe_shader_state *cso)
473 {
474 struct nv40_fragment_program *fp;
475
476 fp = calloc(1, sizeof(struct nv40_fragment_program));
477 fp->pipe = cso;
478
479 return (void *)fp;
480 }
481
482 static void
483 nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso)
484 {
485 struct nv40_context *nv40 = (struct nv40_context *)pipe;
486 struct nv40_fragment_program *fp = hwcso;
487
488 nv40->fragprog.current = fp;
489 nv40->dirty |= NV40_NEW_FRAGPROG;
490 }
491
492 static void
493 nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso)
494 {
495 free(hwcso);
496 }
497
498 static void
499 nv40_set_blend_color(struct pipe_context *pipe,
500 const struct pipe_blend_color *bcol)
501 {
502 struct nv40_context *nv40 = (struct nv40_context *)pipe;
503
504 BEGIN_RING(curie, NV40TCL_BLEND_COLOR, 1);
505 OUT_RING ((float_to_ubyte(bcol->color[3]) << 24) |
506 (float_to_ubyte(bcol->color[0]) << 16) |
507 (float_to_ubyte(bcol->color[1]) << 8) |
508 (float_to_ubyte(bcol->color[2]) << 0));
509 }
510
511 static void
512 nv40_set_clip_state(struct pipe_context *pipe,
513 const struct pipe_clip_state *clip)
514 {
515 struct nv40_context *nv40 = (struct nv40_context *)pipe;
516
517 nv40->dirty |= NV40_NEW_VERTPROG;
518 }
519
520 static void
521 nv40_set_clear_color_state(struct pipe_context *pipe,
522 const struct pipe_clear_color_state *ccol)
523 {
524 struct nv40_context *nv40 = (struct nv40_context *)pipe;
525
526 BEGIN_RING(curie, NV40TCL_CLEAR_VALUE_COLOR, 1);
527 OUT_RING ((float_to_ubyte(ccol->color[3]) << 24) |
528 (float_to_ubyte(ccol->color[0]) << 16) |
529 (float_to_ubyte(ccol->color[1]) << 8) |
530 (float_to_ubyte(ccol->color[2]) << 0));
531 }
532
533 static void
534 nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
535 const struct pipe_constant_buffer *buf )
536 {
537 struct nv40_context *nv40 = (struct nv40_context *)pipe;
538
539 if (shader == PIPE_SHADER_VERTEX) {
540 nv40->vertprog.constant_buf = buf->buffer;
541 nv40->dirty |= NV40_NEW_VERTPROG;
542 } else
543 if (shader == PIPE_SHADER_FRAGMENT) {
544 nv40->fragprog.constant_buf = buf->buffer;
545 nv40->dirty |= NV40_NEW_FRAGPROG;
546 }
547 }
548
549 static void
550 nv40_set_framebuffer_state(struct pipe_context *pipe,
551 const struct pipe_framebuffer_state *fb)
552 {
553 struct nv40_context *nv40 = (struct nv40_context *)pipe;
554 struct pipe_region *region[4], *zregion;
555 uint32_t rt_enable, rt_format, w, h;
556 int i, colour_format = 0, zeta_format = 0;
557
558 rt_enable = 0;
559 for (i = 0; i < 4; i++) {
560 if (!fb->cbufs[i])
561 continue;
562
563 if (colour_format) {
564 assert(w == fb->cbufs[i]->width);
565 assert(h == fb->cbufs[i]->height);
566 assert(colour_format == fb->cbufs[i]->format);
567 } else {
568 w = fb->cbufs[i]->width;
569 h = fb->cbufs[i]->height;
570 colour_format = fb->cbufs[i]->format;
571 rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i);
572 region[i] = fb->cbufs[i]->region;
573 }
574 }
575
576 if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 |
577 NV40TCL_RT_ENABLE_COLOR3))
578 rt_enable |= NV40TCL_RT_ENABLE_MRT;
579
580 if (fb->zbuf) {
581 if (colour_format) {
582 assert(w == fb->zbuf->width);
583 assert(h == fb->zbuf->height);
584 } else {
585 w = fb->zbuf->width;
586 h = fb->zbuf->height;
587 }
588
589 zeta_format = fb->zbuf->format;
590 zregion = fb->zbuf->region;
591 }
592
593 if (fb->sbuf) {
594 if (colour_format) {
595 assert(w == fb->sbuf->width);
596 assert(h == fb->sbuf->height);
597 } else {
598 w = fb->zbuf->width;
599 h = fb->zbuf->height;
600 }
601
602 if (zeta_format) {
603 assert(fb->sbuf->format == zeta_format);
604 assert(fb->sbuf->region == zregion);
605 } else {
606 zeta_format = fb->sbuf->format;
607 zregion = fb->sbuf->region;
608 }
609 }
610
611 rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR;
612
613 switch (colour_format) {
614 case PIPE_FORMAT_U_A8_R8_G8_B8:
615 case 0:
616 rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8;
617 break;
618 case PIPE_FORMAT_U_R5_G6_B5:
619 rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5;
620 break;
621 default:
622 assert(0);
623 }
624
625 switch (zeta_format) {
626 case PIPE_FORMAT_U_Z16:
627 rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16;
628 break;
629 case PIPE_FORMAT_Z24_S8:
630 rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8;
631 break;
632 case 0:
633 break;
634 default:
635 assert(0);
636 }
637
638 if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) {
639 BEGIN_RING(curie, NV40TCL_DMA_COLOR0, 1);
640 OUT_RELOCo(region[0]->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
641 BEGIN_RING(curie, NV40TCL_COLOR0_PITCH, 2);
642 OUT_RING (region[0]->pitch * region[0]->cpp);
643 OUT_RELOCl(region[0]->buffer, 0,
644 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
645 }
646
647 if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) {
648 BEGIN_RING(curie, NV40TCL_DMA_COLOR1, 1);
649 OUT_RELOCo(region[1]->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
650 BEGIN_RING(curie, NV40TCL_COLOR1_OFFSET, 2);
651 OUT_RELOCl(region[1]->buffer, 0,
652 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
653 OUT_RING (region[1]->pitch * region[1]->cpp);
654 }
655
656 if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
657 BEGIN_RING(curie, NV40TCL_DMA_COLOR2, 1);
658 OUT_RELOCo(region[2]->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
659 BEGIN_RING(curie, NV40TCL_COLOR2_OFFSET, 1);
660 OUT_RELOCl(region[2]->buffer, 0,
661 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
662 BEGIN_RING(curie, NV40TCL_COLOR2_PITCH, 1);
663 OUT_RING (region[2]->pitch * region[2]->cpp);
664 }
665
666 if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
667 BEGIN_RING(curie, NV40TCL_DMA_COLOR3, 1);
668 OUT_RELOCo(region[3]->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
669 BEGIN_RING(curie, NV40TCL_COLOR3_OFFSET, 1);
670 OUT_RELOCl(region[3]->buffer, 0,
671 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
672 BEGIN_RING(curie, NV40TCL_COLOR3_PITCH, 1);
673 OUT_RING (region[3]->pitch * region[3]->cpp);
674 }
675
676 if (zeta_format) {
677 BEGIN_RING(curie, NV40TCL_DMA_ZETA, 1);
678 OUT_RELOCo(zregion->buffer,
679 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR | NOUVEAU_BO_RD);
680 BEGIN_RING(curie, NV40TCL_ZETA_OFFSET, 1);
681 OUT_RELOCl(zregion->buffer, 0,
682 NOUVEAU_BO_VRAM | NOUVEAU_BO_WR | NOUVEAU_BO_RD);
683 BEGIN_RING(curie, NV40TCL_ZETA_PITCH, 1);
684 OUT_RING (zregion->pitch * zregion->cpp);
685 }
686
687 BEGIN_RING(curie, NV40TCL_RT_ENABLE, 1);
688 OUT_RING (rt_enable);
689 BEGIN_RING(curie, NV40TCL_RT_HORIZ, 3);
690 OUT_RING ((w << 16) | 0);
691 OUT_RING ((h << 16) | 0);
692 OUT_RING (rt_format);
693 BEGIN_RING(curie, NV40TCL_VIEWPORT_HORIZ, 2);
694 OUT_RING ((w << 16) | 0);
695 OUT_RING ((h << 16) | 0);
696 BEGIN_RING(curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
697 OUT_RING (((w - 1) << 16) | 0);
698 OUT_RING (((h - 1) << 16) | 0);
699 }
700
701 static void
702 nv40_set_polygon_stipple(struct pipe_context *pipe,
703 const struct pipe_poly_stipple *stipple)
704 {
705 struct nv40_context *nv40 = (struct nv40_context *)pipe;
706
707 BEGIN_RING(curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
708 OUT_RINGp ((uint32_t *)stipple->stipple, 32);
709 }
710
711 static void
712 nv40_set_sampler_units(struct pipe_context *pipe,
713 uint num_samplers, const uint *units)
714 {
715 }
716
717 static void
718 nv40_set_scissor_state(struct pipe_context *pipe,
719 const struct pipe_scissor_state *s)
720 {
721 struct nv40_context *nv40 = (struct nv40_context *)pipe;
722
723 BEGIN_RING(curie, NV40TCL_SCISSOR_HORIZ, 2);
724 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
725 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);
726 }
727
728 static void
729 nv40_set_texture_state(struct pipe_context *pipe, unsigned unit,
730 struct pipe_mipmap_tree *miptree)
731 {
732 struct nv40_context *nv40 = (struct nv40_context *)pipe;
733
734 nv40->tex_miptree[unit] = miptree;
735 nv40->tex_dirty |= unit;
736
737 nv40->dirty |= NV40_NEW_TEXTURE;
738 }
739
740 static void
741 nv40_set_viewport_state(struct pipe_context *pipe,
742 const struct pipe_viewport_state *vpt)
743 {
744 struct nv40_context *nv40 = (struct nv40_context *)pipe;
745
746 BEGIN_RING(curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8);
747 OUT_RINGf (vpt->translate[0]);
748 OUT_RINGf (vpt->translate[1]);
749 OUT_RINGf (vpt->translate[2]);
750 OUT_RINGf (vpt->translate[3]);
751 OUT_RINGf (vpt->scale[0]);
752 OUT_RINGf (vpt->scale[1]);
753 OUT_RINGf (vpt->scale[2]);
754 OUT_RINGf (vpt->scale[3]);
755 }
756
757 static void
758 nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index,
759 const struct pipe_vertex_buffer *vb)
760 {
761 struct nv40_context *nv40 = (struct nv40_context *)pipe;
762
763 nv40->vtxbuf[index] = *vb;
764
765 nv40->dirty |= NV40_NEW_ARRAYS;
766 }
767
768 static void
769 nv40_set_vertex_element(struct pipe_context *pipe, unsigned index,
770 const struct pipe_vertex_element *ve)
771 {
772 struct nv40_context *nv40 = (struct nv40_context *)pipe;
773
774 nv40->vtxelt[index] = *ve;
775
776 nv40->dirty |= NV40_NEW_ARRAYS;
777 }
778
779 void
780 nv40_init_state_functions(struct nv40_context *nv40)
781 {
782 nv40->pipe.create_alpha_test_state = nv40_alpha_test_state_create;
783 nv40->pipe.bind_alpha_test_state = nv40_alpha_test_state_bind;
784 nv40->pipe.delete_alpha_test_state = nv40_alpha_test_state_delete;
785
786 nv40->pipe.create_blend_state = nv40_blend_state_create;
787 nv40->pipe.bind_blend_state = nv40_blend_state_bind;
788 nv40->pipe.delete_blend_state = nv40_blend_state_delete;
789
790 nv40->pipe.create_sampler_state = nv40_sampler_state_create;
791 nv40->pipe.bind_sampler_state = nv40_sampler_state_bind;
792 nv40->pipe.delete_sampler_state = nv40_sampler_state_delete;
793
794 nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create;
795 nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind;
796 nv40->pipe.delete_rasterizer_state = nv40_rasterizer_state_delete;
797
798 nv40->pipe.create_depth_stencil_state = nv40_depth_stencil_state_create;
799 nv40->pipe.bind_depth_stencil_state = nv40_depth_stencil_state_bind;
800 nv40->pipe.delete_depth_stencil_state = nv40_depth_stencil_state_delete;
801
802 nv40->pipe.create_vs_state = nv40_vp_state_create;
803 nv40->pipe.bind_vs_state = nv40_vp_state_bind;
804 nv40->pipe.delete_vs_state = nv40_vp_state_delete;
805
806 nv40->pipe.create_fs_state = nv40_fp_state_create;
807 nv40->pipe.bind_fs_state = nv40_fp_state_bind;
808 nv40->pipe.delete_fs_state = nv40_fp_state_delete;
809
810 nv40->pipe.set_blend_color = nv40_set_blend_color;
811 nv40->pipe.set_clip_state = nv40_set_clip_state;
812 nv40->pipe.set_clear_color_state = nv40_set_clear_color_state;
813 nv40->pipe.set_constant_buffer = nv40_set_constant_buffer;
814 nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state;
815 nv40->pipe.set_polygon_stipple = nv40_set_polygon_stipple;
816 nv40->pipe.set_sampler_units = nv40_set_sampler_units;
817 nv40->pipe.set_scissor_state = nv40_set_scissor_state;
818 nv40->pipe.set_texture_state = nv40_set_texture_state;
819 nv40->pipe.set_viewport_state = nv40_set_viewport_state;
820
821 nv40->pipe.set_vertex_buffer = nv40_set_vertex_buffer;
822 nv40->pipe.set_vertex_element = nv40_set_vertex_element;
823
824 // nv40->pipe.set_feedback_state = nv40_set_feedback_state;
825 // nv40->pipe.set_feedback_buffer = nv40_set_feedback_buffer;
826 }
827