12722709f6baae03f674c62b5e6cdd41efcbe398
[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->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;
286
287 rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
288 rs->line_smooth_en = cso->line_smooth ? 1 : 0;
289
290 rs->point_size = *(uint32_t*)&cso->point_size;
291
292 rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;
293
294 if (cso->front_winding == PIPE_WINDING_CCW) {
295 rs->front_face = NV10TCL_FRONT_FACE_CCW;
296 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
297 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
298 } else {
299 rs->front_face = NV10TCL_FRONT_FACE_CW;
300 rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
301 rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
302 }
303
304 switch (cso->cull_mode) {
305 case PIPE_WINDING_CCW:
306 rs->cull_face_en = 1;
307 if (cso->front_winding == PIPE_WINDING_CCW)
308 rs->cull_face = NV10TCL_CULL_FACE_FRONT;
309 else
310 rs->cull_face = NV10TCL_CULL_FACE_BACK;
311 break;
312 case PIPE_WINDING_CW:
313 rs->cull_face_en = 1;
314 if (cso->front_winding == PIPE_WINDING_CW)
315 rs->cull_face = NV10TCL_CULL_FACE_FRONT;
316 else
317 rs->cull_face = NV10TCL_CULL_FACE_BACK;
318 break;
319 case PIPE_WINDING_BOTH:
320 rs->cull_face_en = 1;
321 rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK;
322 break;
323 case PIPE_WINDING_NONE:
324 default:
325 rs->cull_face_en = 0;
326 rs->cull_face = 0;
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 nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
345 {
346 struct nv10_context *nv10 = nv10_context(pipe);
347
348 nv10->rast = (struct nv10_rasterizer_state*)rast;
349
350 nv10->dirty |= NV10_NEW_RAST;
351 }
352
353 static void
354 nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
355 {
356 FREE(hwcso);
357 }
358
359 static void *
360 nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe,
361 const struct pipe_depth_stencil_alpha_state *cso)
362 {
363 struct nv10_depth_stencil_alpha_state *hw;
364
365 hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state));
366
367 hw->depth.func = nvgl_comparison_op(cso->depth.func);
368 hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
369 hw->depth.test_enable = cso->depth.enabled ? 1 : 0;
370
371 hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
372 hw->stencil.wmask = cso->stencil[0].write_mask;
373 hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
374 hw->stencil.ref = cso->stencil[0].ref_value;
375 hw->stencil.vmask = cso->stencil[0].value_mask;
376 hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
377 hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
378 hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);
379
380 hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
381 hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
382 hw->alpha.ref = float_to_ubyte(cso->alpha.ref);
383
384 return (void *)hw;
385 }
386
387 static void
388 nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa)
389 {
390 struct nv10_context *nv10 = nv10_context(pipe);
391
392 nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa;
393
394 nv10->dirty |= NV10_NEW_DSA;
395 }
396
397 static void
398 nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
399 {
400 FREE(hwcso);
401 }
402
403 static void *
404 nv10_vp_state_create(struct pipe_context *pipe,
405 const struct pipe_shader_state *cso)
406 {
407 struct nv10_vertex_program *vp;
408
409 vp = CALLOC(1, sizeof(struct nv10_vertex_program));
410 vp->pipe = cso;
411
412 return (void *)vp;
413 }
414
415 static void
416 nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso)
417 {
418 struct nv10_context *nv10 = nv10_context(pipe);
419 struct nv10_vertex_program *vp = hwcso;
420
421 nv10->vertprog.current = vp;
422 nv10->dirty |= NV10_NEW_VERTPROG;
423 }
424
425 static void
426 nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso)
427 {
428 //struct nv10_context *nv10 = nv10_context(pipe);
429 struct nv10_vertex_program *vp = hwcso;
430
431 //nv10_vertprog_destroy(nv10, vp);
432 FREE(vp);
433 }
434
435 static void *
436 nv10_fp_state_create(struct pipe_context *pipe,
437 const struct pipe_shader_state *cso)
438 {
439 struct nv10_fragment_program *fp;
440
441 fp = CALLOC(1, sizeof(struct nv10_fragment_program));
442 fp->pipe = cso;
443
444 tgsi_scan_shader(cso->tokens, &fp->info);
445
446 return (void *)fp;
447 }
448
449 static void
450 nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso)
451 {
452 struct nv10_context *nv10 = nv10_context(pipe);
453 struct nv10_fragment_program *fp = hwcso;
454
455 nv10->fragprog.current = fp;
456 nv10->dirty |= NV10_NEW_FRAGPROG;
457 }
458
459 static void
460 nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso)
461 {
462 struct nv10_context *nv10 = nv10_context(pipe);
463 struct nv10_fragment_program *fp = hwcso;
464
465 nv10_fragprog_destroy(nv10, fp);
466 FREE(fp);
467 }
468
469 static void
470 nv10_set_blend_color(struct pipe_context *pipe,
471 const struct pipe_blend_color *bcol)
472 {
473 struct nv10_context *nv10 = nv10_context(pipe);
474
475 nv10->blend_color = (struct pipe_blend_color*)bcol;
476
477 nv10->dirty |= NV10_NEW_BLENDCOL;
478 }
479
480 static void
481 nv10_set_clip_state(struct pipe_context *pipe,
482 const struct pipe_clip_state *clip)
483 {
484 }
485
486 static void
487 nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
488 const struct pipe_constant_buffer *buf )
489 {
490 struct nv10_context *nv10 = nv10_context(pipe);
491
492 if (shader == PIPE_SHADER_VERTEX) {
493 nv10->vertprog.constant_buf = buf->buffer;
494 nv10->dirty |= NV10_NEW_VERTPROG;
495 } else
496 if (shader == PIPE_SHADER_FRAGMENT) {
497 nv10->fragprog.constant_buf = buf->buffer;
498 nv10->dirty |= NV10_NEW_FRAGPROG;
499 }
500 }
501
502 static void
503 nv10_set_framebuffer_state(struct pipe_context *pipe,
504 const struct pipe_framebuffer_state *fb)
505 {
506 struct nv10_context *nv10 = nv10_context(pipe);
507
508 nv10->framebuffer = (struct pipe_framebuffer_state*)fb;
509
510 nv10->dirty |= NV10_NEW_FRAMEBUFFER;
511 }
512
513 static void
514 nv10_set_polygon_stipple(struct pipe_context *pipe,
515 const struct pipe_poly_stipple *stipple)
516 {
517 NOUVEAU_ERR("line stipple hahaha\n");
518 }
519
520 static void
521 nv10_set_scissor_state(struct pipe_context *pipe,
522 const struct pipe_scissor_state *s)
523 {
524 struct nv10_context *nv10 = nv10_context(pipe);
525
526 nv10->scissor = (struct pipe_scissor_state*)s;
527
528 nv10->dirty |= NV10_NEW_SCISSOR;
529 }
530
531 static void
532 nv10_set_viewport_state(struct pipe_context *pipe,
533 const struct pipe_viewport_state *vpt)
534 {
535 struct nv10_context *nv10 = nv10_context(pipe);
536
537 nv10->viewport = (struct pipe_viewport_state*)vpt;
538
539 nv10->dirty |= NV10_NEW_VIEWPORT;
540 }
541
542 static void
543 nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
544 const struct pipe_vertex_buffer *vb)
545 {
546 struct nv10_context *nv10 = nv10_context(pipe);
547
548 memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count);
549 nv10->dirty |= NV10_NEW_ARRAYS;
550 }
551
552 static void
553 nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count,
554 const struct pipe_vertex_element *ve)
555 {
556 struct nv10_context *nv10 = nv10_context(pipe);
557
558 memcpy(nv10->vtxelt, ve, sizeof(*ve) * count);
559 nv10->dirty |= NV10_NEW_ARRAYS;
560 }
561
562 void
563 nv10_init_state_functions(struct nv10_context *nv10)
564 {
565 nv10->pipe.create_blend_state = nv10_blend_state_create;
566 nv10->pipe.bind_blend_state = nv10_blend_state_bind;
567 nv10->pipe.delete_blend_state = nv10_blend_state_delete;
568
569 nv10->pipe.create_sampler_state = nv10_sampler_state_create;
570 nv10->pipe.bind_sampler_states = nv10_sampler_state_bind;
571 nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
572 nv10->pipe.set_sampler_textures = nv10_set_sampler_texture;
573
574 nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
575 nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
576 nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete;
577
578 nv10->pipe.create_depth_stencil_alpha_state =
579 nv10_depth_stencil_alpha_state_create;
580 nv10->pipe.bind_depth_stencil_alpha_state =
581 nv10_depth_stencil_alpha_state_bind;
582 nv10->pipe.delete_depth_stencil_alpha_state =
583 nv10_depth_stencil_alpha_state_delete;
584
585 nv10->pipe.create_vs_state = nv10_vp_state_create;
586 nv10->pipe.bind_vs_state = nv10_vp_state_bind;
587 nv10->pipe.delete_vs_state = nv10_vp_state_delete;
588
589 nv10->pipe.create_fs_state = nv10_fp_state_create;
590 nv10->pipe.bind_fs_state = nv10_fp_state_bind;
591 nv10->pipe.delete_fs_state = nv10_fp_state_delete;
592
593 nv10->pipe.set_blend_color = nv10_set_blend_color;
594 nv10->pipe.set_clip_state = nv10_set_clip_state;
595 nv10->pipe.set_constant_buffer = nv10_set_constant_buffer;
596 nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state;
597 nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple;
598 nv10->pipe.set_scissor_state = nv10_set_scissor_state;
599 nv10->pipe.set_viewport_state = nv10_set_viewport_state;
600
601 nv10->pipe.set_vertex_buffers = nv10_set_vertex_buffers;
602 nv10->pipe.set_vertex_elements = nv10_set_vertex_elements;
603 }
604