1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2020 Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "brw_kernel.h"
25*61046927SAndroid Build Coastguard Worker #include "brw_nir.h"
26*61046927SAndroid Build Coastguard Worker #include "elk/elk_nir_options.h"
27*61046927SAndroid Build Coastguard Worker #include "intel_nir.h"
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include "intel_nir.h"
30*61046927SAndroid Build Coastguard Worker #include "nir_clc_helpers.h"
31*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir_builder.h"
32*61046927SAndroid Build Coastguard Worker #include "compiler/spirv/nir_spirv.h"
33*61046927SAndroid Build Coastguard Worker #include "compiler/spirv/spirv_info.h"
34*61046927SAndroid Build Coastguard Worker #include "dev/intel_debug.h"
35*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
36*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker static const nir_shader *
load_clc_shader(struct brw_compiler * compiler,struct disk_cache * disk_cache,const nir_shader_compiler_options * nir_options,const struct spirv_to_nir_options * spirv_options)39*61046927SAndroid Build Coastguard Worker load_clc_shader(struct brw_compiler *compiler, struct disk_cache *disk_cache,
40*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options,
41*61046927SAndroid Build Coastguard Worker const struct spirv_to_nir_options *spirv_options)
42*61046927SAndroid Build Coastguard Worker {
43*61046927SAndroid Build Coastguard Worker if (compiler->clc_shader)
44*61046927SAndroid Build Coastguard Worker return compiler->clc_shader;
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker nir_shader *nir = nir_load_libclc_shader(64, disk_cache,
47*61046927SAndroid Build Coastguard Worker spirv_options, nir_options,
48*61046927SAndroid Build Coastguard Worker disk_cache != NULL);
49*61046927SAndroid Build Coastguard Worker if (nir == NULL)
50*61046927SAndroid Build Coastguard Worker return NULL;
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker const nir_shader *old_nir =
53*61046927SAndroid Build Coastguard Worker p_atomic_cmpxchg(&compiler->clc_shader, NULL, nir);
54*61046927SAndroid Build Coastguard Worker if (old_nir == NULL) {
55*61046927SAndroid Build Coastguard Worker /* We won the race */
56*61046927SAndroid Build Coastguard Worker ralloc_steal(compiler, nir);
57*61046927SAndroid Build Coastguard Worker return nir;
58*61046927SAndroid Build Coastguard Worker } else {
59*61046927SAndroid Build Coastguard Worker /* Someone else built the shader first */
60*61046927SAndroid Build Coastguard Worker ralloc_free(nir);
61*61046927SAndroid Build Coastguard Worker return old_nir;
62*61046927SAndroid Build Coastguard Worker }
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker static nir_builder
builder_init_new_impl(nir_function * func)66*61046927SAndroid Build Coastguard Worker builder_init_new_impl(nir_function *func)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_function_impl_create(func);
69*61046927SAndroid Build Coastguard Worker return nir_builder_at(nir_before_impl(impl));
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker static void
implement_atomic_builtin(nir_function * func,nir_atomic_op atomic_op,enum glsl_base_type data_base_type,nir_variable_mode mode)73*61046927SAndroid Build Coastguard Worker implement_atomic_builtin(nir_function *func, nir_atomic_op atomic_op,
74*61046927SAndroid Build Coastguard Worker enum glsl_base_type data_base_type,
75*61046927SAndroid Build Coastguard Worker nir_variable_mode mode)
76*61046927SAndroid Build Coastguard Worker {
77*61046927SAndroid Build Coastguard Worker nir_builder b = builder_init_new_impl(func);
78*61046927SAndroid Build Coastguard Worker const struct glsl_type *data_type = glsl_scalar_type(data_base_type);
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker unsigned p = 0;
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker nir_deref_instr *ret = NULL;
83*61046927SAndroid Build Coastguard Worker ret = nir_build_deref_cast(&b, nir_load_param(&b, p++),
84*61046927SAndroid Build Coastguard Worker nir_var_function_temp, data_type, 0);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker nir_intrinsic_op op = nir_intrinsic_deref_atomic;
87*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *atomic = nir_intrinsic_instr_create(b.shader, op);
88*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_atomic_op(atomic, atomic_op);
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < nir_intrinsic_infos[op].num_srcs; i++) {
91*61046927SAndroid Build Coastguard Worker nir_def *src = nir_load_param(&b, p++);
92*61046927SAndroid Build Coastguard Worker if (i == 0) {
93*61046927SAndroid Build Coastguard Worker /* The first source is our deref */
94*61046927SAndroid Build Coastguard Worker assert(nir_intrinsic_infos[op].src_components[i] == -1);
95*61046927SAndroid Build Coastguard Worker src = &nir_build_deref_cast(&b, src, mode, data_type, 0)->def;
96*61046927SAndroid Build Coastguard Worker }
97*61046927SAndroid Build Coastguard Worker atomic->src[i] = nir_src_for_ssa(src);
98*61046927SAndroid Build Coastguard Worker }
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker nir_def_init_for_type(&atomic->instr, &atomic->def, data_type);
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &atomic->instr);
103*61046927SAndroid Build Coastguard Worker nir_store_deref(&b, ret, &atomic->def, ~0);
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker static void
implement_sub_group_ballot_builtin(nir_function * func)107*61046927SAndroid Build Coastguard Worker implement_sub_group_ballot_builtin(nir_function *func)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker nir_builder b = builder_init_new_impl(func);
110*61046927SAndroid Build Coastguard Worker nir_deref_instr *ret =
111*61046927SAndroid Build Coastguard Worker nir_build_deref_cast(&b, nir_load_param(&b, 0),
112*61046927SAndroid Build Coastguard Worker nir_var_function_temp, glsl_uint_type(), 0);
113*61046927SAndroid Build Coastguard Worker nir_def *cond = nir_load_param(&b, 1);
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *ballot =
116*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_create(b.shader, nir_intrinsic_ballot);
117*61046927SAndroid Build Coastguard Worker ballot->src[0] = nir_src_for_ssa(cond);
118*61046927SAndroid Build Coastguard Worker ballot->num_components = 1;
119*61046927SAndroid Build Coastguard Worker nir_def_init(&ballot->instr, &ballot->def, 1, 32);
120*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &ballot->instr);
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker nir_store_deref(&b, ret, &ballot->def, ~0);
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker static bool
implement_intel_builtins(nir_shader * nir)126*61046927SAndroid Build Coastguard Worker implement_intel_builtins(nir_shader *nir)
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker bool progress = false;
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker nir_foreach_function(func, nir) {
131*61046927SAndroid Build Coastguard Worker if (strcmp(func->name, "_Z10atomic_minPU3AS1Vff") == 0) {
132*61046927SAndroid Build Coastguard Worker /* float atom_min(__global float volatile *p, float val) */
133*61046927SAndroid Build Coastguard Worker implement_atomic_builtin(func, nir_atomic_op_fmin,
134*61046927SAndroid Build Coastguard Worker GLSL_TYPE_FLOAT, nir_var_mem_global);
135*61046927SAndroid Build Coastguard Worker progress = true;
136*61046927SAndroid Build Coastguard Worker } else if (strcmp(func->name, "_Z10atomic_maxPU3AS1Vff") == 0) {
137*61046927SAndroid Build Coastguard Worker /* float atom_max(__global float volatile *p, float val) */
138*61046927SAndroid Build Coastguard Worker implement_atomic_builtin(func, nir_atomic_op_fmax,
139*61046927SAndroid Build Coastguard Worker GLSL_TYPE_FLOAT, nir_var_mem_global);
140*61046927SAndroid Build Coastguard Worker progress = true;
141*61046927SAndroid Build Coastguard Worker } else if (strcmp(func->name, "_Z10atomic_minPU3AS3Vff") == 0) {
142*61046927SAndroid Build Coastguard Worker /* float atomic_min(__shared float volatile *, float) */
143*61046927SAndroid Build Coastguard Worker implement_atomic_builtin(func, nir_atomic_op_fmin,
144*61046927SAndroid Build Coastguard Worker GLSL_TYPE_FLOAT, nir_var_mem_shared);
145*61046927SAndroid Build Coastguard Worker progress = true;
146*61046927SAndroid Build Coastguard Worker } else if (strcmp(func->name, "_Z10atomic_maxPU3AS3Vff") == 0) {
147*61046927SAndroid Build Coastguard Worker /* float atomic_max(__shared float volatile *, float) */
148*61046927SAndroid Build Coastguard Worker implement_atomic_builtin(func, nir_atomic_op_fmax,
149*61046927SAndroid Build Coastguard Worker GLSL_TYPE_FLOAT, nir_var_mem_shared);
150*61046927SAndroid Build Coastguard Worker progress = true;
151*61046927SAndroid Build Coastguard Worker } else if (strcmp(func->name, "intel_sub_group_ballot") == 0) {
152*61046927SAndroid Build Coastguard Worker implement_sub_group_ballot_builtin(func);
153*61046927SAndroid Build Coastguard Worker progress = true;
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker nir_shader_preserve_all_metadata(nir);
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker return progress;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker static bool
lower_kernel_intrinsics(nir_shader * nir)163*61046927SAndroid Build Coastguard Worker lower_kernel_intrinsics(nir_shader *nir)
164*61046927SAndroid Build Coastguard Worker {
165*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_shader_get_entrypoint(nir);
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker bool progress = false;
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker unsigned kernel_sysvals_start = 0;
170*61046927SAndroid Build Coastguard Worker unsigned kernel_arg_start = sizeof(struct brw_kernel_sysvals);
171*61046927SAndroid Build Coastguard Worker nir->num_uniforms += kernel_arg_start;
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker nir_builder b = nir_builder_create(impl);
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, impl) {
176*61046927SAndroid Build Coastguard Worker nir_foreach_instr_safe(instr, block) {
177*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_intrinsic)
178*61046927SAndroid Build Coastguard Worker continue;
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
181*61046927SAndroid Build Coastguard Worker switch (intrin->intrinsic) {
182*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_kernel_input: {
183*61046927SAndroid Build Coastguard Worker b.cursor = nir_instr_remove(&intrin->instr);
184*61046927SAndroid Build Coastguard Worker
185*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *load =
186*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_create(nir, nir_intrinsic_load_uniform);
187*61046927SAndroid Build Coastguard Worker load->num_components = intrin->num_components;
188*61046927SAndroid Build Coastguard Worker load->src[0] = nir_src_for_ssa(nir_u2u32(&b, intrin->src[0].ssa));
189*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_base(load, kernel_arg_start);
190*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_range(load, nir->num_uniforms);
191*61046927SAndroid Build Coastguard Worker nir_def_init(&load->instr, &load->def,
192*61046927SAndroid Build Coastguard Worker intrin->def.num_components,
193*61046927SAndroid Build Coastguard Worker intrin->def.bit_size);
194*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &load->instr);
195*61046927SAndroid Build Coastguard Worker
196*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses(&intrin->def, &load->def);
197*61046927SAndroid Build Coastguard Worker progress = true;
198*61046927SAndroid Build Coastguard Worker break;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_constant_base_ptr: {
202*61046927SAndroid Build Coastguard Worker b.cursor = nir_instr_remove(&intrin->instr);
203*61046927SAndroid Build Coastguard Worker nir_def *const_data_base_addr = nir_pack_64_2x32_split(&b,
204*61046927SAndroid Build Coastguard Worker nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW),
205*61046927SAndroid Build Coastguard Worker nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH));
206*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses(&intrin->def, const_data_base_addr);
207*61046927SAndroid Build Coastguard Worker progress = true;
208*61046927SAndroid Build Coastguard Worker break;
209*61046927SAndroid Build Coastguard Worker }
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_num_workgroups: {
212*61046927SAndroid Build Coastguard Worker b.cursor = nir_instr_remove(&intrin->instr);
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *load =
215*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr_create(nir, nir_intrinsic_load_uniform);
216*61046927SAndroid Build Coastguard Worker load->num_components = 3;
217*61046927SAndroid Build Coastguard Worker load->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
218*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_base(load, kernel_sysvals_start +
219*61046927SAndroid Build Coastguard Worker offsetof(struct brw_kernel_sysvals, num_work_groups));
220*61046927SAndroid Build Coastguard Worker nir_intrinsic_set_range(load, 3 * 4);
221*61046927SAndroid Build Coastguard Worker nir_def_init(&load->instr, &load->def, 3, 32);
222*61046927SAndroid Build Coastguard Worker nir_builder_instr_insert(&b, &load->instr);
223*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses(&intrin->def, &load->def);
224*61046927SAndroid Build Coastguard Worker progress = true;
225*61046927SAndroid Build Coastguard Worker break;
226*61046927SAndroid Build Coastguard Worker }
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker default:
229*61046927SAndroid Build Coastguard Worker break;
230*61046927SAndroid Build Coastguard Worker }
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker if (progress) {
235*61046927SAndroid Build Coastguard Worker nir_metadata_preserve(impl, nir_metadata_control_flow);
236*61046927SAndroid Build Coastguard Worker } else {
237*61046927SAndroid Build Coastguard Worker nir_metadata_preserve(impl, nir_metadata_all);
238*61046927SAndroid Build Coastguard Worker }
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker return progress;
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker static const struct spirv_capabilities spirv_caps = {
244*61046927SAndroid Build Coastguard Worker .Addresses = true,
245*61046927SAndroid Build Coastguard Worker .Float16 = true,
246*61046927SAndroid Build Coastguard Worker .Float64 = true,
247*61046927SAndroid Build Coastguard Worker .Groups = true,
248*61046927SAndroid Build Coastguard Worker .StorageImageWriteWithoutFormat = true,
249*61046927SAndroid Build Coastguard Worker .Int8 = true,
250*61046927SAndroid Build Coastguard Worker .Int16 = true,
251*61046927SAndroid Build Coastguard Worker .Int64 = true,
252*61046927SAndroid Build Coastguard Worker .Int64Atomics = true,
253*61046927SAndroid Build Coastguard Worker .Kernel = true,
254*61046927SAndroid Build Coastguard Worker .Linkage = true, /* We receive linked kernel from clc */
255*61046927SAndroid Build Coastguard Worker .DenormFlushToZero = true,
256*61046927SAndroid Build Coastguard Worker .DenormPreserve = true,
257*61046927SAndroid Build Coastguard Worker .SignedZeroInfNanPreserve = true,
258*61046927SAndroid Build Coastguard Worker .RoundingModeRTE = true,
259*61046927SAndroid Build Coastguard Worker .RoundingModeRTZ = true,
260*61046927SAndroid Build Coastguard Worker .GenericPointer = true,
261*61046927SAndroid Build Coastguard Worker .GroupNonUniform = true,
262*61046927SAndroid Build Coastguard Worker .GroupNonUniformArithmetic = true,
263*61046927SAndroid Build Coastguard Worker .GroupNonUniformClustered = true,
264*61046927SAndroid Build Coastguard Worker .GroupNonUniformBallot = true,
265*61046927SAndroid Build Coastguard Worker .GroupNonUniformQuad = true,
266*61046927SAndroid Build Coastguard Worker .GroupNonUniformShuffle = true,
267*61046927SAndroid Build Coastguard Worker .GroupNonUniformVote = true,
268*61046927SAndroid Build Coastguard Worker .SubgroupDispatch = true,
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker .SubgroupShuffleINTEL = true,
271*61046927SAndroid Build Coastguard Worker .SubgroupBufferBlockIOINTEL = true,
272*61046927SAndroid Build Coastguard Worker };
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker bool
brw_kernel_from_spirv(struct brw_compiler * compiler,struct disk_cache * disk_cache,struct brw_kernel * kernel,void * log_data,void * mem_ctx,const uint32_t * spirv,size_t spirv_size,const char * entrypoint_name,char ** error_str)275*61046927SAndroid Build Coastguard Worker brw_kernel_from_spirv(struct brw_compiler *compiler,
276*61046927SAndroid Build Coastguard Worker struct disk_cache *disk_cache,
277*61046927SAndroid Build Coastguard Worker struct brw_kernel *kernel,
278*61046927SAndroid Build Coastguard Worker void *log_data, void *mem_ctx,
279*61046927SAndroid Build Coastguard Worker const uint32_t *spirv, size_t spirv_size,
280*61046927SAndroid Build Coastguard Worker const char *entrypoint_name,
281*61046927SAndroid Build Coastguard Worker char **error_str)
282*61046927SAndroid Build Coastguard Worker {
283*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = compiler->devinfo;
284*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
285*61046927SAndroid Build Coastguard Worker compiler->nir_options[MESA_SHADER_KERNEL];
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker struct spirv_to_nir_options spirv_options = {
288*61046927SAndroid Build Coastguard Worker .environment = NIR_SPIRV_OPENCL,
289*61046927SAndroid Build Coastguard Worker .capabilities = &spirv_caps,
290*61046927SAndroid Build Coastguard Worker .printf = true,
291*61046927SAndroid Build Coastguard Worker .shared_addr_format = nir_address_format_62bit_generic,
292*61046927SAndroid Build Coastguard Worker .global_addr_format = nir_address_format_62bit_generic,
293*61046927SAndroid Build Coastguard Worker .temp_addr_format = nir_address_format_62bit_generic,
294*61046927SAndroid Build Coastguard Worker .constant_addr_format = nir_address_format_64bit_global,
295*61046927SAndroid Build Coastguard Worker };
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker spirv_options.clc_shader = load_clc_shader(compiler, disk_cache,
298*61046927SAndroid Build Coastguard Worker nir_options, &spirv_options);
299*61046927SAndroid Build Coastguard Worker if (spirv_options.clc_shader == NULL) {
300*61046927SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: libclc shader missing."
301*61046927SAndroid Build Coastguard Worker " Consider installing the libclc package\n");
302*61046927SAndroid Build Coastguard Worker abort();
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker assert(spirv_size % 4 == 0);
306*61046927SAndroid Build Coastguard Worker nir_shader *nir =
307*61046927SAndroid Build Coastguard Worker spirv_to_nir(spirv, spirv_size / 4, NULL, 0, MESA_SHADER_KERNEL,
308*61046927SAndroid Build Coastguard Worker entrypoint_name, &spirv_options, nir_options);
309*61046927SAndroid Build Coastguard Worker nir_validate_shader(nir, "after spirv_to_nir");
310*61046927SAndroid Build Coastguard Worker nir_validate_ssa_dominance(nir, "after spirv_to_nir");
311*61046927SAndroid Build Coastguard Worker ralloc_steal(mem_ctx, nir);
312*61046927SAndroid Build Coastguard Worker nir->info.name = ralloc_strdup(nir, entrypoint_name);
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(DEBUG_CS)) {
315*61046927SAndroid Build Coastguard Worker /* Re-index SSA defs so we print more sensible numbers. */
316*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, nir) {
317*61046927SAndroid Build Coastguard Worker nir_index_ssa_defs(impl);
318*61046927SAndroid Build Coastguard Worker }
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR (from SPIR-V) for kernel\n");
321*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker nir_lower_printf_options printf_opts = {
325*61046927SAndroid Build Coastguard Worker .ptr_bit_size = 64,
326*61046927SAndroid Build Coastguard Worker .use_printf_base_identifier = true,
327*61046927SAndroid Build Coastguard Worker };
328*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_printf, &printf_opts);
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, implement_intel_builtins);
331*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_link_shader_functions, spirv_options.clc_shader);
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker /* We have to lower away local constant initializers right before we
334*61046927SAndroid Build Coastguard Worker * inline functions. That way they get properly initialized at the top
335*61046927SAndroid Build Coastguard Worker * of the function and not at the top of its caller.
336*61046927SAndroid Build Coastguard Worker */
337*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
338*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_returns);
339*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_inline_functions);
340*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_copy_prop);
341*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_opt_deref);
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker /* Pick off the single entrypoint that we want */
344*61046927SAndroid Build Coastguard Worker nir_remove_non_entrypoints(nir);
345*61046927SAndroid Build Coastguard Worker
346*61046927SAndroid Build Coastguard Worker /* Now that we've deleted all but the main function, we can go ahead and
347*61046927SAndroid Build Coastguard Worker * lower the rest of the constant initializers. We do this here so that
348*61046927SAndroid Build Coastguard Worker * nir_remove_dead_variables and split_per_member_structs below see the
349*61046927SAndroid Build Coastguard Worker * corresponding stores.
350*61046927SAndroid Build Coastguard Worker */
351*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker /* LLVM loves take advantage of the fact that vec3s in OpenCL are 16B
354*61046927SAndroid Build Coastguard Worker * aligned and so it can just read/write them as vec4s. This results in a
355*61046927SAndroid Build Coastguard Worker * LOT of vec4->vec3 casts on loads and stores. One solution to this
356*61046927SAndroid Build Coastguard Worker * problem is to get rid of all vec3 variables.
357*61046927SAndroid Build Coastguard Worker */
358*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vec3_to_vec4,
359*61046927SAndroid Build Coastguard Worker nir_var_shader_temp | nir_var_function_temp |
360*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global|
361*61046927SAndroid Build Coastguard Worker nir_var_mem_constant);
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker /* We assign explicit types early so that the optimizer can take advantage
364*61046927SAndroid Build Coastguard Worker * of that information and hopefully get rid of some of our memcpys.
365*61046927SAndroid Build Coastguard Worker */
366*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
367*61046927SAndroid Build Coastguard Worker nir_var_uniform |
368*61046927SAndroid Build Coastguard Worker nir_var_shader_temp | nir_var_function_temp |
369*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global,
370*61046927SAndroid Build Coastguard Worker glsl_get_cl_type_size_align);
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker struct brw_nir_compiler_opts opts = {};
373*61046927SAndroid Build Coastguard Worker brw_preprocess_nir(compiler, nir, &opts);
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker int max_arg_idx = -1;
376*61046927SAndroid Build Coastguard Worker nir_foreach_uniform_variable(var, nir) {
377*61046927SAndroid Build Coastguard Worker assert(var->data.location < 256);
378*61046927SAndroid Build Coastguard Worker max_arg_idx = MAX2(max_arg_idx, var->data.location);
379*61046927SAndroid Build Coastguard Worker }
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker kernel->args_size = nir->num_uniforms;
382*61046927SAndroid Build Coastguard Worker kernel->arg_count = max_arg_idx + 1;
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker /* No bindings */
385*61046927SAndroid Build Coastguard Worker struct brw_kernel_arg_desc *args =
386*61046927SAndroid Build Coastguard Worker rzalloc_array(mem_ctx, struct brw_kernel_arg_desc, kernel->arg_count);
387*61046927SAndroid Build Coastguard Worker kernel->args = args;
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker nir_foreach_uniform_variable(var, nir) {
390*61046927SAndroid Build Coastguard Worker struct brw_kernel_arg_desc arg_desc = {
391*61046927SAndroid Build Coastguard Worker .offset = var->data.driver_location,
392*61046927SAndroid Build Coastguard Worker .size = glsl_get_explicit_size(var->type, false),
393*61046927SAndroid Build Coastguard Worker };
394*61046927SAndroid Build Coastguard Worker assert(arg_desc.offset + arg_desc.size <= nir->num_uniforms);
395*61046927SAndroid Build Coastguard Worker
396*61046927SAndroid Build Coastguard Worker assert(var->data.location >= 0);
397*61046927SAndroid Build Coastguard Worker args[var->data.location] = arg_desc;
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_all, NULL);
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker /* Lower again, this time after dead-variables to get more compact variable
403*61046927SAndroid Build Coastguard Worker * layouts.
404*61046927SAndroid Build Coastguard Worker */
405*61046927SAndroid Build Coastguard Worker nir->global_mem_size = 0;
406*61046927SAndroid Build Coastguard Worker nir->scratch_size = 0;
407*61046927SAndroid Build Coastguard Worker nir->info.shared_size = 0;
408*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
409*61046927SAndroid Build Coastguard Worker nir_var_shader_temp | nir_var_function_temp |
410*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global | nir_var_mem_constant,
411*61046927SAndroid Build Coastguard Worker glsl_get_cl_type_size_align);
412*61046927SAndroid Build Coastguard Worker if (nir->constant_data_size > 0) {
413*61046927SAndroid Build Coastguard Worker assert(nir->constant_data == NULL);
414*61046927SAndroid Build Coastguard Worker nir->constant_data = rzalloc_size(nir, nir->constant_data_size);
415*61046927SAndroid Build Coastguard Worker nir_gather_explicit_io_initializers(nir, nir->constant_data,
416*61046927SAndroid Build Coastguard Worker nir->constant_data_size,
417*61046927SAndroid Build Coastguard Worker nir_var_mem_constant);
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(DEBUG_CS)) {
421*61046927SAndroid Build Coastguard Worker /* Re-index SSA defs so we print more sensible numbers. */
422*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, nir) {
423*61046927SAndroid Build Coastguard Worker nir_index_ssa_defs(impl);
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR (before I/O lowering) for kernel\n");
427*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
428*61046927SAndroid Build Coastguard Worker }
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_memcpy);
431*61046927SAndroid Build Coastguard Worker
432*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_constant,
433*61046927SAndroid Build Coastguard Worker nir_address_format_64bit_global);
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_uniform,
436*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_offset_as_64bit);
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io,
439*61046927SAndroid Build Coastguard Worker nir_var_shader_temp | nir_var_function_temp |
440*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global,
441*61046927SAndroid Build Coastguard Worker nir_address_format_62bit_generic);
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_convert_alu_types, NULL);
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, brw_nir_lower_cs_intrinsics, devinfo, NULL);
446*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, lower_kernel_intrinsics);
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker struct brw_cs_prog_key key = { };
449*61046927SAndroid Build Coastguard Worker
450*61046927SAndroid Build Coastguard Worker memset(&kernel->prog_data, 0, sizeof(kernel->prog_data));
451*61046927SAndroid Build Coastguard Worker kernel->prog_data.base.nr_params = DIV_ROUND_UP(nir->num_uniforms, 4);
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker struct brw_compile_cs_params params = {
454*61046927SAndroid Build Coastguard Worker .base = {
455*61046927SAndroid Build Coastguard Worker .nir = nir,
456*61046927SAndroid Build Coastguard Worker .stats = kernel->stats,
457*61046927SAndroid Build Coastguard Worker .log_data = log_data,
458*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
459*61046927SAndroid Build Coastguard Worker },
460*61046927SAndroid Build Coastguard Worker .key = &key,
461*61046927SAndroid Build Coastguard Worker .prog_data = &kernel->prog_data,
462*61046927SAndroid Build Coastguard Worker };
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker kernel->code = brw_compile_cs(compiler, ¶ms);
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker if (error_str)
467*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
468*61046927SAndroid Build Coastguard Worker
469*61046927SAndroid Build Coastguard Worker return kernel->code != NULL;
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker static nir_def *
rebuild_value_from_store(struct util_dynarray * stores,nir_def * value,unsigned read_offset)473*61046927SAndroid Build Coastguard Worker rebuild_value_from_store(struct util_dynarray *stores,
474*61046927SAndroid Build Coastguard Worker nir_def *value, unsigned read_offset)
475*61046927SAndroid Build Coastguard Worker {
476*61046927SAndroid Build Coastguard Worker unsigned read_size = value->num_components * value->bit_size / 8;
477*61046927SAndroid Build Coastguard Worker
478*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(stores, nir_intrinsic_instr *, _store) {
479*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *store = *_store;
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker unsigned write_offset = nir_src_as_uint(store->src[1]);
482*61046927SAndroid Build Coastguard Worker unsigned write_size = nir_src_num_components(store->src[0]) *
483*61046927SAndroid Build Coastguard Worker nir_src_bit_size(store->src[0]) / 8;
484*61046927SAndroid Build Coastguard Worker if (write_offset <= read_offset &&
485*61046927SAndroid Build Coastguard Worker (write_offset + write_size) >= (read_offset + read_size)) {
486*61046927SAndroid Build Coastguard Worker assert(nir_block_dominates(store->instr.block, value->parent_instr->block));
487*61046927SAndroid Build Coastguard Worker assert(write_size == read_size);
488*61046927SAndroid Build Coastguard Worker return store->src[0].ssa;
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker unreachable("Matching scratch store not found");
492*61046927SAndroid Build Coastguard Worker }
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker /**
495*61046927SAndroid Build Coastguard Worker * Remove temporary variables stored to scratch to be then reloaded
496*61046927SAndroid Build Coastguard Worker * immediately. Remap the load to the store SSA value.
497*61046927SAndroid Build Coastguard Worker *
498*61046927SAndroid Build Coastguard Worker * This workaround is only meant to be applied to shaders in src/intel/shaders
499*61046927SAndroid Build Coastguard Worker * were we know there should be no issue. More complex cases might not work
500*61046927SAndroid Build Coastguard Worker * with this approach.
501*61046927SAndroid Build Coastguard Worker */
502*61046927SAndroid Build Coastguard Worker static bool
nir_remove_llvm17_scratch(nir_shader * nir)503*61046927SAndroid Build Coastguard Worker nir_remove_llvm17_scratch(nir_shader *nir)
504*61046927SAndroid Build Coastguard Worker {
505*61046927SAndroid Build Coastguard Worker struct util_dynarray scratch_stores;
506*61046927SAndroid Build Coastguard Worker void *mem_ctx = ralloc_context(NULL);
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker util_dynarray_init(&scratch_stores, mem_ctx);
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(func, nir) {
511*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, func) {
512*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block) {
513*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_intrinsic)
514*61046927SAndroid Build Coastguard Worker continue;
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_store_scratch)
519*61046927SAndroid Build Coastguard Worker continue;
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker nir_const_value *offset = nir_src_as_const_value(intrin->src[1]);
522*61046927SAndroid Build Coastguard Worker if (offset != NULL) {
523*61046927SAndroid Build Coastguard Worker util_dynarray_append(&scratch_stores, nir_intrinsic_instr *, intrin);
524*61046927SAndroid Build Coastguard Worker }
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker }
528*61046927SAndroid Build Coastguard Worker
529*61046927SAndroid Build Coastguard Worker bool progress = false;
530*61046927SAndroid Build Coastguard Worker if (util_dynarray_num_elements(&scratch_stores, nir_intrinsic_instr *) > 0) {
531*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(func, nir) {
532*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, func) {
533*61046927SAndroid Build Coastguard Worker nir_foreach_instr_safe(instr, block) {
534*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_intrinsic)
535*61046927SAndroid Build Coastguard Worker continue;
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_load_scratch)
540*61046927SAndroid Build Coastguard Worker continue;
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker nir_const_value *offset = nir_src_as_const_value(intrin->src[0]);
543*61046927SAndroid Build Coastguard Worker if (offset == NULL)
544*61046927SAndroid Build Coastguard Worker continue;
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker nir_def_replace(&intrin->def,
547*61046927SAndroid Build Coastguard Worker rebuild_value_from_store(&scratch_stores, &intrin->def, nir_src_as_uint(intrin->src[0])));
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker progress = true;
550*61046927SAndroid Build Coastguard Worker }
551*61046927SAndroid Build Coastguard Worker }
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&scratch_stores, nir_intrinsic_instr *, _store) {
556*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *store = *_store;
557*61046927SAndroid Build Coastguard Worker nir_instr_remove(&store->instr);
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker /* Quick sanity check */
561*61046927SAndroid Build Coastguard Worker assert(util_dynarray_num_elements(&scratch_stores, nir_intrinsic_instr *) == 0 ||
562*61046927SAndroid Build Coastguard Worker progress);
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker return progress;
567*61046927SAndroid Build Coastguard Worker }
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker static void
cleanup_llvm17_scratch(nir_shader * nir)570*61046927SAndroid Build Coastguard Worker cleanup_llvm17_scratch(nir_shader *nir)
571*61046927SAndroid Build Coastguard Worker {
572*61046927SAndroid Build Coastguard Worker {
573*61046927SAndroid Build Coastguard Worker bool progress;
574*61046927SAndroid Build Coastguard Worker do {
575*61046927SAndroid Build Coastguard Worker progress = false;
576*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
577*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
578*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
579*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_cse);
580*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_algebraic);
581*61046927SAndroid Build Coastguard Worker } while (progress);
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker nir_remove_llvm17_scratch(nir);
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker {
587*61046927SAndroid Build Coastguard Worker bool progress;
588*61046927SAndroid Build Coastguard Worker do {
589*61046927SAndroid Build Coastguard Worker progress = false;
590*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
591*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
592*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
593*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_cse);
594*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_algebraic);
595*61046927SAndroid Build Coastguard Worker } while (progress);
596*61046927SAndroid Build Coastguard Worker }
597*61046927SAndroid Build Coastguard Worker }
598*61046927SAndroid Build Coastguard Worker
599*61046927SAndroid Build Coastguard Worker nir_shader *
brw_nir_from_spirv(void * mem_ctx,unsigned gfx_version,const uint32_t * spirv,size_t spirv_size,bool llvm17_wa)600*61046927SAndroid Build Coastguard Worker brw_nir_from_spirv(void *mem_ctx, unsigned gfx_version, const uint32_t *spirv,
601*61046927SAndroid Build Coastguard Worker size_t spirv_size, bool llvm17_wa)
602*61046927SAndroid Build Coastguard Worker {
603*61046927SAndroid Build Coastguard Worker struct spirv_to_nir_options spirv_options = {
604*61046927SAndroid Build Coastguard Worker .environment = NIR_SPIRV_OPENCL,
605*61046927SAndroid Build Coastguard Worker .capabilities = &spirv_caps,
606*61046927SAndroid Build Coastguard Worker .printf = true,
607*61046927SAndroid Build Coastguard Worker .shared_addr_format = nir_address_format_62bit_generic,
608*61046927SAndroid Build Coastguard Worker .global_addr_format = nir_address_format_62bit_generic,
609*61046927SAndroid Build Coastguard Worker .temp_addr_format = nir_address_format_62bit_generic,
610*61046927SAndroid Build Coastguard Worker .constant_addr_format = nir_address_format_64bit_global,
611*61046927SAndroid Build Coastguard Worker .create_library = true,
612*61046927SAndroid Build Coastguard Worker };
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker assert(spirv_size % 4 == 0);
615*61046927SAndroid Build Coastguard Worker
616*61046927SAndroid Build Coastguard Worker assert(gfx_version);
617*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
618*61046927SAndroid Build Coastguard Worker gfx_version >= 9 ? &brw_scalar_nir_options
619*61046927SAndroid Build Coastguard Worker : &elk_scalar_nir_options;
620*61046927SAndroid Build Coastguard Worker
621*61046927SAndroid Build Coastguard Worker nir_shader *nir =
622*61046927SAndroid Build Coastguard Worker spirv_to_nir(spirv, spirv_size / 4, NULL, 0, MESA_SHADER_KERNEL,
623*61046927SAndroid Build Coastguard Worker "library", &spirv_options, nir_options);
624*61046927SAndroid Build Coastguard Worker nir_validate_shader(nir, "after spirv_to_nir");
625*61046927SAndroid Build Coastguard Worker nir_validate_ssa_dominance(nir, "after spirv_to_nir");
626*61046927SAndroid Build Coastguard Worker ralloc_steal(mem_ctx, nir);
627*61046927SAndroid Build Coastguard Worker nir->info.name = ralloc_strdup(nir, "library");
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(DEBUG_CS)) {
630*61046927SAndroid Build Coastguard Worker /* Re-index SSA defs so we print more sensible numbers. */
631*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, nir) {
632*61046927SAndroid Build Coastguard Worker nir_index_ssa_defs(impl);
633*61046927SAndroid Build Coastguard Worker }
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR (from SPIR-V) for kernel\n");
636*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
637*61046927SAndroid Build Coastguard Worker }
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker nir_lower_printf_options printf_opts = {
640*61046927SAndroid Build Coastguard Worker .ptr_bit_size = 64,
641*61046927SAndroid Build Coastguard Worker .use_printf_base_identifier = true,
642*61046927SAndroid Build Coastguard Worker };
643*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_printf, &printf_opts);
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, implement_intel_builtins);
646*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_link_shader_functions, spirv_options.clc_shader);
647*61046927SAndroid Build Coastguard Worker
648*61046927SAndroid Build Coastguard Worker /* We have to lower away local constant initializers right before we
649*61046927SAndroid Build Coastguard Worker * inline functions. That way they get properly initialized at the top
650*61046927SAndroid Build Coastguard Worker * of the function and not at the top of its caller.
651*61046927SAndroid Build Coastguard Worker */
652*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_variable_initializers, ~(nir_var_shader_temp |
653*61046927SAndroid Build Coastguard Worker nir_var_function_temp));
654*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_uniform | nir_var_mem_ubo |
655*61046927SAndroid Build Coastguard Worker nir_var_mem_constant | nir_var_function_temp | nir_var_image, NULL);
656*61046927SAndroid Build Coastguard Worker {
657*61046927SAndroid Build Coastguard Worker bool progress;
658*61046927SAndroid Build Coastguard Worker do
659*61046927SAndroid Build Coastguard Worker {
660*61046927SAndroid Build Coastguard Worker progress = false;
661*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
662*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
663*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_deref);
664*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
665*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_undef);
666*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
667*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_cse);
668*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
669*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_algebraic);
670*61046927SAndroid Build Coastguard Worker } while (progress);
671*61046927SAndroid Build Coastguard Worker }
672*61046927SAndroid Build Coastguard Worker
673*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
674*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_returns);
675*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_inline_functions);
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker assert(nir->scratch_size == 0);
678*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_function_temp, glsl_get_cl_type_size_align);
679*61046927SAndroid Build Coastguard Worker
680*61046927SAndroid Build Coastguard Worker {
681*61046927SAndroid Build Coastguard Worker bool progress;
682*61046927SAndroid Build Coastguard Worker do
683*61046927SAndroid Build Coastguard Worker {
684*61046927SAndroid Build Coastguard Worker progress = false;
685*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
686*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
687*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_deref);
688*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
689*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_undef);
690*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
691*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_cse);
692*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_split_var_copies);
693*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_var_copies);
694*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
695*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_algebraic);
696*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_if, nir_opt_if_optimize_phi_true_false);
697*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dead_cf);
698*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_remove_phis);
699*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
700*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_vec3_to_vec4, nir_var_mem_generic | nir_var_uniform);
701*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_memcpy);
702*61046927SAndroid Build Coastguard Worker } while (progress);
703*61046927SAndroid Build Coastguard Worker }
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_scale_fdiv);
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_uniform | nir_var_mem_ubo |
708*61046927SAndroid Build Coastguard Worker nir_var_mem_constant | nir_var_function_temp | nir_var_image, NULL);
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker
711*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_mem_shared | nir_var_function_temp, NULL);
712*61046927SAndroid Build Coastguard Worker
713*61046927SAndroid Build Coastguard Worker nir->scratch_size = 0;
714*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
715*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_function_temp | nir_var_shader_temp |
716*61046927SAndroid Build Coastguard Worker nir_var_mem_global | nir_var_mem_constant,
717*61046927SAndroid Build Coastguard Worker glsl_get_cl_type_size_align);
718*61046927SAndroid Build Coastguard Worker
719*61046927SAndroid Build Coastguard Worker // Lower memcpy - needs to wait until types are sized
720*61046927SAndroid Build Coastguard Worker {
721*61046927SAndroid Build Coastguard Worker bool progress;
722*61046927SAndroid Build Coastguard Worker do {
723*61046927SAndroid Build Coastguard Worker progress = false;
724*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_memcpy);
725*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
726*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
727*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_deref);
728*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
729*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_split_var_copies);
730*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_var_copies);
731*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
732*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
733*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_cse);
734*61046927SAndroid Build Coastguard Worker } while (progress);
735*61046927SAndroid Build Coastguard Worker }
736*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_memcpy);
737*61046927SAndroid Build Coastguard Worker
738*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io,
739*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_function_temp | nir_var_shader_temp | nir_var_uniform,
740*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_offset_as_64bit);
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_system_values);
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker /* Hopefully we can drop this once lower_vars_to_ssa has improved to not
745*61046927SAndroid Build Coastguard Worker * lower everything to scratch.
746*61046927SAndroid Build Coastguard Worker */
747*61046927SAndroid Build Coastguard Worker if (llvm17_wa)
748*61046927SAndroid Build Coastguard Worker cleanup_llvm17_scratch(nir);
749*61046927SAndroid Build Coastguard Worker
750*61046927SAndroid Build Coastguard Worker /* Lower again, this time after dead-variables to get more compact variable
751*61046927SAndroid Build Coastguard Worker * layouts.
752*61046927SAndroid Build Coastguard Worker */
753*61046927SAndroid Build Coastguard Worker nir->global_mem_size = 0;
754*61046927SAndroid Build Coastguard Worker nir->scratch_size = 0;
755*61046927SAndroid Build Coastguard Worker nir->info.shared_size = 0;
756*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_vars_to_explicit_types,
757*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global | nir_var_mem_constant,
758*61046927SAndroid Build Coastguard Worker glsl_get_cl_type_size_align);
759*61046927SAndroid Build Coastguard Worker if (nir->constant_data_size > 0) {
760*61046927SAndroid Build Coastguard Worker assert(nir->constant_data == NULL);
761*61046927SAndroid Build Coastguard Worker nir->constant_data = rzalloc_size(nir, nir->constant_data_size);
762*61046927SAndroid Build Coastguard Worker nir_gather_explicit_io_initializers(nir, nir->constant_data,
763*61046927SAndroid Build Coastguard Worker nir->constant_data_size,
764*61046927SAndroid Build Coastguard Worker nir_var_mem_constant);
765*61046927SAndroid Build Coastguard Worker }
766*61046927SAndroid Build Coastguard Worker
767*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_constant,
768*61046927SAndroid Build Coastguard Worker nir_address_format_64bit_global);
769*61046927SAndroid Build Coastguard Worker
770*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_uniform,
771*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_offset_as_64bit);
772*61046927SAndroid Build Coastguard Worker
773*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_explicit_io,
774*61046927SAndroid Build Coastguard Worker nir_var_shader_temp | nir_var_function_temp |
775*61046927SAndroid Build Coastguard Worker nir_var_mem_shared | nir_var_mem_global,
776*61046927SAndroid Build Coastguard Worker nir_address_format_62bit_generic);
777*61046927SAndroid Build Coastguard Worker
778*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(DEBUG_CS)) {
779*61046927SAndroid Build Coastguard Worker /* Re-index SSA defs so we print more sensible numbers. */
780*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, nir) {
781*61046927SAndroid Build Coastguard Worker nir_index_ssa_defs(impl);
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR (before I/O lowering) for kernel\n");
785*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
786*61046927SAndroid Build Coastguard Worker }
787*61046927SAndroid Build Coastguard Worker
788*61046927SAndroid Build Coastguard Worker return nir;
789*61046927SAndroid Build Coastguard Worker }
790