nv50: disable ztest for now - it doesn't work still
[mesa.git] / src / gallium / drivers / nv50 / nv50_state.c
1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4
5 #include "nv50_context.h"
6
7 #include "nouveau/nouveau_stateobj.h"
8
9 static void *
10 nv50_blend_state_create(struct pipe_context *pipe,
11 const struct pipe_blend_state *cso)
12 {
13 struct nouveau_stateobj *so = so_new(64, 0);
14 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
15 struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj);
16 unsigned cmask = 0, i;
17
18 /*XXX ignored:
19 * - dither
20 */
21
22 if (cso->blend_enable == 0) {
23 so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
24 for (i = 0; i < 8; i++)
25 so_data(so, 0);
26 } else {
27 so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
28 for (i = 0; i < 8; i++)
29 so_data(so, 1);
30 so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5);
31 so_data (so, nvgl_blend_eqn(cso->rgb_func));
32 so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_src_factor));
33 so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_dst_factor));
34 so_data (so, nvgl_blend_eqn(cso->alpha_func));
35 so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_src_factor));
36 so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1);
37 so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor));
38 }
39
40 if (cso->logicop_enable == 0 ) {
41 so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1);
42 so_data (so, 0);
43 } else {
44 so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2);
45 so_data (so, 1);
46 so_data (so, nvgl_logicop_func(cso->logicop_func));
47 }
48
49 if (cso->colormask & PIPE_MASK_R)
50 cmask |= (1 << 0);
51 if (cso->colormask & PIPE_MASK_G)
52 cmask |= (1 << 4);
53 if (cso->colormask & PIPE_MASK_B)
54 cmask |= (1 << 8);
55 if (cso->colormask & PIPE_MASK_A)
56 cmask |= (1 << 12);
57 so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8);
58 for (i = 0; i < 8; i++)
59 so_data(so, cmask);
60
61 bso->pipe = *cso;
62 so_ref(so, &bso->so);
63 return (void *)bso;
64 }
65
66 static void
67 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
68 {
69 struct nv50_context *nv50 = nv50_context(pipe);
70
71 nv50->blend = hwcso;
72 nv50->dirty |= NV50_NEW_BLEND;
73 }
74
75 static void
76 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
77 {
78 struct nv50_blend_stateobj *bso = hwcso;
79
80 so_ref(NULL, &bso->so);
81 FREE(bso);
82 }
83
84 static void *
85 nv50_sampler_state_create(struct pipe_context *pipe,
86 const struct pipe_sampler_state *cso)
87 {
88 return NULL;
89 }
90
91 static void
92 nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
93 {
94 }
95
96 static void
97 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
98 {
99 }
100
101 static void
102 nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
103 struct pipe_texture **pt)
104 {
105 }
106
107 static void *
108 nv50_rasterizer_state_create(struct pipe_context *pipe,
109 const struct pipe_rasterizer_state *cso)
110 {
111 struct nouveau_stateobj *so = so_new(64, 0);
112 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
113 struct nv50_rasterizer_stateobj *rso =
114 CALLOC_STRUCT(nv50_rasterizer_stateobj);
115
116 /*XXX: ignored
117 * - light_twosize
118 * - point_smooth
119 * - multisample
120 * - point_sprite / sprite_coord_mode
121 */
122
123 so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
124 so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
125 NV50TCL_SHADE_MODEL_SMOOTH);
126
127 so_method(so, tesla, NV50TCL_LINE_WIDTH, 1);
128 so_data (so, fui(cso->line_width));
129 so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1);
130 so_data (so, cso->line_smooth ? 1 : 0);
131 if (cso->line_stipple_enable) {
132 so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
133 so_data (so, 1);
134 so_method(so, tesla, NV50TCL_LINE_STIPPLE_PATTERN, 1);
135 so_data (so, (cso->line_stipple_pattern << 16) |
136 cso->line_stipple_factor);
137 } else {
138 so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
139 so_data (so, 0);
140 }
141
142 so_method(so, tesla, NV50TCL_POINT_SIZE, 1);
143 so_data (so, fui(cso->point_size));
144
145 so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
146 if (cso->front_winding == PIPE_WINDING_CCW) {
147 so_data(so, nvgl_polygon_mode(cso->fill_ccw));
148 so_data(so, nvgl_polygon_mode(cso->fill_cw));
149 } else {
150 so_data(so, nvgl_polygon_mode(cso->fill_cw));
151 so_data(so, nvgl_polygon_mode(cso->fill_ccw));
152 }
153 so_data(so, cso->poly_smooth ? 1 : 0);
154
155 so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3);
156 so_data (so, cso->cull_mode != PIPE_WINDING_NONE);
157 if (cso->front_winding == PIPE_WINDING_CCW) {
158 so_data(so, NV50TCL_FRONT_FACE_CCW);
159 switch (cso->cull_mode) {
160 case PIPE_WINDING_CCW:
161 so_data(so, NV50TCL_CULL_FACE_FRONT);
162 break;
163 case PIPE_WINDING_CW:
164 so_data(so, NV50TCL_CULL_FACE_BACK);
165 break;
166 case PIPE_WINDING_BOTH:
167 so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
168 break;
169 default:
170 so_data(so, NV50TCL_CULL_FACE_BACK);
171 break;
172 }
173 } else {
174 so_data(so, NV50TCL_FRONT_FACE_CW);
175 switch (cso->cull_mode) {
176 case PIPE_WINDING_CCW:
177 so_data(so, NV50TCL_CULL_FACE_BACK);
178 break;
179 case PIPE_WINDING_CW:
180 so_data(so, NV50TCL_CULL_FACE_FRONT);
181 break;
182 case PIPE_WINDING_BOTH:
183 so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
184 break;
185 default:
186 so_data(so, NV50TCL_CULL_FACE_BACK);
187 break;
188 }
189 }
190
191 so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1);
192 so_data (so, cso->poly_stipple_enable ? 1 : 0);
193
194 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
195 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
196 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
197 so_data(so, 1);
198 else
199 so_data(so, 0);
200 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
201 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
202 so_data(so, 1);
203 else
204 so_data(so, 0);
205 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
206 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
207 so_data(so, 1);
208 else
209 so_data(so, 0);
210
211 if (cso->offset_cw || cso->offset_ccw) {
212 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1);
213 so_data (so, fui(cso->offset_scale));
214 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1);
215 so_data (so, fui(cso->offset_units * 2));
216 }
217
218 rso->pipe = *cso;
219 so_ref(so, &rso->so);
220 return (void *)rso;
221 }
222
223 static void
224 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
225 {
226 struct nv50_context *nv50 = nv50_context(pipe);
227
228 nv50->rasterizer = hwcso;
229 nv50->dirty |= NV50_NEW_RASTERIZER;
230 }
231
232 static void
233 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
234 {
235 struct nv50_rasterizer_stateobj *rso = hwcso;
236
237 so_ref(NULL, &rso->so);
238 FREE(rso);
239 }
240
241 static void *
242 nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
243 const struct pipe_depth_stencil_alpha_state *cso)
244 {
245 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
246 struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj);
247 struct nouveau_stateobj *so = so_new(64, 0);
248
249 so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
250 so_data (so, 0); //cso->depth.writemask ? 1 : 0);
251 if (cso->depth.enabled) {
252 so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
253 so_data (so, 0); //1);
254 so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1);
255 so_data (so, nvgl_comparison_op(cso->depth.func));
256 } else {
257 so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
258 so_data (so, 0);
259 }
260
261 if (cso->stencil[0].enabled) {
262 so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5);
263 so_data (so, 1);
264 so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
265 so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
266 so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
267 so_data (so, nvgl_comparison_op(cso->stencil[0].func));
268 so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 3);
269 so_data (so, cso->stencil[0].ref_value);
270 so_data (so, cso->stencil[0].write_mask);
271 so_data (so, cso->stencil[0].value_mask);
272 } else {
273 so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
274 so_data (so, 0);
275 }
276
277 if (cso->stencil[1].enabled) {
278 so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 8);
279 so_data (so, 1);
280 so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
281 so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
282 so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
283 so_data (so, nvgl_comparison_op(cso->stencil[1].func));
284 so_data (so, cso->stencil[1].ref_value);
285 so_data (so, cso->stencil[1].write_mask);
286 so_data (so, cso->stencil[1].value_mask);
287 } else {
288 so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
289 so_data (so, 0);
290 }
291
292 if (cso->alpha.enabled) {
293 so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
294 so_data (so, 1);
295 so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2);
296 so_data (so, fui(cso->alpha.ref));
297 so_data (so, nvgl_comparison_op(cso->alpha.func));
298 } else {
299 so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
300 so_data (so, 0);
301 }
302
303 zsa->pipe = *cso;
304 so_ref(so, &zsa->so);
305 return (void *)zsa;
306 }
307
308 static void
309 nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
310 {
311 struct nv50_context *nv50 = nv50_context(pipe);
312
313 nv50->zsa = hwcso;
314 nv50->dirty |= NV50_NEW_ZSA;
315 }
316
317 static void
318 nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
319 {
320 struct nv50_zsa_stateobj *zsa = hwcso;
321
322 so_ref(NULL, &zsa->so);
323 FREE(zsa);
324 }
325
326 static void *
327 nv50_vp_state_create(struct pipe_context *pipe,
328 const struct pipe_shader_state *cso)
329 {
330 struct nv50_program *p = CALLOC_STRUCT(nv50_program);
331
332 p->pipe = *cso;
333 p->type = PIPE_SHADER_VERTEX;
334 tgsi_scan_shader(p->pipe.tokens, &p->info);
335 return (void *)p;
336 }
337
338 static void
339 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
340 {
341 struct nv50_context *nv50 = nv50_context(pipe);
342
343 nv50->vertprog = hwcso;
344 nv50->dirty |= NV50_NEW_VERTPROG;
345 }
346
347 static void
348 nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso)
349 {
350 struct nv50_context *nv50 = nv50_context(pipe);
351
352 nv50_program_destroy(nv50, hwcso);
353 FREE(hwcso);
354 }
355
356 static void *
357 nv50_fp_state_create(struct pipe_context *pipe,
358 const struct pipe_shader_state *cso)
359 {
360 struct nv50_program *p = CALLOC_STRUCT(nv50_program);
361
362 p->pipe = *cso;
363 p->type = PIPE_SHADER_FRAGMENT;
364 tgsi_scan_shader(p->pipe.tokens, &p->info);
365 return (void *)p;
366 }
367
368 static void
369 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
370 {
371 struct nv50_context *nv50 = nv50_context(pipe);
372
373 nv50->fragprog = hwcso;
374 nv50->dirty |= NV50_NEW_FRAGPROG;
375 }
376
377 static void
378 nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso)
379 {
380 struct nv50_context *nv50 = nv50_context(pipe);
381
382 nv50_program_destroy(nv50, hwcso);
383 FREE(hwcso);
384 }
385
386 static void
387 nv50_set_blend_color(struct pipe_context *pipe,
388 const struct pipe_blend_color *bcol)
389 {
390 struct nv50_context *nv50 = nv50_context(pipe);
391
392 nv50->blend_colour = *bcol;
393 nv50->dirty |= NV50_NEW_BLEND_COLOUR;
394 }
395
396 static void
397 nv50_set_clip_state(struct pipe_context *pipe,
398 const struct pipe_clip_state *clip)
399 {
400 }
401
402 static void
403 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
404 const struct pipe_constant_buffer *buf )
405 {
406 struct nv50_context *nv50 = nv50_context(pipe);
407
408 if (shader == PIPE_SHADER_VERTEX) {
409 nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer;
410 nv50->dirty |= NV50_NEW_VERTPROG_CB;
411 } else
412 if (shader == PIPE_SHADER_FRAGMENT) {
413 nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer;
414 nv50->dirty |= NV50_NEW_FRAGPROG_CB;
415 }
416 }
417
418 static void
419 nv50_set_framebuffer_state(struct pipe_context *pipe,
420 const struct pipe_framebuffer_state *fb)
421 {
422 struct nv50_context *nv50 = nv50_context(pipe);
423
424 nv50->framebuffer = *fb;
425 nv50->dirty |= NV50_NEW_FRAMEBUFFER;
426 }
427
428 static void
429 nv50_set_polygon_stipple(struct pipe_context *pipe,
430 const struct pipe_poly_stipple *stipple)
431 {
432 struct nv50_context *nv50 = nv50_context(pipe);
433
434 nv50->stipple = *stipple;
435 nv50->dirty |= NV50_NEW_STIPPLE;
436 }
437
438 static void
439 nv50_set_scissor_state(struct pipe_context *pipe,
440 const struct pipe_scissor_state *s)
441 {
442 struct nv50_context *nv50 = nv50_context(pipe);
443
444 nv50->scissor = *s;
445 nv50->dirty |= NV50_NEW_SCISSOR;
446 }
447
448 static void
449 nv50_set_viewport_state(struct pipe_context *pipe,
450 const struct pipe_viewport_state *vpt)
451 {
452 struct nv50_context *nv50 = nv50_context(pipe);
453
454 nv50->viewport = *vpt;
455 nv50->dirty |= NV50_NEW_VIEWPORT;
456 }
457
458 static void
459 nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
460 const struct pipe_vertex_buffer *vb)
461 {
462 struct nv50_context *nv50 = nv50_context(pipe);
463
464 memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
465 nv50->vtxbuf_nr = count;
466
467 nv50->dirty |= NV50_NEW_ARRAYS;
468 }
469
470 static void
471 nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
472 const struct pipe_vertex_element *ve)
473 {
474 struct nv50_context *nv50 = nv50_context(pipe);
475
476 memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
477 nv50->vtxelt_nr = count;
478
479 nv50->dirty |= NV50_NEW_ARRAYS;
480 }
481
482 void
483 nv50_init_state_functions(struct nv50_context *nv50)
484 {
485 nv50->pipe.create_blend_state = nv50_blend_state_create;
486 nv50->pipe.bind_blend_state = nv50_blend_state_bind;
487 nv50->pipe.delete_blend_state = nv50_blend_state_delete;
488
489 nv50->pipe.create_sampler_state = nv50_sampler_state_create;
490 nv50->pipe.bind_sampler_states = nv50_sampler_state_bind;
491 nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
492 nv50->pipe.set_sampler_textures = nv50_set_sampler_texture;
493
494 nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
495 nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
496 nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete;
497
498 nv50->pipe.create_depth_stencil_alpha_state =
499 nv50_depth_stencil_alpha_state_create;
500 nv50->pipe.bind_depth_stencil_alpha_state =
501 nv50_depth_stencil_alpha_state_bind;
502 nv50->pipe.delete_depth_stencil_alpha_state =
503 nv50_depth_stencil_alpha_state_delete;
504
505 nv50->pipe.create_vs_state = nv50_vp_state_create;
506 nv50->pipe.bind_vs_state = nv50_vp_state_bind;
507 nv50->pipe.delete_vs_state = nv50_vp_state_delete;
508
509 nv50->pipe.create_fs_state = nv50_fp_state_create;
510 nv50->pipe.bind_fs_state = nv50_fp_state_bind;
511 nv50->pipe.delete_fs_state = nv50_fp_state_delete;
512
513 nv50->pipe.set_blend_color = nv50_set_blend_color;
514 nv50->pipe.set_clip_state = nv50_set_clip_state;
515 nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
516 nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
517 nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple;
518 nv50->pipe.set_scissor_state = nv50_set_scissor_state;
519 nv50->pipe.set_viewport_state = nv50_set_viewport_state;
520
521 nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
522 nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
523 }
524