Merge remote branch 'origin/master' into pipe-video
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_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 "nvc0_stateobj.h"
30 #include "nvc0_context.h"
31
32 #include "nvc0_3d.xml.h"
33 #include "nv50_texture.xml.h"
34
35 #include "nouveau/nouveau_gldefs.h"
36
37 static INLINE uint32_t
38 nvc0_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 NVC0_BLEND_FACTOR_CASE(a, b) \
55 case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b
56
57 static INLINE uint32_t
58 nvc0_blend_fac(unsigned factor)
59 {
60 switch (factor) {
61 NVC0_BLEND_FACTOR_CASE(ONE, ONE);
62 NVC0_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);
63 NVC0_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);
64 NVC0_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);
65 NVC0_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);
66 NVC0_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);
67 NVC0_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);
68 NVC0_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);
69 NVC0_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);
70 NVC0_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);
71 NVC0_BLEND_FACTOR_CASE(ZERO, ZERO);
72 NVC0_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);
73 NVC0_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
74 NVC0_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);
75 NVC0_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);
76 NVC0_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);
77 NVC0_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);
78 NVC0_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);
79 NVC0_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 nvc0_blend_state_create(struct pipe_context *pipe,
87 const struct pipe_blend_state *cso)
88 {
89 struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj);
90 int i;
91
92 so->pipe = *cso;
93
94 SB_IMMED_3D(so, BLEND_INDEPENDENT, cso->independent_blend_enable);
95
96 if (!cso->independent_blend_enable) {
97 SB_BEGIN_3D(so, BLEND_ENABLES, 1);
98 SB_DATA (so, cso->rt[0].blend_enable ? 0xff : 0);
99
100 if (cso->rt[0].blend_enable) {
101 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
102 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
103 SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_src_factor));
104 SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_dst_factor));
105 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
106 SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_src_factor));
107 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
108 SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_dst_factor));
109 }
110
111 SB_BEGIN_3D(so, COLOR_MASK_BROADCAST, 1);
112 SB_DATA (so, nvc0_colormask(cso->rt[0].colormask));
113 } else {
114 uint8_t en = 0;
115
116 for (i = 0; i < 8; ++i) {
117 if (!cso->rt[i].blend_enable)
118 continue;
119 en |= 1 << i;
120
121 SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6);
122 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
123 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor));
124 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor));
125 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
126 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor));
127 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor));
128 }
129 SB_BEGIN_3D(so, BLEND_ENABLES, 1);
130 SB_DATA (so, en);
131
132 SB_BEGIN_3D(so, COLOR_MASK(0), 8);
133 for (i = 0; i < 8; ++i)
134 SB_DATA(so, nvc0_colormask(cso->rt[i].colormask));
135 }
136
137 if (cso->logicop_enable) {
138 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
139 SB_DATA (so, 1);
140 SB_DATA (so, nvgl_logicop_func(cso->logicop_func));
141 } else {
142 SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0);
143 }
144
145 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
146 return so;
147 }
148
149 static void
150 nvc0_blend_state_bind(struct pipe_context *pipe, void *hwcso)
151 {
152 struct nvc0_context *nvc0 = nvc0_context(pipe);
153
154 nvc0->blend = hwcso;
155 nvc0->dirty |= NVC0_NEW_BLEND;
156 }
157
158 static void
159 nvc0_blend_state_delete(struct pipe_context *pipe, void *hwcso)
160 {
161 FREE(hwcso);
162 }
163
164 static void *
165 nvc0_rasterizer_state_create(struct pipe_context *pipe,
166 const struct pipe_rasterizer_state *cso)
167 {
168 struct nvc0_rasterizer_stateobj *so;
169
170 so = CALLOC_STRUCT(nvc0_rasterizer_stateobj);
171 if (!so)
172 return NULL;
173 so->pipe = *cso;
174
175 /* Scissor enables are handled in scissor state, we will not want to
176 * always emit 16 commands, one for each scissor rectangle, here.
177 */
178
179 SB_BEGIN_3D(so, SHADE_MODEL, 1);
180 SB_DATA (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT :
181 NVC0_3D_SHADE_MODEL_SMOOTH);
182 SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first);
183 SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside);
184
185 SB_BEGIN_3D(so, LINE_WIDTH, 1);
186 SB_DATA (so, fui(cso->line_width));
187 SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth);
188
189 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
190 if (cso->line_stipple_enable) {
191 SB_DATA (so, 1);
192 SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1);
193 SB_DATA (so, (cso->line_stipple_pattern << 8) |
194 cso->line_stipple_factor);
195
196 } else {
197 SB_DATA (so, 0);
198 }
199
200 SB_IMMED_3D(so, VP_POINT_SIZE_EN, cso->point_size_per_vertex);
201 if (!cso->point_size_per_vertex) {
202 SB_BEGIN_3D(so, POINT_SIZE, 1);
203 SB_DATA (so, fui(cso->point_size));
204 }
205 SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization);
206 SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth);
207
208 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1);
209 SB_DATA (so, nvgl_polygon_mode(cso->fill_front));
210 SB_BEGIN_3D(so, POLYGON_MODE_BACK, 1);
211 SB_DATA (so, nvgl_polygon_mode(cso->fill_back));
212 SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth);
213
214 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
215 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);
216 SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW :
217 NVC0_3D_FRONT_FACE_CW);
218 switch (cso->cull_face) {
219 case PIPE_FACE_FRONT_AND_BACK:
220 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK);
221 break;
222 case PIPE_FACE_FRONT:
223 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT);
224 break;
225 case PIPE_FACE_BACK:
226 default:
227 SB_DATA(so, NVC0_3D_CULL_FACE_BACK);
228 break;
229 }
230
231 SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable);
232 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
233 SB_DATA (so, cso->offset_point);
234 SB_DATA (so, cso->offset_line);
235 SB_DATA (so, cso->offset_tri);
236
237 if (cso->offset_point || cso->offset_line || cso->offset_tri) {
238 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
239 SB_DATA (so, fui(cso->offset_scale));
240 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
241 SB_DATA (so, fui(cso->offset_units * 2.0f));
242 }
243
244 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
245 return (void *)so;
246 }
247
248 static void
249 nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
250 {
251 struct nvc0_context *nvc0 = nvc0_context(pipe);
252
253 nvc0->rast = hwcso;
254 nvc0->dirty |= NVC0_NEW_RASTERIZER;
255 }
256
257 static void
258 nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
259 {
260 FREE(hwcso);
261 }
262
263 static void *
264 nvc0_zsa_state_create(struct pipe_context *pipe,
265 const struct pipe_depth_stencil_alpha_state *cso)
266 {
267 struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj);
268
269 so->pipe = *cso;
270
271 SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
272 SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
273 if (cso->depth.enabled) {
274 SB_DATA (so, 1);
275 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
276 SB_DATA (so, nvgl_comparison_op(cso->depth.func));
277 } else {
278 SB_DATA (so, 0);
279 }
280
281 if (cso->stencil[0].enabled) {
282 SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
283 SB_DATA (so, 1);
284 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));
285 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
286 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
287 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));
288 SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2);
289 SB_DATA (so, cso->stencil[0].valuemask);
290 SB_DATA (so, cso->stencil[0].writemask);
291 } else {
292 SB_IMMED_3D(so, STENCIL_ENABLE, 0);
293 }
294
295 if (cso->stencil[1].enabled) {
296 assert(cso->stencil[0].enabled);
297 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
298 SB_DATA (so, 1);
299 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));
300 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
301 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
302 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));
303 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
304 SB_DATA (so, cso->stencil[1].writemask);
305 SB_DATA (so, cso->stencil[1].valuemask);
306 } else
307 if (cso->stencil[0].enabled) {
308 SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0);
309 }
310
311 SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
312 if (cso->alpha.enabled) {
313 SB_DATA (so, 1);
314 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
315 SB_DATA (so, fui(cso->alpha.ref_value));
316 SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
317 } else {
318 SB_DATA (so, 0);
319 }
320
321 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
322 return (void *)so;
323 }
324
325 static void
326 nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
327 {
328 struct nvc0_context *nvc0 = nvc0_context(pipe);
329
330 nvc0->zsa = hwcso;
331 nvc0->dirty |= NVC0_NEW_ZSA;
332 }
333
334 static void
335 nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
336 {
337 FREE(hwcso);
338 }
339
340 /* ====================== SAMPLERS AND TEXTURES ================================
341 */
342
343 #define NV50_TSC_WRAP_CASE(n) \
344 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
345
346 static INLINE unsigned
347 nv50_tsc_wrap_mode(unsigned wrap)
348 {
349 switch (wrap) {
350 NV50_TSC_WRAP_CASE(REPEAT);
351 NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
352 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
353 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
354 NV50_TSC_WRAP_CASE(CLAMP);
355 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
356 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
357 NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
358 default:
359 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
360 return NV50_TSC_WRAP_REPEAT;
361 }
362 }
363
364 static void *
365 nvc0_sampler_state_create(struct pipe_context *pipe,
366 const struct pipe_sampler_state *cso)
367 {
368 struct nvc0_tsc_entry *so = CALLOC_STRUCT(nvc0_tsc_entry);
369 float f[2];
370
371 so->id = -1;
372
373 so->tsc[0] = (0x00026000 |
374 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
375 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
376 (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
377
378 switch (cso->mag_img_filter) {
379 case PIPE_TEX_FILTER_LINEAR:
380 so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
381 break;
382 case PIPE_TEX_FILTER_NEAREST:
383 default:
384 so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
385 break;
386 }
387
388 switch (cso->min_img_filter) {
389 case PIPE_TEX_FILTER_LINEAR:
390 so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
391 break;
392 case PIPE_TEX_FILTER_NEAREST:
393 default:
394 so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
395 break;
396 }
397
398 switch (cso->min_mip_filter) {
399 case PIPE_TEX_MIPFILTER_LINEAR:
400 so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
401 break;
402 case PIPE_TEX_MIPFILTER_NEAREST:
403 so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
404 break;
405 case PIPE_TEX_MIPFILTER_NONE:
406 default:
407 so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
408 break;
409 }
410
411 if (cso->max_anisotropy >= 16)
412 so->tsc[0] |= (7 << 20);
413 else
414 if (cso->max_anisotropy >= 12)
415 so->tsc[0] |= (6 << 20);
416 else {
417 so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
418
419 if (cso->max_anisotropy >= 4)
420 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
421 else
422 if (cso->max_anisotropy >= 2)
423 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
424 }
425
426 if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
427 /* NOTE: must be deactivated for non-shadow textures */
428 so->tsc[0] |= (1 << 9);
429 so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
430 }
431
432 f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
433 so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
434
435 f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
436 f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
437 so->tsc[2] |=
438 (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
439
440 so->tsc[4] = fui(cso->border_color[0]);
441 so->tsc[5] = fui(cso->border_color[1]);
442 so->tsc[6] = fui(cso->border_color[2]);
443 so->tsc[7] = fui(cso->border_color[3]);
444
445 return (void *)so;
446 }
447
448 static void
449 nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
450 {
451 unsigned s, i;
452
453 for (s = 0; s < 5; ++s)
454 for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i)
455 if (nvc0_context(pipe)->samplers[s][i] == hwcso)
456 nvc0_context(pipe)->samplers[s][i] = NULL;
457
458 nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nvc0_tsc_entry(hwcso));
459
460 FREE(hwcso);
461 }
462
463 static INLINE void
464 nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s,
465 unsigned nr, void **hwcso)
466 {
467 unsigned i;
468
469 for (i = 0; i < nr; ++i) {
470 struct nvc0_tsc_entry *old = nvc0->samplers[s][i];
471
472 nvc0->samplers[s][i] = nvc0_tsc_entry(hwcso[i]);
473 if (old)
474 nvc0_screen_tsc_unlock(nvc0->screen, old);
475 }
476 for (; i < nvc0->num_samplers[s]; ++i)
477 if (nvc0->samplers[s][i])
478 nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]);
479
480 nvc0->num_samplers[s] = nr;
481
482 nvc0->dirty |= NVC0_NEW_SAMPLERS;
483 }
484
485 static void
486 nvc0_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
487 {
488 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 0, nr, s);
489 }
490
491 static void
492 nvc0_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
493 {
494 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 4, nr, s);
495 }
496
497 static void
498 nvc0_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
499 {
500 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 3, nr, s);
501 }
502
503 /* NOTE: only called when not referenced anywhere, won't be bound */
504 static void
505 nvc0_sampler_view_destroy(struct pipe_context *pipe,
506 struct pipe_sampler_view *view)
507 {
508 pipe_resource_reference(&view->texture, NULL);
509
510 nvc0_screen_tic_free(nvc0_context(pipe)->screen, nvc0_tic_entry(view));
511
512 FREE(nvc0_tic_entry(view));
513 }
514
515 static INLINE void
516 nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
517 unsigned nr,
518 struct pipe_sampler_view **views)
519 {
520 unsigned i;
521
522 for (i = 0; i < nr; ++i) {
523 struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]);
524 if (old)
525 nvc0_screen_tic_unlock(nvc0->screen, old);
526
527 pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
528 }
529
530 for (i = nr; i < nvc0->num_textures[s]; ++i) {
531 struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]);
532 if (!old)
533 continue;
534 nvc0_screen_tic_unlock(nvc0->screen, old);
535
536 pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
537 }
538
539 nvc0->num_textures[s] = nr;
540
541 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);
542
543 nvc0->dirty |= NVC0_NEW_TEXTURES;
544 }
545
546 static void
547 nvc0_vp_set_sampler_views(struct pipe_context *pipe,
548 unsigned nr,
549 struct pipe_sampler_view **views)
550 {
551 nvc0_stage_set_sampler_views(nvc0_context(pipe), 0, nr, views);
552 }
553
554 static void
555 nvc0_fp_set_sampler_views(struct pipe_context *pipe,
556 unsigned nr,
557 struct pipe_sampler_view **views)
558 {
559 nvc0_stage_set_sampler_views(nvc0_context(pipe), 4, nr, views);
560 }
561
562 static void
563 nvc0_gp_set_sampler_views(struct pipe_context *pipe,
564 unsigned nr,
565 struct pipe_sampler_view **views)
566 {
567 nvc0_stage_set_sampler_views(nvc0_context(pipe), 3, nr, views);
568 }
569
570 /* ============================= SHADERS =======================================
571 */
572
573 static void *
574 nvc0_sp_state_create(struct pipe_context *pipe,
575 const struct pipe_shader_state *cso, unsigned type)
576 {
577 struct nvc0_program *prog;
578
579 prog = CALLOC_STRUCT(nvc0_program);
580 if (!prog)
581 return NULL;
582
583 prog->type = type;
584 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
585
586 return (void *)prog;
587 }
588
589 static void
590 nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
591 {
592 struct nvc0_program *prog = (struct nvc0_program *)hwcso;
593
594 nvc0_program_destroy(nvc0_context(pipe), prog);
595
596 FREE((void *)prog->pipe.tokens);
597 FREE(prog);
598 }
599
600 static void *
601 nvc0_vp_state_create(struct pipe_context *pipe,
602 const struct pipe_shader_state *cso)
603 {
604 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
605 }
606
607 static void
608 nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso)
609 {
610 struct nvc0_context *nvc0 = nvc0_context(pipe);
611
612 nvc0->vertprog = hwcso;
613 nvc0->dirty |= NVC0_NEW_VERTPROG;
614 }
615
616 static void *
617 nvc0_fp_state_create(struct pipe_context *pipe,
618 const struct pipe_shader_state *cso)
619 {
620 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
621 }
622
623 static void
624 nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso)
625 {
626 struct nvc0_context *nvc0 = nvc0_context(pipe);
627
628 nvc0->fragprog = hwcso;
629 nvc0->dirty |= NVC0_NEW_FRAGPROG;
630 }
631
632 static void *
633 nvc0_gp_state_create(struct pipe_context *pipe,
634 const struct pipe_shader_state *cso)
635 {
636 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
637 }
638
639 static void
640 nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso)
641 {
642 struct nvc0_context *nvc0 = nvc0_context(pipe);
643
644 nvc0->gmtyprog = hwcso;
645 nvc0->dirty |= NVC0_NEW_GMTYPROG;
646 }
647
648 static void
649 nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
650 struct pipe_resource *res)
651 {
652 struct nvc0_context *nvc0 = nvc0_context(pipe);
653
654 switch (shader) {
655 case PIPE_SHADER_VERTEX: shader = 0; break;
656 /*
657 case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break;
658 case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break;
659 */
660 case PIPE_SHADER_GEOMETRY: shader = 3; break;
661 case PIPE_SHADER_FRAGMENT: shader = 4; break;
662 default:
663 assert(0);
664 break;
665 }
666
667 if (nvc0->constbuf[shader][index])
668 nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
669 nvc0_resource(
670 nvc0->constbuf[shader][index]));
671
672 pipe_resource_reference(&nvc0->constbuf[shader][index], res);
673
674 nvc0->constbuf_dirty[shader] |= 1 << index;
675
676 nvc0->dirty |= NVC0_NEW_CONSTBUF;
677 }
678
679 /* =============================================================================
680 */
681
682 static void
683 nvc0_set_blend_color(struct pipe_context *pipe,
684 const struct pipe_blend_color *bcol)
685 {
686 struct nvc0_context *nvc0 = nvc0_context(pipe);
687
688 nvc0->blend_colour = *bcol;
689 nvc0->dirty |= NVC0_NEW_BLEND_COLOUR;
690 }
691
692 static void
693 nvc0_set_stencil_ref(struct pipe_context *pipe,
694 const struct pipe_stencil_ref *sr)
695 {
696 struct nvc0_context *nvc0 = nvc0_context(pipe);
697
698 nvc0->stencil_ref = *sr;
699 nvc0->dirty |= NVC0_NEW_STENCIL_REF;
700 }
701
702 static void
703 nvc0_set_clip_state(struct pipe_context *pipe,
704 const struct pipe_clip_state *clip)
705 {
706 struct nvc0_context *nvc0 = nvc0_context(pipe);
707 const unsigned size = clip->nr * sizeof(clip->ucp[0]);
708
709 memcpy(&nvc0->clip.ucp[0][0], &clip->ucp[0][0], size);
710 nvc0->clip.nr = clip->nr;
711
712 nvc0->clip.depth_clamp = clip->depth_clamp;
713
714 nvc0->dirty |= NVC0_NEW_CLIP;
715 }
716
717 static void
718 nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
719 {
720 struct nvc0_context *nvc0 = nvc0_context(pipe);
721
722 nvc0->sample_mask = sample_mask;
723 nvc0->dirty |= NVC0_NEW_SAMPLE_MASK;
724 }
725
726
727 static void
728 nvc0_set_framebuffer_state(struct pipe_context *pipe,
729 const struct pipe_framebuffer_state *fb)
730 {
731 struct nvc0_context *nvc0 = nvc0_context(pipe);
732
733 nvc0->framebuffer = *fb;
734 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
735 }
736
737 static void
738 nvc0_set_polygon_stipple(struct pipe_context *pipe,
739 const struct pipe_poly_stipple *stipple)
740 {
741 struct nvc0_context *nvc0 = nvc0_context(pipe);
742
743 nvc0->stipple = *stipple;
744 nvc0->dirty |= NVC0_NEW_STIPPLE;
745 }
746
747 static void
748 nvc0_set_scissor_state(struct pipe_context *pipe,
749 const struct pipe_scissor_state *scissor)
750 {
751 struct nvc0_context *nvc0 = nvc0_context(pipe);
752
753 nvc0->scissor = *scissor;
754 nvc0->dirty |= NVC0_NEW_SCISSOR;
755 }
756
757 static void
758 nvc0_set_viewport_state(struct pipe_context *pipe,
759 const struct pipe_viewport_state *vpt)
760 {
761 struct nvc0_context *nvc0 = nvc0_context(pipe);
762
763 nvc0->viewport = *vpt;
764 nvc0->dirty |= NVC0_NEW_VIEWPORT;
765 }
766
767 static void
768 nvc0_set_vertex_buffers(struct pipe_context *pipe,
769 unsigned count,
770 const struct pipe_vertex_buffer *vb)
771 {
772 struct nvc0_context *nvc0 = nvc0_context(pipe);
773 unsigned i;
774
775 for (i = 0; i < count; ++i)
776 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer);
777 for (; i < nvc0->num_vtxbufs; ++i)
778 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
779
780 memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
781 nvc0->num_vtxbufs = count;
782
783 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
784
785 nvc0->dirty |= NVC0_NEW_ARRAYS;
786 }
787
788 static void
789 nvc0_set_index_buffer(struct pipe_context *pipe,
790 const struct pipe_index_buffer *ib)
791 {
792 struct nvc0_context *nvc0 = nvc0_context(pipe);
793
794 if (ib)
795 memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
796 else
797 nvc0->idxbuf.buffer = NULL;
798 }
799
800 static void
801 nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
802 {
803 struct nvc0_context *nvc0 = nvc0_context(pipe);
804
805 nvc0->vertex = hwcso;
806 nvc0->dirty |= NVC0_NEW_VERTEX;
807 }
808
809 static void *
810 nvc0_tfb_state_create(struct pipe_context *pipe,
811 const struct pipe_stream_output_state *pso)
812 {
813 struct nvc0_transform_feedback_state *so;
814 int n = 0;
815 int i, c, b;
816
817 so = MALLOC(sizeof(*so) + pso->num_outputs * 4 * sizeof(uint8_t));
818 if (!so)
819 return NULL;
820
821 for (b = 0; b < 4; ++b) {
822 for (i = 0; i < pso->num_outputs; ++i) {
823 if (pso->output_buffer[i] != b)
824 continue;
825 for (c = 0; c < 4; ++c) {
826 if (!(pso->register_mask[i] & (1 << c)))
827 continue;
828 so->varying_count[b]++;
829 so->varying_index[n++] = (pso->register_index[i] << 2) | c;
830 }
831 }
832 so->stride[b] = so->varying_count[b] * 4;
833 }
834 if (pso->stride)
835 so->stride[0] = pso->stride;
836
837 return so;
838 }
839
840 static void
841 nvc0_tfb_state_delete(struct pipe_context *pipe, void *hwcso)
842 {
843 FREE(hwcso);
844 }
845
846 static void
847 nvc0_tfb_state_bind(struct pipe_context *pipe, void *hwcso)
848 {
849 nvc0_context(pipe)->tfb = hwcso;
850 nvc0_context(pipe)->dirty |= NVC0_NEW_TFB;
851 }
852
853 static void
854 nvc0_set_transform_feedback_buffers(struct pipe_context *pipe,
855 struct pipe_resource **buffers,
856 int *offsets,
857 int num_buffers)
858 {
859 struct nvc0_context *nvc0 = nvc0_context(pipe);
860 int i;
861
862 assert(num_buffers >= 0 && num_buffers <= 4); /* why signed ? */
863
864 for (i = 0; i < num_buffers; ++i) {
865 assert(offsets[i] >= 0);
866 nvc0->tfb_offset[i] = offsets[i];
867 pipe_resource_reference(&nvc0->tfbbuf[i], buffers[i]);
868 }
869 for (; i < nvc0->num_tfbbufs; ++i)
870 pipe_resource_reference(&nvc0->tfbbuf[i], NULL);
871
872 nvc0->num_tfbbufs = num_buffers;
873
874 nvc0->dirty |= NVC0_NEW_TFB_BUFFERS;
875 }
876
877 void
878 nvc0_init_state_functions(struct nvc0_context *nvc0)
879 {
880 nvc0->pipe.create_blend_state = nvc0_blend_state_create;
881 nvc0->pipe.bind_blend_state = nvc0_blend_state_bind;
882 nvc0->pipe.delete_blend_state = nvc0_blend_state_delete;
883
884 nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create;
885 nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind;
886 nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete;
887
888 nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create;
889 nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind;
890 nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete;
891
892 nvc0->pipe.create_sampler_state = nvc0_sampler_state_create;
893 nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete;
894 nvc0->pipe.bind_vertex_sampler_states = nvc0_vp_sampler_states_bind;
895 nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind;
896 nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind;
897
898 nvc0->pipe.create_sampler_view = nvc0_create_sampler_view;
899 nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy;
900 nvc0->pipe.set_vertex_sampler_views = nvc0_vp_set_sampler_views;
901 nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views;
902 nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views;
903
904 nvc0->pipe.create_vs_state = nvc0_vp_state_create;
905 nvc0->pipe.create_fs_state = nvc0_fp_state_create;
906 nvc0->pipe.create_gs_state = nvc0_gp_state_create;
907 nvc0->pipe.bind_vs_state = nvc0_vp_state_bind;
908 nvc0->pipe.bind_fs_state = nvc0_fp_state_bind;
909 nvc0->pipe.bind_gs_state = nvc0_gp_state_bind;
910 nvc0->pipe.delete_vs_state = nvc0_sp_state_delete;
911 nvc0->pipe.delete_fs_state = nvc0_sp_state_delete;
912 nvc0->pipe.delete_gs_state = nvc0_sp_state_delete;
913
914 nvc0->pipe.set_blend_color = nvc0_set_blend_color;
915 nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref;
916 nvc0->pipe.set_clip_state = nvc0_set_clip_state;
917 nvc0->pipe.set_sample_mask = nvc0_set_sample_mask;
918 nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer;
919 nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state;
920 nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple;
921 nvc0->pipe.set_scissor_state = nvc0_set_scissor_state;
922 nvc0->pipe.set_viewport_state = nvc0_set_viewport_state;
923
924 nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create;
925 nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete;
926 nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind;
927
928 nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers;
929 nvc0->pipe.set_index_buffer = nvc0_set_index_buffer;
930
931 nvc0->pipe.create_stream_output_state = nvc0_tfb_state_create;
932 nvc0->pipe.delete_stream_output_state = nvc0_tfb_state_delete;
933 nvc0->pipe.bind_stream_output_state = nvc0_tfb_state_bind;
934 nvc0->pipe.set_stream_output_buffers = nvc0_set_transform_feedback_buffers;
935
936 nvc0->pipe.redefine_user_buffer = u_default_redefine_user_buffer;
937 }
938