3c497451d8bbe50cc623955c7b70a4272571aba4
[mesa.git] / src / gallium / drivers / nv50 / nv50_state.c
1 /*
2 * Copyright 2010 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #include "pipe/p_defines.h"
24 #include "util/u_inlines.h"
25 #include "util/u_transfer.h"
26
27 #include "tgsi/tgsi_parse.h"
28
29 #include "nv50_stateobj.h"
30 #include "nv50_context.h"
31
32 #include "nv50_3d.xml.h"
33 #include "nv50_texture.xml.h"
34
35 #include "nouveau/nouveau_gldefs.h"
36
37 static INLINE uint32_t
38 nv50_colormask(unsigned mask)
39 {
40 uint32_t ret = 0;
41
42 if (mask & PIPE_MASK_R)
43 ret |= 0x0001;
44 if (mask & PIPE_MASK_G)
45 ret |= 0x0010;
46 if (mask & PIPE_MASK_B)
47 ret |= 0x0100;
48 if (mask & PIPE_MASK_A)
49 ret |= 0x1000;
50
51 return ret;
52 }
53
54 #define NV50_BLEND_FACTOR_CASE(a, b) \
55 case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b
56
57 static INLINE uint32_t
58 nv50_blend_fac(unsigned factor)
59 {
60 switch (factor) {
61 NV50_BLEND_FACTOR_CASE(ONE, ONE);
62 NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);
63 NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);
64 NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);
65 NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);
66 NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);
67 NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);
68 NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);
69 NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);
70 NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);
71 NV50_BLEND_FACTOR_CASE(ZERO, ZERO);
72 NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);
73 NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
74 NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);
75 NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);
76 NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);
77 NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);
78 NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);
79 NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA);
80 default:
81 return NV50_3D_BLEND_FACTOR_ZERO;
82 }
83 }
84
85 static void *
86 nv50_blend_state_create(struct pipe_context *pipe,
87 const struct pipe_blend_state *cso)
88 {
89 struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);
90 int i;
91 boolean emit_common_func = cso->rt[0].blend_enable;
92
93 if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
94 SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
95 SB_DATA (so, cso->independent_blend_enable);
96 }
97
98 so->pipe = *cso;
99
100 SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
101 if (cso->independent_blend_enable) {
102 for (i = 0; i < 8; ++i) {
103 SB_DATA(so, cso->rt[i].blend_enable);
104 if (cso->rt[i].blend_enable)
105 emit_common_func = TRUE;
106 }
107
108 if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
109 emit_common_func = FALSE;
110
111 for (i = 0; i < 8; ++i) {
112 if (!cso->rt[i].blend_enable)
113 continue;
114 SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);
115 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
116 SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));
117 SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));
118 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
119 SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));
120 SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));
121 }
122 }
123 } else {
124 for (i = 0; i < 8; ++i)
125 SB_DATA(so, cso->rt[0].blend_enable);
126 }
127
128 if (emit_common_func) {
129 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
130 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
131 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
132 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor));
133 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
134 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor));
135 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
136 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor));
137 }
138
139 if (cso->logicop_enable) {
140 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
141 SB_DATA (so, 1);
142 SB_DATA (so, nvgl_logicop_func(cso->logicop_func));
143 } else {
144 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1);
145 SB_DATA (so, 0);
146 }
147
148 SB_BEGIN_3D(so, COLOR_MASK(0), 8);
149 if (cso->independent_blend_enable) {
150 for (i = 0; i < 8; ++i)
151 SB_DATA(so, nv50_colormask(cso->rt[i].colormask));
152 } else {
153 uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
154 for (i = 0; i < 8; ++i)
155 SB_DATA(so, cmask);
156 }
157
158 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
159 return so;
160 }
161
162 static void
163 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
164 {
165 struct nv50_context *nv50 = nv50_context(pipe);
166
167 nv50->blend = hwcso;
168 nv50->dirty |= NV50_NEW_BLEND;
169 }
170
171 static void
172 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
173 {
174 FREE(hwcso);
175 }
176
177 static void *
178 nv50_rasterizer_state_create(struct pipe_context *pipe,
179 const struct pipe_rasterizer_state *cso)
180 {
181 struct nv50_rasterizer_stateobj *so;
182
183 so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
184 if (!so)
185 return NULL;
186 so->pipe = *cso;
187
188 #ifndef NV50_SCISSORS_CLIPPING
189 SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1);
190 SB_DATA (so, cso->scissor);
191 #endif
192
193 SB_BEGIN_3D(so, SHADE_MODEL, 1);
194 SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT :
195 NV50_3D_SHADE_MODEL_SMOOTH);
196 SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1);
197 SB_DATA (so, !cso->flatshade_first);
198 SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);
199 SB_DATA (so, cso->light_twoside);
200
201 SB_BEGIN_3D(so, LINE_WIDTH, 1);
202 SB_DATA (so, fui(cso->line_width));
203 SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);
204 SB_DATA (so, cso->line_smooth);
205
206 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
207 if (cso->line_stipple_enable) {
208 SB_DATA (so, 1);
209 SB_BEGIN_3D(so, LINE_STIPPLE, 1);
210 SB_DATA (so, (cso->line_stipple_pattern << 8) |
211 cso->line_stipple_factor);
212 } else {
213 SB_DATA (so, 0);
214 }
215
216 if (!cso->point_size_per_vertex) {
217 SB_BEGIN_3D(so, POINT_SIZE, 1);
218 SB_DATA (so, fui(cso->point_size));
219 }
220 SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1);
221 SB_DATA (so, cso->point_quad_rasterization);
222 SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1);
223 SB_DATA (so, cso->point_smooth);
224
225 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3);
226 SB_DATA (so, nvgl_polygon_mode(cso->fill_front));
227 SB_DATA (so, nvgl_polygon_mode(cso->fill_back));
228 SB_DATA (so, cso->poly_smooth);
229
230 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
231 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);
232 SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW :
233 NV50_3D_FRONT_FACE_CW);
234 switch (cso->cull_face) {
235 case PIPE_FACE_FRONT_AND_BACK:
236 SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK);
237 break;
238 case PIPE_FACE_FRONT:
239 SB_DATA(so, NV50_3D_CULL_FACE_FRONT);
240 break;
241 case PIPE_FACE_BACK:
242 default:
243 SB_DATA(so, NV50_3D_CULL_FACE_BACK);
244 break;
245 }
246
247 SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1);
248 SB_DATA (so, cso->poly_stipple_enable);
249 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
250 SB_DATA (so, cso->offset_point);
251 SB_DATA (so, cso->offset_line);
252 SB_DATA (so, cso->offset_tri);
253
254 if (cso->offset_point || cso->offset_line || cso->offset_tri) {
255 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
256 SB_DATA (so, fui(cso->offset_scale));
257 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
258 SB_DATA (so, fui(cso->offset_units * 2.0f));
259 }
260
261 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
262 return (void *)so;
263 }
264
265 static void
266 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
267 {
268 struct nv50_context *nv50 = nv50_context(pipe);
269
270 nv50->rast = hwcso;
271 nv50->dirty |= NV50_NEW_RASTERIZER;
272 }
273
274 static void
275 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
276 {
277 FREE(hwcso);
278 }
279
280 static void *
281 nv50_zsa_state_create(struct pipe_context *pipe,
282 const struct pipe_depth_stencil_alpha_state *cso)
283 {
284 struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj);
285
286 so->pipe = *cso;
287
288 SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1);
289 SB_DATA (so, cso->depth.writemask);
290 SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
291 if (cso->depth.enabled) {
292 SB_DATA (so, 1);
293 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
294 SB_DATA (so, nvgl_comparison_op(cso->depth.func));
295 } else {
296 SB_DATA (so, 0);
297 }
298
299 if (cso->stencil[0].enabled) {
300 SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
301 SB_DATA (so, 1);
302 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));
303 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
304 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
305 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));
306 SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);
307 SB_DATA (so, cso->stencil[0].writemask);
308 SB_DATA (so, cso->stencil[0].valuemask);
309 } else {
310 SB_BEGIN_3D(so, STENCIL_ENABLE, 1);
311 SB_DATA (so, 0);
312 }
313
314 if (cso->stencil[1].enabled) {
315 assert(cso->stencil[0].enabled);
316 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
317 SB_DATA (so, 1);
318 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));
319 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
320 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
321 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));
322 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
323 SB_DATA (so, cso->stencil[1].writemask);
324 SB_DATA (so, cso->stencil[1].valuemask);
325 } else {
326 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1);
327 SB_DATA (so, 0);
328 }
329
330 SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
331 if (cso->alpha.enabled) {
332 SB_DATA (so, 1);
333 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
334 SB_DATA (so, fui(cso->alpha.ref_value));
335 SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
336 } else {
337 SB_DATA (so, 0);
338 }
339
340 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
341 return (void *)so;
342 }
343
344 static void
345 nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
346 {
347 struct nv50_context *nv50 = nv50_context(pipe);
348
349 nv50->zsa = hwcso;
350 nv50->dirty |= NV50_NEW_ZSA;
351 }
352
353 static void
354 nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
355 {
356 FREE(hwcso);
357 }
358
359 /* ====================== SAMPLERS AND TEXTURES ================================
360 */
361
362 #define NV50_TSC_WRAP_CASE(n) \
363 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
364
365 static INLINE unsigned
366 nv50_tsc_wrap_mode(unsigned wrap)
367 {
368 switch (wrap) {
369 NV50_TSC_WRAP_CASE(REPEAT);
370 NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
371 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
372 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
373 NV50_TSC_WRAP_CASE(CLAMP);
374 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
375 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
376 NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
377 default:
378 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
379 return NV50_TSC_WRAP_REPEAT;
380 }
381 }
382
383 void *
384 nv50_sampler_state_create(struct pipe_context *pipe,
385 const struct pipe_sampler_state *cso)
386 {
387 struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry);
388 float f[2];
389
390 so->id = -1;
391
392 so->tsc[0] = (0x00026000 |
393 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
394 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
395 (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
396
397 switch (cso->mag_img_filter) {
398 case PIPE_TEX_FILTER_LINEAR:
399 so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
400 break;
401 case PIPE_TEX_FILTER_NEAREST:
402 default:
403 so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
404 break;
405 }
406
407 switch (cso->min_img_filter) {
408 case PIPE_TEX_FILTER_LINEAR:
409 so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
410 break;
411 case PIPE_TEX_FILTER_NEAREST:
412 default:
413 so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
414 break;
415 }
416
417 switch (cso->min_mip_filter) {
418 case PIPE_TEX_MIPFILTER_LINEAR:
419 so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
420 break;
421 case PIPE_TEX_MIPFILTER_NEAREST:
422 so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
423 break;
424 case PIPE_TEX_MIPFILTER_NONE:
425 default:
426 so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
427 break;
428 }
429
430 if (cso->max_anisotropy >= 16)
431 so->tsc[0] |= (7 << 20);
432 else
433 if (cso->max_anisotropy >= 12)
434 so->tsc[0] |= (6 << 20);
435 else {
436 so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
437
438 if (cso->max_anisotropy >= 4)
439 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
440 else
441 if (cso->max_anisotropy >= 2)
442 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
443 }
444
445 if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
446 /* NOTE: must be deactivated for non-shadow textures */
447 so->tsc[0] |= (1 << 9);
448 so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
449 }
450
451 f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
452 so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
453
454 f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
455 f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
456 so->tsc[2] |=
457 (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
458
459 so->tsc[4] = fui(cso->border_color[0]);
460 so->tsc[5] = fui(cso->border_color[1]);
461 so->tsc[6] = fui(cso->border_color[2]);
462 so->tsc[7] = fui(cso->border_color[3]);
463
464 return (void *)so;
465 }
466
467 static void
468 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
469 {
470 unsigned s, i;
471
472 for (s = 0; s < 5; ++s)
473 for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)
474 if (nv50_context(pipe)->samplers[s][i] == hwcso)
475 nv50_context(pipe)->samplers[s][i] = NULL;
476
477 nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso));
478
479 FREE(hwcso);
480 }
481
482 static INLINE void
483 nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,
484 unsigned nr, void **hwcso)
485 {
486 unsigned i;
487
488 for (i = 0; i < nr; ++i) {
489 struct nv50_tsc_entry *old = nv50->samplers[s][i];
490
491 nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
492 if (old)
493 nv50_screen_tsc_unlock(nv50->screen, old);
494 }
495 for (; i < nv50->num_samplers[s]; ++i)
496 if (nv50->samplers[s][i])
497 nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]);
498
499 nv50->num_samplers[s] = nr;
500
501 nv50->dirty |= NV50_NEW_SAMPLERS;
502 }
503
504 static void
505 nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
506 {
507 nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s);
508 }
509
510 static void
511 nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
512 {
513 nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s);
514 }
515
516 static void
517 nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
518 {
519 nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s);
520 }
521
522 /* NOTE: only called when not referenced anywhere, won't be bound */
523 static void
524 nv50_sampler_view_destroy(struct pipe_context *pipe,
525 struct pipe_sampler_view *view)
526 {
527 pipe_resource_reference(&view->texture, NULL);
528
529 nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));
530
531 FREE(nv50_tic_entry(view));
532 }
533
534 static INLINE void
535 nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
536 unsigned nr,
537 struct pipe_sampler_view **views)
538 {
539 unsigned i;
540
541 for (i = 0; i < nr; ++i) {
542 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
543 if (old)
544 nv50_screen_tic_unlock(nv50->screen, old);
545
546 pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
547 }
548
549 for (i = nr; i < nv50->num_textures[s]; ++i) {
550 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
551 if (!old)
552 continue;
553 nv50_screen_tic_unlock(nv50->screen, old);
554
555 pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
556 }
557
558 nv50->num_textures[s] = nr;
559
560 nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
561
562 nv50->dirty |= NV50_NEW_TEXTURES;
563 }
564
565 static void
566 nv50_vp_set_sampler_views(struct pipe_context *pipe,
567 unsigned nr,
568 struct pipe_sampler_view **views)
569 {
570 nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views);
571 }
572
573 static void
574 nv50_fp_set_sampler_views(struct pipe_context *pipe,
575 unsigned nr,
576 struct pipe_sampler_view **views)
577 {
578 nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views);
579 }
580
581 static void
582 nv50_gp_set_sampler_views(struct pipe_context *pipe,
583 unsigned nr,
584 struct pipe_sampler_view **views)
585 {
586 nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views);
587 }
588
589 /* ============================= SHADERS =======================================
590 */
591
592 static void *
593 nv50_sp_state_create(struct pipe_context *pipe,
594 const struct pipe_shader_state *cso, unsigned type)
595 {
596 struct nv50_program *prog;
597
598 prog = CALLOC_STRUCT(nv50_program);
599 if (!prog)
600 return NULL;
601
602 prog->type = type;
603 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
604
605 return (void *)prog;
606 }
607
608 static void
609 nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
610 {
611 struct nv50_program *prog = (struct nv50_program *)hwcso;
612
613 nv50_program_destroy(nv50_context(pipe), prog);
614
615 FREE((void *)prog->pipe.tokens);
616 FREE(prog);
617 }
618
619 static void *
620 nv50_vp_state_create(struct pipe_context *pipe,
621 const struct pipe_shader_state *cso)
622 {
623 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
624 }
625
626 static void
627 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
628 {
629 struct nv50_context *nv50 = nv50_context(pipe);
630
631 nv50->vertprog = hwcso;
632 nv50->dirty |= NV50_NEW_VERTPROG;
633 }
634
635 static void *
636 nv50_fp_state_create(struct pipe_context *pipe,
637 const struct pipe_shader_state *cso)
638 {
639 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
640 }
641
642 static void
643 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
644 {
645 struct nv50_context *nv50 = nv50_context(pipe);
646
647 nv50->fragprog = hwcso;
648 nv50->dirty |= NV50_NEW_FRAGPROG;
649 }
650
651 static void *
652 nv50_gp_state_create(struct pipe_context *pipe,
653 const struct pipe_shader_state *cso)
654 {
655 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
656 }
657
658 static void
659 nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
660 {
661 struct nv50_context *nv50 = nv50_context(pipe);
662
663 nv50->gmtyprog = hwcso;
664 nv50->dirty |= NV50_NEW_GMTYPROG;
665 }
666
667 static void
668 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
669 struct pipe_resource *res)
670 {
671 struct nv50_context *nv50 = nv50_context(pipe);
672
673 if (nv50->constbuf[shader][index])
674 nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
675 nv04_resource(nv50->constbuf[shader][index]));
676
677 pipe_resource_reference(&nv50->constbuf[shader][index], res);
678
679 nv50->constbuf_dirty[shader] |= 1 << index;
680
681 nv50->dirty |= NV50_NEW_CONSTBUF;
682 }
683
684 /* =============================================================================
685 */
686
687 static void
688 nv50_set_blend_color(struct pipe_context *pipe,
689 const struct pipe_blend_color *bcol)
690 {
691 struct nv50_context *nv50 = nv50_context(pipe);
692
693 nv50->blend_colour = *bcol;
694 nv50->dirty |= NV50_NEW_BLEND_COLOUR;
695 }
696
697 static void
698 nv50_set_stencil_ref(struct pipe_context *pipe,
699 const struct pipe_stencil_ref *sr)
700 {
701 struct nv50_context *nv50 = nv50_context(pipe);
702
703 nv50->stencil_ref = *sr;
704 nv50->dirty |= NV50_NEW_STENCIL_REF;
705 }
706
707 static void
708 nv50_set_clip_state(struct pipe_context *pipe,
709 const struct pipe_clip_state *clip)
710 {
711 struct nv50_context *nv50 = nv50_context(pipe);
712 const unsigned size = clip->nr * sizeof(clip->ucp[0]);
713
714 memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size);
715 nv50->clip.nr = clip->nr;
716
717 nv50->clip.depth_clamp = clip->depth_clamp;
718
719 nv50->dirty |= NV50_NEW_CLIP;
720 }
721
722 static void
723 nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
724 {
725 struct nv50_context *nv50 = nv50_context(pipe);
726
727 nv50->sample_mask = sample_mask;
728 nv50->dirty |= NV50_NEW_SAMPLE_MASK;
729 }
730
731
732 static void
733 nv50_set_framebuffer_state(struct pipe_context *pipe,
734 const struct pipe_framebuffer_state *fb)
735 {
736 struct nv50_context *nv50 = nv50_context(pipe);
737
738 nv50->framebuffer = *fb;
739 nv50->dirty |= NV50_NEW_FRAMEBUFFER;
740 }
741
742 static void
743 nv50_set_polygon_stipple(struct pipe_context *pipe,
744 const struct pipe_poly_stipple *stipple)
745 {
746 struct nv50_context *nv50 = nv50_context(pipe);
747
748 nv50->stipple = *stipple;
749 nv50->dirty |= NV50_NEW_STIPPLE;
750 }
751
752 static void
753 nv50_set_scissor_state(struct pipe_context *pipe,
754 const struct pipe_scissor_state *scissor)
755 {
756 struct nv50_context *nv50 = nv50_context(pipe);
757
758 nv50->scissor = *scissor;
759 nv50->dirty |= NV50_NEW_SCISSOR;
760 }
761
762 static void
763 nv50_set_viewport_state(struct pipe_context *pipe,
764 const struct pipe_viewport_state *vpt)
765 {
766 struct nv50_context *nv50 = nv50_context(pipe);
767
768 nv50->viewport = *vpt;
769 nv50->dirty |= NV50_NEW_VIEWPORT;
770 }
771
772 static void
773 nv50_set_vertex_buffers(struct pipe_context *pipe,
774 unsigned count,
775 const struct pipe_vertex_buffer *vb)
776 {
777 struct nv50_context *nv50 = nv50_context(pipe);
778 unsigned i;
779
780 for (i = 0; i < count; ++i)
781 pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer);
782 for (; i < nv50->num_vtxbufs; ++i)
783 pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
784
785 memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
786 nv50->num_vtxbufs = count;
787
788 nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
789
790 nv50->dirty |= NV50_NEW_ARRAYS;
791 }
792
793 static void
794 nv50_set_index_buffer(struct pipe_context *pipe,
795 const struct pipe_index_buffer *ib)
796 {
797 struct nv50_context *nv50 = nv50_context(pipe);
798
799 if (ib)
800 memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
801 else
802 nv50->idxbuf.buffer = NULL;
803 }
804
805 static void
806 nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
807 {
808 struct nv50_context *nv50 = nv50_context(pipe);
809
810 nv50->vertex = hwcso;
811 nv50->dirty |= NV50_NEW_VERTEX;
812 }
813
814 void
815 nv50_init_state_functions(struct nv50_context *nv50)
816 {
817 struct pipe_context *pipe = &nv50->base.pipe;
818
819 pipe->create_blend_state = nv50_blend_state_create;
820 pipe->bind_blend_state = nv50_blend_state_bind;
821 pipe->delete_blend_state = nv50_blend_state_delete;
822
823 pipe->create_rasterizer_state = nv50_rasterizer_state_create;
824 pipe->bind_rasterizer_state = nv50_rasterizer_state_bind;
825 pipe->delete_rasterizer_state = nv50_rasterizer_state_delete;
826
827 pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create;
828 pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind;
829 pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete;
830
831 pipe->create_sampler_state = nv50_sampler_state_create;
832 pipe->delete_sampler_state = nv50_sampler_state_delete;
833 pipe->bind_vertex_sampler_states = nv50_vp_sampler_states_bind;
834 pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind;
835 pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind;
836
837 pipe->create_sampler_view = nv50_create_sampler_view;
838 pipe->sampler_view_destroy = nv50_sampler_view_destroy;
839 pipe->set_vertex_sampler_views = nv50_vp_set_sampler_views;
840 pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views;
841 pipe->set_geometry_sampler_views = nv50_gp_set_sampler_views;
842
843 pipe->create_vs_state = nv50_vp_state_create;
844 pipe->create_fs_state = nv50_fp_state_create;
845 pipe->create_gs_state = nv50_gp_state_create;
846 pipe->bind_vs_state = nv50_vp_state_bind;
847 pipe->bind_fs_state = nv50_fp_state_bind;
848 pipe->bind_gs_state = nv50_gp_state_bind;
849 pipe->delete_vs_state = nv50_sp_state_delete;
850 pipe->delete_fs_state = nv50_sp_state_delete;
851 pipe->delete_gs_state = nv50_sp_state_delete;
852
853 pipe->set_blend_color = nv50_set_blend_color;
854 pipe->set_stencil_ref = nv50_set_stencil_ref;
855 pipe->set_clip_state = nv50_set_clip_state;
856 pipe->set_sample_mask = nv50_set_sample_mask;
857 pipe->set_constant_buffer = nv50_set_constant_buffer;
858 pipe->set_framebuffer_state = nv50_set_framebuffer_state;
859 pipe->set_polygon_stipple = nv50_set_polygon_stipple;
860 pipe->set_scissor_state = nv50_set_scissor_state;
861 pipe->set_viewport_state = nv50_set_viewport_state;
862
863 pipe->create_vertex_elements_state = nv50_vertex_state_create;
864 pipe->delete_vertex_elements_state = nv50_vertex_state_delete;
865 pipe->bind_vertex_elements_state = nv50_vertex_state_bind;
866
867 pipe->set_vertex_buffers = nv50_set_vertex_buffers;
868 pipe->set_index_buffer = nv50_set_index_buffer;
869
870 pipe->redefine_user_buffer = u_default_redefine_user_buffer;
871 }
872