nvc0_state.c revision 5138ac033ad3708e2b82f2beebc887f65a77309e
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
26#include "tgsi/tgsi_parse.h"
27
28#include "nvc0_stateobj.h"
29#include "nvc0_context.h"
30
31#include "nvc0_3d.xml.h"
32#include "nv50_texture.xml.h"
33
34#include "nouveau/nouveau_gldefs.h"
35
36static INLINE uint32_t
37nvc0_colormask(unsigned mask)
38{
39    uint32_t ret = 0;
40
41    if (mask & PIPE_MASK_R)
42        ret |= 0x0001;
43    if (mask & PIPE_MASK_G)
44        ret |= 0x0010;
45    if (mask & PIPE_MASK_B)
46        ret |= 0x0100;
47    if (mask & PIPE_MASK_A)
48        ret |= 0x1000;
49
50    return ret;
51}
52
53static INLINE uint32_t
54nvc0_blend_fac(unsigned factor)
55{
56    static const uint16_t bf[] = {
57        NV50_3D_BLEND_FACTOR_ZERO, /* 0x00 */
58        NV50_3D_BLEND_FACTOR_ONE,
59        NV50_3D_BLEND_FACTOR_SRC_COLOR,
60        NV50_3D_BLEND_FACTOR_SRC_ALPHA,
61        NV50_3D_BLEND_FACTOR_DST_ALPHA,
62        NV50_3D_BLEND_FACTOR_DST_COLOR,
63        NV50_3D_BLEND_FACTOR_SRC_ALPHA_SATURATE,
64        NV50_3D_BLEND_FACTOR_CONSTANT_COLOR,
65        NV50_3D_BLEND_FACTOR_CONSTANT_ALPHA,
66        NV50_3D_BLEND_FACTOR_SRC1_COLOR,
67        NV50_3D_BLEND_FACTOR_SRC1_ALPHA,
68        NV50_3D_BLEND_FACTOR_ZERO, /* 0x0b */
69        NV50_3D_BLEND_FACTOR_ZERO, /* 0x0c */
70        NV50_3D_BLEND_FACTOR_ZERO, /* 0x0d */
71        NV50_3D_BLEND_FACTOR_ZERO, /* 0x0e */
72        NV50_3D_BLEND_FACTOR_ZERO, /* 0x0f */
73        NV50_3D_BLEND_FACTOR_ZERO, /* 0x10 */
74        NV50_3D_BLEND_FACTOR_ZERO, /* 0x11 */
75        NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
76        NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
77        NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
78        NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
79        NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
80        NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
81        NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
82        NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
83    };
84
85    assert(factor < (sizeof(bf) / sizeof(bf[0])));
86    return bf[factor];
87}
88
89static void *
90nvc0_blend_state_create(struct pipe_context *pipe,
91                        const struct pipe_blend_state *cso)
92{
93    struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj);
94    int i;
95
96    so->pipe = *cso;
97
98    SB_OUT_3D(so, BLEND_INDEPENDENT, cso->independent_blend_enable);
99
100    if (!cso->independent_blend_enable) {
101        SB_BEGIN_3D(so, BLEND_ENABLES, 1);
102        SB_DATA    (so, cso->rt[0].blend_enable ? 0xff : 0);
103
104        if (cso->rt[0].blend_enable) {
105            SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);
106            SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
107            SB_DATA    (so, nvc0_blend_fac(cso->rt[0].rgb_src_factor));
108            SB_DATA    (so, nvc0_blend_fac(cso->rt[0].rgb_dst_factor));
109            SB_DATA    (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
110            SB_DATA    (so, nvc0_blend_fac(cso->rt[0].alpha_src_factor));
111            SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);
112            SB_DATA    (so, nvc0_blend_fac(cso->rt[0].alpha_dst_factor));
113        }
114
115        SB_BEGIN_3D(so, COLOR_MASK_BROADCAST, 1);
116        SB_DATA    (so, nvc0_colormask(cso->rt[0].colormask));
117    } else {
118        uint8_t en = 0;
119
120        for (i = 0; i < 8; ++i) {
121            if (!cso->rt[i].blend_enable)
122                continue;
123            en |= 1 << i;
124
125            SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6);
126            SB_DATA    (so, nvgl_blend_eqn(cso->rt[i].rgb_func));
127            SB_DATA    (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor));
128            SB_DATA    (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor));
129            SB_DATA    (so, nvgl_blend_eqn(cso->rt[i].alpha_func));
130            SB_DATA    (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor));
131            SB_DATA    (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor));
132        }
133        SB_BEGIN_3D(so, BLEND_ENABLES, 1);
134        SB_DATA    (so, en);
135
136        SB_BEGIN_3D(so, COLOR_MASK(0), 8);
137        for (i = 0; i < 8; ++i)
138            SB_DATA(so, nvc0_colormask(cso->rt[i].colormask));
139    }
140
141    if (cso->logicop_enable) {
142       SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);
143       SB_DATA    (so, 1);
144       SB_DATA    (so, nvgl_logicop_func(cso->logicop_func));
145    } else {
146       SB_OUT_3D  (so, LOGIC_OP_ENABLE, 0);
147    }
148
149    assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
150    return so;
151}
152
153static void
154nvc0_blend_state_bind(struct pipe_context *pipe, void *hwcso)
155{
156    struct nvc0_context *nvc0 = nvc0_context(pipe);
157
158    nvc0->blend = hwcso;
159    nvc0->dirty |= NVC0_NEW_BLEND;
160}
161
162static void
163nvc0_blend_state_delete(struct pipe_context *pipe, void *hwcso)
164{
165    FREE(hwcso);
166}
167
168static void *
169nvc0_rasterizer_state_create(struct pipe_context *pipe,
170                             const struct pipe_rasterizer_state *cso)
171{
172    struct nvc0_rasterizer_stateobj *so;
173
174    so = CALLOC_STRUCT(nvc0_rasterizer_stateobj);
175    if (!so)
176        return NULL;
177    so->pipe = *cso;
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_OUT_3D  (so, PROVOKING_VERTEX_LAST, !cso->flatshade_first);
183    SB_OUT_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_OUT_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_OUT_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_OUT_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization);
206
207    SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1);
208    SB_DATA    (so, nvgl_polygon_mode(cso->fill_front));
209    SB_BEGIN_3D(so, POLYGON_MODE_BACK, 1);
210    SB_DATA    (so, nvgl_polygon_mode(cso->fill_back));
211    SB_OUT_3D  (so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth);
212
213    SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);
214    SB_DATA    (so, cso->cull_face != PIPE_FACE_NONE);
215    SB_DATA    (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW :
216                                     NVC0_3D_FRONT_FACE_CW);
217    switch (cso->cull_face) {
218    case PIPE_FACE_FRONT_AND_BACK:
219       SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK);
220       break;
221    case PIPE_FACE_FRONT:
222       SB_DATA(so, NVC0_3D_CULL_FACE_FRONT);
223       break;
224    case PIPE_FACE_BACK:
225    default:
226       SB_DATA(so, NVC0_3D_CULL_FACE_BACK);
227       break;
228    }
229
230    SB_OUT_3D  (so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable);
231    SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);
232    SB_DATA    (so, cso->offset_point);
233    SB_DATA    (so, cso->offset_line);
234    SB_DATA    (so, cso->offset_tri);
235
236    if (cso->offset_point || cso->offset_line || cso->offset_tri) {
237        SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);
238        SB_DATA    (so, fui(cso->offset_scale));
239        SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);
240        SB_DATA    (so, fui(cso->offset_units)); /* XXX: multiply by 2 ? */
241    }
242
243    assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
244    return (void *)so;
245}
246
247static void
248nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
249{
250   struct nvc0_context *nvc0 = nvc0_context(pipe);
251
252   nvc0->rast = hwcso;
253   nvc0->dirty |= NVC0_NEW_RASTERIZER;
254}
255
256static void
257nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
258{
259   FREE(hwcso);
260}
261
262static void *
263nvc0_zsa_state_create(struct pipe_context *pipe,
264                      const struct pipe_depth_stencil_alpha_state *cso)
265{
266   struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj);
267
268   so->pipe = *cso;
269
270   SB_OUT_3D  (so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
271   SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
272   if (cso->depth.enabled) {
273      SB_DATA    (so, 1);
274      SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
275      SB_DATA    (so, nvgl_comparison_op(cso->depth.func));
276   } else {
277      SB_DATA    (so, 0);
278   }
279
280   if (cso->stencil[0].enabled) {
281      SB_BEGIN_3D(so, STENCIL_FRONT_ENABLE, 5);
282      SB_DATA    (so, 1);
283      SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].fail_op));
284      SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
285      SB_DATA    (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
286      SB_DATA    (so, nvgl_comparison_op(cso->stencil[0].func));
287      SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);
288      SB_DATA    (so, cso->stencil[0].writemask);
289      SB_DATA    (so, cso->stencil[0].valuemask);
290   } else {
291      SB_OUT_3D  (so, STENCIL_FRONT_ENABLE, 0);
292   }
293
294   if (cso->stencil[1].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_OUT_3D  (so, STENCIL_TWO_SIDE_ENABLE, 0);
306   }
307
308   SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
309   if (cso->alpha.enabled) {
310      SB_DATA    (so, 1);
311      SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
312      SB_DATA    (so, fui(cso->alpha.ref_value));
313      SB_DATA    (so, nvgl_comparison_op(cso->alpha.func));
314   } else {
315      SB_DATA    (so, 0);
316   }
317
318   assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
319   return (void *)so;
320}
321
322static void
323nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso)
324{
325   struct nvc0_context *nvc0 = nvc0_context(pipe);
326
327   nvc0->zsa = hwcso;
328   nvc0->dirty |= NVC0_NEW_ZSA;
329}
330
331static void
332nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso)
333{
334   FREE(hwcso);
335}
336
337/* ====================== SAMPLERS AND TEXTURES ================================
338 */
339
340#define NV50_TSC_WRAP_CASE(n) \
341    case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n
342
343static INLINE unsigned
344nv50_tsc_wrap_mode(unsigned wrap)
345{
346   switch (wrap) {
347   NV50_TSC_WRAP_CASE(REPEAT);
348   NV50_TSC_WRAP_CASE(MIRROR_REPEAT);
349   NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE);
350   NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER);
351   NV50_TSC_WRAP_CASE(CLAMP);
352   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE);
353   NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER);
354   NV50_TSC_WRAP_CASE(MIRROR_CLAMP);
355   default:
356       NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
357       return NV50_TSC_WRAP_REPEAT;
358   }
359}
360
361static void *
362nvc0_sampler_state_create(struct pipe_context *pipe,
363                          const struct pipe_sampler_state *cso)
364{
365   struct nvc0_tsc_entry *so = CALLOC_STRUCT(nvc0_tsc_entry);
366   float f[2];
367
368   so->id = -1;
369
370   so->tsc[0] = (0x00026000 |
371                 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) |
372                 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) |
373                 (nv50_tsc_wrap_mode(cso->wrap_r) << 6));
374
375   switch (cso->mag_img_filter) {
376   case PIPE_TEX_FILTER_LINEAR:
377      so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR;
378      break;
379   case PIPE_TEX_FILTER_NEAREST:
380   default:
381      so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST;
382      break;
383   }
384
385   switch (cso->min_img_filter) {
386   case PIPE_TEX_FILTER_LINEAR:
387      so->tsc[1] |= NV50_TSC_1_MINF_LINEAR;
388      break;
389   case PIPE_TEX_FILTER_NEAREST:
390   default:
391      so->tsc[1] |= NV50_TSC_1_MINF_NEAREST;
392      break;
393   }
394
395   switch (cso->min_mip_filter) {
396   case PIPE_TEX_MIPFILTER_LINEAR:
397      so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR;
398      break;
399   case PIPE_TEX_MIPFILTER_NEAREST:
400      so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST;
401      break;
402   case PIPE_TEX_MIPFILTER_NONE:
403   default:
404      so->tsc[1] |= NV50_TSC_1_MIPF_NONE;
405      break;
406   }
407
408   if (cso->max_anisotropy >= 16)
409      so->tsc[0] |= (7 << 20);
410   else
411   if (cso->max_anisotropy >= 12)
412      so->tsc[0] |= (6 << 20);
413   else {
414      so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;
415
416      if (cso->max_anisotropy >= 4)
417         so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35;
418      else
419      if (cso->max_anisotropy >= 2)
420         so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15;
421   }
422
423   if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
424      /* NOTE: must be deactivated for non-shadow textures */
425      so->tsc[0] |= (1 << 9);
426      so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;
427   }
428
429   f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);
430   so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;
431
432   f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);
433   f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);
434   so->tsc[2] |=
435      (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);
436
437   so->tsc[4] = fui(cso->border_color[0]);
438   so->tsc[5] = fui(cso->border_color[1]);
439   so->tsc[6] = fui(cso->border_color[2]);
440   so->tsc[7] = fui(cso->border_color[3]);
441
442   return (void *)so;
443}
444
445static void
446nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
447{
448   unsigned s, i;
449
450   for (s = 0; s < 5; ++s)
451      for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i)
452         if (nvc0_context(pipe)->samplers[s][i] == hwcso)
453            nvc0_context(pipe)->samplers[s][i] = NULL;
454
455   nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nvc0_tsc_entry(hwcso));
456
457   FREE(hwcso);
458}
459
460static INLINE void
461nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s,
462                               unsigned nr, void **hwcso)
463{
464   unsigned i;
465
466   for (i = 0; i < nr; ++i) {
467      struct nvc0_tsc_entry *old = nvc0->samplers[s][i];
468
469      nvc0->samplers[s][i] = nvc0_tsc_entry(hwcso[i]);
470      if (old)
471         nvc0_screen_tsc_unlock(nvc0->screen, old);
472   }
473   for (; i < nvc0->num_samplers[s]; ++i)
474      if (nvc0->samplers[s][i])
475         nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]);
476
477   nvc0->num_samplers[s] = nr;
478
479   nvc0->dirty |= NVC0_NEW_SAMPLERS;
480}
481
482static void
483nvc0_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
484{
485   nvc0_stage_sampler_states_bind(nvc0_context(pipe), 0, nr, s);
486}
487
488static void
489nvc0_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
490{
491   nvc0_stage_sampler_states_bind(nvc0_context(pipe), 4, nr, s);
492}
493
494static void
495nvc0_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s)
496{
497   nvc0_stage_sampler_states_bind(nvc0_context(pipe), 3, nr, s);
498}
499
500/* NOTE: only called when not referenced anywhere, won't be bound */
501static void
502nvc0_sampler_view_destroy(struct pipe_context *pipe,
503                          struct pipe_sampler_view *view)
504{
505   pipe_resource_reference(&view->texture, NULL);
506
507   nvc0_screen_tic_free(nvc0_context(pipe)->screen, nvc0_tic_entry(view));
508
509   FREE(nvc0_tic_entry(view));
510}
511
512static INLINE void
513nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
514                             unsigned nr,
515                             struct pipe_sampler_view **views)
516{
517   unsigned i;
518
519   for (i = 0; i < nr; ++i) {
520      struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]);
521      if (old)
522         nvc0_screen_tic_unlock(nvc0->screen, old);
523
524      pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
525   }
526
527   for (i = nr; i < nvc0->num_textures[s]; ++i) {
528      struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]);
529      if (!old)
530         continue;
531      nvc0_screen_tic_unlock(nvc0->screen, old);
532
533      pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
534   }
535
536   nvc0->num_textures[s] = nr;
537
538   nvc0->dirty |= NVC0_NEW_TEXTURES;
539}
540
541static void
542nvc0_vp_set_sampler_views(struct pipe_context *pipe,
543                          unsigned nr,
544                          struct pipe_sampler_view **views)
545{
546   nvc0_stage_set_sampler_views(nvc0_context(pipe), 0, nr, views);
547}
548
549static void
550nvc0_fp_set_sampler_views(struct pipe_context *pipe,
551                          unsigned nr,
552                          struct pipe_sampler_view **views)
553{
554   nvc0_stage_set_sampler_views(nvc0_context(pipe), 4, nr, views);
555}
556
557static void
558nvc0_gp_set_sampler_views(struct pipe_context *pipe,
559                          unsigned nr,
560                          struct pipe_sampler_view **views)
561{
562   nvc0_stage_set_sampler_views(nvc0_context(pipe), 3, nr, views);
563}
564
565/* ============================= SHADERS =======================================
566 */
567
568static void *
569nvc0_sp_state_create(struct pipe_context *pipe,
570                     const struct pipe_shader_state *cso, unsigned type)
571{
572   struct nvc0_program *prog;
573
574   prog = CALLOC_STRUCT(nvc0_program);
575   if (!prog)
576      return NULL;
577
578   prog->type = type;
579   prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);
580
581   return (void *)prog;
582}
583
584static void
585nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
586{
587   struct nvc0_program *prog = (struct nvc0_program *)hwcso;
588
589   nvc0_program_destroy(nvc0_context(pipe), prog);
590
591   FREE((void *)prog->pipe.tokens);
592   FREE(prog);
593}
594
595static void *
596nvc0_vp_state_create(struct pipe_context *pipe,
597                     const struct pipe_shader_state *cso)
598{
599   return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);
600}
601
602static void
603nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso)
604{
605    struct nvc0_context *nvc0 = nvc0_context(pipe);
606
607    nvc0->vertprog = hwcso;
608    nvc0->dirty |= NVC0_NEW_VERTPROG;
609}
610
611static void *
612nvc0_fp_state_create(struct pipe_context *pipe,
613                     const struct pipe_shader_state *cso)
614{
615   return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);
616}
617
618static void
619nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso)
620{
621    struct nvc0_context *nvc0 = nvc0_context(pipe);
622
623    nvc0->fragprog = hwcso;
624    nvc0->dirty |= NVC0_NEW_FRAGPROG;
625}
626
627static void *
628nvc0_gp_state_create(struct pipe_context *pipe,
629                     const struct pipe_shader_state *cso)
630{
631   return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);
632}
633
634static void
635nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso)
636{
637    struct nvc0_context *nvc0 = nvc0_context(pipe);
638
639    nvc0->gmtyprog = hwcso;
640    nvc0->dirty |= NVC0_NEW_GMTYPROG;
641}
642
643static void
644nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
645                         struct pipe_resource *res)
646{
647   struct nvc0_context *nvc0 = nvc0_context(pipe);
648
649   switch (shader) {
650   case PIPE_SHADER_VERTEX: shader = 0; break;
651      /*
652   case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break;
653   case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break;
654      */
655   case PIPE_SHADER_GEOMETRY: shader = 3; break;
656   case PIPE_SHADER_FRAGMENT: shader = 4; break;
657   default:
658      assert(0);
659      break;
660   }
661
662   if (nvc0->constbuf[shader][index])
663      nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
664			       nvc0_resource(
665				       nvc0->constbuf[shader][index]));
666
667   pipe_resource_reference(&nvc0->constbuf[shader][index], res);
668
669   nvc0->constbuf_dirty[shader] |= 1 << index;
670
671   nvc0->dirty |= NVC0_NEW_CONSTBUF;
672}
673
674/* =============================================================================
675 */
676
677static void
678nvc0_set_blend_color(struct pipe_context *pipe,
679                     const struct pipe_blend_color *bcol)
680{
681    struct nvc0_context *nvc0 = nvc0_context(pipe);
682
683    nvc0->blend_colour = *bcol;
684    nvc0->dirty |= NVC0_NEW_BLEND_COLOUR;
685}
686
687static void
688nvc0_set_stencil_ref(struct pipe_context *pipe,
689                     const struct pipe_stencil_ref *sr)
690{
691    struct nvc0_context *nvc0 = nvc0_context(pipe);
692
693    nvc0->stencil_ref = *sr;
694    nvc0->dirty |= NVC0_NEW_STENCIL_REF;
695}
696
697static void
698nvc0_set_clip_state(struct pipe_context *pipe,
699                    const struct pipe_clip_state *clip)
700{
701    struct nvc0_context *nvc0 = nvc0_context(pipe);
702    const unsigned size = clip->nr * sizeof(clip->ucp[0]);
703
704    memcpy(&nvc0->clip.ucp[0][0], &clip->ucp[0][0], size);
705    nvc0->clip.nr = clip->nr;
706
707    nvc0->clip.depth_clamp = clip->depth_clamp;
708
709    nvc0->dirty |= NVC0_NEW_CLIP;
710}
711
712static void
713nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
714{
715    struct nvc0_context *nvc0 = nvc0_context(pipe);
716
717    nvc0->sample_mask = sample_mask;
718    nvc0->dirty |= NVC0_NEW_SAMPLE_MASK;
719}
720
721
722static void
723nvc0_set_framebuffer_state(struct pipe_context *pipe,
724                           const struct pipe_framebuffer_state *fb)
725{
726    struct nvc0_context *nvc0 = nvc0_context(pipe);
727
728    nvc0->framebuffer = *fb;
729    nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
730}
731
732static void
733nvc0_set_polygon_stipple(struct pipe_context *pipe,
734                         const struct pipe_poly_stipple *stipple)
735{
736    struct nvc0_context *nvc0 = nvc0_context(pipe);
737
738    nvc0->stipple = *stipple;
739    nvc0->dirty |= NVC0_NEW_STIPPLE;
740}
741
742static void
743nvc0_set_scissor_state(struct pipe_context *pipe,
744                       const struct pipe_scissor_state *scissor)
745{
746    struct nvc0_context *nvc0 = nvc0_context(pipe);
747
748    nvc0->scissor = *scissor;
749    nvc0->dirty |= NVC0_NEW_SCISSOR;
750}
751
752static void
753nvc0_set_viewport_state(struct pipe_context *pipe,
754                        const struct pipe_viewport_state *vpt)
755{
756    struct nvc0_context *nvc0 = nvc0_context(pipe);
757
758    nvc0->viewport = *vpt;
759    nvc0->dirty |= NVC0_NEW_VIEWPORT;
760}
761
762static void
763nvc0_set_vertex_buffers(struct pipe_context *pipe,
764                        unsigned count,
765                        const struct pipe_vertex_buffer *vb)
766{
767    struct nvc0_context *nvc0 = nvc0_context(pipe);
768
769    memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
770    nvc0->num_vtxbufs = count;
771
772    nvc0->dirty |= NVC0_NEW_ARRAYS;
773}
774
775static void
776nvc0_set_index_buffer(struct pipe_context *pipe,
777                      const struct pipe_index_buffer *ib)
778{
779    struct nvc0_context *nvc0 = nvc0_context(pipe);
780
781    if (ib)
782        memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
783    else
784        nvc0->idxbuf.buffer = NULL;
785}
786
787static void
788nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
789{
790    struct nvc0_context *nvc0 = nvc0_context(pipe);
791
792    nvc0->vertex = hwcso;
793    nvc0->dirty |= NVC0_NEW_VERTEX;
794}
795
796void
797nvc0_init_state_functions(struct nvc0_context *nvc0)
798{
799    nvc0->pipe.create_blend_state = nvc0_blend_state_create;
800    nvc0->pipe.bind_blend_state = nvc0_blend_state_bind;
801    nvc0->pipe.delete_blend_state = nvc0_blend_state_delete;
802
803    nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create;
804    nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind;
805    nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete;
806
807    nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create;
808    nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind;
809    nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete;
810
811    nvc0->pipe.create_sampler_state = nvc0_sampler_state_create;
812    nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete;
813    nvc0->pipe.bind_vertex_sampler_states   = nvc0_vp_sampler_states_bind;
814    nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind;
815    nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind;
816
817    nvc0->pipe.create_sampler_view = nvc0_create_sampler_view;
818    nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy;
819    nvc0->pipe.set_vertex_sampler_views   = nvc0_vp_set_sampler_views;
820    nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views;
821    nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views;
822
823    nvc0->pipe.create_vs_state = nvc0_vp_state_create;
824    nvc0->pipe.create_fs_state = nvc0_fp_state_create;
825    nvc0->pipe.create_gs_state = nvc0_gp_state_create;
826    nvc0->pipe.bind_vs_state = nvc0_vp_state_bind;
827    nvc0->pipe.bind_fs_state = nvc0_fp_state_bind;
828    nvc0->pipe.bind_gs_state = nvc0_gp_state_bind;
829    nvc0->pipe.delete_vs_state = nvc0_sp_state_delete;
830    nvc0->pipe.delete_fs_state = nvc0_sp_state_delete;
831    nvc0->pipe.delete_gs_state = nvc0_sp_state_delete;
832
833    nvc0->pipe.set_blend_color = nvc0_set_blend_color;
834    nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref;
835    nvc0->pipe.set_clip_state = nvc0_set_clip_state;
836    nvc0->pipe.set_sample_mask = nvc0_set_sample_mask;
837    nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer;
838    nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state;
839    nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple;
840    nvc0->pipe.set_scissor_state = nvc0_set_scissor_state;
841    nvc0->pipe.set_viewport_state = nvc0_set_viewport_state;
842
843    nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create;
844    nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete;
845    nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind;
846
847    nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers;
848    nvc0->pipe.set_index_buffer = nvc0_set_index_buffer;
849}
850
851