• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 /* Authors:  Keith Whitwell <keithw@vmware.com>
29  */
30 
31 #include "compiler/nir/nir_builder.h"
32 #include "draw/draw_context.h"
33 #include "nir/nir_to_tgsi.h"
34 #include "tgsi/tgsi_parse.h"
35 #include "util/u_helpers.h"
36 #include "util/u_inlines.h"
37 #include "util/u_math.h"
38 #include "util/u_memory.h"
39 #include "util/u_transfer.h"
40 #include "nir.h"
41 
42 #include "i915_context.h"
43 #include "i915_debug.h"
44 #include "i915_fpc.h"
45 #include "i915_reg.h"
46 #include "i915_resource.h"
47 #include "i915_state.h"
48 #include "i915_state_inlines.h"
49 
50 static void i915_delete_fs_state(struct pipe_context *pipe, void *shader);
51 
52 /* The i915 (and related graphics cores) do not support GL_CLAMP.  The
53  * Intel drivers for "other operating systems" implement GL_CLAMP as
54  * GL_CLAMP_TO_EDGE, so the same is done here.
55  */
56 static unsigned
translate_wrap_mode(unsigned wrap)57 translate_wrap_mode(unsigned wrap)
58 {
59    switch (wrap) {
60    case PIPE_TEX_WRAP_REPEAT:
61       return TEXCOORDMODE_WRAP;
62    case PIPE_TEX_WRAP_CLAMP:
63       return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */
64    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
65       return TEXCOORDMODE_CLAMP_EDGE;
66    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
67       return TEXCOORDMODE_CLAMP_BORDER;
68    case PIPE_TEX_WRAP_MIRROR_REPEAT:
69       return TEXCOORDMODE_MIRROR;
70    default:
71       return TEXCOORDMODE_WRAP;
72    }
73 }
74 
75 static unsigned
translate_img_filter(unsigned filter)76 translate_img_filter(unsigned filter)
77 {
78    switch (filter) {
79    case PIPE_TEX_FILTER_NEAREST:
80       return FILTER_NEAREST;
81    case PIPE_TEX_FILTER_LINEAR:
82       return FILTER_LINEAR;
83    default:
84       assert(0);
85       return FILTER_NEAREST;
86    }
87 }
88 
89 static unsigned
translate_mip_filter(unsigned filter)90 translate_mip_filter(unsigned filter)
91 {
92    switch (filter) {
93    case PIPE_TEX_MIPFILTER_NONE:
94       return MIPFILTER_NONE;
95    case PIPE_TEX_MIPFILTER_NEAREST:
96       return MIPFILTER_NEAREST;
97    case PIPE_TEX_MIPFILTER_LINEAR:
98       return MIPFILTER_LINEAR;
99    default:
100       assert(0);
101       return MIPFILTER_NONE;
102    }
103 }
104 
105 static uint32_t
i915_remap_lis6_blend_dst_alpha(uint32_t lis6,uint32_t normal,uint32_t inv)106 i915_remap_lis6_blend_dst_alpha(uint32_t lis6, uint32_t normal, uint32_t inv)
107 {
108    uint32_t src = (lis6 >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK;
109    lis6 &= ~SRC_BLND_FACT(BLENDFACT_MASK);
110    if (src == BLENDFACT_DST_ALPHA)
111       src = normal;
112    else if (src == BLENDFACT_INV_DST_ALPHA)
113       src = inv;
114    lis6 |= SRC_BLND_FACT(src);
115 
116    uint32_t dst = (lis6 >> S6_CBUF_DST_BLEND_FACT_SHIFT) & BLENDFACT_MASK;
117    lis6 &= ~DST_BLND_FACT(BLENDFACT_MASK);
118    if (dst == BLENDFACT_DST_ALPHA)
119       dst = normal;
120    else if (dst == BLENDFACT_INV_DST_ALPHA)
121       dst = inv;
122    lis6 |= DST_BLND_FACT(dst);
123 
124    return lis6;
125 }
126 
127 static uint32_t
i915_remap_iab_blend_dst_alpha(uint32_t iab,uint32_t normal,uint32_t inv)128 i915_remap_iab_blend_dst_alpha(uint32_t iab, uint32_t normal, uint32_t inv)
129 {
130    uint32_t src = (iab >> IAB_SRC_FACTOR_SHIFT) & BLENDFACT_MASK;
131    iab &= ~SRC_BLND_FACT(BLENDFACT_MASK);
132    if (src == BLENDFACT_DST_ALPHA)
133       src = normal;
134    else if (src == BLENDFACT_INV_DST_ALPHA)
135       src = inv;
136    iab |= SRC_ABLND_FACT(src);
137 
138    uint32_t dst = (iab >> IAB_DST_FACTOR_SHIFT) & BLENDFACT_MASK;
139    iab &= ~DST_BLND_FACT(BLENDFACT_MASK);
140    if (dst == BLENDFACT_DST_ALPHA)
141       dst = normal;
142    else if (dst == BLENDFACT_INV_DST_ALPHA)
143       dst = inv;
144    iab |= DST_ABLND_FACT(dst);
145 
146    return iab;
147 }
148 
149 /* None of this state is actually used for anything yet.
150  */
151 static void *
i915_create_blend_state(struct pipe_context * pipe,const struct pipe_blend_state * blend)152 i915_create_blend_state(struct pipe_context *pipe,
153                         const struct pipe_blend_state *blend)
154 {
155    struct i915_blend_state *cso_data = CALLOC_STRUCT(i915_blend_state);
156 
157    {
158       unsigned eqRGB = blend->rt[0].rgb_func;
159       unsigned srcRGB = blend->rt[0].rgb_src_factor;
160       unsigned dstRGB = blend->rt[0].rgb_dst_factor;
161 
162       unsigned eqA = blend->rt[0].alpha_func;
163       unsigned srcA = blend->rt[0].alpha_src_factor;
164       unsigned dstA = blend->rt[0].alpha_dst_factor;
165 
166       /* Special handling for MIN/MAX filter modes handled at
167        * frontend level.
168        */
169 
170       if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
171 
172          cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
173                           IAB_MODIFY_ENABLE | IAB_ENABLE | IAB_MODIFY_FUNC |
174                           IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR |
175                           SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) |
176                           DST_ABLND_FACT(i915_translate_blend_factor(dstA)) |
177                           (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT));
178       } else {
179          cso_data->iab =
180             (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 0);
181       }
182    }
183 
184    cso_data->modes4 |=
185       (_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC |
186        LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func)));
187 
188    if (blend->logicop_enable)
189       cso_data->LIS5 |= S5_LOGICOP_ENABLE;
190 
191    if (blend->dither)
192       cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE;
193 
194    /* We potentially do some fixup at emission for non-BGRA targets */
195    if ((blend->rt[0].colormask & PIPE_MASK_R) == 0)
196       cso_data->LIS5 |= S5_WRITEDISABLE_RED;
197 
198    if ((blend->rt[0].colormask & PIPE_MASK_G) == 0)
199       cso_data->LIS5 |= S5_WRITEDISABLE_GREEN;
200 
201    if ((blend->rt[0].colormask & PIPE_MASK_B) == 0)
202       cso_data->LIS5 |= S5_WRITEDISABLE_BLUE;
203 
204    if ((blend->rt[0].colormask & PIPE_MASK_A) == 0)
205       cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA;
206 
207    if (blend->rt[0].blend_enable) {
208       unsigned funcRGB = blend->rt[0].rgb_func;
209       unsigned srcRGB = blend->rt[0].rgb_src_factor;
210       unsigned dstRGB = blend->rt[0].rgb_dst_factor;
211 
212       cso_data->LIS6 |=
213          (S6_CBUF_BLEND_ENABLE |
214           SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) |
215           DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) |
216           (i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT));
217    }
218 
219    cso_data->LIS6_alpha_in_g = i915_remap_lis6_blend_dst_alpha(
220       cso_data->LIS6, BLENDFACT_DST_COLR, BLENDFACT_INV_DST_COLR);
221    cso_data->LIS6_alpha_is_x = i915_remap_lis6_blend_dst_alpha(
222       cso_data->LIS6, BLENDFACT_ONE, BLENDFACT_ZERO);
223 
224    cso_data->iab_alpha_in_g = i915_remap_iab_blend_dst_alpha(
225       cso_data->iab, BLENDFACT_DST_COLR, BLENDFACT_INV_DST_COLR);
226    cso_data->iab_alpha_is_x = i915_remap_iab_blend_dst_alpha(
227       cso_data->iab, BLENDFACT_ONE, BLENDFACT_ZERO);
228 
229    return cso_data;
230 }
231 
232 static void
i915_bind_blend_state(struct pipe_context * pipe,void * blend)233 i915_bind_blend_state(struct pipe_context *pipe, void *blend)
234 {
235    struct i915_context *i915 = i915_context(pipe);
236 
237    if (i915->blend == blend)
238       return;
239 
240    i915->blend = (struct i915_blend_state *)blend;
241 
242    i915->dirty |= I915_NEW_BLEND;
243 }
244 
245 static void
i915_delete_blend_state(struct pipe_context * pipe,void * blend)246 i915_delete_blend_state(struct pipe_context *pipe, void *blend)
247 {
248    FREE(blend);
249 }
250 
251 static void
i915_set_blend_color(struct pipe_context * pipe,const struct pipe_blend_color * blend_color)252 i915_set_blend_color(struct pipe_context *pipe,
253                      const struct pipe_blend_color *blend_color)
254 {
255    struct i915_context *i915 = i915_context(pipe);
256 
257    if (!blend_color)
258       return;
259 
260    i915->blend_color = *blend_color;
261 
262    i915->dirty |= I915_NEW_BLEND;
263 }
264 
265 static void
i915_set_stencil_ref(struct pipe_context * pipe,const struct pipe_stencil_ref stencil_ref)266 i915_set_stencil_ref(struct pipe_context *pipe,
267                      const struct pipe_stencil_ref stencil_ref)
268 {
269    struct i915_context *i915 = i915_context(pipe);
270 
271    i915->stencil_ref = stencil_ref;
272 
273    i915->dirty |= I915_NEW_DEPTH_STENCIL;
274 }
275 
276 static void *
i915_create_sampler_state(struct pipe_context * pipe,const struct pipe_sampler_state * sampler)277 i915_create_sampler_state(struct pipe_context *pipe,
278                           const struct pipe_sampler_state *sampler)
279 {
280    struct i915_sampler_state *cso = CALLOC_STRUCT(i915_sampler_state);
281    const unsigned ws = sampler->wrap_s;
282    const unsigned wt = sampler->wrap_t;
283    const unsigned wr = sampler->wrap_r;
284    unsigned minFilt, magFilt;
285    unsigned mipFilt;
286 
287    cso->templ = *sampler;
288 
289    mipFilt = translate_mip_filter(sampler->min_mip_filter);
290    minFilt = translate_img_filter(sampler->min_img_filter);
291    magFilt = translate_img_filter(sampler->mag_img_filter);
292 
293    if (sampler->max_anisotropy > 1)
294       minFilt = magFilt = FILTER_ANISOTROPIC;
295 
296    if (sampler->max_anisotropy > 2) {
297       cso->state[0] |= SS2_MAX_ANISO_4;
298    }
299 
300    {
301       int b = (int)(sampler->lod_bias * 16.0);
302       b = CLAMP(b, -256, 255);
303       cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
304    }
305 
306    /* Shadow:
307     */
308    if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
309       cso->state[0] |= (SS2_SHADOW_ENABLE | i915_translate_shadow_compare_func(
310                                                sampler->compare_func));
311 
312       minFilt = FILTER_4X4_FLAT;
313       magFilt = FILTER_4X4_FLAT;
314    }
315 
316    cso->state[0] |=
317       ((minFilt << SS2_MIN_FILTER_SHIFT) | (mipFilt << SS2_MIP_FILTER_SHIFT) |
318        (magFilt << SS2_MAG_FILTER_SHIFT));
319 
320    cso->state[1] |= ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
321                      (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
322                      (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
323 
324    if (!sampler->unnormalized_coords)
325       cso->state[1] |= SS3_NORMALIZED_COORDS;
326 
327    {
328       int minlod = (int)(16.0 * sampler->min_lod);
329       int maxlod = (int)(16.0 * sampler->max_lod);
330       minlod = CLAMP(minlod, 0, 16 * 11);
331       maxlod = CLAMP(maxlod, 0, 16 * 11);
332 
333       if (minlod > maxlod)
334          maxlod = minlod;
335 
336       cso->minlod = minlod;
337       cso->maxlod = maxlod;
338    }
339 
340    {
341       uint8_t r = float_to_ubyte(sampler->border_color.f[0]);
342       uint8_t g = float_to_ubyte(sampler->border_color.f[1]);
343       uint8_t b = float_to_ubyte(sampler->border_color.f[2]);
344       uint8_t a = float_to_ubyte(sampler->border_color.f[3]);
345       cso->state[2] = I915PACKCOLOR8888(r, g, b, a);
346    }
347    return cso;
348 }
349 
350 static void
i915_bind_sampler_states(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned num,void ** samplers)351 i915_bind_sampler_states(struct pipe_context *pipe,
352                          enum pipe_shader_type shader, unsigned start,
353                          unsigned num, void **samplers)
354 {
355    if (shader != PIPE_SHADER_FRAGMENT) {
356       assert(num == 0);
357       return;
358    }
359 
360    struct i915_context *i915 = i915_context(pipe);
361    unsigned i;
362 
363    /* Check for no-op */
364    if (num == i915->num_samplers &&
365        !memcmp(i915->fragment_sampler + start, samplers, num * sizeof(void *)))
366       return;
367 
368    for (i = 0; i < num; ++i)
369       i915->fragment_sampler[i + start] = samplers[i];
370 
371    /* find highest non-null samplers[] entry */
372    {
373       unsigned j = MAX2(i915->num_samplers, start + num);
374       while (j > 0 && i915->fragment_sampler[j - 1] == NULL)
375          j--;
376       i915->num_samplers = j;
377    }
378 
379    i915->dirty |= I915_NEW_SAMPLER;
380 }
381 
382 static void
i915_delete_sampler_state(struct pipe_context * pipe,void * sampler)383 i915_delete_sampler_state(struct pipe_context *pipe, void *sampler)
384 {
385    FREE(sampler);
386 }
387 
388 /** XXX move someday?  Or consolidate all these simple state setters
389  * into one file.
390  */
391 
392 static uint32_t
i915_get_modes4_stencil(const struct pipe_stencil_state * stencil)393 i915_get_modes4_stencil(const struct pipe_stencil_state *stencil)
394 {
395    int testmask = stencil->valuemask & 0xff;
396    int writemask = stencil->writemask & 0xff;
397 
398    return (_3DSTATE_MODES_4_CMD | ENABLE_STENCIL_TEST_MASK |
399            STENCIL_TEST_MASK(testmask) | ENABLE_STENCIL_WRITE_MASK |
400            STENCIL_WRITE_MASK(writemask));
401 }
402 
403 static uint32_t
i915_get_lis5_stencil(const struct pipe_stencil_state * stencil)404 i915_get_lis5_stencil(const struct pipe_stencil_state *stencil)
405 {
406    int test = i915_translate_compare_func(stencil->func);
407    int fop = i915_translate_stencil_op(stencil->fail_op);
408    int dfop = i915_translate_stencil_op(stencil->zfail_op);
409    int dpop = i915_translate_stencil_op(stencil->zpass_op);
410 
411    return (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE |
412            (test << S5_STENCIL_TEST_FUNC_SHIFT) |
413            (fop << S5_STENCIL_FAIL_SHIFT) |
414            (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) |
415            (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));
416 }
417 
418 static uint32_t
i915_get_bfo(const struct pipe_stencil_state * stencil)419 i915_get_bfo(const struct pipe_stencil_state *stencil)
420 {
421    int test = i915_translate_compare_func(stencil->func);
422    int fop = i915_translate_stencil_op(stencil->fail_op);
423    int dfop = i915_translate_stencil_op(stencil->zfail_op);
424    int dpop = i915_translate_stencil_op(stencil->zpass_op);
425 
426    return (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_FUNCS |
427            BFO_ENABLE_STENCIL_TWO_SIDE | BFO_ENABLE_STENCIL_REF |
428            BFO_STENCIL_TWO_SIDE | (test << BFO_STENCIL_TEST_SHIFT) |
429            (fop << BFO_STENCIL_FAIL_SHIFT) |
430            (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
431            (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
432 }
433 
434 static uint32_t
i915_get_bfm(const struct pipe_stencil_state * stencil)435 i915_get_bfm(const struct pipe_stencil_state *stencil)
436 {
437    return (_3DSTATE_BACKFACE_STENCIL_MASKS | BFM_ENABLE_STENCIL_TEST_MASK |
438            BFM_ENABLE_STENCIL_WRITE_MASK |
439            ((stencil->valuemask & 0xff) << BFM_STENCIL_TEST_MASK_SHIFT) |
440            ((stencil->writemask & 0xff) << BFM_STENCIL_WRITE_MASK_SHIFT));
441 }
442 
443 static void *
i915_create_depth_stencil_state(struct pipe_context * pipe,const struct pipe_depth_stencil_alpha_state * depth_stencil)444 i915_create_depth_stencil_state(
445    struct pipe_context *pipe,
446    const struct pipe_depth_stencil_alpha_state *depth_stencil)
447 {
448    struct i915_depth_stencil_state *cso =
449       CALLOC_STRUCT(i915_depth_stencil_state);
450 
451    cso->stencil_modes4_cw = i915_get_modes4_stencil(&depth_stencil->stencil[0]);
452    cso->stencil_modes4_ccw =
453       i915_get_modes4_stencil(&depth_stencil->stencil[1]);
454 
455    if (depth_stencil->stencil[0].enabled) {
456       cso->stencil_LIS5_cw = i915_get_lis5_stencil(&depth_stencil->stencil[0]);
457    }
458 
459    if (depth_stencil->stencil[1].enabled) {
460       cso->bfo_cw[0] = i915_get_bfo(&depth_stencil->stencil[1]);
461       cso->bfo_cw[1] = i915_get_bfm(&depth_stencil->stencil[1]);
462 
463       /* Precompute the backface stencil settings if front winding order is
464        * reversed -- HW doesn't have a bit to flip it for us.
465        */
466       cso->stencil_LIS5_ccw = i915_get_lis5_stencil(&depth_stencil->stencil[1]);
467       cso->bfo_ccw[0] = i915_get_bfo(&depth_stencil->stencil[0]);
468       cso->bfo_ccw[1] = i915_get_bfm(&depth_stencil->stencil[0]);
469    } else {
470       /* This actually disables two-side stencil: The bit set is a
471        * modify-enable bit to indicate we are changing the two-side
472        * setting.  Then there is a symbolic zero to show that we are
473        * setting the flag to zero/off.
474        */
475       cso->bfo_cw[0] = cso->bfo_ccw[0] =
476          (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);
477       cso->bfo_cw[1] = cso->bfo_ccw[1] = 0;
478 
479       cso->stencil_LIS5_ccw = cso->stencil_LIS5_cw;
480    }
481 
482    if (depth_stencil->depth_enabled) {
483       int func = i915_translate_compare_func(depth_stencil->depth_func);
484 
485       cso->depth_LIS6 |=
486          (S6_DEPTH_TEST_ENABLE | (func << S6_DEPTH_TEST_FUNC_SHIFT));
487 
488       if (depth_stencil->depth_writemask)
489          cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE;
490    }
491 
492    if (depth_stencil->alpha_enabled) {
493       int test = i915_translate_compare_func(depth_stencil->alpha_func);
494       uint8_t refByte = float_to_ubyte(depth_stencil->alpha_ref_value);
495 
496       cso->depth_LIS6 |=
497          (S6_ALPHA_TEST_ENABLE | (test << S6_ALPHA_TEST_FUNC_SHIFT) |
498           (((unsigned)refByte) << S6_ALPHA_REF_SHIFT));
499    }
500 
501    return cso;
502 }
503 
504 static void
i915_bind_depth_stencil_state(struct pipe_context * pipe,void * depth_stencil)505 i915_bind_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
506 {
507    struct i915_context *i915 = i915_context(pipe);
508 
509    if (i915->depth_stencil == depth_stencil)
510       return;
511 
512    i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil;
513 
514    i915->dirty |= I915_NEW_DEPTH_STENCIL;
515 }
516 
517 static void
i915_delete_depth_stencil_state(struct pipe_context * pipe,void * depth_stencil)518 i915_delete_depth_stencil_state(struct pipe_context *pipe, void *depth_stencil)
519 {
520    FREE(depth_stencil);
521 }
522 
523 static void
i915_set_scissor_states(struct pipe_context * pipe,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * scissor)524 i915_set_scissor_states(struct pipe_context *pipe, unsigned start_slot,
525                         unsigned num_scissors,
526                         const struct pipe_scissor_state *scissor)
527 {
528    struct i915_context *i915 = i915_context(pipe);
529 
530    memcpy(&i915->scissor, scissor, sizeof(*scissor));
531    i915->dirty |= I915_NEW_SCISSOR;
532 }
533 
534 static void
i915_set_polygon_stipple(struct pipe_context * pipe,const struct pipe_poly_stipple * stipple)535 i915_set_polygon_stipple(struct pipe_context *pipe,
536                          const struct pipe_poly_stipple *stipple)
537 {
538 }
539 
540 static const struct nir_to_tgsi_options ntt_options = {
541    .lower_fabs = true,
542 };
543 
544 static char *
i915_check_control_flow(nir_shader * s)545 i915_check_control_flow(nir_shader *s)
546 {
547    nir_function_impl *impl = nir_shader_get_entrypoint(s);
548    nir_block *first = nir_start_block(impl);
549    nir_cf_node *next = nir_cf_node_next(&first->cf_node);
550 
551    if (next) {
552       switch (next->type) {
553       case nir_cf_node_if:
554          return "if/then statements not supported by i915 fragment shaders, "
555                 "should have been flattened by peephole_select.";
556       case nir_cf_node_loop:
557          return "looping not supported i915 fragment shaders, all loops "
558                 "must be statically unrollable.";
559       default:
560          return "Unknown control flow type";
561       }
562    }
563 
564    return NULL;
565 }
566 
567 static void *
i915_create_fs_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)568 i915_create_fs_state(struct pipe_context *pipe,
569                      const struct pipe_shader_state *templ)
570 {
571    struct i915_context *i915 = i915_context(pipe);
572    struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
573    if (!ifs)
574       return NULL;
575 
576    ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
577 
578    if (templ->type == PIPE_SHADER_IR_NIR) {
579       nir_shader *s = templ->ir.nir;
580       ifs->internal = s->info.internal;
581 
582       char *msg = i915_check_control_flow(s);
583       if (msg) {
584          if (I915_DBG_ON(DBG_FS) &&
585              (!s->info.internal || NIR_DEBUG(PRINT_INTERNAL))) {
586             mesa_logi("failing shader:");
587             nir_log_shaderi(s);
588          }
589          if (templ->report_compile_error) {
590             ((struct pipe_shader_state *)templ)->error_message = strdup(msg);
591             ralloc_free(s);
592             i915_delete_fs_state(NULL, ifs);
593             return NULL;
594          }
595       }
596 
597       ifs->state.tokens = nir_to_tgsi_options(s, pipe->screen, &ntt_options);
598    } else {
599       assert(templ->type == PIPE_SHADER_IR_TGSI);
600       /* we need to keep a local copy of the tokens */
601       ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
602       ifs->internal = i915->no_log_program_errors;
603    }
604 
605    ifs->state.type = PIPE_SHADER_IR_TGSI;
606 
607    tgsi_scan_shader(ifs->state.tokens, &ifs->info);
608 
609    /* The shader's compiled to i915 instructions here */
610    i915_translate_fragment_program(i915, ifs);
611    if (ifs->error && templ->report_compile_error) {
612       ((struct pipe_shader_state *)templ)->error_message = strdup(ifs->error);
613       i915_delete_fs_state(NULL, ifs);
614       return NULL;
615    }
616 
617    return ifs;
618 }
619 
620 static void
i915_bind_fs_state(struct pipe_context * pipe,void * shader)621 i915_bind_fs_state(struct pipe_context *pipe, void *shader)
622 {
623    struct i915_context *i915 = i915_context(pipe);
624 
625    if (i915->fs == shader)
626       return;
627 
628    i915->fs = (struct i915_fragment_shader *)shader;
629 
630    draw_bind_fragment_shader(i915->draw,
631                              (i915->fs ? i915->fs->draw_data : NULL));
632 
633    /* Tell draw if we need to do point sprites so we can get PNTC. */
634    if (i915->fs)
635       draw_wide_point_sprites(i915->draw, i915->fs->reads_pntc);
636 
637    i915->dirty |= I915_NEW_FS;
638 }
639 
640 static void
i915_delete_fs_state(struct pipe_context * pipe,void * shader)641 i915_delete_fs_state(struct pipe_context *pipe, void *shader)
642 {
643    struct i915_fragment_shader *ifs = (struct i915_fragment_shader *)shader;
644 
645    ralloc_free(ifs->error);
646    FREE(ifs->program);
647    ifs->program = NULL;
648    FREE((struct tgsi_token *)ifs->state.tokens);
649    ifs->state.tokens = NULL;
650 
651    ifs->program_len = 0;
652 
653    FREE(ifs);
654 }
655 
656 static void *
i915_create_vs_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)657 i915_create_vs_state(struct pipe_context *pipe,
658                      const struct pipe_shader_state *templ)
659 {
660    struct i915_context *i915 = i915_context(pipe);
661 
662    struct pipe_shader_state from_nir = {PIPE_SHADER_IR_TGSI};
663    if (templ->type == PIPE_SHADER_IR_NIR) {
664       nir_shader *s = templ->ir.nir;
665 
666       NIR_PASS_V(s, nir_lower_point_size, 1.0, 255.0);
667 
668       /* The gallivm draw path doesn't support non-native-integers NIR shaders,
669        * st/mesa does native-integers for the screen as a whole rather than
670        * per-stage, and i915 FS can't do native integers.  So, convert to TGSI,
671        * where the draw path *does* support non-native-integers.
672        */
673       from_nir.tokens = nir_to_tgsi(s, pipe->screen);
674       templ = &from_nir;
675    }
676 
677    return draw_create_vertex_shader(i915->draw, templ);
678 }
679 
680 static void
i915_bind_vs_state(struct pipe_context * pipe,void * shader)681 i915_bind_vs_state(struct pipe_context *pipe, void *shader)
682 {
683    struct i915_context *i915 = i915_context(pipe);
684 
685    if (i915->vs == shader)
686       return;
687 
688    i915->vs = shader;
689 
690    /* just pass-through to draw module */
691    draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *)shader);
692 
693    i915->dirty |= I915_NEW_VS;
694 }
695 
696 static void
i915_delete_vs_state(struct pipe_context * pipe,void * shader)697 i915_delete_vs_state(struct pipe_context *pipe, void *shader)
698 {
699    struct i915_context *i915 = i915_context(pipe);
700 
701    /* just pass-through to draw module */
702    draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *)shader);
703 }
704 
705 static void
i915_set_constant_buffer(struct pipe_context * pipe,enum pipe_shader_type shader,uint32_t index,bool take_ownership,const struct pipe_constant_buffer * cb)706 i915_set_constant_buffer(struct pipe_context *pipe,
707                          enum pipe_shader_type shader, uint32_t index,
708                          bool take_ownership,
709                          const struct pipe_constant_buffer *cb)
710 {
711    struct i915_context *i915 = i915_context(pipe);
712    struct pipe_resource *buf = cb ? cb->buffer : NULL;
713    unsigned new_num = 0;
714    bool diff = true;
715 
716    /* XXX don't support geom shaders now */
717    if (shader == PIPE_SHADER_GEOMETRY)
718       return;
719 
720    if (cb && cb->user_buffer) {
721       buf = i915_user_buffer_create(pipe->screen, (void *)cb->user_buffer,
722                                     cb->buffer_size, PIPE_BIND_CONSTANT_BUFFER);
723    }
724 
725    /* if we have a new buffer compare it with the old one */
726    if (buf) {
727       struct i915_buffer *ibuf = i915_buffer(buf);
728       struct pipe_resource *old_buf = i915->constants[shader];
729       struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL;
730       unsigned old_num = i915->current.num_user_constants[shader];
731 
732       new_num = ibuf->b.width0 / 4 * sizeof(float);
733 
734       if (old_num == new_num) {
735          if (old_num == 0)
736             diff = false;
737 #if 0
738          /* XXX no point in running this code since st/mesa only uses user buffers */
739          /* Can't compare the buffer data since they are userbuffers */
740          else if (old && old->free_on_destroy)
741             diff = memcmp(old->data, ibuf->data, ibuf->b.width0);
742 #else
743          (void)old;
744 #endif
745       }
746    } else {
747       diff = i915->current.num_user_constants[shader] != 0;
748    }
749 
750    if (take_ownership) {
751       pipe_resource_reference(&i915->constants[shader], NULL);
752       i915->constants[shader] = buf;
753    } else {
754       pipe_resource_reference(&i915->constants[shader], buf);
755    }
756    i915->current.num_user_constants[shader] = new_num;
757 
758    if (diff)
759       i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS
760                                                   : I915_NEW_FS_CONSTANTS;
761 
762    if (cb && cb->user_buffer) {
763       pipe_resource_reference(&buf, NULL);
764    }
765 }
766 
767 static void
i915_set_sampler_views(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned num,unsigned unbind_num_trailing_slots,bool take_ownership,struct pipe_sampler_view ** views)768 i915_set_sampler_views(struct pipe_context *pipe, enum pipe_shader_type shader,
769                        unsigned start, unsigned num,
770                        unsigned unbind_num_trailing_slots, bool take_ownership,
771                        struct pipe_sampler_view **views)
772 {
773    if (shader != PIPE_SHADER_FRAGMENT) {
774       /* No support for VS samplers, because it would mean accessing the
775        * write-combined maps of the textures, which is very slow.  VS samplers
776        * are not a required feature of GL2.1 or GLES2.
777        */
778       assert(num == 0);
779       return;
780    }
781    struct i915_context *i915 = i915_context(pipe);
782    uint32_t i;
783 
784    assert(num <= PIPE_MAX_SAMPLERS);
785 
786    /* Check for no-op */
787    if (views && num == i915->num_fragment_sampler_views &&
788        !memcmp(i915->fragment_sampler_views, views,
789                num * sizeof(struct pipe_sampler_view *))) {
790       if (take_ownership) {
791          for (unsigned i = 0; i < num; i++) {
792             struct pipe_sampler_view *view = views[i];
793             pipe_sampler_view_reference(&view, NULL);
794          }
795       }
796       return;
797    }
798 
799    for (i = 0; i < num; i++) {
800       if (take_ownership) {
801          pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL);
802          i915->fragment_sampler_views[i] = views[i];
803       } else {
804          pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
805                                      views[i]);
806       }
807    }
808 
809    for (i = num; i < i915->num_fragment_sampler_views; i++)
810       pipe_sampler_view_reference(&i915->fragment_sampler_views[i], NULL);
811 
812    i915->num_fragment_sampler_views = num;
813 
814    i915->dirty |= I915_NEW_SAMPLER_VIEW;
815 }
816 
817 struct pipe_sampler_view *
i915_create_sampler_view_custom(struct pipe_context * pipe,struct pipe_resource * texture,const struct pipe_sampler_view * templ,unsigned width0,unsigned height0)818 i915_create_sampler_view_custom(struct pipe_context *pipe,
819                                 struct pipe_resource *texture,
820                                 const struct pipe_sampler_view *templ,
821                                 unsigned width0, unsigned height0)
822 {
823    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
824 
825    if (view) {
826       *view = *templ;
827       view->reference.count = 1;
828       view->texture = NULL;
829       pipe_resource_reference(&view->texture, texture);
830       view->context = pipe;
831    }
832 
833    return view;
834 }
835 
836 static struct pipe_sampler_view *
i915_create_sampler_view(struct pipe_context * pipe,struct pipe_resource * texture,const struct pipe_sampler_view * templ)837 i915_create_sampler_view(struct pipe_context *pipe,
838                          struct pipe_resource *texture,
839                          const struct pipe_sampler_view *templ)
840 {
841    struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
842 
843    if (view) {
844       *view = *templ;
845       view->reference.count = 1;
846       view->texture = NULL;
847       pipe_resource_reference(&view->texture, texture);
848       view->context = pipe;
849    }
850 
851    return view;
852 }
853 
854 static void
i915_sampler_view_destroy(struct pipe_context * pipe,struct pipe_sampler_view * view)855 i915_sampler_view_destroy(struct pipe_context *pipe,
856                           struct pipe_sampler_view *view)
857 {
858    pipe_resource_reference(&view->texture, NULL);
859    FREE(view);
860 }
861 
862 static void
i915_set_framebuffer_state(struct pipe_context * pipe,const struct pipe_framebuffer_state * fb)863 i915_set_framebuffer_state(struct pipe_context *pipe,
864                            const struct pipe_framebuffer_state *fb)
865 {
866    struct i915_context *i915 = i915_context(pipe);
867 
868    util_copy_framebuffer_state(&i915->framebuffer, fb);
869    if (fb->nr_cbufs) {
870       struct i915_surface *surf = i915_surface(i915->framebuffer.cbufs[0]);
871       if (i915->current.fixup_swizzle != surf->oc_swizzle) {
872          i915->current.fixup_swizzle = surf->oc_swizzle;
873          memcpy(i915->current.color_swizzle, surf->color_swizzle,
874                 sizeof(surf->color_swizzle));
875          i915->dirty |= I915_NEW_COLOR_SWIZZLE;
876       }
877    }
878    if (fb->zsbuf)
879       draw_set_zs_format(i915->draw, fb->zsbuf->format);
880 
881    i915->dirty |= I915_NEW_FRAMEBUFFER;
882 }
883 
884 static void
i915_set_clip_state(struct pipe_context * pipe,const struct pipe_clip_state * clip)885 i915_set_clip_state(struct pipe_context *pipe,
886                     const struct pipe_clip_state *clip)
887 {
888    struct i915_context *i915 = i915_context(pipe);
889 
890    i915->clip = *clip;
891 
892    draw_set_clip_state(i915->draw, clip);
893 
894    i915->dirty |= I915_NEW_CLIP;
895 }
896 
897 /* Called when gallium frontends notice changes to the viewport
898  * matrix:
899  */
900 static void
i915_set_viewport_states(struct pipe_context * pipe,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * viewport)901 i915_set_viewport_states(struct pipe_context *pipe, unsigned start_slot,
902                          unsigned num_viewports,
903                          const struct pipe_viewport_state *viewport)
904 {
905    struct i915_context *i915 = i915_context(pipe);
906 
907    i915->viewport = *viewport; /* struct copy */
908 
909    /* pass the viewport info to the draw module */
910    draw_set_viewport_states(i915->draw, start_slot, num_viewports,
911                             &i915->viewport);
912 
913    i915->dirty |= I915_NEW_VIEWPORT;
914 }
915 
916 static void *
i915_create_rasterizer_state(struct pipe_context * pipe,const struct pipe_rasterizer_state * rasterizer)917 i915_create_rasterizer_state(struct pipe_context *pipe,
918                              const struct pipe_rasterizer_state *rasterizer)
919 {
920    struct i915_rasterizer_state *cso = CALLOC_STRUCT(i915_rasterizer_state);
921 
922    cso->templ = *rasterizer;
923    cso->light_twoside = rasterizer->light_twoside;
924    cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE;
925    cso->ds[1].f = rasterizer->offset_scale;
926    if (rasterizer->poly_stipple_enable) {
927       cso->st |= ST1_ENABLE;
928    }
929 
930    if (rasterizer->scissor)
931       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT;
932    else
933       cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT;
934 
935    switch (rasterizer->cull_face) {
936    case PIPE_FACE_NONE:
937       cso->LIS4 |= S4_CULLMODE_NONE;
938       break;
939    case PIPE_FACE_FRONT:
940       if (rasterizer->front_ccw)
941          cso->LIS4 |= S4_CULLMODE_CCW;
942       else
943          cso->LIS4 |= S4_CULLMODE_CW;
944       break;
945    case PIPE_FACE_BACK:
946       if (rasterizer->front_ccw)
947          cso->LIS4 |= S4_CULLMODE_CW;
948       else
949          cso->LIS4 |= S4_CULLMODE_CCW;
950       break;
951    case PIPE_FACE_FRONT_AND_BACK:
952       cso->LIS4 |= S4_CULLMODE_BOTH;
953       break;
954    }
955 
956    {
957       int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf);
958 
959       cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT;
960 
961       if (rasterizer->line_smooth)
962          cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE;
963    }
964 
965    {
966       int point_size = CLAMP((int)rasterizer->point_size, 1, 0xff);
967 
968       cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT;
969    }
970 
971    if (rasterizer->flatshade) {
972       cso->LIS4 |=
973          (S4_FLATSHADE_ALPHA | S4_FLATSHADE_COLOR | S4_FLATSHADE_SPECULAR);
974    }
975 
976    if (!rasterizer->flatshade_first)
977       cso->LIS6 |= (2 << S6_TRISTRIP_PV_SHIFT);
978 
979    cso->LIS7 = fui(rasterizer->offset_units);
980 
981    return cso;
982 }
983 
984 static void
i915_bind_rasterizer_state(struct pipe_context * pipe,void * raster)985 i915_bind_rasterizer_state(struct pipe_context *pipe, void *raster)
986 {
987    struct i915_context *i915 = i915_context(pipe);
988 
989    if (i915->rasterizer == raster)
990       return;
991 
992    i915->rasterizer = (struct i915_rasterizer_state *)raster;
993 
994    /* pass-through to draw module */
995    draw_set_rasterizer_state(
996       i915->draw, (i915->rasterizer ? &(i915->rasterizer->templ) : NULL),
997       raster);
998 
999    i915->dirty |= I915_NEW_RASTERIZER;
1000 }
1001 
1002 static void
i915_delete_rasterizer_state(struct pipe_context * pipe,void * raster)1003 i915_delete_rasterizer_state(struct pipe_context *pipe, void *raster)
1004 {
1005    FREE(raster);
1006 }
1007 
1008 static void
i915_set_vertex_buffers(struct pipe_context * pipe,unsigned count,const struct pipe_vertex_buffer * buffers)1009 i915_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
1010                         const struct pipe_vertex_buffer *buffers)
1011 {
1012    struct i915_context *i915 = i915_context(pipe);
1013    struct draw_context *draw = i915->draw;
1014 
1015    util_set_vertex_buffers_count(i915->vertex_buffers, &i915->nr_vertex_buffers,
1016                                  buffers, count, true);
1017 
1018    /* pass-through to draw module */
1019    draw_set_vertex_buffers(draw, count, buffers);
1020 }
1021 
1022 static void *
i915_create_vertex_elements_state(struct pipe_context * pipe,unsigned count,const struct pipe_vertex_element * attribs)1023 i915_create_vertex_elements_state(struct pipe_context *pipe, unsigned count,
1024                                   const struct pipe_vertex_element *attribs)
1025 {
1026    struct i915_velems_state *velems;
1027    assert(count <= PIPE_MAX_ATTRIBS);
1028    velems =
1029       (struct i915_velems_state *)MALLOC(sizeof(struct i915_velems_state));
1030    if (velems) {
1031       velems->count = count;
1032       memcpy(velems->velem, attribs, sizeof(*attribs) * count);
1033    }
1034    return velems;
1035 }
1036 
1037 static void
i915_bind_vertex_elements_state(struct pipe_context * pipe,void * velems)1038 i915_bind_vertex_elements_state(struct pipe_context *pipe, void *velems)
1039 {
1040    struct i915_context *i915 = i915_context(pipe);
1041    struct i915_velems_state *i915_velems = (struct i915_velems_state *)velems;
1042 
1043    if (i915->velems == velems)
1044       return;
1045 
1046    i915->velems = velems;
1047 
1048    /* pass-through to draw module */
1049    if (i915_velems) {
1050       draw_set_vertex_elements(i915->draw, i915_velems->count,
1051                                i915_velems->velem);
1052    }
1053 }
1054 
1055 static void
i915_delete_vertex_elements_state(struct pipe_context * pipe,void * velems)1056 i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
1057 {
1058    FREE(velems);
1059 }
1060 
1061 static void
i915_set_sample_mask(struct pipe_context * pipe,unsigned sample_mask)1062 i915_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
1063 {
1064 }
1065 
1066 void
i915_init_state_functions(struct i915_context * i915)1067 i915_init_state_functions(struct i915_context *i915)
1068 {
1069    i915->base.create_blend_state = i915_create_blend_state;
1070    i915->base.bind_blend_state = i915_bind_blend_state;
1071    i915->base.delete_blend_state = i915_delete_blend_state;
1072 
1073    i915->base.create_sampler_state = i915_create_sampler_state;
1074    i915->base.bind_sampler_states = i915_bind_sampler_states;
1075    i915->base.delete_sampler_state = i915_delete_sampler_state;
1076 
1077    i915->base.create_depth_stencil_alpha_state =
1078       i915_create_depth_stencil_state;
1079    i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
1080    i915->base.delete_depth_stencil_alpha_state =
1081       i915_delete_depth_stencil_state;
1082 
1083    i915->base.create_rasterizer_state = i915_create_rasterizer_state;
1084    i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
1085    i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
1086    i915->base.create_fs_state = i915_create_fs_state;
1087    i915->base.bind_fs_state = i915_bind_fs_state;
1088    i915->base.delete_fs_state = i915_delete_fs_state;
1089    i915->base.create_vs_state = i915_create_vs_state;
1090    i915->base.bind_vs_state = i915_bind_vs_state;
1091    i915->base.delete_vs_state = i915_delete_vs_state;
1092    i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
1093    i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
1094    i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
1095 
1096    i915->base.set_blend_color = i915_set_blend_color;
1097    i915->base.set_stencil_ref = i915_set_stencil_ref;
1098    i915->base.set_clip_state = i915_set_clip_state;
1099    i915->base.set_sample_mask = i915_set_sample_mask;
1100    i915->base.set_constant_buffer = i915_set_constant_buffer;
1101    i915->base.set_framebuffer_state = i915_set_framebuffer_state;
1102 
1103    i915->base.set_polygon_stipple = i915_set_polygon_stipple;
1104    i915->base.set_scissor_states = i915_set_scissor_states;
1105    i915->base.set_sampler_views = i915_set_sampler_views;
1106    i915->base.create_sampler_view = i915_create_sampler_view;
1107    i915->base.sampler_view_destroy = i915_sampler_view_destroy;
1108    i915->base.set_viewport_states = i915_set_viewport_states;
1109    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
1110 }
1111