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