• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2020 Valve Corporation
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 (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24 #include "ac_shader_util.h"
25 #include "nir.h"
26 #include "nir_builder.h"
27 #include "radv_nir.h"
28 #include "radv_private.h"
29 #include "radv_shader.h"
30 #include "radv_shader_args.h"
31 
32 typedef struct {
33    enum amd_gfx_level gfx_level;
34    uint32_t address32_hi;
35    bool disable_aniso_single_level;
36    bool has_image_load_dcc_bug;
37    bool disable_tg4_trunc_coord;
38 
39    const struct radv_shader_args *args;
40    const struct radv_shader_info *info;
41    const struct radv_shader_layout *layout;
42 } apply_layout_state;
43 
44 static nir_def *
get_scalar_arg(nir_builder * b,unsigned size,struct ac_arg arg)45 get_scalar_arg(nir_builder *b, unsigned size, struct ac_arg arg)
46 {
47    assert(arg.used);
48    return nir_load_scalar_arg_amd(b, size, .base = arg.arg_index);
49 }
50 
51 static nir_def *
convert_pointer_to_64_bit(nir_builder * b,apply_layout_state * state,nir_def * ptr)52 convert_pointer_to_64_bit(nir_builder *b, apply_layout_state *state, nir_def *ptr)
53 {
54    return nir_pack_64_2x32_split(b, ptr, nir_imm_int(b, state->address32_hi));
55 }
56 
57 static nir_def *
load_desc_ptr(nir_builder * b,apply_layout_state * state,unsigned set)58 load_desc_ptr(nir_builder *b, apply_layout_state *state, unsigned set)
59 {
60    const struct radv_userdata_locations *user_sgprs_locs = &state->info->user_sgprs_locs;
61    if (user_sgprs_locs->shader_data[AC_UD_INDIRECT_DESCRIPTOR_SETS].sgpr_idx != -1) {
62       nir_def *addr = get_scalar_arg(b, 1, state->args->descriptor_sets[0]);
63       addr = convert_pointer_to_64_bit(b, state, addr);
64       return nir_load_smem_amd(b, 1, addr, nir_imm_int(b, set * 4));
65    }
66 
67    assert(state->args->descriptor_sets[set].used);
68    return get_scalar_arg(b, 1, state->args->descriptor_sets[set]);
69 }
70 
71 static void
visit_vulkan_resource_index(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)72 visit_vulkan_resource_index(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
73 {
74    unsigned desc_set = nir_intrinsic_desc_set(intrin);
75    unsigned binding = nir_intrinsic_binding(intrin);
76    struct radv_descriptor_set_layout *layout = state->layout->set[desc_set].layout;
77    unsigned offset = layout->binding[binding].offset;
78    unsigned stride;
79 
80    nir_def *set_ptr;
81    if (layout->binding[binding].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
82        layout->binding[binding].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
83       unsigned idx = state->layout->set[desc_set].dynamic_offset_start + layout->binding[binding].dynamic_offset_offset;
84       set_ptr = get_scalar_arg(b, 1, state->args->ac.push_constants);
85       offset = state->layout->push_constant_size + idx * 16;
86       stride = 16;
87    } else {
88       set_ptr = load_desc_ptr(b, state, desc_set);
89       stride = layout->binding[binding].size;
90    }
91 
92    nir_def *binding_ptr = nir_imul_imm(b, intrin->src[0].ssa, stride);
93    nir_instr_as_alu(binding_ptr->parent_instr)->no_unsigned_wrap = true;
94 
95    binding_ptr = nir_iadd_imm(b, binding_ptr, offset);
96    nir_instr_as_alu(binding_ptr->parent_instr)->no_unsigned_wrap = true;
97 
98    if (layout->binding[binding].type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
99       assert(stride == 16);
100       nir_def_rewrite_uses(&intrin->def, nir_pack_64_2x32_split(b, set_ptr, binding_ptr));
101    } else {
102       nir_def_rewrite_uses(&intrin->def, nir_vec3(b, set_ptr, binding_ptr, nir_imm_int(b, stride)));
103    }
104    nir_instr_remove(&intrin->instr);
105 }
106 
107 static void
visit_vulkan_resource_reindex(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)108 visit_vulkan_resource_reindex(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
109 {
110    VkDescriptorType desc_type = nir_intrinsic_desc_type(intrin);
111    if (desc_type == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
112       nir_def *set_ptr = nir_unpack_64_2x32_split_x(b, intrin->src[0].ssa);
113       nir_def *binding_ptr = nir_unpack_64_2x32_split_y(b, intrin->src[0].ssa);
114 
115       nir_def *index = nir_imul_imm(b, intrin->src[1].ssa, 16);
116       nir_instr_as_alu(index->parent_instr)->no_unsigned_wrap = true;
117 
118       binding_ptr = nir_iadd_nuw(b, binding_ptr, index);
119 
120       nir_def_rewrite_uses(&intrin->def, nir_pack_64_2x32_split(b, set_ptr, binding_ptr));
121    } else {
122       assert(desc_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || desc_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
123 
124       nir_def *binding_ptr = nir_channel(b, intrin->src[0].ssa, 1);
125       nir_def *stride = nir_channel(b, intrin->src[0].ssa, 2);
126 
127       nir_def *index = nir_imul(b, intrin->src[1].ssa, stride);
128       nir_instr_as_alu(index->parent_instr)->no_unsigned_wrap = true;
129 
130       binding_ptr = nir_iadd_nuw(b, binding_ptr, index);
131 
132       nir_def_rewrite_uses(&intrin->def, nir_vector_insert_imm(b, intrin->src[0].ssa, binding_ptr, 1));
133    }
134    nir_instr_remove(&intrin->instr);
135 }
136 
137 static void
visit_load_vulkan_descriptor(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)138 visit_load_vulkan_descriptor(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
139 {
140    if (nir_intrinsic_desc_type(intrin) == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
141       nir_def *addr = convert_pointer_to_64_bit(b, state,
142                                                 nir_iadd(b, nir_unpack_64_2x32_split_x(b, intrin->src[0].ssa),
143                                                          nir_unpack_64_2x32_split_y(b, intrin->src[0].ssa)));
144       nir_def *desc = nir_build_load_global(b, 1, 64, addr, .access = ACCESS_NON_WRITEABLE);
145 
146       nir_def_rewrite_uses(&intrin->def, desc);
147    } else {
148       nir_def_rewrite_uses(&intrin->def, nir_vector_insert_imm(b, intrin->src[0].ssa, nir_imm_int(b, 0), 2));
149    }
150    nir_instr_remove(&intrin->instr);
151 }
152 
153 static nir_def *
load_inline_buffer_descriptor(nir_builder * b,apply_layout_state * state,nir_def * rsrc)154 load_inline_buffer_descriptor(nir_builder *b, apply_layout_state *state, nir_def *rsrc)
155 {
156    uint32_t desc_type = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
157                         S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
158    if (state->gfx_level >= GFX11) {
159       desc_type |= S_008F0C_FORMAT(V_008F0C_GFX11_FORMAT_32_FLOAT) | S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW);
160    } else if (state->gfx_level >= GFX10) {
161       desc_type |= S_008F0C_FORMAT(V_008F0C_GFX10_FORMAT_32_FLOAT) | S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
162                    S_008F0C_RESOURCE_LEVEL(1);
163    } else {
164       desc_type |=
165          S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) | S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
166    }
167 
168    return nir_vec4(b, rsrc, nir_imm_int(b, S_008F04_BASE_ADDRESS_HI(state->address32_hi)), nir_imm_int(b, 0xffffffff),
169                    nir_imm_int(b, desc_type));
170 }
171 
172 static nir_def *
load_buffer_descriptor(nir_builder * b,apply_layout_state * state,nir_def * rsrc,unsigned access)173 load_buffer_descriptor(nir_builder *b, apply_layout_state *state, nir_def *rsrc, unsigned access)
174 {
175    nir_binding binding = nir_chase_binding(nir_src_for_ssa(rsrc));
176 
177    /* If binding.success=false, then this is a variable pointer, which we don't support with
178     * VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK.
179     */
180    if (binding.success) {
181       struct radv_descriptor_set_layout *layout = state->layout->set[binding.desc_set].layout;
182       if (layout->binding[binding.binding].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) {
183          rsrc = nir_iadd(b, nir_channel(b, rsrc, 0), nir_channel(b, rsrc, 1));
184          return load_inline_buffer_descriptor(b, state, rsrc);
185       }
186    }
187 
188    if (access & ACCESS_NON_UNIFORM)
189       return nir_iadd(b, nir_channel(b, rsrc, 0), nir_channel(b, rsrc, 1));
190 
191    nir_def *desc_set = convert_pointer_to_64_bit(b, state, nir_channel(b, rsrc, 0));
192    return nir_load_smem_amd(b, 4, desc_set, nir_channel(b, rsrc, 1), .align_mul = 16);
193 }
194 
195 static void
visit_get_ssbo_size(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)196 visit_get_ssbo_size(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
197 {
198    nir_def *rsrc = intrin->src[0].ssa;
199 
200    nir_def *size;
201    if (nir_intrinsic_access(intrin) & ACCESS_NON_UNIFORM) {
202       nir_def *ptr = nir_iadd(b, nir_channel(b, rsrc, 0), nir_channel(b, rsrc, 1));
203       ptr = nir_iadd_imm(b, ptr, 8);
204       ptr = convert_pointer_to_64_bit(b, state, ptr);
205       size = nir_build_load_global(b, 4, 32, ptr, .access = ACCESS_NON_WRITEABLE | ACCESS_CAN_REORDER, .align_mul = 16,
206                                    .align_offset = 4);
207    } else {
208       /* load the entire descriptor so it can be CSE'd */
209       nir_def *ptr = convert_pointer_to_64_bit(b, state, nir_channel(b, rsrc, 0));
210       nir_def *desc = nir_load_smem_amd(b, 4, ptr, nir_channel(b, rsrc, 1), .align_mul = 16);
211       size = nir_channel(b, desc, 2);
212    }
213 
214    nir_def_rewrite_uses(&intrin->def, size);
215    nir_instr_remove(&intrin->instr);
216 }
217 
218 static nir_def *
get_sampler_desc(nir_builder * b,apply_layout_state * state,nir_deref_instr * deref,enum ac_descriptor_type desc_type,bool non_uniform,nir_tex_instr * tex,bool write)219 get_sampler_desc(nir_builder *b, apply_layout_state *state, nir_deref_instr *deref, enum ac_descriptor_type desc_type,
220                  bool non_uniform, nir_tex_instr *tex, bool write)
221 {
222    nir_variable *var = nir_deref_instr_get_variable(deref);
223    assert(var);
224    unsigned desc_set = var->data.descriptor_set;
225    unsigned binding_index = var->data.binding;
226    bool indirect = nir_deref_instr_has_indirect(deref);
227 
228    struct radv_descriptor_set_layout *layout = state->layout->set[desc_set].layout;
229    struct radv_descriptor_set_binding_layout *binding = &layout->binding[binding_index];
230 
231    /* Handle immutable and embedded (compile-time) samplers
232     * (VkDescriptorSetLayoutBinding::pImmutableSamplers) We can only do this for constant array
233     * index or if all samplers in the array are the same. Note that indexing is forbidden with
234     * embedded samplers.
235     */
236    if (desc_type == AC_DESC_SAMPLER && binding->immutable_samplers_offset &&
237        (!indirect || binding->immutable_samplers_equal)) {
238       unsigned constant_index = 0;
239       if (!binding->immutable_samplers_equal) {
240          while (deref->deref_type != nir_deref_type_var) {
241             assert(deref->deref_type == nir_deref_type_array);
242             unsigned array_size = MAX2(glsl_get_aoa_size(deref->type), 1);
243             constant_index += nir_src_as_uint(deref->arr.index) * array_size;
244             deref = nir_deref_instr_parent(deref);
245          }
246       }
247 
248       uint32_t dword0_mask =
249          tex->op == nir_texop_tg4 && state->disable_tg4_trunc_coord ? C_008F30_TRUNC_COORD : 0xffffffffu;
250       const uint32_t *samplers = radv_immutable_samplers(layout, binding);
251       return nir_imm_ivec4(b, samplers[constant_index * 4 + 0] & dword0_mask, samplers[constant_index * 4 + 1],
252                            samplers[constant_index * 4 + 2], samplers[constant_index * 4 + 3]);
253    }
254 
255    unsigned size = 8;
256    unsigned offset = binding->offset;
257    switch (desc_type) {
258    case AC_DESC_IMAGE:
259    case AC_DESC_PLANE_0:
260       break;
261    case AC_DESC_FMASK:
262    case AC_DESC_PLANE_1:
263       offset += 32;
264       break;
265    case AC_DESC_SAMPLER:
266       size = 4;
267       if (binding->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
268          offset += radv_combined_image_descriptor_sampler_offset(binding);
269       break;
270    case AC_DESC_BUFFER:
271       size = 4;
272       break;
273    case AC_DESC_PLANE_2:
274       size = 4;
275       offset += 64;
276       break;
277    }
278 
279    nir_def *index = NULL;
280    while (deref->deref_type != nir_deref_type_var) {
281       assert(deref->deref_type == nir_deref_type_array);
282       unsigned array_size = MAX2(glsl_get_aoa_size(deref->type), 1);
283       array_size *= binding->size;
284 
285       nir_def *tmp = nir_imul_imm(b, deref->arr.index.ssa, array_size);
286       if (tmp != deref->arr.index.ssa)
287          nir_instr_as_alu(tmp->parent_instr)->no_unsigned_wrap = true;
288 
289       if (index) {
290          index = nir_iadd(b, tmp, index);
291          nir_instr_as_alu(index->parent_instr)->no_unsigned_wrap = true;
292       } else {
293          index = tmp;
294       }
295 
296       deref = nir_deref_instr_parent(deref);
297    }
298 
299    nir_def *index_offset = index ? nir_iadd_imm(b, index, offset) : nir_imm_int(b, offset);
300    if (index && index_offset != index)
301       nir_instr_as_alu(index_offset->parent_instr)->no_unsigned_wrap = true;
302 
303    if (non_uniform)
304       return nir_iadd(b, load_desc_ptr(b, state, desc_set), index_offset);
305 
306    nir_def *addr = convert_pointer_to_64_bit(b, state, load_desc_ptr(b, state, desc_set));
307    nir_def *desc = nir_load_smem_amd(b, size, addr, index_offset, .align_mul = size * 4u);
308 
309    /* 3 plane formats always have same size and format for plane 1 & 2, so
310     * use the tail from plane 1 so that we can store only the first 16 bytes
311     * of the last plane. */
312    if (desc_type == AC_DESC_PLANE_2) {
313       nir_def *desc2 = get_sampler_desc(b, state, deref, AC_DESC_PLANE_1, non_uniform, tex, write);
314 
315       nir_def *comp[8];
316       for (unsigned i = 0; i < 4; i++)
317          comp[i] = nir_channel(b, desc, i);
318       for (unsigned i = 4; i < 8; i++)
319          comp[i] = nir_channel(b, desc2, i);
320 
321       return nir_vec(b, comp, 8);
322    } else if (desc_type == AC_DESC_IMAGE && state->has_image_load_dcc_bug && !tex && !write) {
323       nir_def *comp[8];
324       for (unsigned i = 0; i < 8; i++)
325          comp[i] = nir_channel(b, desc, i);
326 
327       /* WRITE_COMPRESS_ENABLE must be 0 for all image loads to workaround a
328        * hardware bug.
329        */
330       comp[6] = nir_iand_imm(b, comp[6], C_00A018_WRITE_COMPRESS_ENABLE);
331 
332       return nir_vec(b, comp, 8);
333    } else if (desc_type == AC_DESC_SAMPLER && tex->op == nir_texop_tg4 && state->disable_tg4_trunc_coord) {
334       nir_def *comp[4];
335       for (unsigned i = 0; i < 4; i++)
336          comp[i] = nir_channel(b, desc, i);
337 
338       /* We want to always use the linear filtering truncation behaviour for
339        * nir_texop_tg4, even if the sampler uses nearest/point filtering.
340        */
341       comp[0] = nir_iand_imm(b, comp[0], C_008F30_TRUNC_COORD);
342 
343       return nir_vec(b, comp, 4);
344    }
345 
346    return desc;
347 }
348 
349 static void
update_image_intrinsic(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)350 update_image_intrinsic(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
351 {
352    nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
353    const enum glsl_sampler_dim dim = glsl_get_sampler_dim(deref->type);
354    bool is_load =
355       intrin->intrinsic == nir_intrinsic_image_deref_load || intrin->intrinsic == nir_intrinsic_image_deref_sparse_load;
356 
357    nir_def *desc = get_sampler_desc(b, state, deref, dim == GLSL_SAMPLER_DIM_BUF ? AC_DESC_BUFFER : AC_DESC_IMAGE,
358                                     nir_intrinsic_access(intrin) & ACCESS_NON_UNIFORM, NULL, !is_load);
359 
360    if (intrin->intrinsic == nir_intrinsic_image_deref_descriptor_amd) {
361       nir_def_rewrite_uses(&intrin->def, desc);
362       nir_instr_remove(&intrin->instr);
363    } else {
364       nir_rewrite_image_intrinsic(intrin, desc, true);
365    }
366 }
367 
368 static void
apply_layout_to_intrin(nir_builder * b,apply_layout_state * state,nir_intrinsic_instr * intrin)369 apply_layout_to_intrin(nir_builder *b, apply_layout_state *state, nir_intrinsic_instr *intrin)
370 {
371    b->cursor = nir_before_instr(&intrin->instr);
372 
373    nir_def *rsrc;
374    switch (intrin->intrinsic) {
375    case nir_intrinsic_vulkan_resource_index:
376       visit_vulkan_resource_index(b, state, intrin);
377       break;
378    case nir_intrinsic_vulkan_resource_reindex:
379       visit_vulkan_resource_reindex(b, state, intrin);
380       break;
381    case nir_intrinsic_load_vulkan_descriptor:
382       visit_load_vulkan_descriptor(b, state, intrin);
383       break;
384    case nir_intrinsic_load_ubo:
385    case nir_intrinsic_load_ssbo:
386    case nir_intrinsic_ssbo_atomic:
387    case nir_intrinsic_ssbo_atomic_swap:
388       rsrc = load_buffer_descriptor(b, state, intrin->src[0].ssa, nir_intrinsic_access(intrin));
389       nir_src_rewrite(&intrin->src[0], rsrc);
390       break;
391    case nir_intrinsic_store_ssbo:
392       rsrc = load_buffer_descriptor(b, state, intrin->src[1].ssa, nir_intrinsic_access(intrin));
393       nir_src_rewrite(&intrin->src[1], rsrc);
394       break;
395    case nir_intrinsic_get_ssbo_size:
396       visit_get_ssbo_size(b, state, intrin);
397       break;
398    case nir_intrinsic_image_deref_load:
399    case nir_intrinsic_image_deref_sparse_load:
400    case nir_intrinsic_image_deref_store:
401    case nir_intrinsic_image_deref_atomic:
402    case nir_intrinsic_image_deref_atomic_swap:
403    case nir_intrinsic_image_deref_size:
404    case nir_intrinsic_image_deref_samples:
405    case nir_intrinsic_image_deref_descriptor_amd:
406       update_image_intrinsic(b, state, intrin);
407       break;
408    default:
409       break;
410    }
411 }
412 
413 static void
apply_layout_to_tex(nir_builder * b,apply_layout_state * state,nir_tex_instr * tex)414 apply_layout_to_tex(nir_builder *b, apply_layout_state *state, nir_tex_instr *tex)
415 {
416    b->cursor = nir_before_instr(&tex->instr);
417 
418    nir_deref_instr *texture_deref_instr = NULL;
419    nir_deref_instr *sampler_deref_instr = NULL;
420    int plane = -1;
421 
422    for (unsigned i = 0; i < tex->num_srcs; i++) {
423       switch (tex->src[i].src_type) {
424       case nir_tex_src_texture_deref:
425          texture_deref_instr = nir_src_as_deref(tex->src[i].src);
426          break;
427       case nir_tex_src_sampler_deref:
428          sampler_deref_instr = nir_src_as_deref(tex->src[i].src);
429          break;
430       case nir_tex_src_plane:
431          plane = nir_src_as_int(tex->src[i].src);
432          break;
433       default:
434          break;
435       }
436    }
437 
438    nir_def *image = NULL;
439    nir_def *sampler = NULL;
440    if (plane >= 0) {
441       assert(tex->op != nir_texop_txf_ms && tex->op != nir_texop_samples_identical);
442       assert(tex->sampler_dim != GLSL_SAMPLER_DIM_BUF);
443       image =
444          get_sampler_desc(b, state, texture_deref_instr, AC_DESC_PLANE_0 + plane, tex->texture_non_uniform, tex, false);
445    } else if (tex->sampler_dim == GLSL_SAMPLER_DIM_BUF) {
446       image = get_sampler_desc(b, state, texture_deref_instr, AC_DESC_BUFFER, tex->texture_non_uniform, tex, false);
447    } else if (tex->op == nir_texop_fragment_mask_fetch_amd) {
448       image = get_sampler_desc(b, state, texture_deref_instr, AC_DESC_FMASK, tex->texture_non_uniform, tex, false);
449    } else {
450       image = get_sampler_desc(b, state, texture_deref_instr, AC_DESC_IMAGE, tex->texture_non_uniform, tex, false);
451    }
452 
453    if (sampler_deref_instr) {
454       sampler = get_sampler_desc(b, state, sampler_deref_instr, AC_DESC_SAMPLER, tex->sampler_non_uniform, tex, false);
455 
456       if (state->disable_aniso_single_level && tex->sampler_dim < GLSL_SAMPLER_DIM_RECT && state->gfx_level < GFX8) {
457          /* Disable anisotropic filtering if BASE_LEVEL == LAST_LEVEL.
458           *
459           * GFX6-GFX7:
460           *   If BASE_LEVEL == LAST_LEVEL, the shader must disable anisotropic
461           *   filtering manually. The driver sets img7 to a mask clearing
462           *   MAX_ANISO_RATIO if BASE_LEVEL == LAST_LEVEL. The shader must do:
463           *     s_and_b32 samp0, samp0, img7
464           *
465           * GFX8:
466           *   The ANISO_OVERRIDE sampler field enables this fix in TA.
467           */
468          /* TODO: This is unnecessary for combined image+sampler.
469           * We can do this when updating the desc set. */
470          nir_def *comp[4];
471          for (unsigned i = 0; i < 4; i++)
472             comp[i] = nir_channel(b, sampler, i);
473          comp[0] = nir_iand(b, comp[0], nir_channel(b, image, 7));
474 
475          sampler = nir_vec(b, comp, 4);
476       }
477    }
478 
479    if (tex->op == nir_texop_descriptor_amd) {
480       nir_def_rewrite_uses(&tex->def, image);
481       nir_instr_remove(&tex->instr);
482       return;
483    }
484 
485    for (unsigned i = 0; i < tex->num_srcs; i++) {
486       switch (tex->src[i].src_type) {
487       case nir_tex_src_texture_deref:
488          tex->src[i].src_type = nir_tex_src_texture_handle;
489          nir_src_rewrite(&tex->src[i].src, image);
490          break;
491       case nir_tex_src_sampler_deref:
492          tex->src[i].src_type = nir_tex_src_sampler_handle;
493          nir_src_rewrite(&tex->src[i].src, sampler);
494          break;
495       default:
496          break;
497       }
498    }
499 }
500 
501 void
radv_nir_apply_pipeline_layout(nir_shader * shader,struct radv_device * device,const struct radv_shader_stage * stage)502 radv_nir_apply_pipeline_layout(nir_shader *shader, struct radv_device *device, const struct radv_shader_stage *stage)
503 {
504    apply_layout_state state = {
505       .gfx_level = device->physical_device->rad_info.gfx_level,
506       .address32_hi = device->physical_device->rad_info.address32_hi,
507       .disable_aniso_single_level = device->instance->drirc.disable_aniso_single_level,
508       .has_image_load_dcc_bug = device->physical_device->rad_info.has_image_load_dcc_bug,
509       .disable_tg4_trunc_coord =
510          !device->physical_device->rad_info.conformant_trunc_coord && !device->disable_trunc_coord,
511       .args = &stage->args,
512       .info = &stage->info,
513       .layout = &stage->layout,
514    };
515 
516    nir_builder b;
517 
518    nir_foreach_function (function, shader) {
519       if (!function->impl)
520          continue;
521 
522       b = nir_builder_create(function->impl);
523 
524       /* Iterate in reverse so load_ubo lowering can look at
525        * the vulkan_resource_index to tell if it's an inline
526        * ubo.
527        */
528       nir_foreach_block_reverse (block, function->impl) {
529          nir_foreach_instr_reverse_safe (instr, block) {
530             if (instr->type == nir_instr_type_tex)
531                apply_layout_to_tex(&b, &state, nir_instr_as_tex(instr));
532             else if (instr->type == nir_instr_type_intrinsic)
533                apply_layout_to_intrin(&b, &state, nir_instr_as_intrinsic(instr));
534          }
535       }
536 
537       nir_metadata_preserve(function->impl, nir_metadata_block_index | nir_metadata_dominance);
538    }
539 }
540