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