• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © Microsoft Corporation
3  * Copyright © 2022 Valve Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * on the rights to use, copy, modify, merge, publish, distribute, sub
9  * license, and/or sell copies of the Software, and to permit persons to whom
10  * the Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "nir_builder.h"
26 #include "nir_builtin_builder.h"
27 
28 
29 static const struct glsl_type *
make_2darray_sampler_from_cubemap(const struct glsl_type * type)30 make_2darray_sampler_from_cubemap(const struct glsl_type *type)
31 {
32    return  glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE ?
33             glsl_sampler_type(
34                GLSL_SAMPLER_DIM_2D,
35                false, true,
36                glsl_get_sampler_result_type(type)) : type;
37 }
38 
39 static const struct glsl_type *
make_2darray_from_cubemap_with_array(const struct glsl_type * type)40 make_2darray_from_cubemap_with_array(const struct glsl_type *type)
41 {
42    if (glsl_type_is_array(type)) {
43       const struct glsl_type *new_type = glsl_without_array(type);
44       return new_type != type ? glsl_array_type(make_2darray_from_cubemap_with_array(glsl_without_array(type)),
45                                                 glsl_get_length(type), 0) : type;
46    }
47    return make_2darray_sampler_from_cubemap(type);
48 }
49 
50 static bool
lower_cubemap_to_array_filter(const nir_instr * instr,const void * mask)51 lower_cubemap_to_array_filter(const nir_instr *instr, const void *mask)
52 {
53    const uint32_t *nonseamless_cube_mask = mask;
54    if (instr->type == nir_instr_type_tex) {
55       nir_tex_instr *tex = nir_instr_as_tex(instr);
56 
57       if (tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE)
58          return false;
59 
60       switch (tex->op) {
61       case nir_texop_tex:
62       case nir_texop_txb:
63       case nir_texop_txd:
64       case nir_texop_txl:
65       case nir_texop_txs:
66       case nir_texop_lod:
67       case nir_texop_tg4:
68          break;
69       default:
70          return false;
71       }
72       return (BITFIELD_BIT(tex->sampler_index) & (*nonseamless_cube_mask)) != 0;
73    }
74 
75    return false;
76 }
77 
78 typedef struct {
79    nir_def *rx;
80    nir_def *ry;
81    nir_def *rz;
82    nir_def *arx;
83    nir_def *ary;
84    nir_def *arz;
85    nir_def *array;
86 } coord_t;
87 
88 
89 /* This is taken from from sp_tex_sample:convert_cube */
90 static nir_def *
evaluate_face_x(nir_builder * b,coord_t * coord)91 evaluate_face_x(nir_builder *b, coord_t *coord)
92 {
93    nir_def *sign = nir_fsign(b, coord->rx);
94    nir_def *positive = nir_fge_imm(b, coord->rx, 0.0);
95    nir_def *ima = nir_fdiv(b, nir_imm_float(b, -0.5), coord->arx);
96 
97    nir_def *x = nir_fadd_imm(b, nir_fmul(b, nir_fmul(b, sign, ima), coord->rz), 0.5);
98    nir_def *y = nir_fadd_imm(b, nir_fmul(b, ima, coord->ry), 0.5);
99    nir_def *face = nir_bcsel(b, positive, nir_imm_float(b, 0.0), nir_imm_float(b, 1.0));
100 
101    if (coord->array)
102       face = nir_fadd(b, face, coord->array);
103 
104    return nir_vec3(b, x,y, face);
105 }
106 
107 static nir_def *
evaluate_face_y(nir_builder * b,coord_t * coord)108 evaluate_face_y(nir_builder *b, coord_t *coord)
109 {
110    nir_def *sign = nir_fsign(b, coord->ry);
111    nir_def *positive = nir_fge_imm(b, coord->ry, 0.0);
112    nir_def *ima = nir_fdiv(b, nir_imm_float(b, 0.5), coord->ary);
113 
114    nir_def *x = nir_fadd_imm(b, nir_fmul(b, ima, coord->rx), 0.5);
115    nir_def *y = nir_fadd_imm(b, nir_fmul(b, nir_fmul(b, sign, ima), coord->rz), 0.5);
116    nir_def *face = nir_bcsel(b, positive, nir_imm_float(b, 2.0), nir_imm_float(b, 3.0));
117 
118    if (coord->array)
119       face = nir_fadd(b, face, coord->array);
120 
121    return nir_vec3(b, x,y, face);
122 }
123 
124 static nir_def *
evaluate_face_z(nir_builder * b,coord_t * coord)125 evaluate_face_z(nir_builder *b, coord_t *coord)
126 {
127    nir_def *sign = nir_fsign(b, coord->rz);
128    nir_def *positive = nir_fge_imm(b, coord->rz, 0.0);
129    nir_def *ima = nir_fdiv(b, nir_imm_float(b, -0.5), coord->arz);
130 
131    nir_def *x = nir_fadd_imm(b, nir_fmul(b, nir_fmul(b, sign, ima), nir_fneg(b, coord->rx)), 0.5);
132    nir_def *y = nir_fadd_imm(b, nir_fmul(b, ima, coord->ry), 0.5);
133    nir_def *face = nir_bcsel(b, positive, nir_imm_float(b, 4.0), nir_imm_float(b, 5.0));
134 
135    if (coord->array)
136       face = nir_fadd(b, face, coord->array);
137 
138    return nir_vec3(b, x,y, face);
139 }
140 
141 static nir_def *
create_array_tex_from_cube_tex(nir_builder * b,nir_tex_instr * tex,nir_def * coord,nir_texop op)142 create_array_tex_from_cube_tex(nir_builder *b, nir_tex_instr *tex, nir_def *coord, nir_texop op)
143 {
144    nir_tex_instr *array_tex;
145 
146    unsigned num_srcs = tex->num_srcs;
147    if (op == nir_texop_txf && nir_tex_instr_src_index(tex, nir_tex_src_comparator) != -1)
148       num_srcs--;
149    array_tex = nir_tex_instr_create(b->shader, num_srcs);
150    array_tex->op = op;
151    array_tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
152    array_tex->is_array = true;
153    array_tex->is_shadow = tex->is_shadow;
154    array_tex->is_sparse = tex->is_sparse;
155    array_tex->is_new_style_shadow = tex->is_new_style_shadow;
156    array_tex->texture_index = tex->texture_index;
157    array_tex->sampler_index = tex->sampler_index;
158    array_tex->dest_type = tex->dest_type;
159    array_tex->coord_components = 3;
160 
161    nir_src coord_src = nir_src_for_ssa(coord);
162    unsigned s = 0;
163    for (unsigned i = 0; i < tex->num_srcs; i++) {
164       if (op == nir_texop_txf && tex->src[i].src_type == nir_tex_src_comparator)
165          continue;
166       nir_src *psrc = (tex->src[i].src_type == nir_tex_src_coord) ?
167                          &coord_src : &tex->src[i].src;
168 
169       array_tex->src[s].src_type = tex->src[i].src_type;
170       if (psrc->ssa->num_components != nir_tex_instr_src_size(array_tex, s)) {
171          nir_def *c = nir_trim_vector(b, psrc->ssa,
172                                           nir_tex_instr_src_size(array_tex, s));
173          array_tex->src[s].src = nir_src_for_ssa(c);
174       } else
175          array_tex->src[s].src = nir_src_for_ssa(psrc->ssa);
176       s++;
177    }
178 
179    nir_def_init(&array_tex->instr, &array_tex->def,
180                 nir_tex_instr_dest_size(array_tex),
181                 tex->def.bit_size);
182    nir_builder_instr_insert(b, &array_tex->instr);
183    return &array_tex->def;
184 }
185 
186 static nir_def *
handle_cube_edge(nir_builder * b,nir_def * x,nir_def * y,nir_def * face,nir_def * array_slice_cube_base,nir_def * tex_size)187 handle_cube_edge(nir_builder *b, nir_def *x, nir_def *y, nir_def *face, nir_def *array_slice_cube_base, nir_def *tex_size)
188 {
189    enum cube_remap
190    {
191       cube_remap_zero = 0,
192       cube_remap_x,
193       cube_remap_y,
194       cube_remap_tex_size,
195       cube_remap_tex_size_minus_x,
196       cube_remap_tex_size_minus_y,
197 
198       cube_remap_size,
199    };
200 
201    struct cube_remap_table
202    {
203       enum cube_remap remap_x;
204       enum cube_remap remap_y;
205       uint32_t        remap_face;
206    };
207 
208    static const struct cube_remap_table cube_remap_neg_x[6] =
209    {
210        {cube_remap_tex_size,         cube_remap_y,         4},
211        {cube_remap_tex_size,         cube_remap_y,         5},
212        {cube_remap_y,                cube_remap_zero,      1},
213        {cube_remap_tex_size_minus_y, cube_remap_tex_size,  1},
214        {cube_remap_tex_size,         cube_remap_y,         1},
215        {cube_remap_tex_size,         cube_remap_y,         0},
216    };
217 
218    static const struct cube_remap_table cube_remap_pos_x[6] =
219    {
220        {cube_remap_zero,             cube_remap_y,         5},
221        {cube_remap_zero,             cube_remap_y,         4},
222        {cube_remap_tex_size_minus_y, cube_remap_zero,      0},
223        {cube_remap_y,                cube_remap_tex_size,  0},
224        {cube_remap_zero,             cube_remap_y,         0},
225        {cube_remap_zero,             cube_remap_y,         1},
226    };
227 
228    static const struct cube_remap_table cube_remap_neg_y[6] =
229    {
230        {cube_remap_tex_size,         cube_remap_tex_size_minus_x, 2},
231        {cube_remap_zero,             cube_remap_x,                2},
232        {cube_remap_tex_size_minus_x, cube_remap_zero,             5},
233        {cube_remap_x,                cube_remap_tex_size,         4},
234        {cube_remap_x,                cube_remap_tex_size,         2},
235        {cube_remap_tex_size_minus_x, cube_remap_zero,             2},
236    };
237 
238    static const struct cube_remap_table cube_remap_pos_y[6] =
239    {
240        {cube_remap_tex_size,         cube_remap_x,                   3},
241        {cube_remap_zero,             cube_remap_tex_size_minus_x,    3},
242        {cube_remap_x,                cube_remap_zero,                4},
243        {cube_remap_tex_size_minus_x, cube_remap_tex_size,            5},
244        {cube_remap_x,                cube_remap_zero,                3},
245        {cube_remap_tex_size_minus_x, cube_remap_tex_size,            3},
246    };
247 
248    static const struct cube_remap_table* remap_tables[4] = {
249       cube_remap_neg_x,
250       cube_remap_pos_x,
251       cube_remap_neg_y,
252       cube_remap_pos_y
253    };
254 
255    nir_def *zero = nir_imm_int(b, 0);
256 
257    /* Doesn't matter since the texture is square */
258    tex_size = nir_channel(b, tex_size, 0);
259 
260    nir_def *x_on = nir_iand(b, nir_ige(b, x, zero), nir_ige(b, tex_size, x));
261    nir_def *y_on = nir_iand(b, nir_ige(b, y, zero), nir_ige(b, tex_size, y));
262    nir_def *one_on = nir_ixor(b, x_on, y_on);
263 
264    /* If the sample did not fall off the face in either dimension, then set output = input */
265    nir_def *x_result = x;
266    nir_def *y_result = y;
267    nir_def *face_result = face;
268 
269    /* otherwise, if the sample fell off the face in either the X or the Y direction, remap to the new face */
270    nir_def *remap_predicates[4] =
271    {
272       nir_iand(b, one_on, nir_ilt(b, x, zero)),
273       nir_iand(b, one_on, nir_ilt(b, tex_size, x)),
274       nir_iand(b, one_on, nir_ilt(b, y, zero)),
275       nir_iand(b, one_on, nir_ilt(b, tex_size, y)),
276    };
277 
278    nir_def *remap_array[cube_remap_size];
279 
280    remap_array[cube_remap_zero] = zero;
281    remap_array[cube_remap_x] = x;
282    remap_array[cube_remap_y] = y;
283    remap_array[cube_remap_tex_size] = tex_size;
284    remap_array[cube_remap_tex_size_minus_x] = nir_isub(b, tex_size, x);
285    remap_array[cube_remap_tex_size_minus_y] = nir_isub(b, tex_size, y);
286 
287    /* For each possible way the sample could have fallen off */
288    for (unsigned i = 0; i < 4; i++) {
289       const struct cube_remap_table* remap_table = remap_tables[i];
290 
291       /* For each possible original face */
292       for (unsigned j = 0; j < 6; j++) {
293          nir_def *predicate = nir_iand(b, remap_predicates[i], nir_ieq_imm(b, face, j));
294 
295          x_result = nir_bcsel(b, predicate, remap_array[remap_table[j].remap_x], x_result);
296          y_result = nir_bcsel(b, predicate, remap_array[remap_table[j].remap_y], y_result);
297          face_result = nir_bcsel(b, predicate, remap_array[remap_table[j].remap_face], face_result);
298       }
299    }
300 
301    return nir_vec3(b, x_result, y_result, nir_iadd(b, face_result, array_slice_cube_base));
302 }
303 
304 static nir_def *
handle_cube_gather(nir_builder * b,nir_tex_instr * tex,nir_def * coord)305 handle_cube_gather(nir_builder *b, nir_tex_instr *tex, nir_def *coord)
306 {
307    tex->is_array = true;
308    nir_def *tex_size = nir_get_texture_size(b, tex);
309 
310    /* nir_get_texture_size puts the cursor before the tex op */
311    b->cursor = nir_after_instr(coord->parent_instr);
312 
313    nir_def *const_05 = nir_imm_float(b, 0.5f);
314    nir_def *texel_coords = nir_fmul(b, nir_trim_vector(b, coord, 2),
315                                         nir_i2f32(b, nir_trim_vector(b, tex_size, 2)));
316 
317    nir_def *x_orig = nir_channel(b, texel_coords, 0);
318    nir_def *y_orig = nir_channel(b, texel_coords, 1);
319 
320    nir_def *x_pos = nir_f2i32(b, nir_fadd(b, x_orig, const_05));
321    nir_def *x_neg = nir_f2i32(b, nir_fsub(b, x_orig, const_05));
322    nir_def *y_pos = nir_f2i32(b, nir_fadd(b, y_orig, const_05));
323    nir_def *y_neg = nir_f2i32(b, nir_fsub(b, y_orig, const_05));
324    nir_def *coords[4][2] = {
325       { x_neg, y_pos },
326       { x_pos, y_pos },
327       { x_pos, y_neg },
328       { x_neg, y_neg },
329    };
330 
331    nir_def *array_slice_2d = nir_f2i32(b, nir_channel(b, coord, 2));
332    nir_def *face = nir_imod_imm(b, array_slice_2d, 6);
333    nir_def *array_slice_cube_base = nir_isub(b, array_slice_2d, face);
334 
335    nir_def *channels[4];
336    for (unsigned i = 0; i < 4; ++i) {
337       nir_def *final_coord = handle_cube_edge(b, coords[i][0], coords[i][1], face, array_slice_cube_base, tex_size);
338       nir_def *sampled_val = create_array_tex_from_cube_tex(b, tex, final_coord, nir_texop_txf);
339       channels[i] = nir_channel(b, sampled_val, tex->component);
340    }
341 
342    return nir_vec(b, channels, 4);
343 }
344 
345 static nir_def *
lower_cube_coords(nir_builder * b,nir_def * coord,bool is_array)346 lower_cube_coords(nir_builder *b, nir_def *coord, bool is_array)
347 {
348    coord_t coords;
349    coords.rx = nir_channel(b, coord, 0);
350    coords.ry = nir_channel(b, coord, 1);
351    coords.rz = nir_channel(b, coord, 2);
352    coords.arx = nir_fabs(b, coords.rx);
353    coords.ary = nir_fabs(b, coords.ry);
354    coords.arz = nir_fabs(b, coords.rz);
355    coords.array = NULL;
356    if (is_array)
357       coords.array = nir_fmul_imm(b, nir_channel(b, coord, 3), 6.0f);
358 
359    nir_def *use_face_x = nir_iand(b,
360                                       nir_fge(b, coords.arx, coords.ary),
361                                       nir_fge(b, coords.arx, coords.arz));
362 
363    nir_if *use_face_x_if = nir_push_if(b, use_face_x);
364    nir_def *face_x_coord = evaluate_face_x(b, &coords);
365    nir_if *use_face_x_else = nir_push_else(b, use_face_x_if);
366 
367    nir_def *use_face_y = nir_iand(b,
368                                       nir_fge(b, coords.ary, coords.arx),
369                                       nir_fge(b, coords.ary, coords.arz));
370 
371    nir_if *use_face_y_if = nir_push_if(b, use_face_y);
372    nir_def *face_y_coord = evaluate_face_y(b, &coords);
373    nir_if *use_face_y_else = nir_push_else(b, use_face_y_if);
374 
375    nir_def *face_z_coord = evaluate_face_z(b, &coords);
376 
377    nir_pop_if(b, use_face_y_else);
378    nir_def *face_y_or_z_coord = nir_if_phi(b, face_y_coord, face_z_coord);
379    nir_pop_if(b, use_face_x_else);
380 
381    // This contains in xy the normalized sample coordinates, and in z the face index
382    nir_def *coord_and_face = nir_if_phi(b, face_x_coord, face_y_or_z_coord);
383 
384    return coord_and_face;
385 }
386 
387 static void
rewrite_cube_var_type(nir_builder * b,nir_tex_instr * tex)388 rewrite_cube_var_type(nir_builder *b, nir_tex_instr *tex)
389 {
390    unsigned index = tex->texture_index;
391    nir_variable *sampler = NULL;
392    int highest = -1;
393    nir_foreach_variable_with_modes(var, b->shader, nir_var_uniform) {
394       if (!glsl_type_is_sampler(glsl_without_array(var->type)))
395          continue;
396       unsigned size = glsl_type_is_array(var->type) ? glsl_get_length(var->type) : 1;
397       if (var->data.driver_location == index ||
398           (var->data.driver_location < index && var->data.driver_location + size > index)) {
399          sampler = var;
400          break;
401       }
402       /* handle array sampler access: use the next-closest sampler */
403       if (var->data.driver_location > highest && var->data.driver_location < index) {
404          highest = var->data.driver_location;
405          sampler = var;
406       }
407    }
408    assert(sampler);
409    sampler->type = make_2darray_from_cubemap_with_array(sampler->type);
410 }
411 
412 /* txb(s, coord, bias) = txl(s, coord, lod(s, coord).y + bias) */
413 /* tex(s, coord) = txl(s, coord, lod(s, coord).x) */
414 static nir_tex_instr *
lower_tex_to_txl(nir_builder * b,nir_tex_instr * tex)415 lower_tex_to_txl(nir_builder *b, nir_tex_instr *tex)
416 {
417    b->cursor = nir_after_instr(&tex->instr);
418    int bias_idx = nir_tex_instr_src_index(tex, nir_tex_src_bias);
419    unsigned num_srcs = bias_idx >= 0 ? tex->num_srcs : tex->num_srcs + 1;
420    nir_tex_instr *txl = nir_tex_instr_create(b->shader, num_srcs);
421 
422    txl->op = nir_texop_txl;
423    txl->sampler_dim = tex->sampler_dim;
424    txl->dest_type = tex->dest_type;
425    txl->coord_components = tex->coord_components;
426    txl->texture_index = tex->texture_index;
427    txl->sampler_index = tex->sampler_index;
428    txl->is_array = tex->is_array;
429    txl->is_shadow = tex->is_shadow;
430    txl->is_sparse = tex->is_sparse;
431    txl->is_new_style_shadow = tex->is_new_style_shadow;
432 
433    unsigned s = 0;
434    for (int i = 0; i < tex->num_srcs; i++) {
435       if (i == bias_idx)
436          continue;
437       txl->src[s].src = nir_src_for_ssa(tex->src[i].src.ssa);
438       txl->src[s].src_type = tex->src[i].src_type;
439       s++;
440    }
441    nir_def *lod = nir_get_texture_lod(b, tex);
442 
443    if (bias_idx >= 0)
444       lod = nir_fadd(b, lod, tex->src[bias_idx].src.ssa);
445    lod = nir_fadd_imm(b, lod, -1.0);
446    txl->src[s] = nir_tex_src_for_ssa(nir_tex_src_lod, lod);
447 
448    b->cursor = nir_before_instr(&tex->instr);
449    nir_def_init(&txl->instr, &txl->def,
450                 tex->def.num_components,
451                 tex->def.bit_size);
452    nir_builder_instr_insert(b, &txl->instr);
453    nir_def_rewrite_uses(&tex->def, &txl->def);
454    return txl;
455 }
456 
457 static nir_def *
lower_cube_sample(nir_builder * b,nir_tex_instr * tex)458 lower_cube_sample(nir_builder *b, nir_tex_instr *tex)
459 {
460    if (!tex->is_shadow && (tex->op == nir_texop_txb || tex->op == nir_texop_tex)) {
461       tex = lower_tex_to_txl(b, tex);
462    }
463 
464    int coord_index = nir_tex_instr_src_index(tex, nir_tex_src_coord);
465    assert(coord_index >= 0);
466 
467    /* Evaluate the face and the xy coordinates for a 2D tex op */
468    nir_def *coord = tex->src[coord_index].src.ssa;
469    nir_def *coord_and_face = lower_cube_coords(b, coord, tex->is_array);
470 
471    rewrite_cube_var_type(b, tex);
472 
473    if (tex->op == nir_texop_tg4 && !tex->is_shadow)
474       return handle_cube_gather(b, tex, coord_and_face);
475    else
476       return create_array_tex_from_cube_tex(b, tex, coord_and_face, tex->op);
477 }
478 
479 static nir_def *
lower_cube_txs(nir_builder * b,nir_tex_instr * tex)480 lower_cube_txs(nir_builder *b, nir_tex_instr *tex)
481 {
482    b->cursor = nir_after_instr(&tex->instr);
483 
484    rewrite_cube_var_type(b, tex);
485    unsigned num_components = tex->def.num_components;
486    /* force max components to unbreak textureSize().xy */
487    tex->def.num_components = 3;
488    tex->is_array = true;
489    nir_def *array_dim = nir_channel(b, &tex->def, 2);
490    nir_def *cube_array_dim = nir_idiv(b, array_dim, nir_imm_int(b, 6));
491    nir_def *size = nir_vec3(b, nir_channel(b, &tex->def, 0),
492                                    nir_channel(b, &tex->def, 1),
493                                    cube_array_dim);
494    return nir_trim_vector(b, size, num_components);
495 }
496 
497 static nir_def *
lower_cubemap_to_array_tex(nir_builder * b,nir_tex_instr * tex)498 lower_cubemap_to_array_tex(nir_builder *b, nir_tex_instr *tex)
499 {
500    switch (tex->op) {
501    case nir_texop_tex:
502    case nir_texop_txb:
503    case nir_texop_txd:
504    case nir_texop_txl:
505    case nir_texop_lod:
506    case nir_texop_tg4:
507       return lower_cube_sample(b, tex);
508    case nir_texop_txs:
509       return lower_cube_txs(b, tex);
510    default:
511       unreachable("Unsupported cupe map texture operation");
512    }
513 }
514 
515 static nir_def *
lower_cubemap_to_array_impl(nir_builder * b,nir_instr * instr,UNUSED void * _options)516 lower_cubemap_to_array_impl(nir_builder *b, nir_instr *instr,
517                                UNUSED void *_options)
518 {
519    if (instr->type == nir_instr_type_tex)
520       return lower_cubemap_to_array_tex(b, nir_instr_as_tex(instr));
521    return NULL;
522 }
523 
524 bool
525 zink_lower_cubemap_to_array(nir_shader *s, uint32_t nonseamless_cube_mask);
526 bool
zink_lower_cubemap_to_array(nir_shader * s,uint32_t nonseamless_cube_mask)527 zink_lower_cubemap_to_array(nir_shader *s, uint32_t nonseamless_cube_mask)
528 {
529    return nir_shader_lower_instructions(s,
530                                         lower_cubemap_to_array_filter,
531                                         lower_cubemap_to_array_impl,
532                                         &nonseamless_cube_mask);
533 }
534