1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2017 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci */
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci/**
24bf215546Sopenharmony_ci * @file iris_program.c
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci * This file contains the driver interface for compiling shaders.
27bf215546Sopenharmony_ci *
28bf215546Sopenharmony_ci * See iris_program_cache.c for the in-memory program cache where the
29bf215546Sopenharmony_ci * compiled shaders are stored.
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include <stdio.h>
33bf215546Sopenharmony_ci#include <errno.h>
34bf215546Sopenharmony_ci#include "pipe/p_defines.h"
35bf215546Sopenharmony_ci#include "pipe/p_state.h"
36bf215546Sopenharmony_ci#include "pipe/p_context.h"
37bf215546Sopenharmony_ci#include "pipe/p_screen.h"
38bf215546Sopenharmony_ci#include "util/u_atomic.h"
39bf215546Sopenharmony_ci#include "util/u_upload_mgr.h"
40bf215546Sopenharmony_ci#include "util/debug.h"
41bf215546Sopenharmony_ci#include "util/u_async_debug.h"
42bf215546Sopenharmony_ci#include "compiler/nir/nir.h"
43bf215546Sopenharmony_ci#include "compiler/nir/nir_builder.h"
44bf215546Sopenharmony_ci#include "compiler/nir/nir_serialize.h"
45bf215546Sopenharmony_ci#include "intel/compiler/brw_compiler.h"
46bf215546Sopenharmony_ci#include "intel/compiler/brw_nir.h"
47bf215546Sopenharmony_ci#include "intel/compiler/brw_prim.h"
48bf215546Sopenharmony_ci#include "iris_context.h"
49bf215546Sopenharmony_ci#include "nir/tgsi_to_nir.h"
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci#define KEY_INIT(prefix)                                                   \
52bf215546Sopenharmony_ci   .prefix.program_string_id = ish->program_id,                            \
53bf215546Sopenharmony_ci   .prefix.limit_trig_input_range = screen->driconf.limit_trig_input_range
54bf215546Sopenharmony_ci#define BRW_KEY_INIT(gen, prog_id, limit_trig_input)       \
55bf215546Sopenharmony_ci   .base.program_string_id = prog_id,                      \
56bf215546Sopenharmony_ci   .base.limit_trig_input_range = limit_trig_input,        \
57bf215546Sopenharmony_ci   .base.tex.swizzles[0 ... BRW_MAX_SAMPLERS - 1] = 0x688, \
58bf215546Sopenharmony_ci   .base.tex.compressed_multisample_layout_mask = ~0,      \
59bf215546Sopenharmony_ci   .base.tex.msaa_16 = (gen >= 9 ? ~0 : 0)
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_cistruct iris_threaded_compile_job {
62bf215546Sopenharmony_ci   struct iris_screen *screen;
63bf215546Sopenharmony_ci   struct u_upload_mgr *uploader;
64bf215546Sopenharmony_ci   struct util_debug_callback *dbg;
65bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish;
66bf215546Sopenharmony_ci   struct iris_compiled_shader *shader;
67bf215546Sopenharmony_ci};
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_cistatic unsigned
70bf215546Sopenharmony_ciget_new_program_id(struct iris_screen *screen)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   return p_atomic_inc_return(&screen->program_id);
73bf215546Sopenharmony_ci}
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_civoid
76bf215546Sopenharmony_ciiris_finalize_program(struct iris_compiled_shader *shader,
77bf215546Sopenharmony_ci                      struct brw_stage_prog_data *prog_data,
78bf215546Sopenharmony_ci                      uint32_t *streamout,
79bf215546Sopenharmony_ci                      enum brw_param_builtin *system_values,
80bf215546Sopenharmony_ci                      unsigned num_system_values,
81bf215546Sopenharmony_ci                      unsigned kernel_input_size,
82bf215546Sopenharmony_ci                      unsigned num_cbufs,
83bf215546Sopenharmony_ci                      const struct iris_binding_table *bt)
84bf215546Sopenharmony_ci{
85bf215546Sopenharmony_ci   shader->prog_data = prog_data;
86bf215546Sopenharmony_ci   shader->streamout = streamout;
87bf215546Sopenharmony_ci   shader->system_values = system_values;
88bf215546Sopenharmony_ci   shader->num_system_values = num_system_values;
89bf215546Sopenharmony_ci   shader->kernel_input_size = kernel_input_size;
90bf215546Sopenharmony_ci   shader->num_cbufs = num_cbufs;
91bf215546Sopenharmony_ci   shader->bt = *bt;
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   ralloc_steal(shader, shader->prog_data);
94bf215546Sopenharmony_ci   ralloc_steal(shader->prog_data, (void *)prog_data->relocs);
95bf215546Sopenharmony_ci   ralloc_steal(shader->prog_data, prog_data->param);
96bf215546Sopenharmony_ci   ralloc_steal(shader, shader->streamout);
97bf215546Sopenharmony_ci   ralloc_steal(shader, shader->system_values);
98bf215546Sopenharmony_ci}
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cistatic struct brw_vs_prog_key
101bf215546Sopenharmony_ciiris_to_brw_vs_key(const struct iris_screen *screen,
102bf215546Sopenharmony_ci                   const struct iris_vs_prog_key *key)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci   return (struct brw_vs_prog_key) {
105bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id,
106bf215546Sopenharmony_ci                   key->vue.base.limit_trig_input_range),
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci      /* Don't tell the backend about our clip plane constants, we've
109bf215546Sopenharmony_ci       * already lowered them in NIR and don't want it doing it again.
110bf215546Sopenharmony_ci       */
111bf215546Sopenharmony_ci      .nr_userclip_plane_consts = 0,
112bf215546Sopenharmony_ci   };
113bf215546Sopenharmony_ci}
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_cistatic struct brw_tcs_prog_key
116bf215546Sopenharmony_ciiris_to_brw_tcs_key(const struct iris_screen *screen,
117bf215546Sopenharmony_ci                    const struct iris_tcs_prog_key *key)
118bf215546Sopenharmony_ci{
119bf215546Sopenharmony_ci   return (struct brw_tcs_prog_key) {
120bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id,
121bf215546Sopenharmony_ci                   key->vue.base.limit_trig_input_range),
122bf215546Sopenharmony_ci      ._tes_primitive_mode = key->_tes_primitive_mode,
123bf215546Sopenharmony_ci      .input_vertices = key->input_vertices,
124bf215546Sopenharmony_ci      .patch_outputs_written = key->patch_outputs_written,
125bf215546Sopenharmony_ci      .outputs_written = key->outputs_written,
126bf215546Sopenharmony_ci      .quads_workaround = key->quads_workaround,
127bf215546Sopenharmony_ci   };
128bf215546Sopenharmony_ci}
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_cistatic struct brw_tes_prog_key
131bf215546Sopenharmony_ciiris_to_brw_tes_key(const struct iris_screen *screen,
132bf215546Sopenharmony_ci                    const struct iris_tes_prog_key *key)
133bf215546Sopenharmony_ci{
134bf215546Sopenharmony_ci   return (struct brw_tes_prog_key) {
135bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id,
136bf215546Sopenharmony_ci                   key->vue.base.limit_trig_input_range),
137bf215546Sopenharmony_ci      .patch_inputs_read = key->patch_inputs_read,
138bf215546Sopenharmony_ci      .inputs_read = key->inputs_read,
139bf215546Sopenharmony_ci   };
140bf215546Sopenharmony_ci}
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_cistatic struct brw_gs_prog_key
143bf215546Sopenharmony_ciiris_to_brw_gs_key(const struct iris_screen *screen,
144bf215546Sopenharmony_ci                   const struct iris_gs_prog_key *key)
145bf215546Sopenharmony_ci{
146bf215546Sopenharmony_ci   return (struct brw_gs_prog_key) {
147bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id,
148bf215546Sopenharmony_ci                   key->vue.base.limit_trig_input_range),
149bf215546Sopenharmony_ci   };
150bf215546Sopenharmony_ci}
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_cistatic struct brw_wm_prog_key
153bf215546Sopenharmony_ciiris_to_brw_fs_key(const struct iris_screen *screen,
154bf215546Sopenharmony_ci                   const struct iris_fs_prog_key *key)
155bf215546Sopenharmony_ci{
156bf215546Sopenharmony_ci   return (struct brw_wm_prog_key) {
157bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->base.program_string_id,
158bf215546Sopenharmony_ci                   key->base.limit_trig_input_range),
159bf215546Sopenharmony_ci      .nr_color_regions = key->nr_color_regions,
160bf215546Sopenharmony_ci      .flat_shade = key->flat_shade,
161bf215546Sopenharmony_ci      .alpha_test_replicate_alpha = key->alpha_test_replicate_alpha,
162bf215546Sopenharmony_ci      .alpha_to_coverage = key->alpha_to_coverage,
163bf215546Sopenharmony_ci      .clamp_fragment_color = key->clamp_fragment_color,
164bf215546Sopenharmony_ci      .persample_interp = key->persample_interp,
165bf215546Sopenharmony_ci      .multisample_fbo = key->multisample_fbo,
166bf215546Sopenharmony_ci      .force_dual_color_blend = key->force_dual_color_blend,
167bf215546Sopenharmony_ci      .coherent_fb_fetch = key->coherent_fb_fetch,
168bf215546Sopenharmony_ci      .color_outputs_valid = key->color_outputs_valid,
169bf215546Sopenharmony_ci      .input_slots_valid = key->input_slots_valid,
170bf215546Sopenharmony_ci      .ignore_sample_mask_out = !key->multisample_fbo,
171bf215546Sopenharmony_ci   };
172bf215546Sopenharmony_ci}
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_cistatic struct brw_cs_prog_key
175bf215546Sopenharmony_ciiris_to_brw_cs_key(const struct iris_screen *screen,
176bf215546Sopenharmony_ci                   const struct iris_cs_prog_key *key)
177bf215546Sopenharmony_ci{
178bf215546Sopenharmony_ci   return (struct brw_cs_prog_key) {
179bf215546Sopenharmony_ci      BRW_KEY_INIT(screen->devinfo.ver, key->base.program_string_id,
180bf215546Sopenharmony_ci                   key->base.limit_trig_input_range),
181bf215546Sopenharmony_ci   };
182bf215546Sopenharmony_ci}
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_cistatic void *
185bf215546Sopenharmony_ciupload_state(struct u_upload_mgr *uploader,
186bf215546Sopenharmony_ci             struct iris_state_ref *ref,
187bf215546Sopenharmony_ci             unsigned size,
188bf215546Sopenharmony_ci             unsigned alignment)
189bf215546Sopenharmony_ci{
190bf215546Sopenharmony_ci   void *p = NULL;
191bf215546Sopenharmony_ci   u_upload_alloc(uploader, 0, size, alignment, &ref->offset, &ref->res, &p);
192bf215546Sopenharmony_ci   return p;
193bf215546Sopenharmony_ci}
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_civoid
196bf215546Sopenharmony_ciiris_upload_ubo_ssbo_surf_state(struct iris_context *ice,
197bf215546Sopenharmony_ci                                struct pipe_shader_buffer *buf,
198bf215546Sopenharmony_ci                                struct iris_state_ref *surf_state,
199bf215546Sopenharmony_ci                                isl_surf_usage_flags_t usage)
200bf215546Sopenharmony_ci{
201bf215546Sopenharmony_ci   struct pipe_context *ctx = &ice->ctx;
202bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *) ctx->screen;
203bf215546Sopenharmony_ci   bool ssbo = usage & ISL_SURF_USAGE_STORAGE_BIT;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   void *map =
206bf215546Sopenharmony_ci      upload_state(ice->state.surface_uploader, surf_state,
207bf215546Sopenharmony_ci                   screen->isl_dev.ss.size, 64);
208bf215546Sopenharmony_ci   if (!unlikely(map)) {
209bf215546Sopenharmony_ci      surf_state->res = NULL;
210bf215546Sopenharmony_ci      return;
211bf215546Sopenharmony_ci   }
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   struct iris_resource *res = (void *) buf->buffer;
214bf215546Sopenharmony_ci   struct iris_bo *surf_bo = iris_resource_bo(surf_state->res);
215bf215546Sopenharmony_ci   surf_state->offset += iris_bo_offset_from_base_address(surf_bo);
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   const bool dataport = ssbo || !screen->compiler->indirect_ubos_use_sampler;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   isl_buffer_fill_state(&screen->isl_dev, map,
220bf215546Sopenharmony_ci                         .address = res->bo->address + res->offset +
221bf215546Sopenharmony_ci                                    buf->buffer_offset,
222bf215546Sopenharmony_ci                         .size_B = buf->buffer_size - res->offset,
223bf215546Sopenharmony_ci                         .format = dataport ? ISL_FORMAT_RAW
224bf215546Sopenharmony_ci                                            : ISL_FORMAT_R32G32B32A32_FLOAT,
225bf215546Sopenharmony_ci                         .swizzle = ISL_SWIZZLE_IDENTITY,
226bf215546Sopenharmony_ci                         .stride_B = 1,
227bf215546Sopenharmony_ci                         .mocs = iris_mocs(res->bo, &screen->isl_dev, usage));
228bf215546Sopenharmony_ci}
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_cistatic nir_ssa_def *
231bf215546Sopenharmony_ciget_aoa_deref_offset(nir_builder *b,
232bf215546Sopenharmony_ci                     nir_deref_instr *deref,
233bf215546Sopenharmony_ci                     unsigned elem_size)
234bf215546Sopenharmony_ci{
235bf215546Sopenharmony_ci   unsigned array_size = elem_size;
236bf215546Sopenharmony_ci   nir_ssa_def *offset = nir_imm_int(b, 0);
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   while (deref->deref_type != nir_deref_type_var) {
239bf215546Sopenharmony_ci      assert(deref->deref_type == nir_deref_type_array);
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci      /* This level's element size is the previous level's array size */
242bf215546Sopenharmony_ci      nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
243bf215546Sopenharmony_ci      assert(deref->arr.index.ssa);
244bf215546Sopenharmony_ci      offset = nir_iadd(b, offset,
245bf215546Sopenharmony_ci                           nir_imul(b, index, nir_imm_int(b, array_size)));
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci      deref = nir_deref_instr_parent(deref);
248bf215546Sopenharmony_ci      assert(glsl_type_is_array(deref->type));
249bf215546Sopenharmony_ci      array_size *= glsl_get_length(deref->type);
250bf215546Sopenharmony_ci   }
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   /* Accessing an invalid surface index with the dataport can result in a
253bf215546Sopenharmony_ci    * hang.  According to the spec "if the index used to select an individual
254bf215546Sopenharmony_ci    * element is negative or greater than or equal to the size of the array,
255bf215546Sopenharmony_ci    * the results of the operation are undefined but may not lead to
256bf215546Sopenharmony_ci    * termination" -- which is one of the possible outcomes of the hang.
257bf215546Sopenharmony_ci    * Clamp the index to prevent access outside of the array bounds.
258bf215546Sopenharmony_ci    */
259bf215546Sopenharmony_ci   return nir_umin(b, offset, nir_imm_int(b, array_size - elem_size));
260bf215546Sopenharmony_ci}
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_cistatic void
263bf215546Sopenharmony_ciiris_lower_storage_image_derefs(nir_shader *nir)
264bf215546Sopenharmony_ci{
265bf215546Sopenharmony_ci   nir_function_impl *impl = nir_shader_get_entrypoint(nir);
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci   nir_builder b;
268bf215546Sopenharmony_ci   nir_builder_init(&b, impl);
269bf215546Sopenharmony_ci
270bf215546Sopenharmony_ci   nir_foreach_block(block, impl) {
271bf215546Sopenharmony_ci      nir_foreach_instr_safe(instr, block) {
272bf215546Sopenharmony_ci         if (instr->type != nir_instr_type_intrinsic)
273bf215546Sopenharmony_ci            continue;
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
276bf215546Sopenharmony_ci         switch (intrin->intrinsic) {
277bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_load:
278bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_store:
279bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_add:
280bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_imin:
281bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_umin:
282bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_imax:
283bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_umax:
284bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_and:
285bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_or:
286bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_xor:
287bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_exchange:
288bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_atomic_comp_swap:
289bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_size:
290bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_samples:
291bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_load_raw_intel:
292bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_store_raw_intel: {
293bf215546Sopenharmony_ci            nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
294bf215546Sopenharmony_ci            nir_variable *var = nir_deref_instr_get_variable(deref);
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci            b.cursor = nir_before_instr(&intrin->instr);
297bf215546Sopenharmony_ci            nir_ssa_def *index =
298bf215546Sopenharmony_ci               nir_iadd(&b, nir_imm_int(&b, var->data.driver_location),
299bf215546Sopenharmony_ci                            get_aoa_deref_offset(&b, deref, 1));
300bf215546Sopenharmony_ci            nir_rewrite_image_intrinsic(intrin, index, false);
301bf215546Sopenharmony_ci            break;
302bf215546Sopenharmony_ci         }
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci         default:
305bf215546Sopenharmony_ci            break;
306bf215546Sopenharmony_ci         }
307bf215546Sopenharmony_ci      }
308bf215546Sopenharmony_ci   }
309bf215546Sopenharmony_ci}
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_cistatic bool
312bf215546Sopenharmony_ciiris_uses_image_atomic(const nir_shader *shader)
313bf215546Sopenharmony_ci{
314bf215546Sopenharmony_ci   nir_foreach_function(function, shader) {
315bf215546Sopenharmony_ci      if (function->impl == NULL)
316bf215546Sopenharmony_ci         continue;
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci      nir_foreach_block(block, function->impl) {
319bf215546Sopenharmony_ci         nir_foreach_instr(instr, block) {
320bf215546Sopenharmony_ci            if (instr->type != nir_instr_type_intrinsic)
321bf215546Sopenharmony_ci               continue;
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci            nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
324bf215546Sopenharmony_ci            switch (intrin->intrinsic) {
325bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_add:
326bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_imin:
327bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_umin:
328bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_imax:
329bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_umax:
330bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_and:
331bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_or:
332bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_xor:
333bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_exchange:
334bf215546Sopenharmony_ci            case nir_intrinsic_image_deref_atomic_comp_swap:
335bf215546Sopenharmony_ci               unreachable("Should have been lowered in "
336bf215546Sopenharmony_ci                           "iris_lower_storage_image_derefs");
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_add:
339bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_imin:
340bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_umin:
341bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_imax:
342bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_umax:
343bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_and:
344bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_or:
345bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_xor:
346bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_exchange:
347bf215546Sopenharmony_ci            case nir_intrinsic_image_atomic_comp_swap:
348bf215546Sopenharmony_ci               return true;
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ci            default:
351bf215546Sopenharmony_ci               break;
352bf215546Sopenharmony_ci            }
353bf215546Sopenharmony_ci         }
354bf215546Sopenharmony_ci      }
355bf215546Sopenharmony_ci   }
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   return false;
358bf215546Sopenharmony_ci}
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci/**
361bf215546Sopenharmony_ci * Undo nir_lower_passthrough_edgeflags but keep the inputs_read flag.
362bf215546Sopenharmony_ci */
363bf215546Sopenharmony_cistatic bool
364bf215546Sopenharmony_ciiris_fix_edge_flags(nir_shader *nir)
365bf215546Sopenharmony_ci{
366bf215546Sopenharmony_ci   if (nir->info.stage != MESA_SHADER_VERTEX) {
367bf215546Sopenharmony_ci      nir_shader_preserve_all_metadata(nir);
368bf215546Sopenharmony_ci      return false;
369bf215546Sopenharmony_ci   }
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out,
372bf215546Sopenharmony_ci                                                       VARYING_SLOT_EDGE);
373bf215546Sopenharmony_ci   if (!var) {
374bf215546Sopenharmony_ci      nir_shader_preserve_all_metadata(nir);
375bf215546Sopenharmony_ci      return false;
376bf215546Sopenharmony_ci   }
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci   var->data.mode = nir_var_shader_temp;
379bf215546Sopenharmony_ci   nir->info.outputs_written &= ~VARYING_BIT_EDGE;
380bf215546Sopenharmony_ci   nir->info.inputs_read &= ~VERT_BIT_EDGEFLAG;
381bf215546Sopenharmony_ci   nir_fixup_deref_modes(nir);
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   nir_foreach_function(f, nir) {
384bf215546Sopenharmony_ci      if (f->impl) {
385bf215546Sopenharmony_ci         nir_metadata_preserve(f->impl, nir_metadata_block_index |
386bf215546Sopenharmony_ci                                        nir_metadata_dominance |
387bf215546Sopenharmony_ci                                        nir_metadata_live_ssa_defs |
388bf215546Sopenharmony_ci                                        nir_metadata_loop_analysis);
389bf215546Sopenharmony_ci      } else {
390bf215546Sopenharmony_ci         nir_metadata_preserve(f->impl, nir_metadata_all);
391bf215546Sopenharmony_ci      }
392bf215546Sopenharmony_ci   }
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci   return true;
395bf215546Sopenharmony_ci}
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci/**
398bf215546Sopenharmony_ci * Fix an uncompiled shader's stream output info.
399bf215546Sopenharmony_ci *
400bf215546Sopenharmony_ci * Core Gallium stores output->register_index as a "slot" number, where
401bf215546Sopenharmony_ci * slots are assigned consecutively to all outputs in info->outputs_written.
402bf215546Sopenharmony_ci * This naive packing of outputs doesn't work for us - we too have slots,
403bf215546Sopenharmony_ci * but the layout is defined by the VUE map, which we won't have until we
404bf215546Sopenharmony_ci * compile a specific shader variant.  So, we remap these and simply store
405bf215546Sopenharmony_ci * VARYING_SLOT_* in our copy's output->register_index fields.
406bf215546Sopenharmony_ci *
407bf215546Sopenharmony_ci * We also fix up VARYING_SLOT_{LAYER,VIEWPORT,PSIZ} to select the Y/Z/W
408bf215546Sopenharmony_ci * components of our VUE header.  See brw_vue_map.c for the layout.
409bf215546Sopenharmony_ci */
410bf215546Sopenharmony_cistatic void
411bf215546Sopenharmony_ciupdate_so_info(struct pipe_stream_output_info *so_info,
412bf215546Sopenharmony_ci               uint64_t outputs_written)
413bf215546Sopenharmony_ci{
414bf215546Sopenharmony_ci   uint8_t reverse_map[64] = {};
415bf215546Sopenharmony_ci   unsigned slot = 0;
416bf215546Sopenharmony_ci   while (outputs_written) {
417bf215546Sopenharmony_ci      reverse_map[slot++] = u_bit_scan64(&outputs_written);
418bf215546Sopenharmony_ci   }
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   for (unsigned i = 0; i < so_info->num_outputs; i++) {
421bf215546Sopenharmony_ci      struct pipe_stream_output *output = &so_info->output[i];
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_ci      /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */
424bf215546Sopenharmony_ci      output->register_index = reverse_map[output->register_index];
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci      /* The VUE header contains three scalar fields packed together:
427bf215546Sopenharmony_ci       * - gl_PointSize is stored in VARYING_SLOT_PSIZ.w
428bf215546Sopenharmony_ci       * - gl_Layer is stored in VARYING_SLOT_PSIZ.y
429bf215546Sopenharmony_ci       * - gl_ViewportIndex is stored in VARYING_SLOT_PSIZ.z
430bf215546Sopenharmony_ci       */
431bf215546Sopenharmony_ci      switch (output->register_index) {
432bf215546Sopenharmony_ci      case VARYING_SLOT_LAYER:
433bf215546Sopenharmony_ci         assert(output->num_components == 1);
434bf215546Sopenharmony_ci         output->register_index = VARYING_SLOT_PSIZ;
435bf215546Sopenharmony_ci         output->start_component = 1;
436bf215546Sopenharmony_ci         break;
437bf215546Sopenharmony_ci      case VARYING_SLOT_VIEWPORT:
438bf215546Sopenharmony_ci         assert(output->num_components == 1);
439bf215546Sopenharmony_ci         output->register_index = VARYING_SLOT_PSIZ;
440bf215546Sopenharmony_ci         output->start_component = 2;
441bf215546Sopenharmony_ci         break;
442bf215546Sopenharmony_ci      case VARYING_SLOT_PSIZ:
443bf215546Sopenharmony_ci         assert(output->num_components == 1);
444bf215546Sopenharmony_ci         output->start_component = 3;
445bf215546Sopenharmony_ci         break;
446bf215546Sopenharmony_ci      }
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci      //info->outputs_written |= 1ull << output->register_index;
449bf215546Sopenharmony_ci   }
450bf215546Sopenharmony_ci}
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_cistatic void
453bf215546Sopenharmony_cisetup_vec4_image_sysval(uint32_t *sysvals, uint32_t idx,
454bf215546Sopenharmony_ci                        unsigned offset, unsigned n)
455bf215546Sopenharmony_ci{
456bf215546Sopenharmony_ci   assert(offset % sizeof(uint32_t) == 0);
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci   for (unsigned i = 0; i < n; ++i)
459bf215546Sopenharmony_ci      sysvals[i] = BRW_PARAM_IMAGE(idx, offset / sizeof(uint32_t) + i);
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_ci   for (unsigned i = n; i < 4; ++i)
462bf215546Sopenharmony_ci      sysvals[i] = BRW_PARAM_BUILTIN_ZERO;
463bf215546Sopenharmony_ci}
464bf215546Sopenharmony_ci
465bf215546Sopenharmony_ci/**
466bf215546Sopenharmony_ci * Associate NIR uniform variables with the prog_data->param[] mechanism
467bf215546Sopenharmony_ci * used by the backend.  Also, decide which UBOs we'd like to push in an
468bf215546Sopenharmony_ci * ideal situation (though the backend can reduce this).
469bf215546Sopenharmony_ci */
470bf215546Sopenharmony_cistatic void
471bf215546Sopenharmony_ciiris_setup_uniforms(const struct brw_compiler *compiler,
472bf215546Sopenharmony_ci                    void *mem_ctx,
473bf215546Sopenharmony_ci                    nir_shader *nir,
474bf215546Sopenharmony_ci                    struct brw_stage_prog_data *prog_data,
475bf215546Sopenharmony_ci                    unsigned kernel_input_size,
476bf215546Sopenharmony_ci                    enum brw_param_builtin **out_system_values,
477bf215546Sopenharmony_ci                    unsigned *out_num_system_values,
478bf215546Sopenharmony_ci                    unsigned *out_num_cbufs)
479bf215546Sopenharmony_ci{
480bf215546Sopenharmony_ci   UNUSED const struct intel_device_info *devinfo = compiler->devinfo;
481bf215546Sopenharmony_ci
482bf215546Sopenharmony_ci   unsigned system_values_start = ALIGN(kernel_input_size, sizeof(uint32_t));
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   const unsigned IRIS_MAX_SYSTEM_VALUES =
485bf215546Sopenharmony_ci      PIPE_MAX_SHADER_IMAGES * BRW_IMAGE_PARAM_SIZE;
486bf215546Sopenharmony_ci   enum brw_param_builtin *system_values =
487bf215546Sopenharmony_ci      rzalloc_array(mem_ctx, enum brw_param_builtin, IRIS_MAX_SYSTEM_VALUES);
488bf215546Sopenharmony_ci   unsigned num_system_values = 0;
489bf215546Sopenharmony_ci
490bf215546Sopenharmony_ci   unsigned patch_vert_idx = -1;
491bf215546Sopenharmony_ci   unsigned ucp_idx[IRIS_MAX_CLIP_PLANES];
492bf215546Sopenharmony_ci   unsigned img_idx[PIPE_MAX_SHADER_IMAGES];
493bf215546Sopenharmony_ci   unsigned variable_group_size_idx = -1;
494bf215546Sopenharmony_ci   unsigned work_dim_idx = -1;
495bf215546Sopenharmony_ci   memset(ucp_idx, -1, sizeof(ucp_idx));
496bf215546Sopenharmony_ci   memset(img_idx, -1, sizeof(img_idx));
497bf215546Sopenharmony_ci
498bf215546Sopenharmony_ci   nir_function_impl *impl = nir_shader_get_entrypoint(nir);
499bf215546Sopenharmony_ci
500bf215546Sopenharmony_ci   nir_builder b;
501bf215546Sopenharmony_ci   nir_builder_init(&b, impl);
502bf215546Sopenharmony_ci
503bf215546Sopenharmony_ci   b.cursor = nir_before_block(nir_start_block(impl));
504bf215546Sopenharmony_ci   nir_ssa_def *temp_ubo_name = nir_ssa_undef(&b, 1, 32);
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci   /* Turn system value intrinsics into uniforms */
507bf215546Sopenharmony_ci   nir_foreach_block(block, impl) {
508bf215546Sopenharmony_ci      nir_foreach_instr_safe(instr, block) {
509bf215546Sopenharmony_ci         if (instr->type != nir_instr_type_intrinsic)
510bf215546Sopenharmony_ci            continue;
511bf215546Sopenharmony_ci
512bf215546Sopenharmony_ci         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
513bf215546Sopenharmony_ci         nir_ssa_def *offset;
514bf215546Sopenharmony_ci
515bf215546Sopenharmony_ci         switch (intrin->intrinsic) {
516bf215546Sopenharmony_ci         case nir_intrinsic_load_constant: {
517bf215546Sopenharmony_ci            unsigned load_size = intrin->dest.ssa.num_components *
518bf215546Sopenharmony_ci                                 intrin->dest.ssa.bit_size / 8;
519bf215546Sopenharmony_ci            unsigned load_align = intrin->dest.ssa.bit_size / 8;
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_ci            /* This one is special because it reads from the shader constant
522bf215546Sopenharmony_ci             * data and not cbuf0 which gallium uploads for us.
523bf215546Sopenharmony_ci             */
524bf215546Sopenharmony_ci            b.cursor = nir_instr_remove(&intrin->instr);
525bf215546Sopenharmony_ci
526bf215546Sopenharmony_ci            nir_ssa_def *offset =
527bf215546Sopenharmony_ci               nir_iadd_imm(&b, nir_ssa_for_src(&b, intrin->src[0], 1),
528bf215546Sopenharmony_ci                                nir_intrinsic_base(intrin));
529bf215546Sopenharmony_ci
530bf215546Sopenharmony_ci            assert(load_size < b.shader->constant_data_size);
531bf215546Sopenharmony_ci            unsigned max_offset = b.shader->constant_data_size - load_size;
532bf215546Sopenharmony_ci            offset = nir_umin(&b, offset, nir_imm_int(&b, max_offset));
533bf215546Sopenharmony_ci
534bf215546Sopenharmony_ci            nir_ssa_def *const_data_base_addr = nir_pack_64_2x32_split(&b,
535bf215546Sopenharmony_ci               nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW),
536bf215546Sopenharmony_ci               nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH));
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci            nir_ssa_def *data =
539bf215546Sopenharmony_ci               nir_load_global(&b, nir_iadd(&b, const_data_base_addr,
540bf215546Sopenharmony_ci                                                nir_u2u64(&b, offset)),
541bf215546Sopenharmony_ci                               load_align,
542bf215546Sopenharmony_ci                               intrin->dest.ssa.num_components,
543bf215546Sopenharmony_ci                               intrin->dest.ssa.bit_size);
544bf215546Sopenharmony_ci
545bf215546Sopenharmony_ci            nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
546bf215546Sopenharmony_ci                                     data);
547bf215546Sopenharmony_ci            continue;
548bf215546Sopenharmony_ci         }
549bf215546Sopenharmony_ci         case nir_intrinsic_load_user_clip_plane: {
550bf215546Sopenharmony_ci            unsigned ucp = nir_intrinsic_ucp_id(intrin);
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci            if (ucp_idx[ucp] == -1) {
553bf215546Sopenharmony_ci               ucp_idx[ucp] = num_system_values;
554bf215546Sopenharmony_ci               num_system_values += 4;
555bf215546Sopenharmony_ci            }
556bf215546Sopenharmony_ci
557bf215546Sopenharmony_ci            for (int i = 0; i < 4; i++) {
558bf215546Sopenharmony_ci               system_values[ucp_idx[ucp] + i] =
559bf215546Sopenharmony_ci                  BRW_PARAM_BUILTIN_CLIP_PLANE(ucp, i);
560bf215546Sopenharmony_ci            }
561bf215546Sopenharmony_ci
562bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
563bf215546Sopenharmony_ci            offset = nir_imm_int(&b, system_values_start +
564bf215546Sopenharmony_ci                                     ucp_idx[ucp] * sizeof(uint32_t));
565bf215546Sopenharmony_ci            break;
566bf215546Sopenharmony_ci         }
567bf215546Sopenharmony_ci         case nir_intrinsic_load_patch_vertices_in:
568bf215546Sopenharmony_ci            if (patch_vert_idx == -1)
569bf215546Sopenharmony_ci               patch_vert_idx = num_system_values++;
570bf215546Sopenharmony_ci
571bf215546Sopenharmony_ci            system_values[patch_vert_idx] =
572bf215546Sopenharmony_ci               BRW_PARAM_BUILTIN_PATCH_VERTICES_IN;
573bf215546Sopenharmony_ci
574bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
575bf215546Sopenharmony_ci            offset = nir_imm_int(&b, system_values_start +
576bf215546Sopenharmony_ci                                     patch_vert_idx * sizeof(uint32_t));
577bf215546Sopenharmony_ci            break;
578bf215546Sopenharmony_ci         case nir_intrinsic_image_deref_load_param_intel: {
579bf215546Sopenharmony_ci            assert(devinfo->ver < 9);
580bf215546Sopenharmony_ci            nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
581bf215546Sopenharmony_ci            nir_variable *var = nir_deref_instr_get_variable(deref);
582bf215546Sopenharmony_ci
583bf215546Sopenharmony_ci            if (img_idx[var->data.binding] == -1) {
584bf215546Sopenharmony_ci               /* GL only allows arrays of arrays of images. */
585bf215546Sopenharmony_ci               assert(glsl_type_is_image(glsl_without_array(var->type)));
586bf215546Sopenharmony_ci               unsigned num_images = MAX2(1, glsl_get_aoa_size(var->type));
587bf215546Sopenharmony_ci
588bf215546Sopenharmony_ci               for (int i = 0; i < num_images; i++) {
589bf215546Sopenharmony_ci                  const unsigned img = var->data.binding + i;
590bf215546Sopenharmony_ci
591bf215546Sopenharmony_ci                  img_idx[img] = num_system_values;
592bf215546Sopenharmony_ci                  num_system_values += BRW_IMAGE_PARAM_SIZE;
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci                  uint32_t *img_sv = &system_values[img_idx[img]];
595bf215546Sopenharmony_ci
596bf215546Sopenharmony_ci                  setup_vec4_image_sysval(
597bf215546Sopenharmony_ci                     img_sv + BRW_IMAGE_PARAM_OFFSET_OFFSET, img,
598bf215546Sopenharmony_ci                     offsetof(struct brw_image_param, offset), 2);
599bf215546Sopenharmony_ci                  setup_vec4_image_sysval(
600bf215546Sopenharmony_ci                     img_sv + BRW_IMAGE_PARAM_SIZE_OFFSET, img,
601bf215546Sopenharmony_ci                     offsetof(struct brw_image_param, size), 3);
602bf215546Sopenharmony_ci                  setup_vec4_image_sysval(
603bf215546Sopenharmony_ci                     img_sv + BRW_IMAGE_PARAM_STRIDE_OFFSET, img,
604bf215546Sopenharmony_ci                     offsetof(struct brw_image_param, stride), 4);
605bf215546Sopenharmony_ci                  setup_vec4_image_sysval(
606bf215546Sopenharmony_ci                     img_sv + BRW_IMAGE_PARAM_TILING_OFFSET, img,
607bf215546Sopenharmony_ci                     offsetof(struct brw_image_param, tiling), 3);
608bf215546Sopenharmony_ci                  setup_vec4_image_sysval(
609bf215546Sopenharmony_ci                     img_sv + BRW_IMAGE_PARAM_SWIZZLING_OFFSET, img,
610bf215546Sopenharmony_ci                     offsetof(struct brw_image_param, swizzling), 2);
611bf215546Sopenharmony_ci               }
612bf215546Sopenharmony_ci            }
613bf215546Sopenharmony_ci
614bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
615bf215546Sopenharmony_ci            offset = nir_iadd(&b,
616bf215546Sopenharmony_ci               get_aoa_deref_offset(&b, deref, BRW_IMAGE_PARAM_SIZE * 4),
617bf215546Sopenharmony_ci               nir_imm_int(&b, system_values_start +
618bf215546Sopenharmony_ci                               img_idx[var->data.binding] * 4 +
619bf215546Sopenharmony_ci                               nir_intrinsic_base(intrin) * 16));
620bf215546Sopenharmony_ci            break;
621bf215546Sopenharmony_ci         }
622bf215546Sopenharmony_ci         case nir_intrinsic_load_workgroup_size: {
623bf215546Sopenharmony_ci            assert(nir->info.workgroup_size_variable);
624bf215546Sopenharmony_ci            if (variable_group_size_idx == -1) {
625bf215546Sopenharmony_ci               variable_group_size_idx = num_system_values;
626bf215546Sopenharmony_ci               num_system_values += 3;
627bf215546Sopenharmony_ci               for (int i = 0; i < 3; i++) {
628bf215546Sopenharmony_ci                  system_values[variable_group_size_idx + i] =
629bf215546Sopenharmony_ci                     BRW_PARAM_BUILTIN_WORK_GROUP_SIZE_X + i;
630bf215546Sopenharmony_ci               }
631bf215546Sopenharmony_ci            }
632bf215546Sopenharmony_ci
633bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
634bf215546Sopenharmony_ci            offset = nir_imm_int(&b, system_values_start +
635bf215546Sopenharmony_ci                                     variable_group_size_idx * sizeof(uint32_t));
636bf215546Sopenharmony_ci            break;
637bf215546Sopenharmony_ci         }
638bf215546Sopenharmony_ci         case nir_intrinsic_load_work_dim: {
639bf215546Sopenharmony_ci            if (work_dim_idx == -1) {
640bf215546Sopenharmony_ci               work_dim_idx = num_system_values++;
641bf215546Sopenharmony_ci               system_values[work_dim_idx] = BRW_PARAM_BUILTIN_WORK_DIM;
642bf215546Sopenharmony_ci            }
643bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
644bf215546Sopenharmony_ci            offset = nir_imm_int(&b, system_values_start +
645bf215546Sopenharmony_ci                                     work_dim_idx * sizeof(uint32_t));
646bf215546Sopenharmony_ci            break;
647bf215546Sopenharmony_ci         }
648bf215546Sopenharmony_ci         case nir_intrinsic_load_kernel_input: {
649bf215546Sopenharmony_ci            assert(nir_intrinsic_base(intrin) +
650bf215546Sopenharmony_ci                   nir_intrinsic_range(intrin) <= kernel_input_size);
651bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
652bf215546Sopenharmony_ci            offset = nir_iadd_imm(&b, intrin->src[0].ssa,
653bf215546Sopenharmony_ci                                      nir_intrinsic_base(intrin));
654bf215546Sopenharmony_ci            break;
655bf215546Sopenharmony_ci         }
656bf215546Sopenharmony_ci         default:
657bf215546Sopenharmony_ci            continue;
658bf215546Sopenharmony_ci         }
659bf215546Sopenharmony_ci
660bf215546Sopenharmony_ci         nir_ssa_def *load =
661bf215546Sopenharmony_ci            nir_load_ubo(&b, intrin->dest.ssa.num_components, intrin->dest.ssa.bit_size,
662bf215546Sopenharmony_ci                         temp_ubo_name, offset,
663bf215546Sopenharmony_ci                         .align_mul = 4,
664bf215546Sopenharmony_ci                         .align_offset = 0,
665bf215546Sopenharmony_ci                         .range_base = 0,
666bf215546Sopenharmony_ci                         .range = ~0);
667bf215546Sopenharmony_ci
668bf215546Sopenharmony_ci         nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
669bf215546Sopenharmony_ci                                  load);
670bf215546Sopenharmony_ci         nir_instr_remove(instr);
671bf215546Sopenharmony_ci      }
672bf215546Sopenharmony_ci   }
673bf215546Sopenharmony_ci
674bf215546Sopenharmony_ci   nir_validate_shader(nir, "before remapping");
675bf215546Sopenharmony_ci
676bf215546Sopenharmony_ci   /* Uniforms are stored in constant buffer 0, the
677bf215546Sopenharmony_ci    * user-facing UBOs are indexed by one.  So if any constant buffer is
678bf215546Sopenharmony_ci    * needed, the constant buffer 0 will be needed, so account for it.
679bf215546Sopenharmony_ci    */
680bf215546Sopenharmony_ci   unsigned num_cbufs = nir->info.num_ubos;
681bf215546Sopenharmony_ci   if (num_cbufs || nir->num_uniforms)
682bf215546Sopenharmony_ci      num_cbufs++;
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   /* Place the new params in a new cbuf. */
685bf215546Sopenharmony_ci   if (num_system_values > 0 || kernel_input_size > 0) {
686bf215546Sopenharmony_ci      unsigned sysval_cbuf_index = num_cbufs;
687bf215546Sopenharmony_ci      num_cbufs++;
688bf215546Sopenharmony_ci
689bf215546Sopenharmony_ci      system_values = reralloc(mem_ctx, system_values, enum brw_param_builtin,
690bf215546Sopenharmony_ci                               num_system_values);
691bf215546Sopenharmony_ci
692bf215546Sopenharmony_ci      nir_foreach_block(block, impl) {
693bf215546Sopenharmony_ci         nir_foreach_instr_safe(instr, block) {
694bf215546Sopenharmony_ci            if (instr->type != nir_instr_type_intrinsic)
695bf215546Sopenharmony_ci               continue;
696bf215546Sopenharmony_ci
697bf215546Sopenharmony_ci            nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr);
698bf215546Sopenharmony_ci
699bf215546Sopenharmony_ci            if (load->intrinsic != nir_intrinsic_load_ubo)
700bf215546Sopenharmony_ci               continue;
701bf215546Sopenharmony_ci
702bf215546Sopenharmony_ci            b.cursor = nir_before_instr(instr);
703bf215546Sopenharmony_ci
704bf215546Sopenharmony_ci            assert(load->src[0].is_ssa);
705bf215546Sopenharmony_ci
706bf215546Sopenharmony_ci            if (load->src[0].ssa == temp_ubo_name) {
707bf215546Sopenharmony_ci               nir_ssa_def *imm = nir_imm_int(&b, sysval_cbuf_index);
708bf215546Sopenharmony_ci               nir_instr_rewrite_src(instr, &load->src[0],
709bf215546Sopenharmony_ci                                     nir_src_for_ssa(imm));
710bf215546Sopenharmony_ci            }
711bf215546Sopenharmony_ci         }
712bf215546Sopenharmony_ci      }
713bf215546Sopenharmony_ci
714bf215546Sopenharmony_ci      /* We need to fold the new iadds for brw_nir_analyze_ubo_ranges */
715bf215546Sopenharmony_ci      nir_opt_constant_folding(nir);
716bf215546Sopenharmony_ci   } else {
717bf215546Sopenharmony_ci      ralloc_free(system_values);
718bf215546Sopenharmony_ci      system_values = NULL;
719bf215546Sopenharmony_ci   }
720bf215546Sopenharmony_ci
721bf215546Sopenharmony_ci   assert(num_cbufs < PIPE_MAX_CONSTANT_BUFFERS);
722bf215546Sopenharmony_ci   nir_validate_shader(nir, "after remap");
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci   /* We don't use params[] but gallium leaves num_uniforms set.  We use this
725bf215546Sopenharmony_ci    * to detect when cbuf0 exists but we don't need it anymore when we get
726bf215546Sopenharmony_ci    * here.  Instead, zero it out so that the back-end doesn't get confused
727bf215546Sopenharmony_ci    * when nr_params * 4 != num_uniforms != nr_params * 4.
728bf215546Sopenharmony_ci    */
729bf215546Sopenharmony_ci   nir->num_uniforms = 0;
730bf215546Sopenharmony_ci
731bf215546Sopenharmony_ci   *out_system_values = system_values;
732bf215546Sopenharmony_ci   *out_num_system_values = num_system_values;
733bf215546Sopenharmony_ci   *out_num_cbufs = num_cbufs;
734bf215546Sopenharmony_ci}
735bf215546Sopenharmony_ci
736bf215546Sopenharmony_cistatic const char *surface_group_names[] = {
737bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_RENDER_TARGET]      = "render target",
738bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_RENDER_TARGET_READ] = "non-coherent render target read",
739bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_CS_WORK_GROUPS]     = "CS work groups",
740bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_TEXTURE]            = "texture",
741bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_UBO]                = "ubo",
742bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_SSBO]               = "ssbo",
743bf215546Sopenharmony_ci   [IRIS_SURFACE_GROUP_IMAGE]              = "image",
744bf215546Sopenharmony_ci};
745bf215546Sopenharmony_ci
746bf215546Sopenharmony_cistatic void
747bf215546Sopenharmony_ciiris_print_binding_table(FILE *fp, const char *name,
748bf215546Sopenharmony_ci                         const struct iris_binding_table *bt)
749bf215546Sopenharmony_ci{
750bf215546Sopenharmony_ci   STATIC_ASSERT(ARRAY_SIZE(surface_group_names) == IRIS_SURFACE_GROUP_COUNT);
751bf215546Sopenharmony_ci
752bf215546Sopenharmony_ci   uint32_t total = 0;
753bf215546Sopenharmony_ci   uint32_t compacted = 0;
754bf215546Sopenharmony_ci
755bf215546Sopenharmony_ci   for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) {
756bf215546Sopenharmony_ci      uint32_t size = bt->sizes[i];
757bf215546Sopenharmony_ci      total += size;
758bf215546Sopenharmony_ci      if (size)
759bf215546Sopenharmony_ci         compacted += util_bitcount64(bt->used_mask[i]);
760bf215546Sopenharmony_ci   }
761bf215546Sopenharmony_ci
762bf215546Sopenharmony_ci   if (total == 0) {
763bf215546Sopenharmony_ci      fprintf(fp, "Binding table for %s is empty\n\n", name);
764bf215546Sopenharmony_ci      return;
765bf215546Sopenharmony_ci   }
766bf215546Sopenharmony_ci
767bf215546Sopenharmony_ci   if (total != compacted) {
768bf215546Sopenharmony_ci      fprintf(fp, "Binding table for %s "
769bf215546Sopenharmony_ci              "(compacted to %u entries from %u entries)\n",
770bf215546Sopenharmony_ci              name, compacted, total);
771bf215546Sopenharmony_ci   } else {
772bf215546Sopenharmony_ci      fprintf(fp, "Binding table for %s (%u entries)\n", name, total);
773bf215546Sopenharmony_ci   }
774bf215546Sopenharmony_ci
775bf215546Sopenharmony_ci   uint32_t entry = 0;
776bf215546Sopenharmony_ci   for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) {
777bf215546Sopenharmony_ci      uint64_t mask = bt->used_mask[i];
778bf215546Sopenharmony_ci      while (mask) {
779bf215546Sopenharmony_ci         int index = u_bit_scan64(&mask);
780bf215546Sopenharmony_ci         fprintf(fp, "  [%u] %s #%d\n", entry++, surface_group_names[i], index);
781bf215546Sopenharmony_ci      }
782bf215546Sopenharmony_ci   }
783bf215546Sopenharmony_ci   fprintf(fp, "\n");
784bf215546Sopenharmony_ci}
785bf215546Sopenharmony_ci
786bf215546Sopenharmony_cienum {
787bf215546Sopenharmony_ci   /* Max elements in a surface group. */
788bf215546Sopenharmony_ci   SURFACE_GROUP_MAX_ELEMENTS = 64,
789bf215546Sopenharmony_ci};
790bf215546Sopenharmony_ci
791bf215546Sopenharmony_ci/**
792bf215546Sopenharmony_ci * Map a <group, index> pair to a binding table index.
793bf215546Sopenharmony_ci *
794bf215546Sopenharmony_ci * For example: <UBO, 5> => binding table index 12
795bf215546Sopenharmony_ci */
796bf215546Sopenharmony_ciuint32_t
797bf215546Sopenharmony_ciiris_group_index_to_bti(const struct iris_binding_table *bt,
798bf215546Sopenharmony_ci                        enum iris_surface_group group, uint32_t index)
799bf215546Sopenharmony_ci{
800bf215546Sopenharmony_ci   assert(index < bt->sizes[group]);
801bf215546Sopenharmony_ci   uint64_t mask = bt->used_mask[group];
802bf215546Sopenharmony_ci   uint64_t bit = 1ull << index;
803bf215546Sopenharmony_ci   if (bit & mask) {
804bf215546Sopenharmony_ci      return bt->offsets[group] + util_bitcount64((bit - 1) & mask);
805bf215546Sopenharmony_ci   } else {
806bf215546Sopenharmony_ci      return IRIS_SURFACE_NOT_USED;
807bf215546Sopenharmony_ci   }
808bf215546Sopenharmony_ci}
809bf215546Sopenharmony_ci
810bf215546Sopenharmony_ci/**
811bf215546Sopenharmony_ci * Map a binding table index back to a <group, index> pair.
812bf215546Sopenharmony_ci *
813bf215546Sopenharmony_ci * For example: binding table index 12 => <UBO, 5>
814bf215546Sopenharmony_ci */
815bf215546Sopenharmony_ciuint32_t
816bf215546Sopenharmony_ciiris_bti_to_group_index(const struct iris_binding_table *bt,
817bf215546Sopenharmony_ci                        enum iris_surface_group group, uint32_t bti)
818bf215546Sopenharmony_ci{
819bf215546Sopenharmony_ci   uint64_t used_mask = bt->used_mask[group];
820bf215546Sopenharmony_ci   assert(bti >= bt->offsets[group]);
821bf215546Sopenharmony_ci
822bf215546Sopenharmony_ci   uint32_t c = bti - bt->offsets[group];
823bf215546Sopenharmony_ci   while (used_mask) {
824bf215546Sopenharmony_ci      int i = u_bit_scan64(&used_mask);
825bf215546Sopenharmony_ci      if (c == 0)
826bf215546Sopenharmony_ci         return i;
827bf215546Sopenharmony_ci      c--;
828bf215546Sopenharmony_ci   }
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_ci   return IRIS_SURFACE_NOT_USED;
831bf215546Sopenharmony_ci}
832bf215546Sopenharmony_ci
833bf215546Sopenharmony_cistatic void
834bf215546Sopenharmony_cirewrite_src_with_bti(nir_builder *b, struct iris_binding_table *bt,
835bf215546Sopenharmony_ci                     nir_instr *instr, nir_src *src,
836bf215546Sopenharmony_ci                     enum iris_surface_group group)
837bf215546Sopenharmony_ci{
838bf215546Sopenharmony_ci   assert(bt->sizes[group] > 0);
839bf215546Sopenharmony_ci
840bf215546Sopenharmony_ci   b->cursor = nir_before_instr(instr);
841bf215546Sopenharmony_ci   nir_ssa_def *bti;
842bf215546Sopenharmony_ci   if (nir_src_is_const(*src)) {
843bf215546Sopenharmony_ci      uint32_t index = nir_src_as_uint(*src);
844bf215546Sopenharmony_ci      bti = nir_imm_intN_t(b, iris_group_index_to_bti(bt, group, index),
845bf215546Sopenharmony_ci                           src->ssa->bit_size);
846bf215546Sopenharmony_ci   } else {
847bf215546Sopenharmony_ci      /* Indirect usage makes all the surfaces of the group to be available,
848bf215546Sopenharmony_ci       * so we can just add the base.
849bf215546Sopenharmony_ci       */
850bf215546Sopenharmony_ci      assert(bt->used_mask[group] == BITFIELD64_MASK(bt->sizes[group]));
851bf215546Sopenharmony_ci      bti = nir_iadd_imm(b, src->ssa, bt->offsets[group]);
852bf215546Sopenharmony_ci   }
853bf215546Sopenharmony_ci   nir_instr_rewrite_src(instr, src, nir_src_for_ssa(bti));
854bf215546Sopenharmony_ci}
855bf215546Sopenharmony_ci
856bf215546Sopenharmony_cistatic void
857bf215546Sopenharmony_cimark_used_with_src(struct iris_binding_table *bt, nir_src *src,
858bf215546Sopenharmony_ci                   enum iris_surface_group group)
859bf215546Sopenharmony_ci{
860bf215546Sopenharmony_ci   assert(bt->sizes[group] > 0);
861bf215546Sopenharmony_ci
862bf215546Sopenharmony_ci   if (nir_src_is_const(*src)) {
863bf215546Sopenharmony_ci      uint64_t index = nir_src_as_uint(*src);
864bf215546Sopenharmony_ci      assert(index < bt->sizes[group]);
865bf215546Sopenharmony_ci      bt->used_mask[group] |= 1ull << index;
866bf215546Sopenharmony_ci   } else {
867bf215546Sopenharmony_ci      /* There's an indirect usage, we need all the surfaces. */
868bf215546Sopenharmony_ci      bt->used_mask[group] = BITFIELD64_MASK(bt->sizes[group]);
869bf215546Sopenharmony_ci   }
870bf215546Sopenharmony_ci}
871bf215546Sopenharmony_ci
872bf215546Sopenharmony_cistatic bool
873bf215546Sopenharmony_ciskip_compacting_binding_tables(void)
874bf215546Sopenharmony_ci{
875bf215546Sopenharmony_ci   static int skip = -1;
876bf215546Sopenharmony_ci   if (skip < 0)
877bf215546Sopenharmony_ci      skip = env_var_as_boolean("INTEL_DISABLE_COMPACT_BINDING_TABLE", false);
878bf215546Sopenharmony_ci   return skip;
879bf215546Sopenharmony_ci}
880bf215546Sopenharmony_ci
881bf215546Sopenharmony_ci/**
882bf215546Sopenharmony_ci * Set up the binding table indices and apply to the shader.
883bf215546Sopenharmony_ci */
884bf215546Sopenharmony_cistatic void
885bf215546Sopenharmony_ciiris_setup_binding_table(const struct intel_device_info *devinfo,
886bf215546Sopenharmony_ci                         struct nir_shader *nir,
887bf215546Sopenharmony_ci                         struct iris_binding_table *bt,
888bf215546Sopenharmony_ci                         unsigned num_render_targets,
889bf215546Sopenharmony_ci                         unsigned num_system_values,
890bf215546Sopenharmony_ci                         unsigned num_cbufs)
891bf215546Sopenharmony_ci{
892bf215546Sopenharmony_ci   const struct shader_info *info = &nir->info;
893bf215546Sopenharmony_ci
894bf215546Sopenharmony_ci   memset(bt, 0, sizeof(*bt));
895bf215546Sopenharmony_ci
896bf215546Sopenharmony_ci   /* Set the sizes for each surface group.  For some groups, we already know
897bf215546Sopenharmony_ci    * upfront how many will be used, so mark them.
898bf215546Sopenharmony_ci    */
899bf215546Sopenharmony_ci   if (info->stage == MESA_SHADER_FRAGMENT) {
900bf215546Sopenharmony_ci      bt->sizes[IRIS_SURFACE_GROUP_RENDER_TARGET] = num_render_targets;
901bf215546Sopenharmony_ci      /* All render targets used. */
902bf215546Sopenharmony_ci      bt->used_mask[IRIS_SURFACE_GROUP_RENDER_TARGET] =
903bf215546Sopenharmony_ci         BITFIELD64_MASK(num_render_targets);
904bf215546Sopenharmony_ci
905bf215546Sopenharmony_ci      /* Setup render target read surface group in order to support non-coherent
906bf215546Sopenharmony_ci       * framebuffer fetch on Gfx8
907bf215546Sopenharmony_ci       */
908bf215546Sopenharmony_ci      if (devinfo->ver == 8 && info->outputs_read) {
909bf215546Sopenharmony_ci         bt->sizes[IRIS_SURFACE_GROUP_RENDER_TARGET_READ] = num_render_targets;
910bf215546Sopenharmony_ci         bt->used_mask[IRIS_SURFACE_GROUP_RENDER_TARGET_READ] =
911bf215546Sopenharmony_ci            BITFIELD64_MASK(num_render_targets);
912bf215546Sopenharmony_ci      }
913bf215546Sopenharmony_ci   } else if (info->stage == MESA_SHADER_COMPUTE) {
914bf215546Sopenharmony_ci      bt->sizes[IRIS_SURFACE_GROUP_CS_WORK_GROUPS] = 1;
915bf215546Sopenharmony_ci   }
916bf215546Sopenharmony_ci
917bf215546Sopenharmony_ci   bt->sizes[IRIS_SURFACE_GROUP_TEXTURE] = BITSET_LAST_BIT(info->textures_used);
918bf215546Sopenharmony_ci   bt->used_mask[IRIS_SURFACE_GROUP_TEXTURE] = info->textures_used[0];
919bf215546Sopenharmony_ci
920bf215546Sopenharmony_ci   bt->sizes[IRIS_SURFACE_GROUP_IMAGE] = info->num_images;
921bf215546Sopenharmony_ci
922bf215546Sopenharmony_ci   /* Allocate an extra slot in the UBO section for NIR constants.
923bf215546Sopenharmony_ci    * Binding table compaction will remove it if unnecessary.
924bf215546Sopenharmony_ci    *
925bf215546Sopenharmony_ci    * We don't include them in iris_compiled_shader::num_cbufs because
926bf215546Sopenharmony_ci    * they are uploaded separately from shs->constbuf[], but from a shader
927bf215546Sopenharmony_ci    * point of view, they're another UBO (at the end of the section).
928bf215546Sopenharmony_ci    */
929bf215546Sopenharmony_ci   bt->sizes[IRIS_SURFACE_GROUP_UBO] = num_cbufs + 1;
930bf215546Sopenharmony_ci
931bf215546Sopenharmony_ci   bt->sizes[IRIS_SURFACE_GROUP_SSBO] = info->num_ssbos;
932bf215546Sopenharmony_ci
933bf215546Sopenharmony_ci   for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++)
934bf215546Sopenharmony_ci      assert(bt->sizes[i] <= SURFACE_GROUP_MAX_ELEMENTS);
935bf215546Sopenharmony_ci
936bf215546Sopenharmony_ci   /* Mark surfaces used for the cases we don't have the information available
937bf215546Sopenharmony_ci    * upfront.
938bf215546Sopenharmony_ci    */
939bf215546Sopenharmony_ci   nir_function_impl *impl = nir_shader_get_entrypoint(nir);
940bf215546Sopenharmony_ci   nir_foreach_block (block, impl) {
941bf215546Sopenharmony_ci      nir_foreach_instr (instr, block) {
942bf215546Sopenharmony_ci         if (instr->type != nir_instr_type_intrinsic)
943bf215546Sopenharmony_ci            continue;
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_ci         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
946bf215546Sopenharmony_ci         switch (intrin->intrinsic) {
947bf215546Sopenharmony_ci         case nir_intrinsic_load_num_workgroups:
948bf215546Sopenharmony_ci            bt->used_mask[IRIS_SURFACE_GROUP_CS_WORK_GROUPS] = 1;
949bf215546Sopenharmony_ci            break;
950bf215546Sopenharmony_ci
951bf215546Sopenharmony_ci         case nir_intrinsic_load_output:
952bf215546Sopenharmony_ci            if (devinfo->ver == 8) {
953bf215546Sopenharmony_ci               mark_used_with_src(bt, &intrin->src[0],
954bf215546Sopenharmony_ci                                  IRIS_SURFACE_GROUP_RENDER_TARGET_READ);
955bf215546Sopenharmony_ci            }
956bf215546Sopenharmony_ci            break;
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci         case nir_intrinsic_image_size:
959bf215546Sopenharmony_ci         case nir_intrinsic_image_load:
960bf215546Sopenharmony_ci         case nir_intrinsic_image_store:
961bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_add:
962bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_imin:
963bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_umin:
964bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_imax:
965bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_umax:
966bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_and:
967bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_or:
968bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_xor:
969bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_exchange:
970bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_comp_swap:
971bf215546Sopenharmony_ci         case nir_intrinsic_image_load_raw_intel:
972bf215546Sopenharmony_ci         case nir_intrinsic_image_store_raw_intel:
973bf215546Sopenharmony_ci            mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_IMAGE);
974bf215546Sopenharmony_ci            break;
975bf215546Sopenharmony_ci
976bf215546Sopenharmony_ci         case nir_intrinsic_load_ubo:
977bf215546Sopenharmony_ci            mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_UBO);
978bf215546Sopenharmony_ci            break;
979bf215546Sopenharmony_ci
980bf215546Sopenharmony_ci         case nir_intrinsic_store_ssbo:
981bf215546Sopenharmony_ci            mark_used_with_src(bt, &intrin->src[1], IRIS_SURFACE_GROUP_SSBO);
982bf215546Sopenharmony_ci            break;
983bf215546Sopenharmony_ci
984bf215546Sopenharmony_ci         case nir_intrinsic_get_ssbo_size:
985bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_add:
986bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_imin:
987bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_umin:
988bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_imax:
989bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_umax:
990bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_and:
991bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_or:
992bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_xor:
993bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_exchange:
994bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_comp_swap:
995bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fmin:
996bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fmax:
997bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fcomp_swap:
998bf215546Sopenharmony_ci         case nir_intrinsic_load_ssbo:
999bf215546Sopenharmony_ci            mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_SSBO);
1000bf215546Sopenharmony_ci            break;
1001bf215546Sopenharmony_ci
1002bf215546Sopenharmony_ci         default:
1003bf215546Sopenharmony_ci            break;
1004bf215546Sopenharmony_ci         }
1005bf215546Sopenharmony_ci      }
1006bf215546Sopenharmony_ci   }
1007bf215546Sopenharmony_ci
1008bf215546Sopenharmony_ci   /* When disable we just mark everything as used. */
1009bf215546Sopenharmony_ci   if (unlikely(skip_compacting_binding_tables())) {
1010bf215546Sopenharmony_ci      for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++)
1011bf215546Sopenharmony_ci         bt->used_mask[i] = BITFIELD64_MASK(bt->sizes[i]);
1012bf215546Sopenharmony_ci   }
1013bf215546Sopenharmony_ci
1014bf215546Sopenharmony_ci   /* Calculate the offsets and the binding table size based on the used
1015bf215546Sopenharmony_ci    * surfaces.  After this point, the functions to go between "group indices"
1016bf215546Sopenharmony_ci    * and binding table indices can be used.
1017bf215546Sopenharmony_ci    */
1018bf215546Sopenharmony_ci   uint32_t next = 0;
1019bf215546Sopenharmony_ci   for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) {
1020bf215546Sopenharmony_ci      if (bt->used_mask[i] != 0) {
1021bf215546Sopenharmony_ci         bt->offsets[i] = next;
1022bf215546Sopenharmony_ci         next += util_bitcount64(bt->used_mask[i]);
1023bf215546Sopenharmony_ci      }
1024bf215546Sopenharmony_ci   }
1025bf215546Sopenharmony_ci   bt->size_bytes = next * 4;
1026bf215546Sopenharmony_ci
1027bf215546Sopenharmony_ci   if (INTEL_DEBUG(DEBUG_BT)) {
1028bf215546Sopenharmony_ci      iris_print_binding_table(stderr, gl_shader_stage_name(info->stage), bt);
1029bf215546Sopenharmony_ci   }
1030bf215546Sopenharmony_ci
1031bf215546Sopenharmony_ci   /* Apply the binding table indices.  The backend compiler is not expected
1032bf215546Sopenharmony_ci    * to change those, as we haven't set any of the *_start entries in brw
1033bf215546Sopenharmony_ci    * binding_table.
1034bf215546Sopenharmony_ci    */
1035bf215546Sopenharmony_ci   nir_builder b;
1036bf215546Sopenharmony_ci   nir_builder_init(&b, impl);
1037bf215546Sopenharmony_ci
1038bf215546Sopenharmony_ci   nir_foreach_block (block, impl) {
1039bf215546Sopenharmony_ci      nir_foreach_instr (instr, block) {
1040bf215546Sopenharmony_ci         if (instr->type == nir_instr_type_tex) {
1041bf215546Sopenharmony_ci            nir_tex_instr *tex = nir_instr_as_tex(instr);
1042bf215546Sopenharmony_ci            tex->texture_index =
1043bf215546Sopenharmony_ci               iris_group_index_to_bti(bt, IRIS_SURFACE_GROUP_TEXTURE,
1044bf215546Sopenharmony_ci                                       tex->texture_index);
1045bf215546Sopenharmony_ci            continue;
1046bf215546Sopenharmony_ci         }
1047bf215546Sopenharmony_ci
1048bf215546Sopenharmony_ci         if (instr->type != nir_instr_type_intrinsic)
1049bf215546Sopenharmony_ci            continue;
1050bf215546Sopenharmony_ci
1051bf215546Sopenharmony_ci         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
1052bf215546Sopenharmony_ci         switch (intrin->intrinsic) {
1053bf215546Sopenharmony_ci         case nir_intrinsic_image_size:
1054bf215546Sopenharmony_ci         case nir_intrinsic_image_load:
1055bf215546Sopenharmony_ci         case nir_intrinsic_image_store:
1056bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_add:
1057bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_imin:
1058bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_umin:
1059bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_imax:
1060bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_umax:
1061bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_and:
1062bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_or:
1063bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_xor:
1064bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_exchange:
1065bf215546Sopenharmony_ci         case nir_intrinsic_image_atomic_comp_swap:
1066bf215546Sopenharmony_ci         case nir_intrinsic_image_load_raw_intel:
1067bf215546Sopenharmony_ci         case nir_intrinsic_image_store_raw_intel:
1068bf215546Sopenharmony_ci            rewrite_src_with_bti(&b, bt, instr, &intrin->src[0],
1069bf215546Sopenharmony_ci                                 IRIS_SURFACE_GROUP_IMAGE);
1070bf215546Sopenharmony_ci            break;
1071bf215546Sopenharmony_ci
1072bf215546Sopenharmony_ci         case nir_intrinsic_load_ubo:
1073bf215546Sopenharmony_ci            rewrite_src_with_bti(&b, bt, instr, &intrin->src[0],
1074bf215546Sopenharmony_ci                                 IRIS_SURFACE_GROUP_UBO);
1075bf215546Sopenharmony_ci            break;
1076bf215546Sopenharmony_ci
1077bf215546Sopenharmony_ci         case nir_intrinsic_store_ssbo:
1078bf215546Sopenharmony_ci            rewrite_src_with_bti(&b, bt, instr, &intrin->src[1],
1079bf215546Sopenharmony_ci                                 IRIS_SURFACE_GROUP_SSBO);
1080bf215546Sopenharmony_ci            break;
1081bf215546Sopenharmony_ci
1082bf215546Sopenharmony_ci         case nir_intrinsic_load_output:
1083bf215546Sopenharmony_ci            if (devinfo->ver == 8) {
1084bf215546Sopenharmony_ci               rewrite_src_with_bti(&b, bt, instr, &intrin->src[0],
1085bf215546Sopenharmony_ci                                    IRIS_SURFACE_GROUP_RENDER_TARGET_READ);
1086bf215546Sopenharmony_ci            }
1087bf215546Sopenharmony_ci            break;
1088bf215546Sopenharmony_ci
1089bf215546Sopenharmony_ci         case nir_intrinsic_get_ssbo_size:
1090bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_add:
1091bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_imin:
1092bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_umin:
1093bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_imax:
1094bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_umax:
1095bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_and:
1096bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_or:
1097bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_xor:
1098bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_exchange:
1099bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_comp_swap:
1100bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fmin:
1101bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fmax:
1102bf215546Sopenharmony_ci         case nir_intrinsic_ssbo_atomic_fcomp_swap:
1103bf215546Sopenharmony_ci         case nir_intrinsic_load_ssbo:
1104bf215546Sopenharmony_ci            rewrite_src_with_bti(&b, bt, instr, &intrin->src[0],
1105bf215546Sopenharmony_ci                                 IRIS_SURFACE_GROUP_SSBO);
1106bf215546Sopenharmony_ci            break;
1107bf215546Sopenharmony_ci
1108bf215546Sopenharmony_ci         default:
1109bf215546Sopenharmony_ci            break;
1110bf215546Sopenharmony_ci         }
1111bf215546Sopenharmony_ci      }
1112bf215546Sopenharmony_ci   }
1113bf215546Sopenharmony_ci}
1114bf215546Sopenharmony_ci
1115bf215546Sopenharmony_cistatic void
1116bf215546Sopenharmony_ciiris_debug_recompile(struct iris_screen *screen,
1117bf215546Sopenharmony_ci                     struct util_debug_callback *dbg,
1118bf215546Sopenharmony_ci                     struct iris_uncompiled_shader *ish,
1119bf215546Sopenharmony_ci                     const struct brw_base_prog_key *key)
1120bf215546Sopenharmony_ci{
1121bf215546Sopenharmony_ci   if (!ish || list_is_empty(&ish->variants)
1122bf215546Sopenharmony_ci            || list_is_singular(&ish->variants))
1123bf215546Sopenharmony_ci      return;
1124bf215546Sopenharmony_ci
1125bf215546Sopenharmony_ci   const struct brw_compiler *c = screen->compiler;
1126bf215546Sopenharmony_ci   const struct shader_info *info = &ish->nir->info;
1127bf215546Sopenharmony_ci
1128bf215546Sopenharmony_ci   brw_shader_perf_log(c, dbg, "Recompiling %s shader for program %s: %s\n",
1129bf215546Sopenharmony_ci                       _mesa_shader_stage_to_string(info->stage),
1130bf215546Sopenharmony_ci                       info->name ? info->name : "(no identifier)",
1131bf215546Sopenharmony_ci                       info->label ? info->label : "");
1132bf215546Sopenharmony_ci
1133bf215546Sopenharmony_ci   struct iris_compiled_shader *shader =
1134bf215546Sopenharmony_ci      list_first_entry(&ish->variants, struct iris_compiled_shader, link);
1135bf215546Sopenharmony_ci   const void *old_iris_key = &shader->key;
1136bf215546Sopenharmony_ci
1137bf215546Sopenharmony_ci   union brw_any_prog_key old_key;
1138bf215546Sopenharmony_ci
1139bf215546Sopenharmony_ci   switch (info->stage) {
1140bf215546Sopenharmony_ci   case MESA_SHADER_VERTEX:
1141bf215546Sopenharmony_ci      old_key.vs = iris_to_brw_vs_key(screen, old_iris_key);
1142bf215546Sopenharmony_ci      break;
1143bf215546Sopenharmony_ci   case MESA_SHADER_TESS_CTRL:
1144bf215546Sopenharmony_ci      old_key.tcs = iris_to_brw_tcs_key(screen, old_iris_key);
1145bf215546Sopenharmony_ci      break;
1146bf215546Sopenharmony_ci   case MESA_SHADER_TESS_EVAL:
1147bf215546Sopenharmony_ci      old_key.tes = iris_to_brw_tes_key(screen, old_iris_key);
1148bf215546Sopenharmony_ci      break;
1149bf215546Sopenharmony_ci   case MESA_SHADER_GEOMETRY:
1150bf215546Sopenharmony_ci      old_key.gs = iris_to_brw_gs_key(screen, old_iris_key);
1151bf215546Sopenharmony_ci      break;
1152bf215546Sopenharmony_ci   case MESA_SHADER_FRAGMENT:
1153bf215546Sopenharmony_ci      old_key.wm = iris_to_brw_fs_key(screen, old_iris_key);
1154bf215546Sopenharmony_ci      break;
1155bf215546Sopenharmony_ci   case MESA_SHADER_COMPUTE:
1156bf215546Sopenharmony_ci      old_key.cs = iris_to_brw_cs_key(screen, old_iris_key);
1157bf215546Sopenharmony_ci      break;
1158bf215546Sopenharmony_ci   default:
1159bf215546Sopenharmony_ci      unreachable("invalid shader stage");
1160bf215546Sopenharmony_ci   }
1161bf215546Sopenharmony_ci
1162bf215546Sopenharmony_ci   brw_debug_key_recompile(c, dbg, info->stage, &old_key.base, key);
1163bf215546Sopenharmony_ci}
1164bf215546Sopenharmony_ci
1165bf215546Sopenharmony_cistatic void
1166bf215546Sopenharmony_cicheck_urb_size(struct iris_context *ice,
1167bf215546Sopenharmony_ci               unsigned needed_size,
1168bf215546Sopenharmony_ci               gl_shader_stage stage)
1169bf215546Sopenharmony_ci{
1170bf215546Sopenharmony_ci   unsigned last_allocated_size = ice->shaders.urb.size[stage];
1171bf215546Sopenharmony_ci
1172bf215546Sopenharmony_ci   /* If the last URB allocation wasn't large enough for our needs,
1173bf215546Sopenharmony_ci    * flag it as needing to be reconfigured.  Otherwise, we can use
1174bf215546Sopenharmony_ci    * the existing config.  However, if the URB is constrained, and
1175bf215546Sopenharmony_ci    * we can shrink our size for this stage, we may be able to gain
1176bf215546Sopenharmony_ci    * extra concurrency by reconfiguring it to be smaller.  Do so.
1177bf215546Sopenharmony_ci    */
1178bf215546Sopenharmony_ci   if (last_allocated_size < needed_size ||
1179bf215546Sopenharmony_ci       (ice->shaders.urb.constrained && last_allocated_size > needed_size)) {
1180bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_URB;
1181bf215546Sopenharmony_ci   }
1182bf215546Sopenharmony_ci}
1183bf215546Sopenharmony_ci
1184bf215546Sopenharmony_ci/**
1185bf215546Sopenharmony_ci * Get the shader for the last enabled geometry stage.
1186bf215546Sopenharmony_ci *
1187bf215546Sopenharmony_ci * This stage is the one which will feed stream output and the rasterizer.
1188bf215546Sopenharmony_ci */
1189bf215546Sopenharmony_cistatic gl_shader_stage
1190bf215546Sopenharmony_cilast_vue_stage(struct iris_context *ice)
1191bf215546Sopenharmony_ci{
1192bf215546Sopenharmony_ci   if (ice->shaders.uncompiled[MESA_SHADER_GEOMETRY])
1193bf215546Sopenharmony_ci      return MESA_SHADER_GEOMETRY;
1194bf215546Sopenharmony_ci
1195bf215546Sopenharmony_ci   if (ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL])
1196bf215546Sopenharmony_ci      return MESA_SHADER_TESS_EVAL;
1197bf215546Sopenharmony_ci
1198bf215546Sopenharmony_ci   return MESA_SHADER_VERTEX;
1199bf215546Sopenharmony_ci}
1200bf215546Sopenharmony_ci
1201bf215546Sopenharmony_ci/**
1202bf215546Sopenharmony_ci * \param added  Set to \c true if the variant was added to the list (i.e., a
1203bf215546Sopenharmony_ci *               variant matching \c key was not found).  Set to \c false
1204bf215546Sopenharmony_ci *               otherwise.
1205bf215546Sopenharmony_ci */
1206bf215546Sopenharmony_cistatic inline struct iris_compiled_shader *
1207bf215546Sopenharmony_cifind_or_add_variant(const struct iris_screen *screen,
1208bf215546Sopenharmony_ci                    struct iris_uncompiled_shader *ish,
1209bf215546Sopenharmony_ci                    enum iris_program_cache_id cache_id,
1210bf215546Sopenharmony_ci                    const void *key, unsigned key_size,
1211bf215546Sopenharmony_ci                    bool *added)
1212bf215546Sopenharmony_ci{
1213bf215546Sopenharmony_ci   struct list_head *start = ish->variants.next;
1214bf215546Sopenharmony_ci
1215bf215546Sopenharmony_ci   *added = false;
1216bf215546Sopenharmony_ci
1217bf215546Sopenharmony_ci   if (screen->precompile) {
1218bf215546Sopenharmony_ci      /* Check the first list entry.  There will always be at least one
1219bf215546Sopenharmony_ci       * variant in the list (most likely the precompile variant), and
1220bf215546Sopenharmony_ci       * other contexts only append new variants, so we can safely check
1221bf215546Sopenharmony_ci       * it without locking, saving that cost in the common case.
1222bf215546Sopenharmony_ci       */
1223bf215546Sopenharmony_ci      struct iris_compiled_shader *first =
1224bf215546Sopenharmony_ci         list_first_entry(&ish->variants, struct iris_compiled_shader, link);
1225bf215546Sopenharmony_ci
1226bf215546Sopenharmony_ci      if (memcmp(&first->key, key, key_size) == 0) {
1227bf215546Sopenharmony_ci         util_queue_fence_wait(&first->ready);
1228bf215546Sopenharmony_ci         return first;
1229bf215546Sopenharmony_ci      }
1230bf215546Sopenharmony_ci
1231bf215546Sopenharmony_ci      /* Skip this one in the loop below */
1232bf215546Sopenharmony_ci      start = first->link.next;
1233bf215546Sopenharmony_ci   }
1234bf215546Sopenharmony_ci
1235bf215546Sopenharmony_ci   struct iris_compiled_shader *variant = NULL;
1236bf215546Sopenharmony_ci
1237bf215546Sopenharmony_ci   /* If it doesn't match, we have to walk the list; other contexts may be
1238bf215546Sopenharmony_ci    * concurrently appending shaders to it, so we need to lock here.
1239bf215546Sopenharmony_ci    */
1240bf215546Sopenharmony_ci   simple_mtx_lock(&ish->lock);
1241bf215546Sopenharmony_ci
1242bf215546Sopenharmony_ci   list_for_each_entry_from(struct iris_compiled_shader, v, start,
1243bf215546Sopenharmony_ci                            &ish->variants, link) {
1244bf215546Sopenharmony_ci      if (memcmp(&v->key, key, key_size) == 0) {
1245bf215546Sopenharmony_ci         variant = v;
1246bf215546Sopenharmony_ci         break;
1247bf215546Sopenharmony_ci      }
1248bf215546Sopenharmony_ci   }
1249bf215546Sopenharmony_ci
1250bf215546Sopenharmony_ci   if (variant == NULL) {
1251bf215546Sopenharmony_ci      variant = iris_create_shader_variant(screen, NULL, cache_id,
1252bf215546Sopenharmony_ci                                           key_size, key);
1253bf215546Sopenharmony_ci
1254bf215546Sopenharmony_ci      /* Append our new variant to the shader's variant list. */
1255bf215546Sopenharmony_ci      list_addtail(&variant->link, &ish->variants);
1256bf215546Sopenharmony_ci      *added = true;
1257bf215546Sopenharmony_ci
1258bf215546Sopenharmony_ci      simple_mtx_unlock(&ish->lock);
1259bf215546Sopenharmony_ci   } else {
1260bf215546Sopenharmony_ci      simple_mtx_unlock(&ish->lock);
1261bf215546Sopenharmony_ci
1262bf215546Sopenharmony_ci      util_queue_fence_wait(&variant->ready);
1263bf215546Sopenharmony_ci   }
1264bf215546Sopenharmony_ci
1265bf215546Sopenharmony_ci   return variant;
1266bf215546Sopenharmony_ci}
1267bf215546Sopenharmony_ci
1268bf215546Sopenharmony_cistatic void
1269bf215546Sopenharmony_ciiris_threaded_compile_job_delete(void *_job, UNUSED void *_gdata,
1270bf215546Sopenharmony_ci                                 UNUSED int thread_index)
1271bf215546Sopenharmony_ci{
1272bf215546Sopenharmony_ci   free(_job);
1273bf215546Sopenharmony_ci}
1274bf215546Sopenharmony_ci
1275bf215546Sopenharmony_cistatic void
1276bf215546Sopenharmony_ciiris_schedule_compile(struct iris_screen *screen,
1277bf215546Sopenharmony_ci                      struct util_queue_fence *ready_fence,
1278bf215546Sopenharmony_ci                      struct util_debug_callback *dbg,
1279bf215546Sopenharmony_ci                      struct iris_threaded_compile_job *job,
1280bf215546Sopenharmony_ci                      util_queue_execute_func execute)
1281bf215546Sopenharmony_ci
1282bf215546Sopenharmony_ci{
1283bf215546Sopenharmony_ci   struct util_async_debug_callback async_debug;
1284bf215546Sopenharmony_ci
1285bf215546Sopenharmony_ci   if (dbg) {
1286bf215546Sopenharmony_ci      u_async_debug_init(&async_debug);
1287bf215546Sopenharmony_ci      job->dbg = &async_debug.base;
1288bf215546Sopenharmony_ci   }
1289bf215546Sopenharmony_ci
1290bf215546Sopenharmony_ci   util_queue_add_job(&screen->shader_compiler_queue, job, ready_fence, execute,
1291bf215546Sopenharmony_ci                      iris_threaded_compile_job_delete, 0);
1292bf215546Sopenharmony_ci
1293bf215546Sopenharmony_ci   if (screen->driconf.sync_compile || dbg)
1294bf215546Sopenharmony_ci      util_queue_fence_wait(ready_fence);
1295bf215546Sopenharmony_ci
1296bf215546Sopenharmony_ci   if (dbg) {
1297bf215546Sopenharmony_ci      u_async_debug_drain(&async_debug, dbg);
1298bf215546Sopenharmony_ci      u_async_debug_cleanup(&async_debug);
1299bf215546Sopenharmony_ci   }
1300bf215546Sopenharmony_ci}
1301bf215546Sopenharmony_ci
1302bf215546Sopenharmony_ci/**
1303bf215546Sopenharmony_ci * Compile a vertex shader, and upload the assembly.
1304bf215546Sopenharmony_ci */
1305bf215546Sopenharmony_cistatic void
1306bf215546Sopenharmony_ciiris_compile_vs(struct iris_screen *screen,
1307bf215546Sopenharmony_ci                struct u_upload_mgr *uploader,
1308bf215546Sopenharmony_ci                struct util_debug_callback *dbg,
1309bf215546Sopenharmony_ci                struct iris_uncompiled_shader *ish,
1310bf215546Sopenharmony_ci                struct iris_compiled_shader *shader)
1311bf215546Sopenharmony_ci{
1312bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1313bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1314bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
1315bf215546Sopenharmony_ci   struct brw_vs_prog_data *vs_prog_data =
1316bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_vs_prog_data);
1317bf215546Sopenharmony_ci   struct brw_vue_prog_data *vue_prog_data = &vs_prog_data->base;
1318bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &vue_prog_data->base;
1319bf215546Sopenharmony_ci   enum brw_param_builtin *system_values;
1320bf215546Sopenharmony_ci   unsigned num_system_values;
1321bf215546Sopenharmony_ci   unsigned num_cbufs;
1322bf215546Sopenharmony_ci
1323bf215546Sopenharmony_ci   nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
1324bf215546Sopenharmony_ci   const struct iris_vs_prog_key *const key = &shader->key.vs;
1325bf215546Sopenharmony_ci
1326bf215546Sopenharmony_ci   if (key->vue.nr_userclip_plane_consts) {
1327bf215546Sopenharmony_ci      nir_function_impl *impl = nir_shader_get_entrypoint(nir);
1328bf215546Sopenharmony_ci      nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1,
1329bf215546Sopenharmony_ci                        true, false, NULL);
1330bf215546Sopenharmony_ci      nir_lower_io_to_temporaries(nir, impl, true, false);
1331bf215546Sopenharmony_ci      nir_lower_global_vars_to_local(nir);
1332bf215546Sopenharmony_ci      nir_lower_vars_to_ssa(nir);
1333bf215546Sopenharmony_ci      nir_shader_gather_info(nir, impl);
1334bf215546Sopenharmony_ci   }
1335bf215546Sopenharmony_ci
1336bf215546Sopenharmony_ci   prog_data->use_alt_mode = nir->info.use_legacy_math_rules;
1337bf215546Sopenharmony_ci
1338bf215546Sopenharmony_ci   iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values,
1339bf215546Sopenharmony_ci                       &num_system_values, &num_cbufs);
1340bf215546Sopenharmony_ci
1341bf215546Sopenharmony_ci   struct iris_binding_table bt;
1342bf215546Sopenharmony_ci   iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0,
1343bf215546Sopenharmony_ci                            num_system_values, num_cbufs);
1344bf215546Sopenharmony_ci
1345bf215546Sopenharmony_ci   brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges);
1346bf215546Sopenharmony_ci
1347bf215546Sopenharmony_ci   brw_compute_vue_map(devinfo,
1348bf215546Sopenharmony_ci                       &vue_prog_data->vue_map, nir->info.outputs_written,
1349bf215546Sopenharmony_ci                       nir->info.separate_shader, /* pos_slots */ 1);
1350bf215546Sopenharmony_ci
1351bf215546Sopenharmony_ci   struct brw_vs_prog_key brw_key = iris_to_brw_vs_key(screen, key);
1352bf215546Sopenharmony_ci
1353bf215546Sopenharmony_ci   struct brw_compile_vs_params params = {
1354bf215546Sopenharmony_ci      .nir = nir,
1355bf215546Sopenharmony_ci      .key = &brw_key,
1356bf215546Sopenharmony_ci      .prog_data = vs_prog_data,
1357bf215546Sopenharmony_ci      .log_data = dbg,
1358bf215546Sopenharmony_ci   };
1359bf215546Sopenharmony_ci
1360bf215546Sopenharmony_ci   const unsigned *program = brw_compile_vs(compiler, mem_ctx, &params);
1361bf215546Sopenharmony_ci   if (program == NULL) {
1362bf215546Sopenharmony_ci      dbg_printf("Failed to compile vertex shader: %s\n", params.error_str);
1363bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
1364bf215546Sopenharmony_ci
1365bf215546Sopenharmony_ci      shader->compilation_failed = true;
1366bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
1367bf215546Sopenharmony_ci
1368bf215546Sopenharmony_ci      return;
1369bf215546Sopenharmony_ci   }
1370bf215546Sopenharmony_ci
1371bf215546Sopenharmony_ci   shader->compilation_failed = false;
1372bf215546Sopenharmony_ci
1373bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
1374bf215546Sopenharmony_ci
1375bf215546Sopenharmony_ci   uint32_t *so_decls =
1376bf215546Sopenharmony_ci      screen->vtbl.create_so_decl_list(&ish->stream_output,
1377bf215546Sopenharmony_ci                                    &vue_prog_data->vue_map);
1378bf215546Sopenharmony_ci
1379bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, so_decls, system_values,
1380bf215546Sopenharmony_ci                         num_system_values, 0, num_cbufs, &bt);
1381bf215546Sopenharmony_ci
1382bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_VS,
1383bf215546Sopenharmony_ci                      sizeof(*key), key, program);
1384bf215546Sopenharmony_ci
1385bf215546Sopenharmony_ci   iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
1386bf215546Sopenharmony_ci
1387bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
1388bf215546Sopenharmony_ci}
1389bf215546Sopenharmony_ci
1390bf215546Sopenharmony_ci/**
1391bf215546Sopenharmony_ci * Update the current vertex shader variant.
1392bf215546Sopenharmony_ci *
1393bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed.
1394bf215546Sopenharmony_ci */
1395bf215546Sopenharmony_cistatic void
1396bf215546Sopenharmony_ciiris_update_compiled_vs(struct iris_context *ice)
1397bf215546Sopenharmony_ci{
1398bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
1399bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_VERTEX];
1400bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
1401bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
1402bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_VERTEX];
1403bf215546Sopenharmony_ci
1404bf215546Sopenharmony_ci   struct iris_vs_prog_key key = { KEY_INIT(vue.base) };
1405bf215546Sopenharmony_ci   screen->vtbl.populate_vs_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
1406bf215546Sopenharmony_ci
1407bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_VS];
1408bf215546Sopenharmony_ci   bool added;
1409bf215546Sopenharmony_ci   struct iris_compiled_shader *shader =
1410bf215546Sopenharmony_ci      find_or_add_variant(screen, ish, IRIS_CACHE_VS, &key, sizeof(key), &added);
1411bf215546Sopenharmony_ci
1412bf215546Sopenharmony_ci   if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
1413bf215546Sopenharmony_ci                                          &key, sizeof(key))) {
1414bf215546Sopenharmony_ci      iris_compile_vs(screen, uploader, &ice->dbg, ish, shader);
1415bf215546Sopenharmony_ci   }
1416bf215546Sopenharmony_ci
1417bf215546Sopenharmony_ci   if (shader->compilation_failed)
1418bf215546Sopenharmony_ci      shader = NULL;
1419bf215546Sopenharmony_ci
1420bf215546Sopenharmony_ci   if (old != shader) {
1421bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_VERTEX],
1422bf215546Sopenharmony_ci                                    shader);
1423bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_VF_SGVS;
1424bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_VS |
1425bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_VS |
1426bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_VS;
1427bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
1428bf215546Sopenharmony_ci
1429bf215546Sopenharmony_ci      unsigned urb_entry_size = shader ?
1430bf215546Sopenharmony_ci         ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0;
1431bf215546Sopenharmony_ci      check_urb_size(ice, urb_entry_size, MESA_SHADER_VERTEX);
1432bf215546Sopenharmony_ci   }
1433bf215546Sopenharmony_ci}
1434bf215546Sopenharmony_ci
1435bf215546Sopenharmony_ci/**
1436bf215546Sopenharmony_ci * Get the shader_info for a given stage, or NULL if the stage is disabled.
1437bf215546Sopenharmony_ci */
1438bf215546Sopenharmony_ciconst struct shader_info *
1439bf215546Sopenharmony_ciiris_get_shader_info(const struct iris_context *ice, gl_shader_stage stage)
1440bf215546Sopenharmony_ci{
1441bf215546Sopenharmony_ci   const struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[stage];
1442bf215546Sopenharmony_ci
1443bf215546Sopenharmony_ci   if (!ish)
1444bf215546Sopenharmony_ci      return NULL;
1445bf215546Sopenharmony_ci
1446bf215546Sopenharmony_ci   const nir_shader *nir = ish->nir;
1447bf215546Sopenharmony_ci   return &nir->info;
1448bf215546Sopenharmony_ci}
1449bf215546Sopenharmony_ci
1450bf215546Sopenharmony_ci/**
1451bf215546Sopenharmony_ci * Get the union of TCS output and TES input slots.
1452bf215546Sopenharmony_ci *
1453bf215546Sopenharmony_ci * TCS and TES need to agree on a common URB entry layout.  In particular,
1454bf215546Sopenharmony_ci * the data for all patch vertices is stored in a single URB entry (unlike
1455bf215546Sopenharmony_ci * GS which has one entry per input vertex).  This means that per-vertex
1456bf215546Sopenharmony_ci * array indexing needs a stride.
1457bf215546Sopenharmony_ci *
1458bf215546Sopenharmony_ci * SSO requires locations to match, but doesn't require the number of
1459bf215546Sopenharmony_ci * outputs/inputs to match (in fact, the TCS often has extra outputs).
1460bf215546Sopenharmony_ci * So, we need to take the extra step of unifying these on the fly.
1461bf215546Sopenharmony_ci */
1462bf215546Sopenharmony_cistatic void
1463bf215546Sopenharmony_ciget_unified_tess_slots(const struct iris_context *ice,
1464bf215546Sopenharmony_ci                       uint64_t *per_vertex_slots,
1465bf215546Sopenharmony_ci                       uint32_t *per_patch_slots)
1466bf215546Sopenharmony_ci{
1467bf215546Sopenharmony_ci   const struct shader_info *tcs =
1468bf215546Sopenharmony_ci      iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL);
1469bf215546Sopenharmony_ci   const struct shader_info *tes =
1470bf215546Sopenharmony_ci      iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL);
1471bf215546Sopenharmony_ci
1472bf215546Sopenharmony_ci   *per_vertex_slots = tes->inputs_read;
1473bf215546Sopenharmony_ci   *per_patch_slots = tes->patch_inputs_read;
1474bf215546Sopenharmony_ci
1475bf215546Sopenharmony_ci   if (tcs) {
1476bf215546Sopenharmony_ci      *per_vertex_slots |= tcs->outputs_written;
1477bf215546Sopenharmony_ci      *per_patch_slots |= tcs->patch_outputs_written;
1478bf215546Sopenharmony_ci   }
1479bf215546Sopenharmony_ci}
1480bf215546Sopenharmony_ci
1481bf215546Sopenharmony_ci/**
1482bf215546Sopenharmony_ci * Compile a tessellation control shader, and upload the assembly.
1483bf215546Sopenharmony_ci */
1484bf215546Sopenharmony_cistatic void
1485bf215546Sopenharmony_ciiris_compile_tcs(struct iris_screen *screen,
1486bf215546Sopenharmony_ci                 struct hash_table *passthrough_ht,
1487bf215546Sopenharmony_ci                 struct u_upload_mgr *uploader,
1488bf215546Sopenharmony_ci                 struct util_debug_callback *dbg,
1489bf215546Sopenharmony_ci                 struct iris_uncompiled_shader *ish,
1490bf215546Sopenharmony_ci                 struct iris_compiled_shader *shader)
1491bf215546Sopenharmony_ci{
1492bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1493bf215546Sopenharmony_ci   const struct nir_shader_compiler_options *options =
1494bf215546Sopenharmony_ci      compiler->nir_options[MESA_SHADER_TESS_CTRL];
1495bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
1496bf215546Sopenharmony_ci   struct brw_tcs_prog_data *tcs_prog_data =
1497bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_tcs_prog_data);
1498bf215546Sopenharmony_ci   struct brw_vue_prog_data *vue_prog_data = &tcs_prog_data->base;
1499bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &vue_prog_data->base;
1500bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1501bf215546Sopenharmony_ci   enum brw_param_builtin *system_values = NULL;
1502bf215546Sopenharmony_ci   unsigned num_system_values = 0;
1503bf215546Sopenharmony_ci   unsigned num_cbufs = 0;
1504bf215546Sopenharmony_ci
1505bf215546Sopenharmony_ci   nir_shader *nir;
1506bf215546Sopenharmony_ci
1507bf215546Sopenharmony_ci   struct iris_binding_table bt;
1508bf215546Sopenharmony_ci
1509bf215546Sopenharmony_ci   const struct iris_tcs_prog_key *const key = &shader->key.tcs;
1510bf215546Sopenharmony_ci   struct brw_tcs_prog_key brw_key = iris_to_brw_tcs_key(screen, key);
1511bf215546Sopenharmony_ci
1512bf215546Sopenharmony_ci   if (ish) {
1513bf215546Sopenharmony_ci      nir = nir_shader_clone(mem_ctx, ish->nir);
1514bf215546Sopenharmony_ci
1515bf215546Sopenharmony_ci      iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values,
1516bf215546Sopenharmony_ci                          &num_system_values, &num_cbufs);
1517bf215546Sopenharmony_ci      iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0,
1518bf215546Sopenharmony_ci                               num_system_values, num_cbufs);
1519bf215546Sopenharmony_ci      brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges);
1520bf215546Sopenharmony_ci   } else {
1521bf215546Sopenharmony_ci      nir =
1522bf215546Sopenharmony_ci         brw_nir_create_passthrough_tcs(mem_ctx, compiler, options, &brw_key);
1523bf215546Sopenharmony_ci
1524bf215546Sopenharmony_ci      /* Reserve space for passing the default tess levels as constants. */
1525bf215546Sopenharmony_ci      num_cbufs = 1;
1526bf215546Sopenharmony_ci      num_system_values = 8;
1527bf215546Sopenharmony_ci      system_values =
1528bf215546Sopenharmony_ci         rzalloc_array(mem_ctx, enum brw_param_builtin, num_system_values);
1529bf215546Sopenharmony_ci      prog_data->param = rzalloc_array(mem_ctx, uint32_t, num_system_values);
1530bf215546Sopenharmony_ci      prog_data->nr_params = num_system_values;
1531bf215546Sopenharmony_ci
1532bf215546Sopenharmony_ci      if (key->_tes_primitive_mode == TESS_PRIMITIVE_QUADS) {
1533bf215546Sopenharmony_ci         for (int i = 0; i < 4; i++)
1534bf215546Sopenharmony_ci            system_values[7 - i] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X + i;
1535bf215546Sopenharmony_ci
1536bf215546Sopenharmony_ci         system_values[3] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_X;
1537bf215546Sopenharmony_ci         system_values[2] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_Y;
1538bf215546Sopenharmony_ci      } else if (key->_tes_primitive_mode == TESS_PRIMITIVE_TRIANGLES) {
1539bf215546Sopenharmony_ci         for (int i = 0; i < 3; i++)
1540bf215546Sopenharmony_ci            system_values[7 - i] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X + i;
1541bf215546Sopenharmony_ci
1542bf215546Sopenharmony_ci         system_values[4] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_X;
1543bf215546Sopenharmony_ci      } else {
1544bf215546Sopenharmony_ci         assert(key->_tes_primitive_mode == TESS_PRIMITIVE_ISOLINES);
1545bf215546Sopenharmony_ci         system_values[7] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_Y;
1546bf215546Sopenharmony_ci         system_values[6] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X;
1547bf215546Sopenharmony_ci      }
1548bf215546Sopenharmony_ci
1549bf215546Sopenharmony_ci      /* Manually setup the TCS binding table. */
1550bf215546Sopenharmony_ci      memset(&bt, 0, sizeof(bt));
1551bf215546Sopenharmony_ci      bt.sizes[IRIS_SURFACE_GROUP_UBO] = 1;
1552bf215546Sopenharmony_ci      bt.used_mask[IRIS_SURFACE_GROUP_UBO] = 1;
1553bf215546Sopenharmony_ci      bt.size_bytes = 4;
1554bf215546Sopenharmony_ci
1555bf215546Sopenharmony_ci      prog_data->ubo_ranges[0].length = 1;
1556bf215546Sopenharmony_ci   }
1557bf215546Sopenharmony_ci
1558bf215546Sopenharmony_ci   struct brw_compile_tcs_params params = {
1559bf215546Sopenharmony_ci      .nir = nir,
1560bf215546Sopenharmony_ci      .key = &brw_key,
1561bf215546Sopenharmony_ci      .prog_data = tcs_prog_data,
1562bf215546Sopenharmony_ci      .log_data = dbg,
1563bf215546Sopenharmony_ci   };
1564bf215546Sopenharmony_ci
1565bf215546Sopenharmony_ci   const unsigned *program = brw_compile_tcs(compiler, mem_ctx, &params);
1566bf215546Sopenharmony_ci   if (program == NULL) {
1567bf215546Sopenharmony_ci      dbg_printf("Failed to compile control shader: %s\n", params.error_str);
1568bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
1569bf215546Sopenharmony_ci
1570bf215546Sopenharmony_ci      shader->compilation_failed = true;
1571bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
1572bf215546Sopenharmony_ci
1573bf215546Sopenharmony_ci      return;
1574bf215546Sopenharmony_ci   }
1575bf215546Sopenharmony_ci
1576bf215546Sopenharmony_ci   shader->compilation_failed = false;
1577bf215546Sopenharmony_ci
1578bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
1579bf215546Sopenharmony_ci
1580bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, NULL, system_values,
1581bf215546Sopenharmony_ci                         num_system_values, 0, num_cbufs, &bt);
1582bf215546Sopenharmony_ci
1583bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, passthrough_ht, uploader,
1584bf215546Sopenharmony_ci                      IRIS_CACHE_TCS, sizeof(*key), key, program);
1585bf215546Sopenharmony_ci
1586bf215546Sopenharmony_ci   if (ish)
1587bf215546Sopenharmony_ci      iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
1588bf215546Sopenharmony_ci
1589bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
1590bf215546Sopenharmony_ci}
1591bf215546Sopenharmony_ci
1592bf215546Sopenharmony_ci/**
1593bf215546Sopenharmony_ci * Update the current tessellation control shader variant.
1594bf215546Sopenharmony_ci *
1595bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed.
1596bf215546Sopenharmony_ci */
1597bf215546Sopenharmony_cistatic void
1598bf215546Sopenharmony_ciiris_update_compiled_tcs(struct iris_context *ice)
1599bf215546Sopenharmony_ci{
1600bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_TESS_CTRL];
1601bf215546Sopenharmony_ci   struct iris_uncompiled_shader *tcs =
1602bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_TESS_CTRL];
1603bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
1604bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
1605bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1606bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1607bf215546Sopenharmony_ci
1608bf215546Sopenharmony_ci   const struct shader_info *tes_info =
1609bf215546Sopenharmony_ci      iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL);
1610bf215546Sopenharmony_ci   struct iris_tcs_prog_key key = {
1611bf215546Sopenharmony_ci      .vue.base.program_string_id = tcs ? tcs->program_id : 0,
1612bf215546Sopenharmony_ci      ._tes_primitive_mode = tes_info->tess._primitive_mode,
1613bf215546Sopenharmony_ci      .input_vertices =
1614bf215546Sopenharmony_ci         !tcs || compiler->use_tcs_8_patch ? ice->state.vertices_per_patch : 0,
1615bf215546Sopenharmony_ci      .quads_workaround = devinfo->ver < 9 &&
1616bf215546Sopenharmony_ci                          tes_info->tess._primitive_mode == TESS_PRIMITIVE_QUADS &&
1617bf215546Sopenharmony_ci                          tes_info->tess.spacing == TESS_SPACING_EQUAL,
1618bf215546Sopenharmony_ci   };
1619bf215546Sopenharmony_ci   get_unified_tess_slots(ice, &key.outputs_written,
1620bf215546Sopenharmony_ci                          &key.patch_outputs_written);
1621bf215546Sopenharmony_ci   screen->vtbl.populate_tcs_key(ice, &key);
1622bf215546Sopenharmony_ci
1623bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TCS];
1624bf215546Sopenharmony_ci   struct iris_compiled_shader *shader;
1625bf215546Sopenharmony_ci   bool added = false;
1626bf215546Sopenharmony_ci
1627bf215546Sopenharmony_ci   if (tcs != NULL) {
1628bf215546Sopenharmony_ci      shader = find_or_add_variant(screen, tcs, IRIS_CACHE_TCS, &key,
1629bf215546Sopenharmony_ci                                   sizeof(key), &added);
1630bf215546Sopenharmony_ci   } else {
1631bf215546Sopenharmony_ci      /* Look for and possibly create a passthrough TCS */
1632bf215546Sopenharmony_ci      shader = iris_find_cached_shader(ice, IRIS_CACHE_TCS, sizeof(key), &key);
1633bf215546Sopenharmony_ci
1634bf215546Sopenharmony_ci
1635bf215546Sopenharmony_ci      if (shader == NULL) {
1636bf215546Sopenharmony_ci         shader = iris_create_shader_variant(screen, ice->shaders.cache,
1637bf215546Sopenharmony_ci                                             IRIS_CACHE_TCS, sizeof(key), &key);
1638bf215546Sopenharmony_ci         added = true;
1639bf215546Sopenharmony_ci      }
1640bf215546Sopenharmony_ci
1641bf215546Sopenharmony_ci   }
1642bf215546Sopenharmony_ci
1643bf215546Sopenharmony_ci   /* If the shader was not found in (whichever cache), call iris_compile_tcs
1644bf215546Sopenharmony_ci    * if either ish is NULL or the shader could not be found in the disk
1645bf215546Sopenharmony_ci    * cache.
1646bf215546Sopenharmony_ci    */
1647bf215546Sopenharmony_ci   if (added &&
1648bf215546Sopenharmony_ci       (tcs == NULL || !iris_disk_cache_retrieve(screen, uploader, tcs, shader,
1649bf215546Sopenharmony_ci                                                 &key, sizeof(key)))) {
1650bf215546Sopenharmony_ci      iris_compile_tcs(screen, ice->shaders.cache, uploader, &ice->dbg, tcs,
1651bf215546Sopenharmony_ci                       shader);
1652bf215546Sopenharmony_ci   }
1653bf215546Sopenharmony_ci
1654bf215546Sopenharmony_ci   if (shader->compilation_failed)
1655bf215546Sopenharmony_ci      shader = NULL;
1656bf215546Sopenharmony_ci
1657bf215546Sopenharmony_ci   if (old != shader) {
1658bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_CTRL],
1659bf215546Sopenharmony_ci                                    shader);
1660bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TCS |
1661bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_TCS |
1662bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_TCS;
1663bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
1664bf215546Sopenharmony_ci
1665bf215546Sopenharmony_ci      unsigned urb_entry_size = shader ?
1666bf215546Sopenharmony_ci         ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0;
1667bf215546Sopenharmony_ci      check_urb_size(ice, urb_entry_size, MESA_SHADER_TESS_CTRL);
1668bf215546Sopenharmony_ci   }
1669bf215546Sopenharmony_ci}
1670bf215546Sopenharmony_ci
1671bf215546Sopenharmony_ci/**
1672bf215546Sopenharmony_ci * Compile a tessellation evaluation shader, and upload the assembly.
1673bf215546Sopenharmony_ci */
1674bf215546Sopenharmony_cistatic void
1675bf215546Sopenharmony_ciiris_compile_tes(struct iris_screen *screen,
1676bf215546Sopenharmony_ci                 struct u_upload_mgr *uploader,
1677bf215546Sopenharmony_ci                 struct util_debug_callback *dbg,
1678bf215546Sopenharmony_ci                 struct iris_uncompiled_shader *ish,
1679bf215546Sopenharmony_ci                 struct iris_compiled_shader *shader)
1680bf215546Sopenharmony_ci{
1681bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1682bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
1683bf215546Sopenharmony_ci   struct brw_tes_prog_data *tes_prog_data =
1684bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_tes_prog_data);
1685bf215546Sopenharmony_ci   struct brw_vue_prog_data *vue_prog_data = &tes_prog_data->base;
1686bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &vue_prog_data->base;
1687bf215546Sopenharmony_ci   enum brw_param_builtin *system_values;
1688bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1689bf215546Sopenharmony_ci   unsigned num_system_values;
1690bf215546Sopenharmony_ci   unsigned num_cbufs;
1691bf215546Sopenharmony_ci
1692bf215546Sopenharmony_ci   nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
1693bf215546Sopenharmony_ci   const struct iris_tes_prog_key *const key = &shader->key.tes;
1694bf215546Sopenharmony_ci
1695bf215546Sopenharmony_ci   if (key->vue.nr_userclip_plane_consts) {
1696bf215546Sopenharmony_ci      nir_function_impl *impl = nir_shader_get_entrypoint(nir);
1697bf215546Sopenharmony_ci      nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1,
1698bf215546Sopenharmony_ci                        true, false, NULL);
1699bf215546Sopenharmony_ci      nir_lower_io_to_temporaries(nir, impl, true, false);
1700bf215546Sopenharmony_ci      nir_lower_global_vars_to_local(nir);
1701bf215546Sopenharmony_ci      nir_lower_vars_to_ssa(nir);
1702bf215546Sopenharmony_ci      nir_shader_gather_info(nir, impl);
1703bf215546Sopenharmony_ci   }
1704bf215546Sopenharmony_ci
1705bf215546Sopenharmony_ci   iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values,
1706bf215546Sopenharmony_ci                       &num_system_values, &num_cbufs);
1707bf215546Sopenharmony_ci
1708bf215546Sopenharmony_ci   struct iris_binding_table bt;
1709bf215546Sopenharmony_ci   iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0,
1710bf215546Sopenharmony_ci                            num_system_values, num_cbufs);
1711bf215546Sopenharmony_ci
1712bf215546Sopenharmony_ci   brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges);
1713bf215546Sopenharmony_ci
1714bf215546Sopenharmony_ci   struct brw_vue_map input_vue_map;
1715bf215546Sopenharmony_ci   brw_compute_tess_vue_map(&input_vue_map, key->inputs_read,
1716bf215546Sopenharmony_ci                            key->patch_inputs_read);
1717bf215546Sopenharmony_ci
1718bf215546Sopenharmony_ci   struct brw_tes_prog_key brw_key = iris_to_brw_tes_key(screen, key);
1719bf215546Sopenharmony_ci
1720bf215546Sopenharmony_ci   struct brw_compile_tes_params params = {
1721bf215546Sopenharmony_ci      .nir = nir,
1722bf215546Sopenharmony_ci      .key = &brw_key,
1723bf215546Sopenharmony_ci      .prog_data = tes_prog_data,
1724bf215546Sopenharmony_ci      .input_vue_map = &input_vue_map,
1725bf215546Sopenharmony_ci      .log_data = dbg,
1726bf215546Sopenharmony_ci   };
1727bf215546Sopenharmony_ci
1728bf215546Sopenharmony_ci   const unsigned *program = brw_compile_tes(compiler, mem_ctx, &params);
1729bf215546Sopenharmony_ci   if (program == NULL) {
1730bf215546Sopenharmony_ci      dbg_printf("Failed to compile evaluation shader: %s\n", params.error_str);
1731bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
1732bf215546Sopenharmony_ci
1733bf215546Sopenharmony_ci      shader->compilation_failed = true;
1734bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
1735bf215546Sopenharmony_ci
1736bf215546Sopenharmony_ci      return;
1737bf215546Sopenharmony_ci   }
1738bf215546Sopenharmony_ci
1739bf215546Sopenharmony_ci   shader->compilation_failed = false;
1740bf215546Sopenharmony_ci
1741bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
1742bf215546Sopenharmony_ci
1743bf215546Sopenharmony_ci   uint32_t *so_decls =
1744bf215546Sopenharmony_ci      screen->vtbl.create_so_decl_list(&ish->stream_output,
1745bf215546Sopenharmony_ci                                    &vue_prog_data->vue_map);
1746bf215546Sopenharmony_ci
1747bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, so_decls, system_values,
1748bf215546Sopenharmony_ci                         num_system_values, 0, num_cbufs, &bt);
1749bf215546Sopenharmony_ci
1750bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_TES,
1751bf215546Sopenharmony_ci                      sizeof(*key), key, program);
1752bf215546Sopenharmony_ci
1753bf215546Sopenharmony_ci   iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
1754bf215546Sopenharmony_ci
1755bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
1756bf215546Sopenharmony_ci}
1757bf215546Sopenharmony_ci
1758bf215546Sopenharmony_ci/**
1759bf215546Sopenharmony_ci * Update the current tessellation evaluation shader variant.
1760bf215546Sopenharmony_ci *
1761bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed.
1762bf215546Sopenharmony_ci */
1763bf215546Sopenharmony_cistatic void
1764bf215546Sopenharmony_ciiris_update_compiled_tes(struct iris_context *ice)
1765bf215546Sopenharmony_ci{
1766bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
1767bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
1768bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_TESS_EVAL];
1769bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
1770bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
1771bf215546Sopenharmony_ci
1772bf215546Sopenharmony_ci   struct iris_tes_prog_key key = { KEY_INIT(vue.base) };
1773bf215546Sopenharmony_ci   get_unified_tess_slots(ice, &key.inputs_read, &key.patch_inputs_read);
1774bf215546Sopenharmony_ci   screen->vtbl.populate_tes_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
1775bf215546Sopenharmony_ci
1776bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TES];
1777bf215546Sopenharmony_ci   bool added;
1778bf215546Sopenharmony_ci   struct iris_compiled_shader *shader =
1779bf215546Sopenharmony_ci      find_or_add_variant(screen, ish, IRIS_CACHE_TES, &key, sizeof(key), &added);
1780bf215546Sopenharmony_ci
1781bf215546Sopenharmony_ci   if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
1782bf215546Sopenharmony_ci                                          &key, sizeof(key))) {
1783bf215546Sopenharmony_ci      iris_compile_tes(screen, uploader, &ice->dbg, ish, shader);
1784bf215546Sopenharmony_ci   }
1785bf215546Sopenharmony_ci
1786bf215546Sopenharmony_ci   if (shader->compilation_failed)
1787bf215546Sopenharmony_ci      shader = NULL;
1788bf215546Sopenharmony_ci
1789bf215546Sopenharmony_ci   if (old != shader) {
1790bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_EVAL],
1791bf215546Sopenharmony_ci                                    shader);
1792bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TES |
1793bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_TES |
1794bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_TES;
1795bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
1796bf215546Sopenharmony_ci
1797bf215546Sopenharmony_ci      unsigned urb_entry_size = shader ?
1798bf215546Sopenharmony_ci         ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0;
1799bf215546Sopenharmony_ci      check_urb_size(ice, urb_entry_size, MESA_SHADER_TESS_EVAL);
1800bf215546Sopenharmony_ci   }
1801bf215546Sopenharmony_ci
1802bf215546Sopenharmony_ci   /* TODO: Could compare and avoid flagging this. */
1803bf215546Sopenharmony_ci   const struct shader_info *tes_info = &ish->nir->info;
1804bf215546Sopenharmony_ci   if (BITSET_TEST(tes_info->system_values_read, SYSTEM_VALUE_VERTICES_IN)) {
1805bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TES;
1806bf215546Sopenharmony_ci      ice->state.shaders[MESA_SHADER_TESS_EVAL].sysvals_need_upload = true;
1807bf215546Sopenharmony_ci   }
1808bf215546Sopenharmony_ci}
1809bf215546Sopenharmony_ci
1810bf215546Sopenharmony_ci/**
1811bf215546Sopenharmony_ci * Compile a geometry shader, and upload the assembly.
1812bf215546Sopenharmony_ci */
1813bf215546Sopenharmony_cistatic void
1814bf215546Sopenharmony_ciiris_compile_gs(struct iris_screen *screen,
1815bf215546Sopenharmony_ci                struct u_upload_mgr *uploader,
1816bf215546Sopenharmony_ci                struct util_debug_callback *dbg,
1817bf215546Sopenharmony_ci                struct iris_uncompiled_shader *ish,
1818bf215546Sopenharmony_ci                struct iris_compiled_shader *shader)
1819bf215546Sopenharmony_ci{
1820bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1821bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1822bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
1823bf215546Sopenharmony_ci   struct brw_gs_prog_data *gs_prog_data =
1824bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_gs_prog_data);
1825bf215546Sopenharmony_ci   struct brw_vue_prog_data *vue_prog_data = &gs_prog_data->base;
1826bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &vue_prog_data->base;
1827bf215546Sopenharmony_ci   enum brw_param_builtin *system_values;
1828bf215546Sopenharmony_ci   unsigned num_system_values;
1829bf215546Sopenharmony_ci   unsigned num_cbufs;
1830bf215546Sopenharmony_ci
1831bf215546Sopenharmony_ci   nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
1832bf215546Sopenharmony_ci   const struct iris_gs_prog_key *const key = &shader->key.gs;
1833bf215546Sopenharmony_ci
1834bf215546Sopenharmony_ci   if (key->vue.nr_userclip_plane_consts) {
1835bf215546Sopenharmony_ci      nir_function_impl *impl = nir_shader_get_entrypoint(nir);
1836bf215546Sopenharmony_ci      nir_lower_clip_gs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1,
1837bf215546Sopenharmony_ci                        false, NULL);
1838bf215546Sopenharmony_ci      nir_lower_io_to_temporaries(nir, impl, true, false);
1839bf215546Sopenharmony_ci      nir_lower_global_vars_to_local(nir);
1840bf215546Sopenharmony_ci      nir_lower_vars_to_ssa(nir);
1841bf215546Sopenharmony_ci      nir_shader_gather_info(nir, impl);
1842bf215546Sopenharmony_ci   }
1843bf215546Sopenharmony_ci
1844bf215546Sopenharmony_ci   iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values,
1845bf215546Sopenharmony_ci                       &num_system_values, &num_cbufs);
1846bf215546Sopenharmony_ci
1847bf215546Sopenharmony_ci   struct iris_binding_table bt;
1848bf215546Sopenharmony_ci   iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0,
1849bf215546Sopenharmony_ci                            num_system_values, num_cbufs);
1850bf215546Sopenharmony_ci
1851bf215546Sopenharmony_ci   brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges);
1852bf215546Sopenharmony_ci
1853bf215546Sopenharmony_ci   brw_compute_vue_map(devinfo,
1854bf215546Sopenharmony_ci                       &vue_prog_data->vue_map, nir->info.outputs_written,
1855bf215546Sopenharmony_ci                       nir->info.separate_shader, /* pos_slots */ 1);
1856bf215546Sopenharmony_ci
1857bf215546Sopenharmony_ci   struct brw_gs_prog_key brw_key = iris_to_brw_gs_key(screen, key);
1858bf215546Sopenharmony_ci
1859bf215546Sopenharmony_ci   struct brw_compile_gs_params params = {
1860bf215546Sopenharmony_ci      .nir = nir,
1861bf215546Sopenharmony_ci      .key = &brw_key,
1862bf215546Sopenharmony_ci      .prog_data = gs_prog_data,
1863bf215546Sopenharmony_ci      .log_data = dbg,
1864bf215546Sopenharmony_ci   };
1865bf215546Sopenharmony_ci
1866bf215546Sopenharmony_ci   const unsigned *program = brw_compile_gs(compiler, mem_ctx, &params);
1867bf215546Sopenharmony_ci   if (program == NULL) {
1868bf215546Sopenharmony_ci      dbg_printf("Failed to compile geometry shader: %s\n", params.error_str);
1869bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
1870bf215546Sopenharmony_ci
1871bf215546Sopenharmony_ci      shader->compilation_failed = true;
1872bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
1873bf215546Sopenharmony_ci
1874bf215546Sopenharmony_ci      return;
1875bf215546Sopenharmony_ci   }
1876bf215546Sopenharmony_ci
1877bf215546Sopenharmony_ci   shader->compilation_failed = false;
1878bf215546Sopenharmony_ci
1879bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
1880bf215546Sopenharmony_ci
1881bf215546Sopenharmony_ci   uint32_t *so_decls =
1882bf215546Sopenharmony_ci      screen->vtbl.create_so_decl_list(&ish->stream_output,
1883bf215546Sopenharmony_ci                                    &vue_prog_data->vue_map);
1884bf215546Sopenharmony_ci
1885bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, so_decls, system_values,
1886bf215546Sopenharmony_ci                         num_system_values, 0, num_cbufs, &bt);
1887bf215546Sopenharmony_ci
1888bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_GS,
1889bf215546Sopenharmony_ci                      sizeof(*key), key, program);
1890bf215546Sopenharmony_ci
1891bf215546Sopenharmony_ci   iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
1892bf215546Sopenharmony_ci
1893bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
1894bf215546Sopenharmony_ci}
1895bf215546Sopenharmony_ci
1896bf215546Sopenharmony_ci/**
1897bf215546Sopenharmony_ci * Update the current geometry shader variant.
1898bf215546Sopenharmony_ci *
1899bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed.
1900bf215546Sopenharmony_ci */
1901bf215546Sopenharmony_cistatic void
1902bf215546Sopenharmony_ciiris_update_compiled_gs(struct iris_context *ice)
1903bf215546Sopenharmony_ci{
1904bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_GEOMETRY];
1905bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
1906bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
1907bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_GEOMETRY];
1908bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_GS];
1909bf215546Sopenharmony_ci   struct iris_compiled_shader *shader = NULL;
1910bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
1911bf215546Sopenharmony_ci
1912bf215546Sopenharmony_ci   if (ish) {
1913bf215546Sopenharmony_ci      struct iris_gs_prog_key key = { KEY_INIT(vue.base) };
1914bf215546Sopenharmony_ci      screen->vtbl.populate_gs_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
1915bf215546Sopenharmony_ci
1916bf215546Sopenharmony_ci      bool added;
1917bf215546Sopenharmony_ci
1918bf215546Sopenharmony_ci      shader = find_or_add_variant(screen, ish, IRIS_CACHE_GS, &key,
1919bf215546Sopenharmony_ci                                   sizeof(key), &added);
1920bf215546Sopenharmony_ci
1921bf215546Sopenharmony_ci      if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
1922bf215546Sopenharmony_ci                                             &key, sizeof(key))) {
1923bf215546Sopenharmony_ci         iris_compile_gs(screen, uploader, &ice->dbg, ish, shader);
1924bf215546Sopenharmony_ci      }
1925bf215546Sopenharmony_ci
1926bf215546Sopenharmony_ci      if (shader->compilation_failed)
1927bf215546Sopenharmony_ci         shader = NULL;
1928bf215546Sopenharmony_ci   }
1929bf215546Sopenharmony_ci
1930bf215546Sopenharmony_ci   if (old != shader) {
1931bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_GEOMETRY],
1932bf215546Sopenharmony_ci                                    shader);
1933bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_GS |
1934bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_GS |
1935bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_GS;
1936bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
1937bf215546Sopenharmony_ci
1938bf215546Sopenharmony_ci      unsigned urb_entry_size = shader ?
1939bf215546Sopenharmony_ci         ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0;
1940bf215546Sopenharmony_ci      check_urb_size(ice, urb_entry_size, MESA_SHADER_GEOMETRY);
1941bf215546Sopenharmony_ci   }
1942bf215546Sopenharmony_ci}
1943bf215546Sopenharmony_ci
1944bf215546Sopenharmony_ci/**
1945bf215546Sopenharmony_ci * Compile a fragment (pixel) shader, and upload the assembly.
1946bf215546Sopenharmony_ci */
1947bf215546Sopenharmony_cistatic void
1948bf215546Sopenharmony_ciiris_compile_fs(struct iris_screen *screen,
1949bf215546Sopenharmony_ci                struct u_upload_mgr *uploader,
1950bf215546Sopenharmony_ci                struct util_debug_callback *dbg,
1951bf215546Sopenharmony_ci                struct iris_uncompiled_shader *ish,
1952bf215546Sopenharmony_ci                struct iris_compiled_shader *shader,
1953bf215546Sopenharmony_ci                struct brw_vue_map *vue_map)
1954bf215546Sopenharmony_ci{
1955bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
1956bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
1957bf215546Sopenharmony_ci   struct brw_wm_prog_data *fs_prog_data =
1958bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_wm_prog_data);
1959bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &fs_prog_data->base;
1960bf215546Sopenharmony_ci   enum brw_param_builtin *system_values;
1961bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
1962bf215546Sopenharmony_ci   unsigned num_system_values;
1963bf215546Sopenharmony_ci   unsigned num_cbufs;
1964bf215546Sopenharmony_ci
1965bf215546Sopenharmony_ci   nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
1966bf215546Sopenharmony_ci   const struct iris_fs_prog_key *const key = &shader->key.fs;
1967bf215546Sopenharmony_ci
1968bf215546Sopenharmony_ci   prog_data->use_alt_mode = nir->info.use_legacy_math_rules;
1969bf215546Sopenharmony_ci
1970bf215546Sopenharmony_ci   iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values,
1971bf215546Sopenharmony_ci                       &num_system_values, &num_cbufs);
1972bf215546Sopenharmony_ci
1973bf215546Sopenharmony_ci   /* Lower output variables to load_output intrinsics before setting up
1974bf215546Sopenharmony_ci    * binding tables, so iris_setup_binding_table can map any load_output
1975bf215546Sopenharmony_ci    * intrinsics to IRIS_SURFACE_GROUP_RENDER_TARGET_READ on Gfx8 for
1976bf215546Sopenharmony_ci    * non-coherent framebuffer fetches.
1977bf215546Sopenharmony_ci    */
1978bf215546Sopenharmony_ci   brw_nir_lower_fs_outputs(nir);
1979bf215546Sopenharmony_ci
1980bf215546Sopenharmony_ci   /* On Gfx11+, shader RT write messages have a "Null Render Target" bit
1981bf215546Sopenharmony_ci    * and do not need a binding table entry with a null surface.  Earlier
1982bf215546Sopenharmony_ci    * generations need an entry for a null surface.
1983bf215546Sopenharmony_ci    */
1984bf215546Sopenharmony_ci   int null_rts = devinfo->ver < 11 ? 1 : 0;
1985bf215546Sopenharmony_ci
1986bf215546Sopenharmony_ci   struct iris_binding_table bt;
1987bf215546Sopenharmony_ci   iris_setup_binding_table(devinfo, nir, &bt,
1988bf215546Sopenharmony_ci                            MAX2(key->nr_color_regions, null_rts),
1989bf215546Sopenharmony_ci                            num_system_values, num_cbufs);
1990bf215546Sopenharmony_ci
1991bf215546Sopenharmony_ci   brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges);
1992bf215546Sopenharmony_ci
1993bf215546Sopenharmony_ci   struct brw_wm_prog_key brw_key = iris_to_brw_fs_key(screen, key);
1994bf215546Sopenharmony_ci
1995bf215546Sopenharmony_ci   struct brw_compile_fs_params params = {
1996bf215546Sopenharmony_ci      .nir = nir,
1997bf215546Sopenharmony_ci      .key = &brw_key,
1998bf215546Sopenharmony_ci      .prog_data = fs_prog_data,
1999bf215546Sopenharmony_ci
2000bf215546Sopenharmony_ci      .allow_spilling = true,
2001bf215546Sopenharmony_ci      .vue_map = vue_map,
2002bf215546Sopenharmony_ci
2003bf215546Sopenharmony_ci      .log_data = dbg,
2004bf215546Sopenharmony_ci   };
2005bf215546Sopenharmony_ci
2006bf215546Sopenharmony_ci   const unsigned *program = brw_compile_fs(compiler, mem_ctx, &params);
2007bf215546Sopenharmony_ci   if (program == NULL) {
2008bf215546Sopenharmony_ci      dbg_printf("Failed to compile fragment shader: %s\n", params.error_str);
2009bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
2010bf215546Sopenharmony_ci
2011bf215546Sopenharmony_ci      shader->compilation_failed = true;
2012bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
2013bf215546Sopenharmony_ci
2014bf215546Sopenharmony_ci      return;
2015bf215546Sopenharmony_ci   }
2016bf215546Sopenharmony_ci
2017bf215546Sopenharmony_ci   shader->compilation_failed = false;
2018bf215546Sopenharmony_ci
2019bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
2020bf215546Sopenharmony_ci
2021bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, NULL, system_values,
2022bf215546Sopenharmony_ci                         num_system_values, 0, num_cbufs, &bt);
2023bf215546Sopenharmony_ci
2024bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_FS,
2025bf215546Sopenharmony_ci                      sizeof(*key), key, program);
2026bf215546Sopenharmony_ci
2027bf215546Sopenharmony_ci   iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
2028bf215546Sopenharmony_ci
2029bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
2030bf215546Sopenharmony_ci}
2031bf215546Sopenharmony_ci
2032bf215546Sopenharmony_ci/**
2033bf215546Sopenharmony_ci * Update the current fragment shader variant.
2034bf215546Sopenharmony_ci *
2035bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed.
2036bf215546Sopenharmony_ci */
2037bf215546Sopenharmony_cistatic void
2038bf215546Sopenharmony_ciiris_update_compiled_fs(struct iris_context *ice)
2039bf215546Sopenharmony_ci{
2040bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_FRAGMENT];
2041bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
2042bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
2043bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_FRAGMENT];
2044bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
2045bf215546Sopenharmony_ci   struct iris_fs_prog_key key = { KEY_INIT(base) };
2046bf215546Sopenharmony_ci   screen->vtbl.populate_fs_key(ice, &ish->nir->info, &key);
2047bf215546Sopenharmony_ci
2048bf215546Sopenharmony_ci   struct brw_vue_map *last_vue_map =
2049bf215546Sopenharmony_ci      &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map;
2050bf215546Sopenharmony_ci
2051bf215546Sopenharmony_ci   if (ish->nos & (1ull << IRIS_NOS_LAST_VUE_MAP))
2052bf215546Sopenharmony_ci      key.input_slots_valid = last_vue_map->slots_valid;
2053bf215546Sopenharmony_ci
2054bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_FS];
2055bf215546Sopenharmony_ci   bool added;
2056bf215546Sopenharmony_ci   struct iris_compiled_shader *shader =
2057bf215546Sopenharmony_ci      find_or_add_variant(screen, ish, IRIS_CACHE_FS, &key,
2058bf215546Sopenharmony_ci                          sizeof(key), &added);
2059bf215546Sopenharmony_ci
2060bf215546Sopenharmony_ci   if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
2061bf215546Sopenharmony_ci                                          &key, sizeof(key))) {
2062bf215546Sopenharmony_ci      iris_compile_fs(screen, uploader, &ice->dbg, ish, shader, last_vue_map);
2063bf215546Sopenharmony_ci   }
2064bf215546Sopenharmony_ci
2065bf215546Sopenharmony_ci   if (shader->compilation_failed)
2066bf215546Sopenharmony_ci      shader = NULL;
2067bf215546Sopenharmony_ci
2068bf215546Sopenharmony_ci   if (old != shader) {
2069bf215546Sopenharmony_ci      // XXX: only need to flag CLIP if barycentric has NONPERSPECTIVE
2070bf215546Sopenharmony_ci      // toggles.  might be able to avoid flagging SBE too.
2071bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_FRAGMENT],
2072bf215546Sopenharmony_ci                                    shader);
2073bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_WM |
2074bf215546Sopenharmony_ci                          IRIS_DIRTY_CLIP |
2075bf215546Sopenharmony_ci                          IRIS_DIRTY_SBE;
2076bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS |
2077bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_FS |
2078bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_FS;
2079bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
2080bf215546Sopenharmony_ci   }
2081bf215546Sopenharmony_ci}
2082bf215546Sopenharmony_ci
2083bf215546Sopenharmony_ci/**
2084bf215546Sopenharmony_ci * Update the last enabled stage's VUE map.
2085bf215546Sopenharmony_ci *
2086bf215546Sopenharmony_ci * When the shader feeding the rasterizer's output interface changes, we
2087bf215546Sopenharmony_ci * need to re-emit various packets.
2088bf215546Sopenharmony_ci */
2089bf215546Sopenharmony_cistatic void
2090bf215546Sopenharmony_ciupdate_last_vue_map(struct iris_context *ice,
2091bf215546Sopenharmony_ci                    struct iris_compiled_shader *shader)
2092bf215546Sopenharmony_ci{
2093bf215546Sopenharmony_ci   struct brw_vue_prog_data *vue_prog_data = (void *) shader->prog_data;
2094bf215546Sopenharmony_ci   struct brw_vue_map *vue_map = &vue_prog_data->vue_map;
2095bf215546Sopenharmony_ci   struct brw_vue_map *old_map = !ice->shaders.last_vue_shader ? NULL :
2096bf215546Sopenharmony_ci      &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map;
2097bf215546Sopenharmony_ci   const uint64_t changed_slots =
2098bf215546Sopenharmony_ci      (old_map ? old_map->slots_valid : 0ull) ^ vue_map->slots_valid;
2099bf215546Sopenharmony_ci
2100bf215546Sopenharmony_ci   if (changed_slots & VARYING_BIT_VIEWPORT) {
2101bf215546Sopenharmony_ci      ice->state.num_viewports =
2102bf215546Sopenharmony_ci         (vue_map->slots_valid & VARYING_BIT_VIEWPORT) ? IRIS_MAX_VIEWPORTS : 1;
2103bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_CLIP |
2104bf215546Sopenharmony_ci                          IRIS_DIRTY_SF_CL_VIEWPORT |
2105bf215546Sopenharmony_ci                          IRIS_DIRTY_CC_VIEWPORT |
2106bf215546Sopenharmony_ci                          IRIS_DIRTY_SCISSOR_RECT;
2107bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_FS |
2108bf215546Sopenharmony_ci         ice->state.stage_dirty_for_nos[IRIS_NOS_LAST_VUE_MAP];
2109bf215546Sopenharmony_ci   }
2110bf215546Sopenharmony_ci
2111bf215546Sopenharmony_ci   if (changed_slots || (old_map && old_map->separate != vue_map->separate)) {
2112bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_SBE;
2113bf215546Sopenharmony_ci   }
2114bf215546Sopenharmony_ci
2115bf215546Sopenharmony_ci   iris_shader_variant_reference(&ice->shaders.last_vue_shader, shader);
2116bf215546Sopenharmony_ci}
2117bf215546Sopenharmony_ci
2118bf215546Sopenharmony_cistatic void
2119bf215546Sopenharmony_ciiris_update_pull_constant_descriptors(struct iris_context *ice,
2120bf215546Sopenharmony_ci                                      gl_shader_stage stage)
2121bf215546Sopenharmony_ci{
2122bf215546Sopenharmony_ci   struct iris_compiled_shader *shader = ice->shaders.prog[stage];
2123bf215546Sopenharmony_ci
2124bf215546Sopenharmony_ci   if (!shader || !shader->prog_data->has_ubo_pull)
2125bf215546Sopenharmony_ci      return;
2126bf215546Sopenharmony_ci
2127bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[stage];
2128bf215546Sopenharmony_ci   bool any_new_descriptors =
2129bf215546Sopenharmony_ci      shader->num_system_values > 0 && shs->sysvals_need_upload;
2130bf215546Sopenharmony_ci
2131bf215546Sopenharmony_ci   unsigned bound_cbufs = shs->bound_cbufs;
2132bf215546Sopenharmony_ci
2133bf215546Sopenharmony_ci   while (bound_cbufs) {
2134bf215546Sopenharmony_ci      const int i = u_bit_scan(&bound_cbufs);
2135bf215546Sopenharmony_ci      struct pipe_shader_buffer *cbuf = &shs->constbuf[i];
2136bf215546Sopenharmony_ci      struct iris_state_ref *surf_state = &shs->constbuf_surf_state[i];
2137bf215546Sopenharmony_ci      if (!surf_state->res && cbuf->buffer) {
2138bf215546Sopenharmony_ci         iris_upload_ubo_ssbo_surf_state(ice, cbuf, surf_state,
2139bf215546Sopenharmony_ci                                         ISL_SURF_USAGE_CONSTANT_BUFFER_BIT);
2140bf215546Sopenharmony_ci         any_new_descriptors = true;
2141bf215546Sopenharmony_ci      }
2142bf215546Sopenharmony_ci   }
2143bf215546Sopenharmony_ci
2144bf215546Sopenharmony_ci   if (any_new_descriptors)
2145bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << stage;
2146bf215546Sopenharmony_ci}
2147bf215546Sopenharmony_ci
2148bf215546Sopenharmony_ci/**
2149bf215546Sopenharmony_ci * Update the current shader variants for the given state.
2150bf215546Sopenharmony_ci *
2151bf215546Sopenharmony_ci * This should be called on every draw call to ensure that the correct
2152bf215546Sopenharmony_ci * shaders are bound.  It will also flag any dirty state triggered by
2153bf215546Sopenharmony_ci * swapping out those shaders.
2154bf215546Sopenharmony_ci */
2155bf215546Sopenharmony_civoid
2156bf215546Sopenharmony_ciiris_update_compiled_shaders(struct iris_context *ice)
2157bf215546Sopenharmony_ci{
2158bf215546Sopenharmony_ci   const uint64_t stage_dirty = ice->state.stage_dirty;
2159bf215546Sopenharmony_ci
2160bf215546Sopenharmony_ci   if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_TCS |
2161bf215546Sopenharmony_ci                      IRIS_STAGE_DIRTY_UNCOMPILED_TES)) {
2162bf215546Sopenharmony_ci       struct iris_uncompiled_shader *tes =
2163bf215546Sopenharmony_ci          ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL];
2164bf215546Sopenharmony_ci       if (tes) {
2165bf215546Sopenharmony_ci          iris_update_compiled_tcs(ice);
2166bf215546Sopenharmony_ci          iris_update_compiled_tes(ice);
2167bf215546Sopenharmony_ci       } else {
2168bf215546Sopenharmony_ci         iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_CTRL], NULL);
2169bf215546Sopenharmony_ci         iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_EVAL], NULL);
2170bf215546Sopenharmony_ci          ice->state.stage_dirty |=
2171bf215546Sopenharmony_ci             IRIS_STAGE_DIRTY_TCS | IRIS_STAGE_DIRTY_TES |
2172bf215546Sopenharmony_ci             IRIS_STAGE_DIRTY_BINDINGS_TCS | IRIS_STAGE_DIRTY_BINDINGS_TES |
2173bf215546Sopenharmony_ci             IRIS_STAGE_DIRTY_CONSTANTS_TCS | IRIS_STAGE_DIRTY_CONSTANTS_TES;
2174bf215546Sopenharmony_ci
2175bf215546Sopenharmony_ci          if (ice->shaders.urb.constrained)
2176bf215546Sopenharmony_ci             ice->state.dirty |= IRIS_DIRTY_URB;
2177bf215546Sopenharmony_ci       }
2178bf215546Sopenharmony_ci   }
2179bf215546Sopenharmony_ci
2180bf215546Sopenharmony_ci   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_VS)
2181bf215546Sopenharmony_ci      iris_update_compiled_vs(ice);
2182bf215546Sopenharmony_ci   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_GS)
2183bf215546Sopenharmony_ci      iris_update_compiled_gs(ice);
2184bf215546Sopenharmony_ci
2185bf215546Sopenharmony_ci   if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_GS |
2186bf215546Sopenharmony_ci                      IRIS_STAGE_DIRTY_UNCOMPILED_TES)) {
2187bf215546Sopenharmony_ci      const struct iris_compiled_shader *gs =
2188bf215546Sopenharmony_ci         ice->shaders.prog[MESA_SHADER_GEOMETRY];
2189bf215546Sopenharmony_ci      const struct iris_compiled_shader *tes =
2190bf215546Sopenharmony_ci         ice->shaders.prog[MESA_SHADER_TESS_EVAL];
2191bf215546Sopenharmony_ci
2192bf215546Sopenharmony_ci      bool points_or_lines = false;
2193bf215546Sopenharmony_ci
2194bf215546Sopenharmony_ci      if (gs) {
2195bf215546Sopenharmony_ci         const struct brw_gs_prog_data *gs_prog_data = (void *) gs->prog_data;
2196bf215546Sopenharmony_ci         points_or_lines =
2197bf215546Sopenharmony_ci            gs_prog_data->output_topology == _3DPRIM_POINTLIST ||
2198bf215546Sopenharmony_ci            gs_prog_data->output_topology == _3DPRIM_LINESTRIP;
2199bf215546Sopenharmony_ci      } else if (tes) {
2200bf215546Sopenharmony_ci         const struct brw_tes_prog_data *tes_data = (void *) tes->prog_data;
2201bf215546Sopenharmony_ci         points_or_lines =
2202bf215546Sopenharmony_ci            tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_LINE ||
2203bf215546Sopenharmony_ci            tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_POINT;
2204bf215546Sopenharmony_ci      }
2205bf215546Sopenharmony_ci
2206bf215546Sopenharmony_ci      if (ice->shaders.output_topology_is_points_or_lines != points_or_lines) {
2207bf215546Sopenharmony_ci         /* Outbound to XY Clip enables */
2208bf215546Sopenharmony_ci         ice->shaders.output_topology_is_points_or_lines = points_or_lines;
2209bf215546Sopenharmony_ci         ice->state.dirty |= IRIS_DIRTY_CLIP;
2210bf215546Sopenharmony_ci      }
2211bf215546Sopenharmony_ci   }
2212bf215546Sopenharmony_ci
2213bf215546Sopenharmony_ci   gl_shader_stage last_stage = last_vue_stage(ice);
2214bf215546Sopenharmony_ci   struct iris_compiled_shader *shader = ice->shaders.prog[last_stage];
2215bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage];
2216bf215546Sopenharmony_ci   update_last_vue_map(ice, shader);
2217bf215546Sopenharmony_ci   if (ice->state.streamout != shader->streamout) {
2218bf215546Sopenharmony_ci      ice->state.streamout = shader->streamout;
2219bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_SO_DECL_LIST | IRIS_DIRTY_STREAMOUT;
2220bf215546Sopenharmony_ci   }
2221bf215546Sopenharmony_ci
2222bf215546Sopenharmony_ci   if (ice->state.streamout_active) {
2223bf215546Sopenharmony_ci      for (int i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
2224bf215546Sopenharmony_ci         struct iris_stream_output_target *so =
2225bf215546Sopenharmony_ci            (void *) ice->state.so_target[i];
2226bf215546Sopenharmony_ci         if (so)
2227bf215546Sopenharmony_ci            so->stride = ish->stream_output.stride[i] * sizeof(uint32_t);
2228bf215546Sopenharmony_ci      }
2229bf215546Sopenharmony_ci   }
2230bf215546Sopenharmony_ci
2231bf215546Sopenharmony_ci   if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_FS)
2232bf215546Sopenharmony_ci      iris_update_compiled_fs(ice);
2233bf215546Sopenharmony_ci
2234bf215546Sopenharmony_ci   for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
2235bf215546Sopenharmony_ci      if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_CONSTANTS_VS << i))
2236bf215546Sopenharmony_ci         iris_update_pull_constant_descriptors(ice, i);
2237bf215546Sopenharmony_ci   }
2238bf215546Sopenharmony_ci}
2239bf215546Sopenharmony_ci
2240bf215546Sopenharmony_cistatic void
2241bf215546Sopenharmony_ciiris_compile_cs(struct iris_screen *screen,
2242bf215546Sopenharmony_ci                struct u_upload_mgr *uploader,
2243bf215546Sopenharmony_ci                struct util_debug_callback *dbg,
2244bf215546Sopenharmony_ci                struct iris_uncompiled_shader *ish,
2245bf215546Sopenharmony_ci                struct iris_compiled_shader *shader)
2246bf215546Sopenharmony_ci{
2247bf215546Sopenharmony_ci   const struct brw_compiler *compiler = screen->compiler;
2248bf215546Sopenharmony_ci   void *mem_ctx = ralloc_context(NULL);
2249bf215546Sopenharmony_ci   struct brw_cs_prog_data *cs_prog_data =
2250bf215546Sopenharmony_ci      rzalloc(mem_ctx, struct brw_cs_prog_data);
2251bf215546Sopenharmony_ci   struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
2252bf215546Sopenharmony_ci   enum brw_param_builtin *system_values;
2253bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
2254bf215546Sopenharmony_ci   unsigned num_system_values;
2255bf215546Sopenharmony_ci   unsigned num_cbufs;
2256bf215546Sopenharmony_ci
2257bf215546Sopenharmony_ci   nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
2258bf215546Sopenharmony_ci   const struct iris_cs_prog_key *const key = &shader->key.cs;
2259bf215546Sopenharmony_ci
2260bf215546Sopenharmony_ci   NIR_PASS_V(nir, brw_nir_lower_cs_intrinsics);
2261bf215546Sopenharmony_ci
2262bf215546Sopenharmony_ci   iris_setup_uniforms(compiler, mem_ctx, nir, prog_data,
2263bf215546Sopenharmony_ci                       ish->kernel_input_size,
2264bf215546Sopenharmony_ci                       &system_values, &num_system_values, &num_cbufs);
2265bf215546Sopenharmony_ci
2266bf215546Sopenharmony_ci   struct iris_binding_table bt;
2267bf215546Sopenharmony_ci   iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0,
2268bf215546Sopenharmony_ci                            num_system_values, num_cbufs);
2269bf215546Sopenharmony_ci
2270bf215546Sopenharmony_ci   struct brw_cs_prog_key brw_key = iris_to_brw_cs_key(screen, key);
2271bf215546Sopenharmony_ci
2272bf215546Sopenharmony_ci   struct brw_compile_cs_params params = {
2273bf215546Sopenharmony_ci      .nir = nir,
2274bf215546Sopenharmony_ci      .key = &brw_key,
2275bf215546Sopenharmony_ci      .prog_data = cs_prog_data,
2276bf215546Sopenharmony_ci      .log_data = dbg,
2277bf215546Sopenharmony_ci   };
2278bf215546Sopenharmony_ci
2279bf215546Sopenharmony_ci   const unsigned *program = brw_compile_cs(compiler, mem_ctx, &params);
2280bf215546Sopenharmony_ci   if (program == NULL) {
2281bf215546Sopenharmony_ci      dbg_printf("Failed to compile compute shader: %s\n", params.error_str);
2282bf215546Sopenharmony_ci
2283bf215546Sopenharmony_ci      shader->compilation_failed = true;
2284bf215546Sopenharmony_ci      util_queue_fence_signal(&shader->ready);
2285bf215546Sopenharmony_ci
2286bf215546Sopenharmony_ci      return;
2287bf215546Sopenharmony_ci   }
2288bf215546Sopenharmony_ci
2289bf215546Sopenharmony_ci   shader->compilation_failed = false;
2290bf215546Sopenharmony_ci
2291bf215546Sopenharmony_ci   iris_debug_recompile(screen, dbg, ish, &brw_key.base);
2292bf215546Sopenharmony_ci
2293bf215546Sopenharmony_ci   iris_finalize_program(shader, prog_data, NULL, system_values,
2294bf215546Sopenharmony_ci                         num_system_values, ish->kernel_input_size, num_cbufs,
2295bf215546Sopenharmony_ci                         &bt);
2296bf215546Sopenharmony_ci
2297bf215546Sopenharmony_ci   iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_CS,
2298bf215546Sopenharmony_ci                      sizeof(*key), key, program);
2299bf215546Sopenharmony_ci
2300bf215546Sopenharmony_ci   iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
2301bf215546Sopenharmony_ci
2302bf215546Sopenharmony_ci   ralloc_free(mem_ctx);
2303bf215546Sopenharmony_ci}
2304bf215546Sopenharmony_ci
2305bf215546Sopenharmony_cistatic void
2306bf215546Sopenharmony_ciiris_update_compiled_cs(struct iris_context *ice)
2307bf215546Sopenharmony_ci{
2308bf215546Sopenharmony_ci   struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_COMPUTE];
2309bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_driver;
2310bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
2311bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_COMPUTE];
2312bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
2313bf215546Sopenharmony_ci   struct iris_cs_prog_key key = { KEY_INIT(base) };
2314bf215546Sopenharmony_ci   screen->vtbl.populate_cs_key(ice, &key);
2315bf215546Sopenharmony_ci
2316bf215546Sopenharmony_ci   struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_CS];
2317bf215546Sopenharmony_ci   bool added;
2318bf215546Sopenharmony_ci   struct iris_compiled_shader *shader =
2319bf215546Sopenharmony_ci      find_or_add_variant(screen, ish, IRIS_CACHE_CS, &key,
2320bf215546Sopenharmony_ci                          sizeof(key), &added);
2321bf215546Sopenharmony_ci
2322bf215546Sopenharmony_ci   if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
2323bf215546Sopenharmony_ci                                          &key, sizeof(key))) {
2324bf215546Sopenharmony_ci      iris_compile_cs(screen, uploader, &ice->dbg, ish, shader);
2325bf215546Sopenharmony_ci   }
2326bf215546Sopenharmony_ci
2327bf215546Sopenharmony_ci   if (shader->compilation_failed)
2328bf215546Sopenharmony_ci      shader = NULL;
2329bf215546Sopenharmony_ci
2330bf215546Sopenharmony_ci   if (old != shader) {
2331bf215546Sopenharmony_ci      iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_COMPUTE],
2332bf215546Sopenharmony_ci                                    shader);
2333bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CS |
2334bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_BINDINGS_CS |
2335bf215546Sopenharmony_ci                                IRIS_STAGE_DIRTY_CONSTANTS_CS;
2336bf215546Sopenharmony_ci      shs->sysvals_need_upload = true;
2337bf215546Sopenharmony_ci   }
2338bf215546Sopenharmony_ci}
2339bf215546Sopenharmony_ci
2340bf215546Sopenharmony_civoid
2341bf215546Sopenharmony_ciiris_update_compiled_compute_shader(struct iris_context *ice)
2342bf215546Sopenharmony_ci{
2343bf215546Sopenharmony_ci   if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_CS)
2344bf215546Sopenharmony_ci      iris_update_compiled_cs(ice);
2345bf215546Sopenharmony_ci
2346bf215546Sopenharmony_ci   if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_CONSTANTS_CS)
2347bf215546Sopenharmony_ci      iris_update_pull_constant_descriptors(ice, MESA_SHADER_COMPUTE);
2348bf215546Sopenharmony_ci}
2349bf215546Sopenharmony_ci
2350bf215546Sopenharmony_civoid
2351bf215546Sopenharmony_ciiris_fill_cs_push_const_buffer(struct brw_cs_prog_data *cs_prog_data,
2352bf215546Sopenharmony_ci                               unsigned threads,
2353bf215546Sopenharmony_ci                               uint32_t *dst)
2354bf215546Sopenharmony_ci{
2355bf215546Sopenharmony_ci   assert(brw_cs_push_const_total_size(cs_prog_data, threads) > 0);
2356bf215546Sopenharmony_ci   assert(cs_prog_data->push.cross_thread.size == 0);
2357bf215546Sopenharmony_ci   assert(cs_prog_data->push.per_thread.dwords == 1);
2358bf215546Sopenharmony_ci   assert(cs_prog_data->base.param[0] == BRW_PARAM_BUILTIN_SUBGROUP_ID);
2359bf215546Sopenharmony_ci   for (unsigned t = 0; t < threads; t++)
2360bf215546Sopenharmony_ci      dst[8 * t] = t;
2361bf215546Sopenharmony_ci}
2362bf215546Sopenharmony_ci
2363bf215546Sopenharmony_ci/**
2364bf215546Sopenharmony_ci * Allocate scratch BOs as needed for the given per-thread size and stage.
2365bf215546Sopenharmony_ci */
2366bf215546Sopenharmony_cistruct iris_bo *
2367bf215546Sopenharmony_ciiris_get_scratch_space(struct iris_context *ice,
2368bf215546Sopenharmony_ci                       unsigned per_thread_scratch,
2369bf215546Sopenharmony_ci                       gl_shader_stage stage)
2370bf215546Sopenharmony_ci{
2371bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
2372bf215546Sopenharmony_ci   struct iris_bufmgr *bufmgr = screen->bufmgr;
2373bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
2374bf215546Sopenharmony_ci
2375bf215546Sopenharmony_ci   unsigned encoded_size = ffs(per_thread_scratch) - 11;
2376bf215546Sopenharmony_ci   assert(encoded_size < ARRAY_SIZE(ice->shaders.scratch_bos));
2377bf215546Sopenharmony_ci   assert(per_thread_scratch == 1 << (encoded_size + 10));
2378bf215546Sopenharmony_ci
2379bf215546Sopenharmony_ci   /* On GFX version 12.5, scratch access changed to a surface-based model.
2380bf215546Sopenharmony_ci    * Instead of each shader type having its own layout based on IDs passed
2381bf215546Sopenharmony_ci    * from the relevant fixed-function unit, all scratch access is based on
2382bf215546Sopenharmony_ci    * thread IDs like it always has been for compute.
2383bf215546Sopenharmony_ci    */
2384bf215546Sopenharmony_ci   if (devinfo->verx10 >= 125)
2385bf215546Sopenharmony_ci      stage = MESA_SHADER_COMPUTE;
2386bf215546Sopenharmony_ci
2387bf215546Sopenharmony_ci   struct iris_bo **bop = &ice->shaders.scratch_bos[encoded_size][stage];
2388bf215546Sopenharmony_ci
2389bf215546Sopenharmony_ci   if (!*bop) {
2390bf215546Sopenharmony_ci      assert(stage < ARRAY_SIZE(devinfo->max_scratch_ids));
2391bf215546Sopenharmony_ci      uint32_t size = per_thread_scratch * devinfo->max_scratch_ids[stage];
2392bf215546Sopenharmony_ci      *bop = iris_bo_alloc(bufmgr, "scratch", size, 1024,
2393bf215546Sopenharmony_ci                           IRIS_MEMZONE_SHADER, 0);
2394bf215546Sopenharmony_ci   }
2395bf215546Sopenharmony_ci
2396bf215546Sopenharmony_ci   return *bop;
2397bf215546Sopenharmony_ci}
2398bf215546Sopenharmony_ci
2399bf215546Sopenharmony_ciconst struct iris_state_ref *
2400bf215546Sopenharmony_ciiris_get_scratch_surf(struct iris_context *ice,
2401bf215546Sopenharmony_ci                      unsigned per_thread_scratch)
2402bf215546Sopenharmony_ci{
2403bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
2404bf215546Sopenharmony_ci   ASSERTED const struct intel_device_info *devinfo = &screen->devinfo;
2405bf215546Sopenharmony_ci
2406bf215546Sopenharmony_ci   assert(devinfo->verx10 >= 125);
2407bf215546Sopenharmony_ci
2408bf215546Sopenharmony_ci   unsigned encoded_size = ffs(per_thread_scratch) - 11;
2409bf215546Sopenharmony_ci   assert(encoded_size < ARRAY_SIZE(ice->shaders.scratch_surfs));
2410bf215546Sopenharmony_ci   assert(per_thread_scratch == 1 << (encoded_size + 10));
2411bf215546Sopenharmony_ci
2412bf215546Sopenharmony_ci   struct iris_state_ref *ref = &ice->shaders.scratch_surfs[encoded_size];
2413bf215546Sopenharmony_ci
2414bf215546Sopenharmony_ci   if (ref->res)
2415bf215546Sopenharmony_ci      return ref;
2416bf215546Sopenharmony_ci
2417bf215546Sopenharmony_ci   struct iris_bo *scratch_bo =
2418bf215546Sopenharmony_ci      iris_get_scratch_space(ice, per_thread_scratch, MESA_SHADER_COMPUTE);
2419bf215546Sopenharmony_ci
2420bf215546Sopenharmony_ci   void *map = upload_state(ice->state.bindless_uploader, ref,
2421bf215546Sopenharmony_ci                            screen->isl_dev.ss.size, 64);
2422bf215546Sopenharmony_ci
2423bf215546Sopenharmony_ci   isl_buffer_fill_state(&screen->isl_dev, map,
2424bf215546Sopenharmony_ci                         .address = scratch_bo->address,
2425bf215546Sopenharmony_ci                         .size_B = scratch_bo->size,
2426bf215546Sopenharmony_ci                         .format = ISL_FORMAT_RAW,
2427bf215546Sopenharmony_ci                         .swizzle = ISL_SWIZZLE_IDENTITY,
2428bf215546Sopenharmony_ci                         .mocs = iris_mocs(scratch_bo, &screen->isl_dev, 0),
2429bf215546Sopenharmony_ci                         .stride_B = per_thread_scratch,
2430bf215546Sopenharmony_ci                         .is_scratch = true);
2431bf215546Sopenharmony_ci
2432bf215546Sopenharmony_ci   return ref;
2433bf215546Sopenharmony_ci}
2434bf215546Sopenharmony_ci
2435bf215546Sopenharmony_ci/* ------------------------------------------------------------------- */
2436bf215546Sopenharmony_ci
2437bf215546Sopenharmony_ci/**
2438bf215546Sopenharmony_ci * The pipe->create_[stage]_state() driver hooks.
2439bf215546Sopenharmony_ci *
2440bf215546Sopenharmony_ci * Performs basic NIR preprocessing, records any state dependencies, and
2441bf215546Sopenharmony_ci * returns an iris_uncompiled_shader as the Gallium CSO.
2442bf215546Sopenharmony_ci *
2443bf215546Sopenharmony_ci * Actual shader compilation to assembly happens later, at first use.
2444bf215546Sopenharmony_ci */
2445bf215546Sopenharmony_cistatic void *
2446bf215546Sopenharmony_ciiris_create_uncompiled_shader(struct iris_screen *screen,
2447bf215546Sopenharmony_ci                              nir_shader *nir,
2448bf215546Sopenharmony_ci                              const struct pipe_stream_output_info *so_info)
2449bf215546Sopenharmony_ci{
2450bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
2451bf215546Sopenharmony_ci      calloc(1, sizeof(struct iris_uncompiled_shader));
2452bf215546Sopenharmony_ci   if (!ish)
2453bf215546Sopenharmony_ci      return NULL;
2454bf215546Sopenharmony_ci
2455bf215546Sopenharmony_ci   pipe_reference_init(&ish->ref, 1);
2456bf215546Sopenharmony_ci   list_inithead(&ish->variants);
2457bf215546Sopenharmony_ci   simple_mtx_init(&ish->lock, mtx_plain);
2458bf215546Sopenharmony_ci   util_queue_fence_init(&ish->ready);
2459bf215546Sopenharmony_ci
2460bf215546Sopenharmony_ci   ish->uses_atomic_load_store = iris_uses_image_atomic(nir);
2461bf215546Sopenharmony_ci
2462bf215546Sopenharmony_ci   ish->program_id = get_new_program_id(screen);
2463bf215546Sopenharmony_ci   ish->nir = nir;
2464bf215546Sopenharmony_ci   if (so_info) {
2465bf215546Sopenharmony_ci      memcpy(&ish->stream_output, so_info, sizeof(*so_info));
2466bf215546Sopenharmony_ci      update_so_info(&ish->stream_output, nir->info.outputs_written);
2467bf215546Sopenharmony_ci   }
2468bf215546Sopenharmony_ci
2469bf215546Sopenharmony_ci   if (screen->disk_cache) {
2470bf215546Sopenharmony_ci      /* Serialize the NIR to a binary blob that we can hash for the disk
2471bf215546Sopenharmony_ci       * cache.  Drop unnecessary information (like variable names)
2472bf215546Sopenharmony_ci       * so the serialized NIR is smaller, and also to let us detect more
2473bf215546Sopenharmony_ci       * isomorphic shaders when hashing, increasing cache hits.
2474bf215546Sopenharmony_ci       */
2475bf215546Sopenharmony_ci      struct blob blob;
2476bf215546Sopenharmony_ci      blob_init(&blob);
2477bf215546Sopenharmony_ci      nir_serialize(&blob, nir, true);
2478bf215546Sopenharmony_ci      _mesa_sha1_compute(blob.data, blob.size, ish->nir_sha1);
2479bf215546Sopenharmony_ci      blob_finish(&blob);
2480bf215546Sopenharmony_ci   }
2481bf215546Sopenharmony_ci
2482bf215546Sopenharmony_ci   return ish;
2483bf215546Sopenharmony_ci}
2484bf215546Sopenharmony_ci
2485bf215546Sopenharmony_cistatic void *
2486bf215546Sopenharmony_ciiris_create_compute_state(struct pipe_context *ctx,
2487bf215546Sopenharmony_ci                          const struct pipe_compute_state *state)
2488bf215546Sopenharmony_ci{
2489bf215546Sopenharmony_ci   struct iris_context *ice = (void *) ctx;
2490bf215546Sopenharmony_ci   struct iris_screen *screen = (void *) ctx->screen;
2491bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = ice->shaders.uploader_unsync;
2492bf215546Sopenharmony_ci   const nir_shader_compiler_options *options =
2493bf215546Sopenharmony_ci      screen->compiler->nir_options[MESA_SHADER_COMPUTE];
2494bf215546Sopenharmony_ci
2495bf215546Sopenharmony_ci   nir_shader *nir;
2496bf215546Sopenharmony_ci   switch (state->ir_type) {
2497bf215546Sopenharmony_ci   case PIPE_SHADER_IR_NIR:
2498bf215546Sopenharmony_ci      nir = (void *)state->prog;
2499bf215546Sopenharmony_ci      break;
2500bf215546Sopenharmony_ci
2501bf215546Sopenharmony_ci   case PIPE_SHADER_IR_NIR_SERIALIZED: {
2502bf215546Sopenharmony_ci      struct blob_reader reader;
2503bf215546Sopenharmony_ci      const struct pipe_binary_program_header *hdr = state->prog;
2504bf215546Sopenharmony_ci      blob_reader_init(&reader, hdr->blob, hdr->num_bytes);
2505bf215546Sopenharmony_ci      nir = nir_deserialize(NULL, options, &reader);
2506bf215546Sopenharmony_ci      break;
2507bf215546Sopenharmony_ci   }
2508bf215546Sopenharmony_ci
2509bf215546Sopenharmony_ci   default:
2510bf215546Sopenharmony_ci      unreachable("Unsupported IR");
2511bf215546Sopenharmony_ci   }
2512bf215546Sopenharmony_ci
2513bf215546Sopenharmony_ci   /* Most of iris doesn't really care about the difference between compute
2514bf215546Sopenharmony_ci    * shaders and kernels.  We also tend to hard-code COMPUTE everywhere so
2515bf215546Sopenharmony_ci    * it's way easier if we just normalize to COMPUTE here.
2516bf215546Sopenharmony_ci    */
2517bf215546Sopenharmony_ci   assert(nir->info.stage == MESA_SHADER_COMPUTE ||
2518bf215546Sopenharmony_ci          nir->info.stage == MESA_SHADER_KERNEL);
2519bf215546Sopenharmony_ci   nir->info.stage = MESA_SHADER_COMPUTE;
2520bf215546Sopenharmony_ci
2521bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
2522bf215546Sopenharmony_ci      iris_create_uncompiled_shader(screen, nir, NULL);
2523bf215546Sopenharmony_ci   ish->kernel_input_size = state->req_input_mem;
2524bf215546Sopenharmony_ci   ish->kernel_shared_size = state->req_local_mem;
2525bf215546Sopenharmony_ci
2526bf215546Sopenharmony_ci   // XXX: disallow more than 64KB of shared variables
2527bf215546Sopenharmony_ci
2528bf215546Sopenharmony_ci   if (screen->precompile) {
2529bf215546Sopenharmony_ci      struct iris_cs_prog_key key = { KEY_INIT(base) };
2530bf215546Sopenharmony_ci
2531bf215546Sopenharmony_ci      struct iris_compiled_shader *shader =
2532bf215546Sopenharmony_ci         iris_create_shader_variant(screen, NULL, IRIS_CACHE_CS,
2533bf215546Sopenharmony_ci                                    sizeof(key), &key);
2534bf215546Sopenharmony_ci
2535bf215546Sopenharmony_ci      /* Append our new variant to the shader's variant list. */
2536bf215546Sopenharmony_ci      list_addtail(&shader->link, &ish->variants);
2537bf215546Sopenharmony_ci
2538bf215546Sopenharmony_ci      if (!iris_disk_cache_retrieve(screen, uploader, ish, shader,
2539bf215546Sopenharmony_ci                                    &key, sizeof(key))) {
2540bf215546Sopenharmony_ci         iris_compile_cs(screen, uploader, &ice->dbg, ish, shader);
2541bf215546Sopenharmony_ci      }
2542bf215546Sopenharmony_ci   }
2543bf215546Sopenharmony_ci
2544bf215546Sopenharmony_ci   return ish;
2545bf215546Sopenharmony_ci}
2546bf215546Sopenharmony_ci
2547bf215546Sopenharmony_cistatic void
2548bf215546Sopenharmony_ciiris_compile_shader(void *_job, UNUSED void *_gdata, UNUSED int thread_index)
2549bf215546Sopenharmony_ci{
2550bf215546Sopenharmony_ci   const struct iris_threaded_compile_job *job =
2551bf215546Sopenharmony_ci      (struct iris_threaded_compile_job *) _job;
2552bf215546Sopenharmony_ci
2553bf215546Sopenharmony_ci   struct iris_screen *screen = job->screen;
2554bf215546Sopenharmony_ci   struct u_upload_mgr *uploader = job->uploader;
2555bf215546Sopenharmony_ci   struct util_debug_callback *dbg = job->dbg;
2556bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = job->ish;
2557bf215546Sopenharmony_ci   struct iris_compiled_shader *shader = job->shader;
2558bf215546Sopenharmony_ci
2559bf215546Sopenharmony_ci   switch (ish->nir->info.stage) {
2560bf215546Sopenharmony_ci   case MESA_SHADER_VERTEX:
2561bf215546Sopenharmony_ci      iris_compile_vs(screen, uploader, dbg, ish, shader);
2562bf215546Sopenharmony_ci      break;
2563bf215546Sopenharmony_ci   case MESA_SHADER_TESS_CTRL:
2564bf215546Sopenharmony_ci      iris_compile_tcs(screen, NULL, uploader, dbg, ish, shader);
2565bf215546Sopenharmony_ci      break;
2566bf215546Sopenharmony_ci   case MESA_SHADER_TESS_EVAL:
2567bf215546Sopenharmony_ci      iris_compile_tes(screen, uploader, dbg, ish, shader);
2568bf215546Sopenharmony_ci      break;
2569bf215546Sopenharmony_ci   case MESA_SHADER_GEOMETRY:
2570bf215546Sopenharmony_ci      iris_compile_gs(screen, uploader, dbg, ish, shader);
2571bf215546Sopenharmony_ci      break;
2572bf215546Sopenharmony_ci   case MESA_SHADER_FRAGMENT:
2573bf215546Sopenharmony_ci      iris_compile_fs(screen, uploader, dbg, ish, shader, NULL);
2574bf215546Sopenharmony_ci      break;
2575bf215546Sopenharmony_ci
2576bf215546Sopenharmony_ci   default:
2577bf215546Sopenharmony_ci      unreachable("Invalid shader stage.");
2578bf215546Sopenharmony_ci   }
2579bf215546Sopenharmony_ci}
2580bf215546Sopenharmony_ci
2581bf215546Sopenharmony_cistatic void *
2582bf215546Sopenharmony_ciiris_create_shader_state(struct pipe_context *ctx,
2583bf215546Sopenharmony_ci                         const struct pipe_shader_state *state)
2584bf215546Sopenharmony_ci{
2585bf215546Sopenharmony_ci   struct iris_context *ice = (void *) ctx;
2586bf215546Sopenharmony_ci   struct iris_screen *screen = (void *) ctx->screen;
2587bf215546Sopenharmony_ci   struct nir_shader *nir;
2588bf215546Sopenharmony_ci
2589bf215546Sopenharmony_ci   if (state->type == PIPE_SHADER_IR_TGSI)
2590bf215546Sopenharmony_ci      nir = tgsi_to_nir(state->tokens, ctx->screen, false);
2591bf215546Sopenharmony_ci   else
2592bf215546Sopenharmony_ci      nir = state->ir.nir;
2593bf215546Sopenharmony_ci
2594bf215546Sopenharmony_ci   const struct shader_info *const info = &nir->info;
2595bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish =
2596bf215546Sopenharmony_ci      iris_create_uncompiled_shader(screen, nir, &state->stream_output);
2597bf215546Sopenharmony_ci
2598bf215546Sopenharmony_ci   union iris_any_prog_key key;
2599bf215546Sopenharmony_ci   unsigned key_size = 0;
2600bf215546Sopenharmony_ci
2601bf215546Sopenharmony_ci   memset(&key, 0, sizeof(key));
2602bf215546Sopenharmony_ci
2603bf215546Sopenharmony_ci   switch (info->stage) {
2604bf215546Sopenharmony_ci   case MESA_SHADER_VERTEX:
2605bf215546Sopenharmony_ci      /* User clip planes */
2606bf215546Sopenharmony_ci      if (info->clip_distance_array_size == 0)
2607bf215546Sopenharmony_ci         ish->nos |= (1ull << IRIS_NOS_RASTERIZER);
2608bf215546Sopenharmony_ci
2609bf215546Sopenharmony_ci      key.vs = (struct iris_vs_prog_key) { KEY_INIT(vue.base) };
2610bf215546Sopenharmony_ci      key_size = sizeof(key.vs);
2611bf215546Sopenharmony_ci      break;
2612bf215546Sopenharmony_ci
2613bf215546Sopenharmony_ci   case MESA_SHADER_TESS_CTRL: {
2614bf215546Sopenharmony_ci      key.tcs = (struct iris_tcs_prog_key) {
2615bf215546Sopenharmony_ci         KEY_INIT(vue.base),
2616bf215546Sopenharmony_ci         // XXX: make sure the linker fills this out from the TES...
2617bf215546Sopenharmony_ci         ._tes_primitive_mode =
2618bf215546Sopenharmony_ci         info->tess._primitive_mode ? info->tess._primitive_mode
2619bf215546Sopenharmony_ci                                   : TESS_PRIMITIVE_TRIANGLES,
2620bf215546Sopenharmony_ci         .outputs_written = info->outputs_written,
2621bf215546Sopenharmony_ci         .patch_outputs_written = info->patch_outputs_written,
2622bf215546Sopenharmony_ci      };
2623bf215546Sopenharmony_ci
2624bf215546Sopenharmony_ci      /* 8_PATCH mode needs the key to contain the input patch dimensionality.
2625bf215546Sopenharmony_ci       * We don't have that information, so we randomly guess that the input
2626bf215546Sopenharmony_ci       * and output patches are the same size.  This is a bad guess, but we
2627bf215546Sopenharmony_ci       * can't do much better.
2628bf215546Sopenharmony_ci       */
2629bf215546Sopenharmony_ci      if (screen->compiler->use_tcs_8_patch)
2630bf215546Sopenharmony_ci         key.tcs.input_vertices = info->tess.tcs_vertices_out;
2631bf215546Sopenharmony_ci
2632bf215546Sopenharmony_ci      key_size = sizeof(key.tcs);
2633bf215546Sopenharmony_ci      break;
2634bf215546Sopenharmony_ci   }
2635bf215546Sopenharmony_ci
2636bf215546Sopenharmony_ci   case MESA_SHADER_TESS_EVAL:
2637bf215546Sopenharmony_ci      /* User clip planes */
2638bf215546Sopenharmony_ci      if (info->clip_distance_array_size == 0)
2639bf215546Sopenharmony_ci         ish->nos |= (1ull << IRIS_NOS_RASTERIZER);
2640bf215546Sopenharmony_ci
2641bf215546Sopenharmony_ci      key.tes = (struct iris_tes_prog_key) {
2642bf215546Sopenharmony_ci         KEY_INIT(vue.base),
2643bf215546Sopenharmony_ci         // XXX: not ideal, need TCS output/TES input unification
2644bf215546Sopenharmony_ci         .inputs_read = info->inputs_read,
2645bf215546Sopenharmony_ci         .patch_inputs_read = info->patch_inputs_read,
2646bf215546Sopenharmony_ci      };
2647bf215546Sopenharmony_ci
2648bf215546Sopenharmony_ci      key_size = sizeof(key.tes);
2649bf215546Sopenharmony_ci      break;
2650bf215546Sopenharmony_ci
2651bf215546Sopenharmony_ci   case MESA_SHADER_GEOMETRY:
2652bf215546Sopenharmony_ci      /* User clip planes */
2653bf215546Sopenharmony_ci      if (info->clip_distance_array_size == 0)
2654bf215546Sopenharmony_ci         ish->nos |= (1ull << IRIS_NOS_RASTERIZER);
2655bf215546Sopenharmony_ci
2656bf215546Sopenharmony_ci      key.gs = (struct iris_gs_prog_key) { KEY_INIT(vue.base) };
2657bf215546Sopenharmony_ci      key_size = sizeof(key.gs);
2658bf215546Sopenharmony_ci      break;
2659bf215546Sopenharmony_ci
2660bf215546Sopenharmony_ci   case MESA_SHADER_FRAGMENT:
2661bf215546Sopenharmony_ci      ish->nos |= (1ull << IRIS_NOS_FRAMEBUFFER) |
2662bf215546Sopenharmony_ci                  (1ull << IRIS_NOS_DEPTH_STENCIL_ALPHA) |
2663bf215546Sopenharmony_ci                  (1ull << IRIS_NOS_RASTERIZER) |
2664bf215546Sopenharmony_ci                  (1ull << IRIS_NOS_BLEND);
2665bf215546Sopenharmony_ci
2666bf215546Sopenharmony_ci      /* The program key needs the VUE map if there are > 16 inputs */
2667bf215546Sopenharmony_ci      if (util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) > 16) {
2668bf215546Sopenharmony_ci         ish->nos |= (1ull << IRIS_NOS_LAST_VUE_MAP);
2669bf215546Sopenharmony_ci      }
2670bf215546Sopenharmony_ci
2671bf215546Sopenharmony_ci      const uint64_t color_outputs = info->outputs_written &
2672bf215546Sopenharmony_ci         ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
2673bf215546Sopenharmony_ci           BITFIELD64_BIT(FRAG_RESULT_STENCIL) |
2674bf215546Sopenharmony_ci           BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK));
2675bf215546Sopenharmony_ci
2676bf215546Sopenharmony_ci      bool can_rearrange_varyings =
2677bf215546Sopenharmony_ci         util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) <= 16;
2678bf215546Sopenharmony_ci
2679bf215546Sopenharmony_ci      const struct intel_device_info *devinfo = &screen->devinfo;
2680bf215546Sopenharmony_ci
2681bf215546Sopenharmony_ci      key.fs = (struct iris_fs_prog_key) {
2682bf215546Sopenharmony_ci         KEY_INIT(base),
2683bf215546Sopenharmony_ci         .nr_color_regions = util_bitcount(color_outputs),
2684bf215546Sopenharmony_ci         .coherent_fb_fetch = devinfo->ver >= 9,
2685bf215546Sopenharmony_ci         .input_slots_valid =
2686bf215546Sopenharmony_ci            can_rearrange_varyings ? 0 : info->inputs_read | VARYING_BIT_POS,
2687bf215546Sopenharmony_ci      };
2688bf215546Sopenharmony_ci
2689bf215546Sopenharmony_ci      key_size = sizeof(key.fs);
2690bf215546Sopenharmony_ci      break;
2691bf215546Sopenharmony_ci
2692bf215546Sopenharmony_ci   default:
2693bf215546Sopenharmony_ci      unreachable("Invalid shader stage.");
2694bf215546Sopenharmony_ci   }
2695bf215546Sopenharmony_ci
2696bf215546Sopenharmony_ci   if (screen->precompile) {
2697bf215546Sopenharmony_ci      struct u_upload_mgr *uploader = ice->shaders.uploader_unsync;
2698bf215546Sopenharmony_ci
2699bf215546Sopenharmony_ci      struct iris_compiled_shader *shader =
2700bf215546Sopenharmony_ci         iris_create_shader_variant(screen, NULL,
2701bf215546Sopenharmony_ci                                    (enum iris_program_cache_id) info->stage,
2702bf215546Sopenharmony_ci                                    key_size, &key);
2703bf215546Sopenharmony_ci
2704bf215546Sopenharmony_ci      /* Append our new variant to the shader's variant list. */
2705bf215546Sopenharmony_ci      list_addtail(&shader->link, &ish->variants);
2706bf215546Sopenharmony_ci
2707bf215546Sopenharmony_ci      if (!iris_disk_cache_retrieve(screen, uploader, ish, shader,
2708bf215546Sopenharmony_ci                                    &key, key_size)) {
2709bf215546Sopenharmony_ci         assert(!util_queue_fence_is_signalled(&shader->ready));
2710bf215546Sopenharmony_ci
2711bf215546Sopenharmony_ci         struct iris_threaded_compile_job *job = calloc(1, sizeof(*job));
2712bf215546Sopenharmony_ci
2713bf215546Sopenharmony_ci         job->screen = screen;
2714bf215546Sopenharmony_ci         job->uploader = uploader;
2715bf215546Sopenharmony_ci         job->ish = ish;
2716bf215546Sopenharmony_ci         job->shader = shader;
2717bf215546Sopenharmony_ci
2718bf215546Sopenharmony_ci         iris_schedule_compile(screen, &ish->ready, &ice->dbg, job,
2719bf215546Sopenharmony_ci                               iris_compile_shader);
2720bf215546Sopenharmony_ci      }
2721bf215546Sopenharmony_ci   }
2722bf215546Sopenharmony_ci
2723bf215546Sopenharmony_ci   return ish;
2724bf215546Sopenharmony_ci}
2725bf215546Sopenharmony_ci
2726bf215546Sopenharmony_ci/**
2727bf215546Sopenharmony_ci * Called when the refcount on the iris_uncompiled_shader reaches 0.
2728bf215546Sopenharmony_ci *
2729bf215546Sopenharmony_ci * Frees the iris_uncompiled_shader.
2730bf215546Sopenharmony_ci *
2731bf215546Sopenharmony_ci * \sa iris_delete_shader_state
2732bf215546Sopenharmony_ci */
2733bf215546Sopenharmony_civoid
2734bf215546Sopenharmony_ciiris_destroy_shader_state(struct pipe_context *ctx, void *state)
2735bf215546Sopenharmony_ci{
2736bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = state;
2737bf215546Sopenharmony_ci
2738bf215546Sopenharmony_ci   /* No need to take ish->lock; we hold the last reference to ish */
2739bf215546Sopenharmony_ci   list_for_each_entry_safe(struct iris_compiled_shader, shader,
2740bf215546Sopenharmony_ci                            &ish->variants, link) {
2741bf215546Sopenharmony_ci      list_del(&shader->link);
2742bf215546Sopenharmony_ci
2743bf215546Sopenharmony_ci      iris_shader_variant_reference(&shader, NULL);
2744bf215546Sopenharmony_ci   }
2745bf215546Sopenharmony_ci
2746bf215546Sopenharmony_ci   simple_mtx_destroy(&ish->lock);
2747bf215546Sopenharmony_ci   util_queue_fence_destroy(&ish->ready);
2748bf215546Sopenharmony_ci
2749bf215546Sopenharmony_ci   ralloc_free(ish->nir);
2750bf215546Sopenharmony_ci   free(ish);
2751bf215546Sopenharmony_ci}
2752bf215546Sopenharmony_ci
2753bf215546Sopenharmony_ci/**
2754bf215546Sopenharmony_ci * The pipe->delete_[stage]_state() driver hooks.
2755bf215546Sopenharmony_ci *
2756bf215546Sopenharmony_ci * \sa iris_destroy_shader_state
2757bf215546Sopenharmony_ci */
2758bf215546Sopenharmony_cistatic void
2759bf215546Sopenharmony_ciiris_delete_shader_state(struct pipe_context *ctx, void *state)
2760bf215546Sopenharmony_ci{
2761bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = state;
2762bf215546Sopenharmony_ci   struct iris_context *ice = (void *) ctx;
2763bf215546Sopenharmony_ci
2764bf215546Sopenharmony_ci   const gl_shader_stage stage = ish->nir->info.stage;
2765bf215546Sopenharmony_ci
2766bf215546Sopenharmony_ci   if (ice->shaders.uncompiled[stage] == ish) {
2767bf215546Sopenharmony_ci      ice->shaders.uncompiled[stage] = NULL;
2768bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
2769bf215546Sopenharmony_ci   }
2770bf215546Sopenharmony_ci
2771bf215546Sopenharmony_ci   if (pipe_reference(&ish->ref, NULL))
2772bf215546Sopenharmony_ci      iris_destroy_shader_state(ctx, state);
2773bf215546Sopenharmony_ci}
2774bf215546Sopenharmony_ci
2775bf215546Sopenharmony_ci/**
2776bf215546Sopenharmony_ci * The pipe->bind_[stage]_state() driver hook.
2777bf215546Sopenharmony_ci *
2778bf215546Sopenharmony_ci * Binds an uncompiled shader as the current one for a particular stage.
2779bf215546Sopenharmony_ci * Updates dirty tracking to account for the shader's NOS.
2780bf215546Sopenharmony_ci */
2781bf215546Sopenharmony_cistatic void
2782bf215546Sopenharmony_cibind_shader_state(struct iris_context *ice,
2783bf215546Sopenharmony_ci                  struct iris_uncompiled_shader *ish,
2784bf215546Sopenharmony_ci                  gl_shader_stage stage)
2785bf215546Sopenharmony_ci{
2786bf215546Sopenharmony_ci   uint64_t stage_dirty_bit = IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
2787bf215546Sopenharmony_ci   const uint64_t nos = ish ? ish->nos : 0;
2788bf215546Sopenharmony_ci
2789bf215546Sopenharmony_ci   const struct shader_info *old_info = iris_get_shader_info(ice, stage);
2790bf215546Sopenharmony_ci   const struct shader_info *new_info = ish ? &ish->nir->info : NULL;
2791bf215546Sopenharmony_ci
2792bf215546Sopenharmony_ci   if ((old_info ? BITSET_LAST_BIT(old_info->textures_used) : 0) !=
2793bf215546Sopenharmony_ci       (new_info ? BITSET_LAST_BIT(new_info->textures_used) : 0)) {
2794bf215546Sopenharmony_ci      ice->state.stage_dirty |= IRIS_STAGE_DIRTY_SAMPLER_STATES_VS << stage;
2795bf215546Sopenharmony_ci   }
2796bf215546Sopenharmony_ci
2797bf215546Sopenharmony_ci   ice->shaders.uncompiled[stage] = ish;
2798bf215546Sopenharmony_ci   ice->state.stage_dirty |= stage_dirty_bit;
2799bf215546Sopenharmony_ci
2800bf215546Sopenharmony_ci   /* Record that CSOs need to mark IRIS_DIRTY_UNCOMPILED_XS when they change
2801bf215546Sopenharmony_ci    * (or that they no longer need to do so).
2802bf215546Sopenharmony_ci    */
2803bf215546Sopenharmony_ci   for (int i = 0; i < IRIS_NOS_COUNT; i++) {
2804bf215546Sopenharmony_ci      if (nos & (1 << i))
2805bf215546Sopenharmony_ci         ice->state.stage_dirty_for_nos[i] |= stage_dirty_bit;
2806bf215546Sopenharmony_ci      else
2807bf215546Sopenharmony_ci         ice->state.stage_dirty_for_nos[i] &= ~stage_dirty_bit;
2808bf215546Sopenharmony_ci   }
2809bf215546Sopenharmony_ci}
2810bf215546Sopenharmony_ci
2811bf215546Sopenharmony_cistatic void
2812bf215546Sopenharmony_ciiris_bind_vs_state(struct pipe_context *ctx, void *state)
2813bf215546Sopenharmony_ci{
2814bf215546Sopenharmony_ci   struct iris_context *ice = (struct iris_context *)ctx;
2815bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = state;
2816bf215546Sopenharmony_ci
2817bf215546Sopenharmony_ci   if (ish) {
2818bf215546Sopenharmony_ci      const struct shader_info *info = &ish->nir->info;
2819bf215546Sopenharmony_ci      if (ice->state.window_space_position != info->vs.window_space_position) {
2820bf215546Sopenharmony_ci         ice->state.window_space_position = info->vs.window_space_position;
2821bf215546Sopenharmony_ci
2822bf215546Sopenharmony_ci         ice->state.dirty |= IRIS_DIRTY_CLIP |
2823bf215546Sopenharmony_ci                             IRIS_DIRTY_RASTER |
2824bf215546Sopenharmony_ci                             IRIS_DIRTY_CC_VIEWPORT;
2825bf215546Sopenharmony_ci      }
2826bf215546Sopenharmony_ci
2827bf215546Sopenharmony_ci      const bool uses_draw_params =
2828bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read, SYSTEM_VALUE_FIRST_VERTEX) ||
2829bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read, SYSTEM_VALUE_BASE_INSTANCE);
2830bf215546Sopenharmony_ci      const bool uses_derived_draw_params =
2831bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read, SYSTEM_VALUE_DRAW_ID) ||
2832bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read, SYSTEM_VALUE_IS_INDEXED_DRAW);
2833bf215546Sopenharmony_ci      const bool needs_sgvs_element = uses_draw_params ||
2834bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read, SYSTEM_VALUE_INSTANCE_ID) ||
2835bf215546Sopenharmony_ci         BITSET_TEST(info->system_values_read,
2836bf215546Sopenharmony_ci                     SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
2837bf215546Sopenharmony_ci
2838bf215546Sopenharmony_ci      if (ice->state.vs_uses_draw_params != uses_draw_params ||
2839bf215546Sopenharmony_ci          ice->state.vs_uses_derived_draw_params != uses_derived_draw_params ||
2840bf215546Sopenharmony_ci          ice->state.vs_needs_edge_flag != info->vs.needs_edge_flag ||
2841bf215546Sopenharmony_ci          ice->state.vs_needs_sgvs_element != needs_sgvs_element) {
2842bf215546Sopenharmony_ci         ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
2843bf215546Sopenharmony_ci                             IRIS_DIRTY_VERTEX_ELEMENTS;
2844bf215546Sopenharmony_ci      }
2845bf215546Sopenharmony_ci
2846bf215546Sopenharmony_ci      ice->state.vs_uses_draw_params = uses_draw_params;
2847bf215546Sopenharmony_ci      ice->state.vs_uses_derived_draw_params = uses_derived_draw_params;
2848bf215546Sopenharmony_ci      ice->state.vs_needs_sgvs_element = needs_sgvs_element;
2849bf215546Sopenharmony_ci      ice->state.vs_needs_edge_flag = info->vs.needs_edge_flag;
2850bf215546Sopenharmony_ci   }
2851bf215546Sopenharmony_ci
2852bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_VERTEX);
2853bf215546Sopenharmony_ci}
2854bf215546Sopenharmony_ci
2855bf215546Sopenharmony_cistatic void
2856bf215546Sopenharmony_ciiris_bind_tcs_state(struct pipe_context *ctx, void *state)
2857bf215546Sopenharmony_ci{
2858bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_TESS_CTRL);
2859bf215546Sopenharmony_ci}
2860bf215546Sopenharmony_ci
2861bf215546Sopenharmony_cistatic void
2862bf215546Sopenharmony_ciiris_bind_tes_state(struct pipe_context *ctx, void *state)
2863bf215546Sopenharmony_ci{
2864bf215546Sopenharmony_ci   struct iris_context *ice = (struct iris_context *)ctx;
2865bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *) ctx->screen;
2866bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
2867bf215546Sopenharmony_ci
2868bf215546Sopenharmony_ci   /* Enabling/disabling optional stages requires a URB reconfiguration. */
2869bf215546Sopenharmony_ci   if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL])
2870bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_URB | (devinfo->verx10 >= 125 ?
2871bf215546Sopenharmony_ci                                            IRIS_DIRTY_VFG : 0);
2872bf215546Sopenharmony_ci
2873bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_TESS_EVAL);
2874bf215546Sopenharmony_ci}
2875bf215546Sopenharmony_ci
2876bf215546Sopenharmony_cistatic void
2877bf215546Sopenharmony_ciiris_bind_gs_state(struct pipe_context *ctx, void *state)
2878bf215546Sopenharmony_ci{
2879bf215546Sopenharmony_ci   struct iris_context *ice = (struct iris_context *)ctx;
2880bf215546Sopenharmony_ci
2881bf215546Sopenharmony_ci   /* Enabling/disabling optional stages requires a URB reconfiguration. */
2882bf215546Sopenharmony_ci   if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_GEOMETRY])
2883bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_URB;
2884bf215546Sopenharmony_ci
2885bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_GEOMETRY);
2886bf215546Sopenharmony_ci}
2887bf215546Sopenharmony_ci
2888bf215546Sopenharmony_cistatic void
2889bf215546Sopenharmony_ciiris_bind_fs_state(struct pipe_context *ctx, void *state)
2890bf215546Sopenharmony_ci{
2891bf215546Sopenharmony_ci   struct iris_context *ice = (struct iris_context *) ctx;
2892bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *) ctx->screen;
2893bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
2894bf215546Sopenharmony_ci   struct iris_uncompiled_shader *old_ish =
2895bf215546Sopenharmony_ci      ice->shaders.uncompiled[MESA_SHADER_FRAGMENT];
2896bf215546Sopenharmony_ci   struct iris_uncompiled_shader *new_ish = state;
2897bf215546Sopenharmony_ci
2898bf215546Sopenharmony_ci   const unsigned color_bits =
2899bf215546Sopenharmony_ci      BITFIELD64_BIT(FRAG_RESULT_COLOR) |
2900bf215546Sopenharmony_ci      BITFIELD64_RANGE(FRAG_RESULT_DATA0, BRW_MAX_DRAW_BUFFERS);
2901bf215546Sopenharmony_ci
2902bf215546Sopenharmony_ci   /* Fragment shader outputs influence HasWriteableRT */
2903bf215546Sopenharmony_ci   if (!old_ish || !new_ish ||
2904bf215546Sopenharmony_ci       (old_ish->nir->info.outputs_written & color_bits) !=
2905bf215546Sopenharmony_ci       (new_ish->nir->info.outputs_written & color_bits))
2906bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
2907bf215546Sopenharmony_ci
2908bf215546Sopenharmony_ci   if (devinfo->ver == 8)
2909bf215546Sopenharmony_ci      ice->state.dirty |= IRIS_DIRTY_PMA_FIX;
2910bf215546Sopenharmony_ci
2911bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_FRAGMENT);
2912bf215546Sopenharmony_ci}
2913bf215546Sopenharmony_ci
2914bf215546Sopenharmony_cistatic void
2915bf215546Sopenharmony_ciiris_bind_cs_state(struct pipe_context *ctx, void *state)
2916bf215546Sopenharmony_ci{
2917bf215546Sopenharmony_ci   bind_shader_state((void *) ctx, state, MESA_SHADER_COMPUTE);
2918bf215546Sopenharmony_ci}
2919bf215546Sopenharmony_ci
2920bf215546Sopenharmony_cistatic char *
2921bf215546Sopenharmony_ciiris_finalize_nir(struct pipe_screen *_screen, void *nirptr)
2922bf215546Sopenharmony_ci{
2923bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *)_screen;
2924bf215546Sopenharmony_ci   struct nir_shader *nir = (struct nir_shader *) nirptr;
2925bf215546Sopenharmony_ci   const struct intel_device_info *devinfo = &screen->devinfo;
2926bf215546Sopenharmony_ci
2927bf215546Sopenharmony_ci   NIR_PASS_V(nir, iris_fix_edge_flags);
2928bf215546Sopenharmony_ci
2929bf215546Sopenharmony_ci   brw_preprocess_nir(screen->compiler, nir, NULL);
2930bf215546Sopenharmony_ci
2931bf215546Sopenharmony_ci   NIR_PASS_V(nir, brw_nir_lower_storage_image, devinfo);
2932bf215546Sopenharmony_ci   NIR_PASS_V(nir, iris_lower_storage_image_derefs);
2933bf215546Sopenharmony_ci
2934bf215546Sopenharmony_ci   nir_sweep(nir);
2935bf215546Sopenharmony_ci
2936bf215546Sopenharmony_ci   return NULL;
2937bf215546Sopenharmony_ci}
2938bf215546Sopenharmony_ci
2939bf215546Sopenharmony_cistatic void
2940bf215546Sopenharmony_ciiris_set_max_shader_compiler_threads(struct pipe_screen *pscreen,
2941bf215546Sopenharmony_ci                                     unsigned max_threads)
2942bf215546Sopenharmony_ci{
2943bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *) pscreen;
2944bf215546Sopenharmony_ci   util_queue_adjust_num_threads(&screen->shader_compiler_queue, max_threads);
2945bf215546Sopenharmony_ci}
2946bf215546Sopenharmony_ci
2947bf215546Sopenharmony_cistatic bool
2948bf215546Sopenharmony_ciiris_is_parallel_shader_compilation_finished(struct pipe_screen *pscreen,
2949bf215546Sopenharmony_ci                                             void *v_shader,
2950bf215546Sopenharmony_ci                                             enum pipe_shader_type p_stage)
2951bf215546Sopenharmony_ci{
2952bf215546Sopenharmony_ci   struct iris_screen *screen = (struct iris_screen *) pscreen;
2953bf215546Sopenharmony_ci
2954bf215546Sopenharmony_ci   /* Threaded compilation is only used for the precompile.  If precompile is
2955bf215546Sopenharmony_ci    * disabled, threaded compilation is "done."
2956bf215546Sopenharmony_ci    */
2957bf215546Sopenharmony_ci   if (!screen->precompile)
2958bf215546Sopenharmony_ci      return true;
2959bf215546Sopenharmony_ci
2960bf215546Sopenharmony_ci   struct iris_uncompiled_shader *ish = v_shader;
2961bf215546Sopenharmony_ci
2962bf215546Sopenharmony_ci   /* When precompile is enabled, the first entry is the precompile variant.
2963bf215546Sopenharmony_ci    * Check the ready fence of the precompile variant.
2964bf215546Sopenharmony_ci    */
2965bf215546Sopenharmony_ci   struct iris_compiled_shader *first =
2966bf215546Sopenharmony_ci      list_first_entry(&ish->variants, struct iris_compiled_shader, link);
2967bf215546Sopenharmony_ci
2968bf215546Sopenharmony_ci   return util_queue_fence_is_signalled(&first->ready);
2969bf215546Sopenharmony_ci}
2970bf215546Sopenharmony_ci
2971bf215546Sopenharmony_civoid
2972bf215546Sopenharmony_ciiris_init_screen_program_functions(struct pipe_screen *pscreen)
2973bf215546Sopenharmony_ci{
2974bf215546Sopenharmony_ci   pscreen->is_parallel_shader_compilation_finished =
2975bf215546Sopenharmony_ci      iris_is_parallel_shader_compilation_finished;
2976bf215546Sopenharmony_ci   pscreen->set_max_shader_compiler_threads =
2977bf215546Sopenharmony_ci      iris_set_max_shader_compiler_threads;
2978bf215546Sopenharmony_ci   pscreen->finalize_nir = iris_finalize_nir;
2979bf215546Sopenharmony_ci}
2980bf215546Sopenharmony_ci
2981bf215546Sopenharmony_civoid
2982bf215546Sopenharmony_ciiris_init_program_functions(struct pipe_context *ctx)
2983bf215546Sopenharmony_ci{
2984bf215546Sopenharmony_ci   ctx->create_vs_state  = iris_create_shader_state;
2985bf215546Sopenharmony_ci   ctx->create_tcs_state = iris_create_shader_state;
2986bf215546Sopenharmony_ci   ctx->create_tes_state = iris_create_shader_state;
2987bf215546Sopenharmony_ci   ctx->create_gs_state  = iris_create_shader_state;
2988bf215546Sopenharmony_ci   ctx->create_fs_state  = iris_create_shader_state;
2989bf215546Sopenharmony_ci   ctx->create_compute_state = iris_create_compute_state;
2990bf215546Sopenharmony_ci
2991bf215546Sopenharmony_ci   ctx->delete_vs_state  = iris_delete_shader_state;
2992bf215546Sopenharmony_ci   ctx->delete_tcs_state = iris_delete_shader_state;
2993bf215546Sopenharmony_ci   ctx->delete_tes_state = iris_delete_shader_state;
2994bf215546Sopenharmony_ci   ctx->delete_gs_state  = iris_delete_shader_state;
2995bf215546Sopenharmony_ci   ctx->delete_fs_state  = iris_delete_shader_state;
2996bf215546Sopenharmony_ci   ctx->delete_compute_state = iris_delete_shader_state;
2997bf215546Sopenharmony_ci
2998bf215546Sopenharmony_ci   ctx->bind_vs_state  = iris_bind_vs_state;
2999bf215546Sopenharmony_ci   ctx->bind_tcs_state = iris_bind_tcs_state;
3000bf215546Sopenharmony_ci   ctx->bind_tes_state = iris_bind_tes_state;
3001bf215546Sopenharmony_ci   ctx->bind_gs_state  = iris_bind_gs_state;
3002bf215546Sopenharmony_ci   ctx->bind_fs_state  = iris_bind_fs_state;
3003bf215546Sopenharmony_ci   ctx->bind_compute_state = iris_bind_cs_state;
3004bf215546Sopenharmony_ci}
3005