nv50,nvc0: implement colour clamping controls
[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/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 uint32_t reg;
170
171 so = CALLOC_STRUCT(nvc0_rasterizer_stateobj);
172 if (!so)
173 return NULL;
174 so->pipe = *cso;
175
176 /* Scissor enables are handled in scissor state, we will not want to
177 * always emit 16 commands, one for each scissor rectangle, here.
178 */
179
180 SB_BEGIN_3D(so, SHADE_MODEL, 1);
181 SB_DATA (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT :
182 NVC0_3D_SHADE_MODEL_SMOOTH);
183 SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first);
184 SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside);
185
186 SB_IMMED_3D(so, VERT_COLOR_CLAMP_EN, cso->clamp_vertex_color);
187 SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1);
188 SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000);
189
190 SB_BEGIN_3D(so, LINE_WIDTH, 1);
191 SB_DATA (so, fui(cso->line_width));
192 SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth);
193
194 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);
195 if (cso->line_stipple_enable) {
196 SB_DATA (so, 1);
197 SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1);
198 SB_DATA (so, (cso->line_stipple_pattern << 8) |
199 cso->line_stipple_factor);
200
201 } else {
202 SB_DATA (so, 0);
203 }
204
205 SB_IMMED_3D(so, VP_POINT_SIZE_EN, cso->point_size_per_vertex);
206 if (!cso->point_size_per_vertex) {
207 SB_BEGIN_3D(so, POINT_SIZE, 1);
208 SB_DATA (so, fui(cso->point_size));
209 }
210
211 reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ?
212 NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT :
213 NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT;
214
215 SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1);
216 SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg);
217 SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization);
218 SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth);
219
220 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1);
221 SB_DATA (so, nvgl_polygon_mode(cso->fill_front));
222 SB_BEGIN_3D(so, POLYGON_MODE_BACK, 1);
223 SB_DATA (so, nvgl_polygon_mode(cso->fill_back));
224 SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth);
225
226 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
227 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);
228 SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW :
229 NVC0_3D_FRONT_FACE_CW);
230 switch (cso->cull_face) {
231 case PIPE_FACE_FRONT_AND_BACK:
232 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK);
233 break;
234 case PIPE_FACE_FRONT:
235 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT);
236 break;
237 case PIPE_FACE_BACK:
238 default:
239 SB_DATA(so, NVC0_3D_CULL_FACE_BACK);
240 break;
241 }
242
243 SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable);
244 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
245 SB_DATA (so, cso->offset_point);
246 SB_DATA (so, cso->offset_line);
247 SB_DATA (so, cso->offset_tri);
248
249 if (cso->offset_point || cso->offset_line || cso->offset_tri) {
250 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
251 SB_DATA (so, fui(cso->offset_scale));
252 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
253 SB_DATA (so, fui(cso->offset_units * 2.0f));
254 }
255
256 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
257 return (void *)so;
258 }
259
260 static void
261 nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
262 {
263 struct nvc0_context *nvc0 = nvc0_context(pipe);
264
265 nvc0->rast = hwcso;
266 nvc0->dirty |= NVC0_NEW_RASTERIZER;
267 }
268
269 static void
270 nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
271 {
272 FREE(hwcso);
273 }
274
275 static void *
276 nvc0_zsa_state_create(struct pipe_context *pipe,
277 const struct pipe_depth_stencil_alpha_state *cso)
278 {
279 struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj);
280
281 so->pipe = *cso;
282
283 SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled);
284 if (cso->depth.enabled) {
285 SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
286 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
287 SB_DATA (so, nvgl_comparison_op(cso->depth.func));
288 }
289
290 if (cso->stencil[0].enabled) {
291 SB_BEGIN_3D(so, STENCIL_ENABLE, 5);
292 SB_DATA (so, 1);
293 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));
294 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
295 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
296 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));
297 SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2);
298 SB_DATA (so, cso->stencil[0].valuemask);
299 SB_DATA (so, cso->stencil[0].writemask);
300 } else {
301 SB_IMMED_3D(so, STENCIL_ENABLE, 0);
302 }
303
304 if (cso->stencil[1].enabled) {
305 assert(cso->stencil[0].enabled);
306 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);
307 SB_DATA (so, 1);
308 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));
309 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
310 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
311 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));
312 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);
313 SB_DATA (so, cso->stencil[1].writemask);
314 SB_DATA (so, cso->stencil[1].valuemask);
315 } else
316 if (cso->stencil[0].enabled) {
317 SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0);
318 }
319
320 SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled);
321 if (cso->alpha.enabled) {
322 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
323 SB_DATA (so, fui(cso->alpha.ref_value));
324 SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
325 }
326
327 assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
328 return (void *)so;
329 }
330
331 static void
332 nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
333 {
334 struct nvc0_context *nvc0 = nvc0_context(pipe);
335
336 nvc0->zsa = hwcso;
337 nvc0->dirty |= NVC0_NEW_ZSA;
338 }
339
340 static void
341 nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
342 {
343 FREE(hwcso);
344 }
345
346 /* ====================== SAMPLERS AND TEXTURES ================================
347 */
348
349 #define NV50_TSC_WRAP_CASE(n) \
350 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
351
352 static INLINE unsigned
353 nv50_tsc_wrap_mode(unsigned wrap)
354 {
355 switch (wrap) {
356 NV50_TSC_WRAP_CASE(REPEAT);
357 NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
358 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
359 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
360 NV50_TSC_WRAP_CASE(CLAMP);
361 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
362 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
363 NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
364 default:
365 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
366 return NV50_TSC_WRAP_REPEAT;
367 }
368 }
369
370 static void
371 nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
372 {
373 unsigned s, i;
374
375 for (s = 0; s < 5; ++s)
376 for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i)
377 if (nvc0_context(pipe)->samplers[s][i] == hwcso)
378 nvc0_context(pipe)->samplers[s][i] = NULL;
379
380 nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nv50_tsc_entry(hwcso));
381
382 FREE(hwcso);
383 }
384
385 static INLINE void
386 nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s,
387 unsigned nr, void **hwcso)
388 {
389 unsigned i;
390
391 for (i = 0; i < nr; ++i) {
392 struct nv50_tsc_entry *old = nvc0->samplers[s][i];
393
394 nvc0->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
395 if (old)
396 nvc0_screen_tsc_unlock(nvc0->screen, old);
397 }
398 for (; i < nvc0->num_samplers[s]; ++i)
399 if (nvc0->samplers[s][i])
400 nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]);
401
402 nvc0->num_samplers[s] = nr;
403
404 nvc0->dirty |= NVC0_NEW_SAMPLERS;
405 }
406
407 static void
408 nvc0_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
409 {
410 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 0, nr, s);
411 }
412
413 static void
414 nvc0_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
415 {
416 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 4, nr, s);
417 }
418
419 static void
420 nvc0_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
421 {
422 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 3, nr, s);
423 }
424
425 /* NOTE: only called when not referenced anywhere, won't be bound */
426 static void
427 nvc0_sampler_view_destroy(struct pipe_context *pipe,
428 struct pipe_sampler_view *view)
429 {
430 pipe_resource_reference(&view->texture, NULL);
431
432 nvc0_screen_tic_free(nvc0_context(pipe)->screen, nv50_tic_entry(view));
433
434 FREE(nv50_tic_entry(view));
435 }
436
437 static INLINE void
438 nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
439 unsigned nr,
440 struct pipe_sampler_view **views)
441 {
442 unsigned i;
443
444 for (i = 0; i < nr; ++i) {
445 struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
446 if (old)
447 nvc0_screen_tic_unlock(nvc0->screen, old);
448
449 pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
450 }
451
452 for (i = nr; i < nvc0->num_textures[s]; ++i) {
453 struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
454 if (!old)
455 continue;
456 nvc0_screen_tic_unlock(nvc0->screen, old);
457
458 pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
459 }
460
461 nvc0->num_textures[s] = nr;
462
463 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);
464
465 nvc0->dirty |= NVC0_NEW_TEXTURES;
466 }
467
468 static void
469 nvc0_vp_set_sampler_views(struct pipe_context *pipe,
470 unsigned nr,
471 struct pipe_sampler_view **views)
472 {
473 nvc0_stage_set_sampler_views(nvc0_context(pipe), 0, nr, views);
474 }
475
476 static void
477 nvc0_fp_set_sampler_views(struct pipe_context *pipe,
478 unsigned nr,
479 struct pipe_sampler_view **views)
480 {
481 nvc0_stage_set_sampler_views(nvc0_context(pipe), 4, nr, views);
482 }
483
484 static void
485 nvc0_gp_set_sampler_views(struct pipe_context *pipe,
486 unsigned nr,
487 struct pipe_sampler_view **views)
488 {
489 nvc0_stage_set_sampler_views(nvc0_context(pipe), 3, nr, views);
490 }
491
492 /* ============================= SHADERS =======================================
493 */
494
495 static void *
496 nvc0_sp_state_create(struct pipe_context *pipe,
497 const struct pipe_shader_state *cso, unsigned type)
498 {
499 struct nvc0_program *prog;
500
501 prog = CALLOC_STRUCT(nvc0_program);
502 if (!prog)
503 return NULL;
504
505 prog->type = type;
506 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
507
508 return (void *)prog;
509 }
510
511 static void
512 nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
513 {
514 struct nvc0_program *prog = (struct nvc0_program *)hwcso;
515
516 nvc0_program_destroy(nvc0_context(pipe), prog);
517
518 FREE((void *)prog->pipe.tokens);
519 FREE(prog);
520 }
521
522 static void *
523 nvc0_vp_state_create(struct pipe_context *pipe,
524 const struct pipe_shader_state *cso)
525 {
526 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
527 }
528
529 static void
530 nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso)
531 {
532 struct nvc0_context *nvc0 = nvc0_context(pipe);
533
534 nvc0->vertprog = hwcso;
535 nvc0->dirty |= NVC0_NEW_VERTPROG;
536 }
537
538 static void *
539 nvc0_fp_state_create(struct pipe_context *pipe,
540 const struct pipe_shader_state *cso)
541 {
542 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
543 }
544
545 static void
546 nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso)
547 {
548 struct nvc0_context *nvc0 = nvc0_context(pipe);
549
550 nvc0->fragprog = hwcso;
551 nvc0->dirty |= NVC0_NEW_FRAGPROG;
552 }
553
554 static void *
555 nvc0_gp_state_create(struct pipe_context *pipe,
556 const struct pipe_shader_state *cso)
557 {
558 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
559 }
560
561 static void
562 nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso)
563 {
564 struct nvc0_context *nvc0 = nvc0_context(pipe);
565
566 nvc0->gmtyprog = hwcso;
567 nvc0->dirty |= NVC0_NEW_GMTYPROG;
568 }
569
570 static void
571 nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
572 struct pipe_resource *res)
573 {
574 struct nvc0_context *nvc0 = nvc0_context(pipe);
575
576 switch (shader) {
577 case PIPE_SHADER_VERTEX: shader = 0; break;
578 /*
579 case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break;
580 case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break;
581 */
582 case PIPE_SHADER_GEOMETRY: shader = 3; break;
583 case PIPE_SHADER_FRAGMENT: shader = 4; break;
584 default:
585 assert(0);
586 break;
587 }
588
589 if (nvc0->constbuf[shader][index])
590 nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
591 nv04_resource(nvc0->constbuf[shader][index]));
592
593 pipe_resource_reference(&nvc0->constbuf[shader][index], res);
594
595 nvc0->constbuf_dirty[shader] |= 1 << index;
596
597 nvc0->dirty |= NVC0_NEW_CONSTBUF;
598 }
599
600 /* =============================================================================
601 */
602
603 static void
604 nvc0_set_blend_color(struct pipe_context *pipe,
605 const struct pipe_blend_color *bcol)
606 {
607 struct nvc0_context *nvc0 = nvc0_context(pipe);
608
609 nvc0->blend_colour = *bcol;
610 nvc0->dirty |= NVC0_NEW_BLEND_COLOUR;
611 }
612
613 static void
614 nvc0_set_stencil_ref(struct pipe_context *pipe,
615 const struct pipe_stencil_ref *sr)
616 {
617 struct nvc0_context *nvc0 = nvc0_context(pipe);
618
619 nvc0->stencil_ref = *sr;
620 nvc0->dirty |= NVC0_NEW_STENCIL_REF;
621 }
622
623 static void
624 nvc0_set_clip_state(struct pipe_context *pipe,
625 const struct pipe_clip_state *clip)
626 {
627 struct nvc0_context *nvc0 = nvc0_context(pipe);
628 const unsigned size = clip->nr * sizeof(clip->ucp[0]);
629
630 memcpy(&nvc0->clip.ucp[0][0], &clip->ucp[0][0], size);
631 nvc0->clip.nr = clip->nr;
632
633 nvc0->clip.depth_clamp = clip->depth_clamp;
634
635 nvc0->dirty |= NVC0_NEW_CLIP;
636 }
637
638 static void
639 nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
640 {
641 struct nvc0_context *nvc0 = nvc0_context(pipe);
642
643 nvc0->sample_mask = sample_mask;
644 nvc0->dirty |= NVC0_NEW_SAMPLE_MASK;
645 }
646
647
648 static void
649 nvc0_set_framebuffer_state(struct pipe_context *pipe,
650 const struct pipe_framebuffer_state *fb)
651 {
652 struct nvc0_context *nvc0 = nvc0_context(pipe);
653
654 nvc0->framebuffer = *fb;
655 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
656 }
657
658 static void
659 nvc0_set_polygon_stipple(struct pipe_context *pipe,
660 const struct pipe_poly_stipple *stipple)
661 {
662 struct nvc0_context *nvc0 = nvc0_context(pipe);
663
664 nvc0->stipple = *stipple;
665 nvc0->dirty |= NVC0_NEW_STIPPLE;
666 }
667
668 static void
669 nvc0_set_scissor_state(struct pipe_context *pipe,
670 const struct pipe_scissor_state *scissor)
671 {
672 struct nvc0_context *nvc0 = nvc0_context(pipe);
673
674 nvc0->scissor = *scissor;
675 nvc0->dirty |= NVC0_NEW_SCISSOR;
676 }
677
678 static void
679 nvc0_set_viewport_state(struct pipe_context *pipe,
680 const struct pipe_viewport_state *vpt)
681 {
682 struct nvc0_context *nvc0 = nvc0_context(pipe);
683
684 nvc0->viewport = *vpt;
685 nvc0->dirty |= NVC0_NEW_VIEWPORT;
686 }
687
688 static void
689 nvc0_set_vertex_buffers(struct pipe_context *pipe,
690 unsigned count,
691 const struct pipe_vertex_buffer *vb)
692 {
693 struct nvc0_context *nvc0 = nvc0_context(pipe);
694 unsigned i;
695
696 for (i = 0; i < count; ++i)
697 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer);
698 for (; i < nvc0->num_vtxbufs; ++i)
699 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
700
701 memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
702 nvc0->num_vtxbufs = count;
703
704 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
705
706 nvc0->dirty |= NVC0_NEW_ARRAYS;
707 }
708
709 static void
710 nvc0_set_index_buffer(struct pipe_context *pipe,
711 const struct pipe_index_buffer *ib)
712 {
713 struct nvc0_context *nvc0 = nvc0_context(pipe);
714
715 if (ib) {
716 pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
717
718 memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
719 } else {
720 pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
721 }
722 }
723
724 static void
725 nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
726 {
727 struct nvc0_context *nvc0 = nvc0_context(pipe);
728
729 nvc0->vertex = hwcso;
730 nvc0->dirty |= NVC0_NEW_VERTEX;
731 }
732
733 static void *
734 nvc0_tfb_state_create(struct pipe_context *pipe,
735 const struct pipe_stream_output_state *pso)
736 {
737 struct nvc0_transform_feedback_state *so;
738 int n = 0;
739 int i, c, b;
740
741 so = MALLOC(sizeof(*so) + pso->num_outputs * 4 * sizeof(uint8_t));
742 if (!so)
743 return NULL;
744
745 for (b = 0; b < 4; ++b) {
746 for (i = 0; i < pso->num_outputs; ++i) {
747 if (pso->output_buffer[i] != b)
748 continue;
749 for (c = 0; c < 4; ++c) {
750 if (!(pso->register_mask[i] & (1 << c)))
751 continue;
752 so->varying_count[b]++;
753 so->varying_index[n++] = (pso->register_index[i] << 2) | c;
754 }
755 }
756 so->stride[b] = so->varying_count[b] * 4;
757 }
758 if (pso->stride)
759 so->stride[0] = pso->stride;
760
761 return so;
762 }
763
764 static void
765 nvc0_tfb_state_delete(struct pipe_context *pipe, void *hwcso)
766 {
767 FREE(hwcso);
768 }
769
770 static void
771 nvc0_tfb_state_bind(struct pipe_context *pipe, void *hwcso)
772 {
773 nvc0_context(pipe)->tfb = hwcso;
774 nvc0_context(pipe)->dirty |= NVC0_NEW_TFB;
775 }
776
777 static void
778 nvc0_set_transform_feedback_buffers(struct pipe_context *pipe,
779 struct pipe_resource **buffers,
780 int *offsets,
781 int num_buffers)
782 {
783 struct nvc0_context *nvc0 = nvc0_context(pipe);
784 int i;
785
786 assert(num_buffers >= 0 && num_buffers <= 4); /* why signed ? */
787
788 for (i = 0; i < num_buffers; ++i) {
789 assert(offsets[i] >= 0);
790 nvc0->tfb_offset[i] = offsets[i];
791 pipe_resource_reference(&nvc0->tfbbuf[i], buffers[i]);
792 }
793 for (; i < nvc0->num_tfbbufs; ++i)
794 pipe_resource_reference(&nvc0->tfbbuf[i], NULL);
795
796 nvc0->num_tfbbufs = num_buffers;
797
798 nvc0->dirty |= NVC0_NEW_TFB_BUFFERS;
799 }
800
801 void
802 nvc0_init_state_functions(struct nvc0_context *nvc0)
803 {
804 struct pipe_context *pipe = &nvc0->base.pipe;
805
806 pipe->create_blend_state = nvc0_blend_state_create;
807 pipe->bind_blend_state = nvc0_blend_state_bind;
808 pipe->delete_blend_state = nvc0_blend_state_delete;
809
810 pipe->create_rasterizer_state = nvc0_rasterizer_state_create;
811 pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind;
812 pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete;
813
814 pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create;
815 pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind;
816 pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete;
817
818 pipe->create_sampler_state = nv50_sampler_state_create;
819 pipe->delete_sampler_state = nvc0_sampler_state_delete;
820 pipe->bind_vertex_sampler_states = nvc0_vp_sampler_states_bind;
821 pipe->bind_fragment_sampler_states = nvc0_fp_sampler_states_bind;
822 pipe->bind_geometry_sampler_states = nvc0_gp_sampler_states_bind;
823
824 pipe->create_sampler_view = nvc0_create_sampler_view;
825 pipe->sampler_view_destroy = nvc0_sampler_view_destroy;
826 pipe->set_vertex_sampler_views = nvc0_vp_set_sampler_views;
827 pipe->set_fragment_sampler_views = nvc0_fp_set_sampler_views;
828 pipe->set_geometry_sampler_views = nvc0_gp_set_sampler_views;
829
830 pipe->create_vs_state = nvc0_vp_state_create;
831 pipe->create_fs_state = nvc0_fp_state_create;
832 pipe->create_gs_state = nvc0_gp_state_create;
833 pipe->bind_vs_state = nvc0_vp_state_bind;
834 pipe->bind_fs_state = nvc0_fp_state_bind;
835 pipe->bind_gs_state = nvc0_gp_state_bind;
836 pipe->delete_vs_state = nvc0_sp_state_delete;
837 pipe->delete_fs_state = nvc0_sp_state_delete;
838 pipe->delete_gs_state = nvc0_sp_state_delete;
839
840 pipe->set_blend_color = nvc0_set_blend_color;
841 pipe->set_stencil_ref = nvc0_set_stencil_ref;
842 pipe->set_clip_state = nvc0_set_clip_state;
843 pipe->set_sample_mask = nvc0_set_sample_mask;
844 pipe->set_constant_buffer = nvc0_set_constant_buffer;
845 pipe->set_framebuffer_state = nvc0_set_framebuffer_state;
846 pipe->set_polygon_stipple = nvc0_set_polygon_stipple;
847 pipe->set_scissor_state = nvc0_set_scissor_state;
848 pipe->set_viewport_state = nvc0_set_viewport_state;
849
850 pipe->create_vertex_elements_state = nvc0_vertex_state_create;
851 pipe->delete_vertex_elements_state = nvc0_vertex_state_delete;
852 pipe->bind_vertex_elements_state = nvc0_vertex_state_bind;
853
854 pipe->set_vertex_buffers = nvc0_set_vertex_buffers;
855 pipe->set_index_buffer = nvc0_set_index_buffer;
856
857 pipe->create_stream_output_state = nvc0_tfb_state_create;
858 pipe->delete_stream_output_state = nvc0_tfb_state_delete;
859 pipe->bind_stream_output_state = nvc0_tfb_state_bind;
860 pipe->set_stream_output_buffers = nvc0_set_transform_feedback_buffers;
861
862 pipe->redefine_user_buffer = u_default_redefine_user_buffer;
863 }
864