nv10: set rasterizer state.
[mesa.git] / src / gallium / drivers / nv10 / nv10_state.c
1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4 #include "pipe/p_shader_tokens.h"
5
6
7 #include "nv10_context.h"
8 #include "nv10_state.h"
9
10 static void nv10_vertex_layout(struct pipe_context* pipe)
11 {
12 struct nv10_context *nv10 = nv10_context(pipe);
13 struct nv10_fragment_program *fp = nv10->fragprog.current;
14 uint32_t src = 0;
15 int i;
16 struct vertex_info vinfo;
17
18 memset(&vinfo, 0, sizeof(vinfo));
19
20 for (i = 0; i < fp->info.num_inputs; i++) {
21 switch (fp->info.input_semantic_name[i]) {
22 case TGSI_SEMANTIC_POSITION:
23 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
24 break;
25 case TGSI_SEMANTIC_COLOR:
26 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
27 break;
28 default:
29 case TGSI_SEMANTIC_GENERIC:
30 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
31 break;
32 case TGSI_SEMANTIC_FOG:
33 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
34 break;
35 }
36 }
37 draw_compute_vertex_size(&vinfo);
38
39 nv10->dirty |= NV10_NEW_VTXFMT;
40 }
41
42 static void *
43 nv10_blend_state_create(struct pipe_context *pipe,
44 const struct pipe_blend_state *cso)
45 {
46 struct nv10_blend_state *cb;
47
48 cb = malloc(sizeof(struct nv10_blend_state));
49
50 cb->b_enable = cso->blend_enable ? 1 : 0;
51 cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
52 (nvgl_blend_func(cso->rgb_src_factor)));
53 cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
54 (nvgl_blend_func(cso->rgb_dst_factor)));
55
56 cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
57 ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
58 ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
59 ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
60
61 cb->d_enable = cso->dither ? 1 : 0;
62
63 return (void *)cb;
64 }
65
66 static void
67 nv10_blend_state_bind(struct pipe_context *pipe, void *blend)
68 {
69 struct nv10_context *nv10 = nv10_context(pipe);
70
71 nv10->blend = (struct nv10_blend_state*)blend;
72
73 nv10->dirty |= NV10_NEW_BLEND;
74 }
75
76 static void
77 nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso)
78 {
79 FREE(hwcso);
80 }
81
82
83 static INLINE unsigned
84 wrap_mode(unsigned wrap) {
85 unsigned ret;
86
87 switch (wrap) {
88 case PIPE_TEX_WRAP_REPEAT:
89 ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
90 break;
91 case PIPE_TEX_WRAP_MIRROR_REPEAT:
92 ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT;
93 break;
94 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
95 ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE;
96 break;
97 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
98 ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER;
99 break;
100 case PIPE_TEX_WRAP_CLAMP:
101 ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP;
102 break;
103 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
104 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
105 case PIPE_TEX_WRAP_MIRROR_CLAMP:
106 default:
107 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
108 ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
109 break;
110 }
111
112 return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT;
113 }
114
115 static void *
116 nv10_sampler_state_create(struct pipe_context *pipe,
117 const struct pipe_sampler_state *cso)
118 {
119 struct nv10_sampler_state *ps;
120 uint32_t filter = 0;
121
122 ps = malloc(sizeof(struct nv10_sampler_state));
123
124 ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) |
125 (wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT));
126
127 ps->en = 0;
128 if (cso->max_anisotropy > 1.0) {
129 /* no idea, binary driver sets it, works without it.. meh.. */
130 ps->wrap |= (1 << 5);
131
132 /* if (cso->max_anisotropy >= 16.0) {
133 ps->en |= NV10TCL_TX_ENABLE_ANISO_16X;
134 } else
135 if (cso->max_anisotropy >= 12.0) {
136 ps->en |= NV10TCL_TX_ENABLE_ANISO_12X;
137 } else
138 if (cso->max_anisotropy >= 10.0) {
139 ps->en |= NV10TCL_TX_ENABLE_ANISO_10X;
140 } else
141 if (cso->max_anisotropy >= 8.0) {
142 ps->en |= NV10TCL_TX_ENABLE_ANISO_8X;
143 } else
144 if (cso->max_anisotropy >= 6.0) {
145 ps->en |= NV10TCL_TX_ENABLE_ANISO_6X;
146 } else
147 if (cso->max_anisotropy >= 4.0) {
148 ps->en |= NV10TCL_TX_ENABLE_ANISO_4X;
149 } else {
150 ps->en |= NV10TCL_TX_ENABLE_ANISO_2X;
151 }*/
152 }
153
154 switch (cso->mag_img_filter) {
155 case PIPE_TEX_FILTER_LINEAR:
156 filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR;
157 break;
158 case PIPE_TEX_FILTER_NEAREST:
159 default:
160 filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST;
161 break;
162 }
163
164 switch (cso->min_img_filter) {
165 case PIPE_TEX_FILTER_LINEAR:
166 switch (cso->min_mip_filter) {
167 case PIPE_TEX_MIPFILTER_NEAREST:
168 filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
169 break;
170 case PIPE_TEX_MIPFILTER_LINEAR:
171 filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
172 break;
173 case PIPE_TEX_MIPFILTER_NONE:
174 default:
175 filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR;
176 break;
177 }
178 break;
179 case PIPE_TEX_FILTER_NEAREST:
180 default:
181 switch (cso->min_mip_filter) {
182 case PIPE_TEX_MIPFILTER_NEAREST:
183 filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
184 break;
185 case PIPE_TEX_MIPFILTER_LINEAR:
186 filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
187 break;
188 case PIPE_TEX_MIPFILTER_NONE:
189 default:
190 filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST;
191 break;
192 }
193 break;
194 }
195
196 ps->filt = filter;
197
198 /* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
199 switch (cso->compare_func) {
200 case PIPE_FUNC_NEVER:
201 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
202 break;
203 case PIPE_FUNC_GREATER:
204 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
205 break;
206 case PIPE_FUNC_EQUAL:
207 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
208 break;
209 case PIPE_FUNC_GEQUAL:
210 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
211 break;
212 case PIPE_FUNC_LESS:
213 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
214 break;
215 case PIPE_FUNC_NOTEQUAL:
216 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
217 break;
218 case PIPE_FUNC_LEQUAL:
219 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
220 break;
221 case PIPE_FUNC_ALWAYS:
222 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
223 break;
224 default:
225 break;
226 }
227 }*/
228
229 ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
230 (float_to_ubyte(cso->border_color[0]) << 16) |
231 (float_to_ubyte(cso->border_color[1]) << 8) |
232 (float_to_ubyte(cso->border_color[2]) << 0));
233
234 return (void *)ps;
235 }
236
237 static void
238 nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
239 {
240 struct nv10_context *nv10 = nv10_context(pipe);
241 unsigned unit;
242
243 for (unit = 0; unit < nr; unit++) {
244 nv10->tex_sampler[unit] = sampler[unit];
245 nv10->dirty_samplers |= (1 << unit);
246 }
247 }
248
249 static void
250 nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
251 {
252 FREE(hwcso);
253 }
254
255 static void
256 nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
257 struct pipe_texture **miptree)
258 {
259 struct nv10_context *nv10 = nv10_context(pipe);
260 unsigned unit;
261
262 for (unit = 0; unit < nr; unit++) {
263 nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit];
264 nv10->dirty_samplers |= (1 << unit);
265 }
266 }
267
268 static void *
269 nv10_rasterizer_state_create(struct pipe_context *pipe,
270 const struct pipe_rasterizer_state *cso)
271 {
272 struct nv10_rasterizer_state *rs;
273 int i;
274
275 /*XXX: ignored:
276 * light_twoside
277 * offset_cw/ccw -nohw
278 * scissor
279 * point_smooth -nohw
280 * multisample
281 * offset_units / offset_scale
282 */
283 rs = malloc(sizeof(struct nv10_rasterizer_state));
284
285 rs->templ = cso;
286
287 rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;
288
289 rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
290 rs->line_smooth_en = cso->line_smooth ? 1 : 0;
291
292 rs->point_size = *(uint32_t*)&cso->point_size;
293
294 rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
295
296 if (cso->front_winding == PIPE_WINDING_CCW) {
297 rs->front_face = NV10TCL_FRONT_FACE_CCW;
298 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
299 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
300 } else {
301 rs->front_face = NV10TCL_FRONT_FACE_CW;
302 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
303 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
304 }
305
306 switch (cso->cull_mode) {
307 case PIPE_WINDING_CCW:
308 rs->cull_face_en = 1;
309 if (cso->front_winding == PIPE_WINDING_CCW)
310 rs->cull_face = NV10TCL_CULL_FACE_FRONT;
311 else
312 rs->cull_face = NV10TCL_CULL_FACE_BACK;
313 break;
314 case PIPE_WINDING_CW:
315 rs->cull_face_en = 1;
316 if (cso->front_winding == PIPE_WINDING_CW)
317 rs->cull_face = NV10TCL_CULL_FACE_FRONT;
318 else
319 rs->cull_face = NV10TCL_CULL_FACE_BACK;
320 break;
321 case PIPE_WINDING_BOTH:
322 rs->cull_face_en = 1;
323 rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK;
324 break;
325 case PIPE_WINDING_NONE:
326 default:
327 rs->cull_face_en = 0;
328 rs->cull_face = 0;
329 break;
330 }
331
332 if (cso->point_sprite) {
333 rs->point_sprite = (1 << 0);
334 for (i = 0; i < 8; i++) {
335 if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
336 rs->point_sprite |= (1 << (8 + i));
337 }
338 } else {
339 rs->point_sprite = 0;
340 }
341
342 return (void *)rs;
343 }
344
345 static void
346 nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
347 {
348 struct nv10_context *nv10 = nv10_context(pipe);
349
350 nv10->rast = (struct nv10_rasterizer_state*)rast;
351
352 draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL));
353
354 nv10->dirty |= NV10_NEW_RAST;
355 }
356
357 static void
358 nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
359 {
360 FREE(hwcso);
361 }
362
363 static void *
364 nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe,
365 const struct pipe_depth_stencil_alpha_state *cso)
366 {
367 struct nv10_depth_stencil_alpha_state *hw;
368
369 hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state));
370
371 hw->depth.func = nvgl_comparison_op(cso->depth.func);
372 hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
373 hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
374
375 hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
376 hw->stencil.wmask = cso->stencil[0].write_mask;
377 hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
378 hw->stencil.ref = cso->stencil[0].ref_value;
379 hw->stencil.vmask = cso->stencil[0].value_mask;
380 hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
381 hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
382 hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
383
384 hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
385 hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
386 hw->alpha.ref = float_to_ubyte(cso->alpha.ref);
387
388 return (void *)hw;
389 }
390
391 static void
392 nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
393 {
394 struct nv10_context *nv10 = nv10_context(pipe);
395
396 nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa;
397
398 nv10->dirty |= NV10_NEW_DSA;
399 }
400
401 static void
402 nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
403 {
404 FREE(hwcso);
405 }
406
407 static void *
408 nv10_vp_state_create(struct pipe_context *pipe,
409 const struct pipe_shader_state *cso)
410 {
411 struct nv10_vertex_program *vp;
412
413 vp = CALLOC(1, sizeof(struct nv10_vertex_program));
414 vp->pipe = cso;
415
416 return (void *)vp;
417 }
418
419 static void
420 nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso)
421 {
422 struct nv10_context *nv10 = nv10_context(pipe);
423 struct nv10_vertex_program *vp = hwcso;
424
425 nv10->vertprog.current = vp;
426 nv10->dirty |= NV10_NEW_VERTPROG;
427 }
428
429 static void
430 nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso)
431 {
432 //struct nv10_context *nv10 = nv10_context(pipe);
433 struct nv10_vertex_program *vp = hwcso;
434
435 //nv10_vertprog_destroy(nv10, vp);
436 FREE(vp);
437 }
438
439 static void *
440 nv10_fp_state_create(struct pipe_context *pipe,
441 const struct pipe_shader_state *cso)
442 {
443 struct nv10_fragment_program *fp;
444
445 fp = CALLOC(1, sizeof(struct nv10_fragment_program));
446 fp->pipe = cso;
447
448 tgsi_scan_shader(cso->tokens, &fp->info);
449
450 return (void *)fp;
451 }
452
453 static void
454 nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso)
455 {
456 struct nv10_context *nv10 = nv10_context(pipe);
457 struct nv10_fragment_program *fp = hwcso;
458
459 nv10->fragprog.current = fp;
460 nv10->dirty |= NV10_NEW_FRAGPROG;
461 }
462
463 static void
464 nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso)
465 {
466 struct nv10_context *nv10 = nv10_context(pipe);
467 struct nv10_fragment_program *fp = hwcso;
468
469 nv10_fragprog_destroy(nv10, fp);
470 FREE(fp);
471 }
472
473 static void
474 nv10_set_blend_color(struct pipe_context *pipe,
475 const struct pipe_blend_color *bcol)
476 {
477 struct nv10_context *nv10 = nv10_context(pipe);
478
479 nv10->blend_color = (struct pipe_blend_color*)bcol;
480
481 nv10->dirty |= NV10_NEW_BLENDCOL;
482 }
483
484 static void
485 nv10_set_clip_state(struct pipe_context *pipe,
486 const struct pipe_clip_state *clip)
487 {
488 }
489
490 static void
491 nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
492 const struct pipe_constant_buffer *buf )
493 {
494 struct nv10_context *nv10 = nv10_context(pipe);
495
496 if (shader == PIPE_SHADER_VERTEX) {
497 nv10->vertprog.constant_buf = buf->buffer;
498 nv10->dirty |= NV10_NEW_VERTPROG;
499 } else
500 if (shader == PIPE_SHADER_FRAGMENT) {
501 nv10->fragprog.constant_buf = buf->buffer;
502 nv10->dirty |= NV10_NEW_FRAGPROG;
503 }
504 }
505
506 static void
507 nv10_set_framebuffer_state(struct pipe_context *pipe,
508 const struct pipe_framebuffer_state *fb)
509 {
510 struct nv10_context *nv10 = nv10_context(pipe);
511
512 nv10->framebuffer = (struct pipe_framebuffer_state*)fb;
513
514 nv10->dirty |= NV10_NEW_FRAMEBUFFER;
515 }
516
517 static void
518 nv10_set_polygon_stipple(struct pipe_context *pipe,
519 const struct pipe_poly_stipple *stipple)
520 {
521 NOUVEAU_ERR("line stipple hahaha\n");
522 }
523
524 static void
525 nv10_set_scissor_state(struct pipe_context *pipe,
526 const struct pipe_scissor_state *s)
527 {
528 struct nv10_context *nv10 = nv10_context(pipe);
529
530 nv10->scissor = (struct pipe_scissor_state*)s;
531
532 nv10->dirty |= NV10_NEW_SCISSOR;
533 }
534
535 static void
536 nv10_set_viewport_state(struct pipe_context *pipe,
537 const struct pipe_viewport_state *vpt)
538 {
539 struct nv10_context *nv10 = nv10_context(pipe);
540
541 nv10->viewport = (struct pipe_viewport_state*)vpt;
542
543 nv10->dirty |= NV10_NEW_VIEWPORT;
544 }
545
546 static void
547 nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
548 const struct pipe_vertex_buffer *vb)
549 {
550 struct nv10_context *nv10 = nv10_context(pipe);
551
552 memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count);
553 nv10->dirty |= NV10_NEW_ARRAYS;
554 }
555
556 static void
557 nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count,
558 const struct pipe_vertex_element *ve)
559 {
560 struct nv10_context *nv10 = nv10_context(pipe);
561
562 memcpy(nv10->vtxelt, ve, sizeof(*ve) * count);
563 nv10->dirty |= NV10_NEW_ARRAYS;
564 }
565
566 void
567 nv10_init_state_functions(struct nv10_context *nv10)
568 {
569 nv10->pipe.create_blend_state = nv10_blend_state_create;
570 nv10->pipe.bind_blend_state = nv10_blend_state_bind;
571 nv10->pipe.delete_blend_state = nv10_blend_state_delete;
572
573 nv10->pipe.create_sampler_state = nv10_sampler_state_create;
574 nv10->pipe.bind_sampler_states = nv10_sampler_state_bind;
575 nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
576 nv10->pipe.set_sampler_textures = nv10_set_sampler_texture;
577
578 nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
579 nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
580 nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete;
581
582 nv10->pipe.create_depth_stencil_alpha_state =
583 nv10_depth_stencil_alpha_state_create;
584 nv10->pipe.bind_depth_stencil_alpha_state =
585 nv10_depth_stencil_alpha_state_bind;
586 nv10->pipe.delete_depth_stencil_alpha_state =
587 nv10_depth_stencil_alpha_state_delete;
588
589 nv10->pipe.create_vs_state = nv10_vp_state_create;
590 nv10->pipe.bind_vs_state = nv10_vp_state_bind;
591 nv10->pipe.delete_vs_state = nv10_vp_state_delete;
592
593 nv10->pipe.create_fs_state = nv10_fp_state_create;
594 nv10->pipe.bind_fs_state = nv10_fp_state_bind;
595 nv10->pipe.delete_fs_state = nv10_fp_state_delete;
596
597 nv10->pipe.set_blend_color = nv10_set_blend_color;
598 nv10->pipe.set_clip_state = nv10_set_clip_state;
599 nv10->pipe.set_constant_buffer = nv10_set_constant_buffer;
600 nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state;
601 nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple;
602 nv10->pipe.set_scissor_state = nv10_set_scissor_state;
603 nv10->pipe.set_viewport_state = nv10_set_viewport_state;
604
605 nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers;
606 nv10->pipe.set_vertex_elements = nv10_set_vertex_elements;
607 }
608