ed2fd3b0f88edf20f2e5e6a868028388b959b8e3
[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 blend_enabled = cso->rt[0].blend_enable;
92
93 so->pipe = *cso;
94
95 SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);
96 if (cso->independent_blend_enable) {
97 for (i = 0; i < 8; ++i) {
98 SB_DATA(so, cso->rt[i].blend_enable);
99 if (cso->rt[i].blend_enable)
100 blend_enabled = TRUE;
101 }
102 } else {
103 for (i = 0; i < 8; ++i)
104 SB_DATA(so, blend_enabled);
105 }
106
107 if (blend_enabled) {
108 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
109 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
110 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));
111 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor));
112 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
113 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor));
114 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
115 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor));
116 }
117
118 if (cso->logicop_enable) {
119 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
120 SB_DATA (so, 1);
121 SB_DATA (so, nvgl_logicop_func(cso->logicop_func));
122 } else {
123 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1);
124 SB_DATA (so, 0);
125 }
126
127 SB_BEGIN_3D(so, COLOR_MASK(0), 8);
128 if (cso->independent_blend_enable) {
129 for (i = 0; i < 8; ++i)
130 SB_DATA(so, nv50_colormask(cso->rt[i].colormask));
131 } else {
132 uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
133 for (i = 0; i < 8; ++i)
134 SB_DATA(so, cmask);
135 }
136
137 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
138 return so;
139 }
140
141 static void
142 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
143 {
144 struct nv50_context *nv50 = nv50_context(pipe);
145
146 nv50->blend = hwcso;
147 nv50->dirty |= NV50_NEW_BLEND;
148 }
149
150 static void
151 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
152 {
153 FREE(hwcso);
154 }
155
156 static void *
157 nv50_rasterizer_state_create(struct pipe_context *pipe,
158 const struct pipe_rasterizer_state *cso)
159 {
160 struct nv50_rasterizer_stateobj *so;
161
162 so = CALLOC_STRUCT(nv50_rasterizer_stateobj);
163 if (!so)
164 return NULL;
165 so->pipe = *cso;
166
167 #ifndef NV50_SCISSORS_CLIPPING
168 SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1);
169 SB_DATA (so, cso->scissor);
170 #endif
171
172 SB_BEGIN_3D(so, SHADE_MODEL, 1);
173 SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT :
174 NV50_3D_SHADE_MODEL_SMOOTH);
175 SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1);
176 SB_DATA (so, !cso->flatshade_first);
177 SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);
178 SB_DATA (so, cso->light_twoside);
179
180 SB_BEGIN_3D(so, LINE_WIDTH, 1);
181 SB_DATA (so, fui(cso->line_width));
182 SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);
183 SB_DATA (so, cso->line_smooth);
184
185 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
186 if (cso->line_stipple_enable) {
187 SB_DATA (so, 1);
188 SB_BEGIN_3D(so, LINE_STIPPLE, 1);
189 SB_DATA (so, (cso->line_stipple_pattern << 8) |
190 cso->line_stipple_factor);
191 } else {
192 SB_DATA (so, 0);
193 }
194
195 if (!cso->point_size_per_vertex) {
196 SB_BEGIN_3D(so, POINT_SIZE, 1);
197 SB_DATA (so, fui(cso->point_size));
198 }
199 SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1);
200 SB_DATA (so, cso->point_quad_rasterization);
201 SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1);
202 SB_DATA (so, cso->point_smooth);
203
204 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3);
205 SB_DATA (so, nvgl_polygon_mode(cso->fill_front));
206 SB_DATA (so, nvgl_polygon_mode(cso->fill_back));
207 SB_DATA (so, cso->poly_smooth);
208
209 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
210 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);
211 SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW :
212 NV50_3D_FRONT_FACE_CW);
213 switch (cso->cull_face) {
214 case PIPE_FACE_FRONT_AND_BACK:
215 SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK);
216 break;
217 case PIPE_FACE_FRONT:
218 SB_DATA(so, NV50_3D_CULL_FACE_FRONT);
219 break;
220 case PIPE_FACE_BACK:
221 default:
222 SB_DATA(so, NV50_3D_CULL_FACE_BACK);
223 break;
224 }
225
226 SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1);
227 SB_DATA (so, cso->poly_stipple_enable);
228 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
229 SB_DATA (so, cso->offset_point);
230 SB_DATA (so, cso->offset_line);
231 SB_DATA (so, cso->offset_tri);
232
233 if (cso->offset_point || cso->offset_line || cso->offset_tri) {
234 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
235 SB_DATA (so, fui(cso->offset_scale));
236 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
237 SB_DATA (so, fui(cso->offset_units)); /* XXX: multiply by 2 ? */
238 }
239
240 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
241 return (void *)so;
242 }
243
244 static void
245 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
246 {
247 struct nv50_context *nv50 = nv50_context(pipe);
248
249 nv50->rast = hwcso;
250 nv50->dirty |= NV50_NEW_RASTERIZER;
251 }
252
253 static void
254 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
255 {
256 FREE(hwcso);
257 }
258
259 static void *
260 nv50_zsa_state_create(struct pipe_context *pipe,
261 const struct pipe_depth_stencil_alpha_state *cso)
262 {
263 struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj);
264
265 so->pipe = *cso;
266
267 SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1);
268 SB_DATA (so, cso->depth.writemask);
269 SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
270 if (cso->depth.enabled) {
271 SB_DATA (so, 1);
272 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
273 SB_DATA (so, nvgl_comparison_op(cso->depth.func));
274 } else {
275 SB_DATA (so, 0);
276 }
277
278 if (cso->stencil[0].enabled) {
279 SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
280 SB_DATA (so, 1);
281 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));
282 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
283 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
284 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));
285 SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);
286 SB_DATA (so, cso->stencil[0].writemask);
287 SB_DATA (so, cso->stencil[0].valuemask);
288 } else {
289 SB_BEGIN_3D(so, STENCIL_ENABLE, 1);
290 SB_DATA (so, 0);
291 }
292
293 if (cso->stencil[1].enabled) {
294 assert(cso->stencil[0].enabled);
295 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
296 SB_DATA (so, 1);
297 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));
298 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
299 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
300 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));
301 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
302 SB_DATA (so, cso->stencil[1].writemask);
303 SB_DATA (so, cso->stencil[1].valuemask);
304 } else {
305 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1);
306 SB_DATA (so, 0);
307 }
308
309 SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
310 if (cso->alpha.enabled) {
311 SB_DATA (so, 1);
312 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
313 SB_DATA (so, fui(cso->alpha.ref_value));
314 SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
315 } else {
316 SB_DATA (so, 0);
317 }
318
319 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
320 return (void *)so;
321 }
322
323 static void
324 nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
325 {
326 struct nv50_context *nv50 = nv50_context(pipe);
327
328 nv50->zsa = hwcso;
329 nv50->dirty |= NV50_NEW_ZSA;
330 }
331
332 static void
333 nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
334 {
335 FREE(hwcso);
336 }
337
338 /* ====================== SAMPLERS AND TEXTURES ================================
339 */
340
341 #define NV50_TSC_WRAP_CASE(n) \
342 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
343
344 static INLINE unsigned
345 nv50_tsc_wrap_mode(unsigned wrap)
346 {
347 switch (wrap) {
348 NV50_TSC_WRAP_CASE(REPEAT);
349 NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
350 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
351 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
352 NV50_TSC_WRAP_CASE(CLAMP);
353 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
354 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
355 NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
356 default:
357 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
358 return NV50_TSC_WRAP_REPEAT;
359 }
360 }
361
362 static void *
363 nv50_sampler_state_create(struct pipe_context *pipe,
364 const struct pipe_sampler_state *cso)
365 {
366 struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry);
367 float f[2];
368
369 so->id = -1;
370
371 so->tsc[0] = (0x00026000 |
372 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
373 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
374 (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
375
376 switch (cso->mag_img_filter) {
377 case PIPE_TEX_FILTER_LINEAR:
378 so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
379 break;
380 case PIPE_TEX_FILTER_NEAREST:
381 default:
382 so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
383 break;
384 }
385
386 switch (cso->min_img_filter) {
387 case PIPE_TEX_FILTER_LINEAR:
388 so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
389 break;
390 case PIPE_TEX_FILTER_NEAREST:
391 default:
392 so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
393 break;
394 }
395
396 switch (cso->min_mip_filter) {
397 case PIPE_TEX_MIPFILTER_LINEAR:
398 so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
399 break;
400 case PIPE_TEX_MIPFILTER_NEAREST:
401 so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
402 break;
403 case PIPE_TEX_MIPFILTER_NONE:
404 default:
405 so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
406 break;
407 }
408
409 if (cso->max_anisotropy >= 16)
410 so->tsc[0] |= (7 << 20);
411 else
412 if (cso->max_anisotropy >= 12)
413 so->tsc[0] |= (6 << 20);
414 else {
415 so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
416
417 if (cso->max_anisotropy >= 4)
418 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
419 else
420 if (cso->max_anisotropy >= 2)
421 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
422 }
423
424 if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
425 /* NOTE: must be deactivated for non-shadow textures */
426 so->tsc[0] |= (1 << 9);
427 so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
428 }
429
430 f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
431 so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
432
433 f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
434 f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
435 so->tsc[2] |=
436 (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
437
438 so->tsc[4] = fui(cso->border_color[0]);
439 so->tsc[5] = fui(cso->border_color[1]);
440 so->tsc[6] = fui(cso->border_color[2]);
441 so->tsc[7] = fui(cso->border_color[3]);
442
443 return (void *)so;
444 }
445
446 static void
447 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
448 {
449 unsigned s, i;
450
451 for (s = 0; s < 5; ++s)
452 for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)
453 if (nv50_context(pipe)->samplers[s][i] == hwcso)
454 nv50_context(pipe)->samplers[s][i] = NULL;
455
456 nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso));
457
458 FREE(hwcso);
459 }
460
461 static INLINE void
462 nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,
463 unsigned nr, void **hwcso)
464 {
465 unsigned i;
466
467 for (i = 0; i < nr; ++i) {
468 struct nv50_tsc_entry *old = nv50->samplers[s][i];
469
470 nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
471 if (old)
472 nv50_screen_tsc_unlock(nv50->screen, old);
473 }
474 for (; i < nv50->num_samplers[s]; ++i)
475 if (nv50->samplers[s][i])
476 nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]);
477
478 nv50->num_samplers[s] = nr;
479
480 nv50->dirty |= NV50_NEW_SAMPLERS;
481 }
482
483 static void
484 nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
485 {
486 nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s);
487 }
488
489 static void
490 nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
491 {
492 nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s);
493 }
494
495 static void
496 nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
497 {
498 nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s);
499 }
500
501 /* NOTE: only called when not referenced anywhere, won't be bound */
502 static void
503 nv50_sampler_view_destroy(struct pipe_context *pipe,
504 struct pipe_sampler_view *view)
505 {
506 pipe_resource_reference(&view->texture, NULL);
507
508 nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));
509
510 FREE(nv50_tic_entry(view));
511 }
512
513 static INLINE void
514 nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
515 unsigned nr,
516 struct pipe_sampler_view **views)
517 {
518 unsigned i;
519
520 for (i = 0; i < nr; ++i) {
521 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
522 if (old)
523 nv50_screen_tic_unlock(nv50->screen, old);
524
525 pipe_sampler_view_reference(&nv50->textures[s][i], views[i]);
526 }
527
528 for (i = nr; i < nv50->num_textures[s]; ++i) {
529 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);
530 if (!old)
531 continue;
532 nv50_screen_tic_unlock(nv50->screen, old);
533
534 pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
535 }
536
537 nv50->num_textures[s] = nr;
538
539 nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
540
541 nv50->dirty |= NV50_NEW_TEXTURES;
542 }
543
544 static void
545 nv50_vp_set_sampler_views(struct pipe_context *pipe,
546 unsigned nr,
547 struct pipe_sampler_view **views)
548 {
549 nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views);
550 }
551
552 static void
553 nv50_fp_set_sampler_views(struct pipe_context *pipe,
554 unsigned nr,
555 struct pipe_sampler_view **views)
556 {
557 nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views);
558 }
559
560 static void
561 nv50_gp_set_sampler_views(struct pipe_context *pipe,
562 unsigned nr,
563 struct pipe_sampler_view **views)
564 {
565 nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views);
566 }
567
568 /* ============================= SHADERS =======================================
569 */
570
571 static void *
572 nv50_sp_state_create(struct pipe_context *pipe,
573 const struct pipe_shader_state *cso, unsigned type)
574 {
575 struct nv50_program *prog;
576
577 prog = CALLOC_STRUCT(nv50_program);
578 if (!prog)
579 return NULL;
580
581 prog->type = type;
582 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
583
584 return (void *)prog;
585 }
586
587 static void
588 nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
589 {
590 struct nv50_program *prog = (struct nv50_program *)hwcso;
591
592 nv50_program_destroy(nv50_context(pipe), prog);
593
594 FREE((void *)prog->pipe.tokens);
595 FREE(prog);
596 }
597
598 static void *
599 nv50_vp_state_create(struct pipe_context *pipe,
600 const struct pipe_shader_state *cso)
601 {
602 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
603 }
604
605 static void
606 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
607 {
608 struct nv50_context *nv50 = nv50_context(pipe);
609
610 nv50->vertprog = hwcso;
611 nv50->dirty |= NV50_NEW_VERTPROG;
612 }
613
614 static void *
615 nv50_fp_state_create(struct pipe_context *pipe,
616 const struct pipe_shader_state *cso)
617 {
618 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
619 }
620
621 static void
622 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
623 {
624 struct nv50_context *nv50 = nv50_context(pipe);
625
626 nv50->fragprog = hwcso;
627 nv50->dirty |= NV50_NEW_FRAGPROG;
628 }
629
630 static void *
631 nv50_gp_state_create(struct pipe_context *pipe,
632 const struct pipe_shader_state *cso)
633 {
634 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
635 }
636
637 static void
638 nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
639 {
640 struct nv50_context *nv50 = nv50_context(pipe);
641
642 nv50->gmtyprog = hwcso;
643 nv50->dirty |= NV50_NEW_GMTYPROG;
644 }
645
646 static void
647 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
648 struct pipe_resource *res)
649 {
650 struct nv50_context *nv50 = nv50_context(pipe);
651
652 if (nv50->constbuf[shader][index])
653 nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
654 nv04_resource(nv50->constbuf[shader][index]));
655
656 pipe_resource_reference(&nv50->constbuf[shader][index], res);
657
658 nv50->constbuf_dirty[shader] |= 1 << index;
659
660 nv50->dirty |= NV50_NEW_CONSTBUF;
661 }
662
663 /* =============================================================================
664 */
665
666 static void
667 nv50_set_blend_color(struct pipe_context *pipe,
668 const struct pipe_blend_color *bcol)
669 {
670 struct nv50_context *nv50 = nv50_context(pipe);
671
672 nv50->blend_colour = *bcol;
673 nv50->dirty |= NV50_NEW_BLEND_COLOUR;
674 }
675
676 static void
677 nv50_set_stencil_ref(struct pipe_context *pipe,
678 const struct pipe_stencil_ref *sr)
679 {
680 struct nv50_context *nv50 = nv50_context(pipe);
681
682 nv50->stencil_ref = *sr;
683 nv50->dirty |= NV50_NEW_STENCIL_REF;
684 }
685
686 static void
687 nv50_set_clip_state(struct pipe_context *pipe,
688 const struct pipe_clip_state *clip)
689 {
690 struct nv50_context *nv50 = nv50_context(pipe);
691 const unsigned size = clip->nr * sizeof(clip->ucp[0]);
692
693 memcpy(&nv50->clip.ucp[0][0], &clip->ucp[0][0], size);
694 nv50->clip.nr = clip->nr;
695
696 nv50->clip.depth_clamp = clip->depth_clamp;
697
698 nv50->dirty |= NV50_NEW_CLIP;
699 }
700
701 static void
702 nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
703 {
704 struct nv50_context *nv50 = nv50_context(pipe);
705
706 nv50->sample_mask = sample_mask;
707 nv50->dirty |= NV50_NEW_SAMPLE_MASK;
708 }
709
710
711 static void
712 nv50_set_framebuffer_state(struct pipe_context *pipe,
713 const struct pipe_framebuffer_state *fb)
714 {
715 struct nv50_context *nv50 = nv50_context(pipe);
716
717 nv50->framebuffer = *fb;
718 nv50->dirty |= NV50_NEW_FRAMEBUFFER;
719 }
720
721 static void
722 nv50_set_polygon_stipple(struct pipe_context *pipe,
723 const struct pipe_poly_stipple *stipple)
724 {
725 struct nv50_context *nv50 = nv50_context(pipe);
726
727 nv50->stipple = *stipple;
728 nv50->dirty |= NV50_NEW_STIPPLE;
729 }
730
731 static void
732 nv50_set_scissor_state(struct pipe_context *pipe,
733 const struct pipe_scissor_state *scissor)
734 {
735 struct nv50_context *nv50 = nv50_context(pipe);
736
737 nv50->scissor = *scissor;
738 nv50->dirty |= NV50_NEW_SCISSOR;
739 }
740
741 static void
742 nv50_set_viewport_state(struct pipe_context *pipe,
743 const struct pipe_viewport_state *vpt)
744 {
745 struct nv50_context *nv50 = nv50_context(pipe);
746
747 nv50->viewport = *vpt;
748 nv50->dirty |= NV50_NEW_VIEWPORT;
749 }
750
751 static void
752 nv50_set_vertex_buffers(struct pipe_context *pipe,
753 unsigned count,
754 const struct pipe_vertex_buffer *vb)
755 {
756 struct nv50_context *nv50 = nv50_context(pipe);
757 unsigned i;
758
759 for (i = 0; i < count; ++i)
760 pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer);
761 for (; i < nv50->num_vtxbufs; ++i)
762 pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
763
764 memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
765 nv50->num_vtxbufs = count;
766
767 nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
768
769 nv50->dirty |= NV50_NEW_ARRAYS;
770 }
771
772 static void
773 nv50_set_index_buffer(struct pipe_context *pipe,
774 const struct pipe_index_buffer *ib)
775 {
776 struct nv50_context *nv50 = nv50_context(pipe);
777
778 if (ib)
779 memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
780 else
781 nv50->idxbuf.buffer = NULL;
782 }
783
784 static void
785 nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
786 {
787 struct nv50_context *nv50 = nv50_context(pipe);
788
789 nv50->vertex = hwcso;
790 nv50->dirty |= NV50_NEW_VERTEX;
791 }
792
793 void
794 nv50_init_state_functions(struct nv50_context *nv50)
795 {
796 nv50->pipe.create_blend_state = nv50_blend_state_create;
797 nv50->pipe.bind_blend_state = nv50_blend_state_bind;
798 nv50->pipe.delete_blend_state = nv50_blend_state_delete;
799
800 nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
801 nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
802 nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete;
803
804 nv50->pipe.create_depth_stencil_alpha_state = nv50_zsa_state_create;
805 nv50->pipe.bind_depth_stencil_alpha_state = nv50_zsa_state_bind;
806 nv50->pipe.delete_depth_stencil_alpha_state = nv50_zsa_state_delete;
807
808 nv50->pipe.create_sampler_state = nv50_sampler_state_create;
809 nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
810 nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_states_bind;
811 nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_states_bind;
812 nv50->pipe.bind_geometry_sampler_states = nv50_gp_sampler_states_bind;
813
814 nv50->pipe.create_sampler_view = nv50_create_sampler_view;
815 nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;
816 nv50->pipe.set_vertex_sampler_views = nv50_vp_set_sampler_views;
817 nv50->pipe.set_fragment_sampler_views = nv50_fp_set_sampler_views;
818 nv50->pipe.set_geometry_sampler_views = nv50_gp_set_sampler_views;
819
820 nv50->pipe.create_vs_state = nv50_vp_state_create;
821 nv50->pipe.create_fs_state = nv50_fp_state_create;
822 nv50->pipe.create_gs_state = nv50_gp_state_create;
823 nv50->pipe.bind_vs_state = nv50_vp_state_bind;
824 nv50->pipe.bind_fs_state = nv50_fp_state_bind;
825 nv50->pipe.bind_gs_state = nv50_gp_state_bind;
826 nv50->pipe.delete_vs_state = nv50_sp_state_delete;
827 nv50->pipe.delete_fs_state = nv50_sp_state_delete;
828 nv50->pipe.delete_gs_state = nv50_sp_state_delete;
829
830 nv50->pipe.set_blend_color = nv50_set_blend_color;
831 nv50->pipe.set_stencil_ref = nv50_set_stencil_ref;
832 nv50->pipe.set_clip_state = nv50_set_clip_state;
833 nv50->pipe.set_sample_mask = nv50_set_sample_mask;
834 nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
835 nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
836 nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple;
837 nv50->pipe.set_scissor_state = nv50_set_scissor_state;
838 nv50->pipe.set_viewport_state = nv50_set_viewport_state;
839
840 nv50->pipe.create_vertex_elements_state = nv50_vertex_state_create;
841 nv50->pipe.delete_vertex_elements_state = nv50_vertex_state_delete;
842 nv50->pipe.bind_vertex_elements_state = nv50_vertex_state_bind;
843
844 nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
845 nv50->pipe.set_index_buffer = nv50_set_index_buffer;
846 }
847