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