1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2021 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Derived from tu_shader.c which is:
5bf215546Sopenharmony_ci * Copyright © 2019 Google LLC
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Also derived from anv_pipeline.c which is
8bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
9bf215546Sopenharmony_ci *
10bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
11bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
12bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
13bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
15bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
18bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
19bf215546Sopenharmony_ci * Software.
20bf215546Sopenharmony_ci *
21bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
28bf215546Sopenharmony_ci */
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "genxml/gen_macros.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "panvk_private.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "nir_builder.h"
35bf215546Sopenharmony_ci#include "nir_deref.h"
36bf215546Sopenharmony_ci#include "nir_lower_blend.h"
37bf215546Sopenharmony_ci#include "nir_conversion_builder.h"
38bf215546Sopenharmony_ci#include "spirv/nir_spirv.h"
39bf215546Sopenharmony_ci#include "util/mesa-sha1.h"
40bf215546Sopenharmony_ci#include "vk_shader_module.h"
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci#include "pan_shader.h"
43bf215546Sopenharmony_ci#include "util/pan_lower_framebuffer.h"
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci#include "vk_util.h"
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_cistatic void
48bf215546Sopenharmony_cipanvk_init_sysvals(struct panfrost_sysvals *sysvals,
49bf215546Sopenharmony_ci                   gl_shader_stage stage)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci   memset(sysvals, 0, sizeof(*sysvals));
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci#define SYSVAL_SLOT(name) \
54bf215546Sopenharmony_ci   (assert(offsetof(struct panvk_sysvals, name) % 16 == 0), \
55bf215546Sopenharmony_ci    offsetof(struct panvk_sysvals, name) / 16)
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci#define INIT_SYSVAL(name, SYSVAL) \
58bf215546Sopenharmony_ci   sysvals->sysvals[SYSVAL_SLOT(name)] = PAN_SYSVAL_##SYSVAL
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci   if (gl_shader_stage_is_compute(stage)) {
61bf215546Sopenharmony_ci      INIT_SYSVAL(num_work_groups, NUM_WORK_GROUPS);
62bf215546Sopenharmony_ci      INIT_SYSVAL(local_group_size, LOCAL_GROUP_SIZE);
63bf215546Sopenharmony_ci   } else {
64bf215546Sopenharmony_ci      INIT_SYSVAL(viewport_scale, VIEWPORT_SCALE);
65bf215546Sopenharmony_ci      INIT_SYSVAL(viewport_offset, VIEWPORT_OFFSET);
66bf215546Sopenharmony_ci      INIT_SYSVAL(vertex_instance_offsets, VERTEX_INSTANCE_OFFSETS);
67bf215546Sopenharmony_ci      INIT_SYSVAL(blend_constants, BLEND_CONSTANTS);
68bf215546Sopenharmony_ci   }
69bf215546Sopenharmony_ci   sysvals->sysval_count = SYSVAL_SLOT(dyn_ssbos);
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci#undef SYSVAL_SLOT
72bf215546Sopenharmony_ci#undef INIT_SYSVAL
73bf215546Sopenharmony_ci}
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_cistatic bool
76bf215546Sopenharmony_cipanvk_inline_blend_constants(nir_builder *b, nir_instr *instr, void *data)
77bf215546Sopenharmony_ci{
78bf215546Sopenharmony_ci   if (instr->type != nir_instr_type_intrinsic)
79bf215546Sopenharmony_ci      return false;
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
82bf215546Sopenharmony_ci   if (intr->intrinsic != nir_intrinsic_load_blend_const_color_rgba)
83bf215546Sopenharmony_ci      return false;
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   const nir_const_value *constants = data;
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   b->cursor = nir_after_instr(instr);
88bf215546Sopenharmony_ci   nir_ssa_def *constant = nir_build_imm(b, 4, 32, constants);
89bf215546Sopenharmony_ci   nir_ssa_def_rewrite_uses(&intr->dest.ssa, constant);
90bf215546Sopenharmony_ci   nir_instr_remove(instr);
91bf215546Sopenharmony_ci   return true;
92bf215546Sopenharmony_ci}
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_cistatic void
95bf215546Sopenharmony_cipanvk_lower_blend(struct panfrost_device *pdev,
96bf215546Sopenharmony_ci                  nir_shader *nir,
97bf215546Sopenharmony_ci                  struct panfrost_compile_inputs *inputs,
98bf215546Sopenharmony_ci                  struct pan_blend_state *blend_state,
99bf215546Sopenharmony_ci                  bool static_blend_constants)
100bf215546Sopenharmony_ci{
101bf215546Sopenharmony_ci   nir_lower_blend_options options = {
102bf215546Sopenharmony_ci      .logicop_enable = blend_state->logicop_enable,
103bf215546Sopenharmony_ci      .logicop_func = blend_state->logicop_func,
104bf215546Sopenharmony_ci   };
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   bool lower_blend = false;
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   for (unsigned rt = 0; rt < blend_state->rt_count; rt++) {
109bf215546Sopenharmony_ci      struct pan_blend_rt_state *rt_state = &blend_state->rts[rt];
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci      if (!panvk_per_arch(blend_needs_lowering)(pdev, blend_state, rt))
112bf215546Sopenharmony_ci         continue;
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci      enum pipe_format fmt = rt_state->format;
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci      options.format[rt] = fmt;
117bf215546Sopenharmony_ci      options.rt[rt].colormask = rt_state->equation.color_mask;
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci      if (!rt_state->equation.blend_enable) {
120bf215546Sopenharmony_ci         static const nir_lower_blend_channel replace = {
121bf215546Sopenharmony_ci            .func = BLEND_FUNC_ADD,
122bf215546Sopenharmony_ci            .src_factor = BLEND_FACTOR_ZERO,
123bf215546Sopenharmony_ci            .invert_src_factor = true,
124bf215546Sopenharmony_ci            .dst_factor = BLEND_FACTOR_ZERO,
125bf215546Sopenharmony_ci            .invert_dst_factor = false,
126bf215546Sopenharmony_ci         };
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci         options.rt[rt].rgb = replace;
129bf215546Sopenharmony_ci         options.rt[rt].alpha = replace;
130bf215546Sopenharmony_ci      } else {
131bf215546Sopenharmony_ci         options.rt[rt].rgb.func = rt_state->equation.rgb_func;
132bf215546Sopenharmony_ci         options.rt[rt].rgb.src_factor = rt_state->equation.rgb_src_factor;
133bf215546Sopenharmony_ci         options.rt[rt].rgb.invert_src_factor = rt_state->equation.rgb_invert_src_factor;
134bf215546Sopenharmony_ci         options.rt[rt].rgb.dst_factor = rt_state->equation.rgb_dst_factor;
135bf215546Sopenharmony_ci         options.rt[rt].rgb.invert_dst_factor = rt_state->equation.rgb_invert_dst_factor;
136bf215546Sopenharmony_ci         options.rt[rt].alpha.func = rt_state->equation.alpha_func;
137bf215546Sopenharmony_ci         options.rt[rt].alpha.src_factor = rt_state->equation.alpha_src_factor;
138bf215546Sopenharmony_ci         options.rt[rt].alpha.invert_src_factor = rt_state->equation.alpha_invert_src_factor;
139bf215546Sopenharmony_ci         options.rt[rt].alpha.dst_factor = rt_state->equation.alpha_dst_factor;
140bf215546Sopenharmony_ci         options.rt[rt].alpha.invert_dst_factor = rt_state->equation.alpha_invert_dst_factor;
141bf215546Sopenharmony_ci      }
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci      /* Update the equation to force a color replacement */
144bf215546Sopenharmony_ci      rt_state->equation.color_mask = 0xf;
145bf215546Sopenharmony_ci      rt_state->equation.rgb_func = BLEND_FUNC_ADD;
146bf215546Sopenharmony_ci      rt_state->equation.rgb_src_factor = BLEND_FACTOR_ZERO;
147bf215546Sopenharmony_ci      rt_state->equation.rgb_invert_src_factor = true;
148bf215546Sopenharmony_ci      rt_state->equation.rgb_dst_factor = BLEND_FACTOR_ZERO;
149bf215546Sopenharmony_ci      rt_state->equation.rgb_invert_dst_factor = false;
150bf215546Sopenharmony_ci      rt_state->equation.alpha_func = BLEND_FUNC_ADD;
151bf215546Sopenharmony_ci      rt_state->equation.alpha_src_factor = BLEND_FACTOR_ZERO;
152bf215546Sopenharmony_ci      rt_state->equation.alpha_invert_src_factor = true;
153bf215546Sopenharmony_ci      rt_state->equation.alpha_dst_factor = BLEND_FACTOR_ZERO;
154bf215546Sopenharmony_ci      rt_state->equation.alpha_invert_dst_factor = false;
155bf215546Sopenharmony_ci      lower_blend = true;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci      inputs->bifrost.static_rt_conv = true;
158bf215546Sopenharmony_ci      inputs->bifrost.rt_conv[rt] =
159bf215546Sopenharmony_ci         GENX(pan_blend_get_internal_desc)(pdev, fmt, rt, 32, false) >> 32;
160bf215546Sopenharmony_ci   }
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   if (lower_blend) {
163bf215546Sopenharmony_ci      NIR_PASS_V(nir, nir_lower_blend, &options);
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci      if (static_blend_constants) {
166bf215546Sopenharmony_ci         const nir_const_value constants[4] = {
167bf215546Sopenharmony_ci            { .f32 = CLAMP(blend_state->constants[0], 0.0f, 1.0f) },
168bf215546Sopenharmony_ci            { .f32 = CLAMP(blend_state->constants[1], 0.0f, 1.0f) },
169bf215546Sopenharmony_ci            { .f32 = CLAMP(blend_state->constants[2], 0.0f, 1.0f) },
170bf215546Sopenharmony_ci            { .f32 = CLAMP(blend_state->constants[3], 0.0f, 1.0f) },
171bf215546Sopenharmony_ci         };
172bf215546Sopenharmony_ci         NIR_PASS_V(nir, nir_shader_instructions_pass,
173bf215546Sopenharmony_ci                    panvk_inline_blend_constants,
174bf215546Sopenharmony_ci                    nir_metadata_block_index |
175bf215546Sopenharmony_ci                    nir_metadata_dominance,
176bf215546Sopenharmony_ci                    (void *)constants);
177bf215546Sopenharmony_ci      }
178bf215546Sopenharmony_ci   }
179bf215546Sopenharmony_ci}
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_cistatic bool
182bf215546Sopenharmony_cipanvk_lower_load_push_constant(nir_builder *b, nir_instr *instr, void *data)
183bf215546Sopenharmony_ci{
184bf215546Sopenharmony_ci   if (instr->type != nir_instr_type_intrinsic)
185bf215546Sopenharmony_ci      return false;
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci   nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
188bf215546Sopenharmony_ci   if (intr->intrinsic != nir_intrinsic_load_push_constant)
189bf215546Sopenharmony_ci      return false;
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci   b->cursor = nir_before_instr(instr);
192bf215546Sopenharmony_ci   nir_ssa_def *ubo_load =
193bf215546Sopenharmony_ci      nir_load_ubo(b, nir_dest_num_components(intr->dest),
194bf215546Sopenharmony_ci                   nir_dest_bit_size(intr->dest),
195bf215546Sopenharmony_ci                   nir_imm_int(b, PANVK_PUSH_CONST_UBO_INDEX),
196bf215546Sopenharmony_ci                   intr->src[0].ssa,
197bf215546Sopenharmony_ci                   .align_mul = nir_dest_bit_size(intr->dest) / 8,
198bf215546Sopenharmony_ci                   .align_offset = 0,
199bf215546Sopenharmony_ci                   .range_base = nir_intrinsic_base(intr),
200bf215546Sopenharmony_ci                   .range = nir_intrinsic_range(intr));
201bf215546Sopenharmony_ci   nir_ssa_def_rewrite_uses(&intr->dest.ssa, ubo_load);
202bf215546Sopenharmony_ci   nir_instr_remove(instr);
203bf215546Sopenharmony_ci   return true;
204bf215546Sopenharmony_ci}
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_cistatic void
207bf215546Sopenharmony_cishared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
208bf215546Sopenharmony_ci{
209bf215546Sopenharmony_ci   assert(glsl_type_is_vector_or_scalar(type));
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ci   uint32_t comp_size = glsl_type_is_boolean(type)
212bf215546Sopenharmony_ci      ? 4 : glsl_get_bit_size(type) / 8;
213bf215546Sopenharmony_ci   unsigned length = glsl_get_vector_elements(type);
214bf215546Sopenharmony_ci   *size = comp_size * length,
215bf215546Sopenharmony_ci   *align = comp_size * (length == 3 ? 4 : length);
216bf215546Sopenharmony_ci}
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_cistruct panvk_shader *
219bf215546Sopenharmony_cipanvk_per_arch(shader_create)(struct panvk_device *dev,
220bf215546Sopenharmony_ci                              gl_shader_stage stage,
221bf215546Sopenharmony_ci                              const VkPipelineShaderStageCreateInfo *stage_info,
222bf215546Sopenharmony_ci                              const struct panvk_pipeline_layout *layout,
223bf215546Sopenharmony_ci                              unsigned sysval_ubo,
224bf215546Sopenharmony_ci                              struct pan_blend_state *blend_state,
225bf215546Sopenharmony_ci                              bool static_blend_constants,
226bf215546Sopenharmony_ci                              const VkAllocationCallbacks *alloc)
227bf215546Sopenharmony_ci{
228bf215546Sopenharmony_ci   VK_FROM_HANDLE(vk_shader_module, module, stage_info->module);
229bf215546Sopenharmony_ci   struct panfrost_device *pdev = &dev->physical_device->pdev;
230bf215546Sopenharmony_ci   struct panvk_shader *shader;
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   shader = vk_zalloc2(&dev->vk.alloc, alloc, sizeof(*shader), 8,
233bf215546Sopenharmony_ci                       VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
234bf215546Sopenharmony_ci   if (!shader)
235bf215546Sopenharmony_ci      return NULL;
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   util_dynarray_init(&shader->binary, NULL);
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci   /* TODO these are made-up */
240bf215546Sopenharmony_ci   const struct spirv_to_nir_options spirv_options = {
241bf215546Sopenharmony_ci      .caps = {
242bf215546Sopenharmony_ci         .variable_pointers = true,
243bf215546Sopenharmony_ci      },
244bf215546Sopenharmony_ci      .ubo_addr_format = nir_address_format_32bit_index_offset,
245bf215546Sopenharmony_ci      .ssbo_addr_format = dev->vk.enabled_features.robustBufferAccess ?
246bf215546Sopenharmony_ci                          nir_address_format_64bit_bounded_global :
247bf215546Sopenharmony_ci                          nir_address_format_64bit_global_32bit_offset,
248bf215546Sopenharmony_ci   };
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   nir_shader *nir;
251bf215546Sopenharmony_ci   VkResult result = vk_shader_module_to_nir(&dev->vk, module, stage,
252bf215546Sopenharmony_ci                                             stage_info->pName,
253bf215546Sopenharmony_ci                                             stage_info->pSpecializationInfo,
254bf215546Sopenharmony_ci                                             &spirv_options,
255bf215546Sopenharmony_ci                                             GENX(pan_shader_get_compiler_options)(),
256bf215546Sopenharmony_ci                                             NULL, &nir);
257bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
258bf215546Sopenharmony_ci      vk_free2(&dev->vk.alloc, alloc, shader);
259bf215546Sopenharmony_ci      return NULL;
260bf215546Sopenharmony_ci   }
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_io_to_temporaries,
263bf215546Sopenharmony_ci              nir_shader_get_entrypoint(nir), true, true);
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_ci   struct panfrost_sysvals fixed_sysvals;
266bf215546Sopenharmony_ci   panvk_init_sysvals(&fixed_sysvals, stage);
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   struct panfrost_compile_inputs inputs = {
269bf215546Sopenharmony_ci      .gpu_id = pdev->gpu_id,
270bf215546Sopenharmony_ci      .no_ubo_to_push = true,
271bf215546Sopenharmony_ci      .no_idvs = true, /* TODO */
272bf215546Sopenharmony_ci      .fixed_sysval_ubo = sysval_ubo,
273bf215546Sopenharmony_ci      .fixed_sysval_layout = &fixed_sysvals,
274bf215546Sopenharmony_ci   };
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_indirect_derefs,
277bf215546Sopenharmony_ci              nir_var_shader_in | nir_var_shader_out,
278bf215546Sopenharmony_ci              UINT32_MAX);
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_opt_copy_prop_vars);
281bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_opt_combine_stores, nir_var_all);
282bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_opt_trivial_continues);
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   /* Do texture lowering here.  Yes, it's a duplication of the texture
285bf215546Sopenharmony_ci    * lowering in bifrost_compile.  However, we need to lower texture stuff
286bf215546Sopenharmony_ci    * now, before we call panvk_per_arch(nir_lower_descriptors)() because some
287bf215546Sopenharmony_ci    * of the texture lowering generates nir_texop_txs which we handle as part
288bf215546Sopenharmony_ci    * of descriptor lowering.
289bf215546Sopenharmony_ci    *
290bf215546Sopenharmony_ci    * TODO: We really should be doing this in common code, not dpulicated in
291bf215546Sopenharmony_ci    * panvk.  In order to do that, we need to rework the panfrost compile
292bf215546Sopenharmony_ci    * flow to look more like the Intel flow:
293bf215546Sopenharmony_ci    *
294bf215546Sopenharmony_ci    *  1. Compile SPIR-V to NIR and maybe do a tiny bit of lowering that needs
295bf215546Sopenharmony_ci    *     to be done really early.
296bf215546Sopenharmony_ci    *
297bf215546Sopenharmony_ci    *  2. bi_preprocess_nir: Does common lowering and runs the optimization
298bf215546Sopenharmony_ci    *     loop.  Nothing here should be API-specific.
299bf215546Sopenharmony_ci    *
300bf215546Sopenharmony_ci    *  3. Do additional lowering in panvk
301bf215546Sopenharmony_ci    *
302bf215546Sopenharmony_ci    *  4. bi_postprocess_nir: Does final lowering and runs the optimization
303bf215546Sopenharmony_ci    *     loop again.  This can happen as part of the final compile.
304bf215546Sopenharmony_ci    *
305bf215546Sopenharmony_ci    * This would give us a better place to do panvk-specific lowering.
306bf215546Sopenharmony_ci    */
307bf215546Sopenharmony_ci   nir_lower_tex_options lower_tex_options = {
308bf215546Sopenharmony_ci      .lower_txs_lod = true,
309bf215546Sopenharmony_ci      .lower_txp = ~0,
310bf215546Sopenharmony_ci      .lower_tg4_broadcom_swizzle = true,
311bf215546Sopenharmony_ci      .lower_txd = true,
312bf215546Sopenharmony_ci      .lower_invalid_implicit_lod = true,
313bf215546Sopenharmony_ci   };
314bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_tex, &lower_tex_options);
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci   NIR_PASS_V(nir, panvk_per_arch(nir_lower_descriptors),
317bf215546Sopenharmony_ci              dev, layout, &shader->has_img_access);
318bf215546Sopenharmony_ci
319bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo,
320bf215546Sopenharmony_ci              nir_address_format_32bit_index_offset);
321bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ssbo,
322bf215546Sopenharmony_ci              spirv_options.ssbo_addr_format);
323bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_explicit_io,
324bf215546Sopenharmony_ci              nir_var_mem_push_const,
325bf215546Sopenharmony_ci              nir_address_format_32bit_offset);
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci   if (gl_shader_stage_uses_workgroup(stage)) {
328bf215546Sopenharmony_ci      if (!nir->info.shared_memory_explicit_layout) {
329bf215546Sopenharmony_ci         NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
330bf215546Sopenharmony_ci                    nir_var_mem_shared,
331bf215546Sopenharmony_ci                    shared_type_info);
332bf215546Sopenharmony_ci      }
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_ci      NIR_PASS_V(nir, nir_lower_explicit_io,
335bf215546Sopenharmony_ci                 nir_var_mem_shared,
336bf215546Sopenharmony_ci                 nir_address_format_32bit_offset);
337bf215546Sopenharmony_ci   }
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_shader_instructions_pass,
340bf215546Sopenharmony_ci              panvk_lower_load_push_constant,
341bf215546Sopenharmony_ci              nir_metadata_block_index |
342bf215546Sopenharmony_ci              nir_metadata_dominance,
343bf215546Sopenharmony_ci              (void *)layout);
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_system_values);
346bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_split_var_copies);
349bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_var_copies);
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci   /* We have to run nir_lower_blend() after we've gotten rid of copies (it
352bf215546Sopenharmony_ci    * requires load/store) and before we assign output locations.
353bf215546Sopenharmony_ci    */
354bf215546Sopenharmony_ci   if (stage == MESA_SHADER_FRAGMENT) {
355bf215546Sopenharmony_ci      /* This is required for nir_lower_blend */
356bf215546Sopenharmony_ci      NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
357bf215546Sopenharmony_ci      panvk_lower_blend(pdev, nir, &inputs, blend_state, static_blend_constants);
358bf215546Sopenharmony_ci   }
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, stage);
361bf215546Sopenharmony_ci   nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, stage);
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   /* Needed to turn shader_temp into function_temp since the backend only
364bf215546Sopenharmony_ci    * handles the latter for now.
365bf215546Sopenharmony_ci    */
366bf215546Sopenharmony_ci   NIR_PASS_V(nir, nir_lower_global_vars_to_local);
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci   nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
369bf215546Sopenharmony_ci   if (unlikely(dev->physical_device->instance->debug_flags & PANVK_DEBUG_NIR)) {
370bf215546Sopenharmony_ci      fprintf(stderr, "translated nir:\n");
371bf215546Sopenharmony_ci      nir_print_shader(nir, stderr);
372bf215546Sopenharmony_ci   }
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_ci   GENX(pan_shader_compile)(nir, &inputs, &shader->binary, &shader->info);
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   /* System values shouldn't have changed */
377bf215546Sopenharmony_ci   assert(memcmp(&shader->info.sysvals, &fixed_sysvals,
378bf215546Sopenharmony_ci                 sizeof(fixed_sysvals)) == 0);
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci   /* Patch the descriptor count */
381bf215546Sopenharmony_ci   shader->info.ubo_count = PANVK_NUM_BUILTIN_UBOS +
382bf215546Sopenharmony_ci                            layout->num_ubos + layout->num_dyn_ubos;
383bf215546Sopenharmony_ci   shader->info.sampler_count = layout->num_samplers;
384bf215546Sopenharmony_ci   shader->info.texture_count = layout->num_textures;
385bf215546Sopenharmony_ci   if (shader->has_img_access)
386bf215546Sopenharmony_ci      shader->info.attribute_count += layout->num_imgs;
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci   shader->sysval_ubo = sysval_ubo;
389bf215546Sopenharmony_ci   shader->local_size.x = nir->info.workgroup_size[0];
390bf215546Sopenharmony_ci   shader->local_size.y = nir->info.workgroup_size[1];
391bf215546Sopenharmony_ci   shader->local_size.z = nir->info.workgroup_size[2];
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci   ralloc_free(nir);
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci   return shader;
396bf215546Sopenharmony_ci}
397