1 /*
2 * Copyright 2012 Intel Corporation
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "blorp_priv.h"
7 #include "blorp_nir_builder.h"
8 #include "compiler/elk/elk_compiler.h"
9 #include "compiler/elk/elk_nir.h"
10 #include "compiler/intel_nir.h"
11 #include "dev/intel_debug.h"
12
13 static struct blorp_program
blorp_compile_fs_elk(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir,bool multisample_fbo,bool use_repclear)14 blorp_compile_fs_elk(struct blorp_context *blorp, void *mem_ctx,
15 struct nir_shader *nir,
16 bool multisample_fbo,
17 bool use_repclear)
18 {
19 const struct elk_compiler *compiler = blorp->compiler->elk;
20 nir->options = compiler->nir_options[MESA_SHADER_FRAGMENT];
21
22 struct elk_wm_prog_data *wm_prog_data = rzalloc(mem_ctx, struct elk_wm_prog_data);
23 wm_prog_data->base.nr_params = 0;
24 wm_prog_data->base.param = NULL;
25
26 struct elk_nir_compiler_opts opts = {};
27 elk_preprocess_nir(compiler, nir, &opts);
28 nir_remove_dead_variables(nir, nir_var_shader_in, NULL);
29 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
30
31 struct elk_wm_prog_key wm_key;
32 memset(&wm_key, 0, sizeof(wm_key));
33 wm_key.multisample_fbo = multisample_fbo ? ELK_ALWAYS : ELK_NEVER;
34 wm_key.nr_color_regions = 1;
35
36 if (compiler->devinfo->ver < 6) {
37 if (nir->info.fs.uses_discard)
38 wm_key.iz_lookup |= ELK_WM_IZ_PS_KILL_ALPHATEST_BIT;
39
40 wm_key.input_slots_valid = nir->info.inputs_read | VARYING_BIT_POS;
41 }
42
43 struct elk_compile_fs_params params = {
44 .base = {
45 .mem_ctx = mem_ctx,
46 .nir = nir,
47 .log_data = blorp->driver_ctx,
48 .debug_flag = DEBUG_BLORP,
49 },
50 .key = &wm_key,
51 .prog_data = wm_prog_data,
52
53 .use_rep_send = use_repclear,
54 .max_polygons = 1,
55 };
56
57 const unsigned *kernel = elk_compile_fs(compiler, ¶ms);
58 return (struct blorp_program){
59 .kernel = kernel,
60 .kernel_size = wm_prog_data->base.program_size,
61 .prog_data = wm_prog_data,
62 .prog_data_size = sizeof(*wm_prog_data),
63 };
64 }
65
66 static struct blorp_program
blorp_compile_vs_elk(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)67 blorp_compile_vs_elk(struct blorp_context *blorp, void *mem_ctx,
68 struct nir_shader *nir)
69 {
70 const struct elk_compiler *compiler = blorp->compiler->elk;
71
72 nir->options = compiler->nir_options[MESA_SHADER_VERTEX];
73
74 struct elk_nir_compiler_opts opts = {};
75 elk_preprocess_nir(compiler, nir, &opts);
76 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
77
78 struct elk_vs_prog_data *vs_prog_data = rzalloc(mem_ctx, struct elk_vs_prog_data);
79 vs_prog_data->inputs_read = nir->info.inputs_read;
80
81 elk_compute_vue_map(compiler->devinfo,
82 &vs_prog_data->base.vue_map,
83 nir->info.outputs_written,
84 nir->info.separate_shader,
85 1);
86
87 struct elk_vs_prog_key vs_key = { 0, };
88
89 struct elk_compile_vs_params params = {
90 .base = {
91 .mem_ctx = mem_ctx,
92 .nir = nir,
93 .log_data = blorp->driver_ctx,
94 .debug_flag = DEBUG_BLORP,
95 },
96 .key = &vs_key,
97 .prog_data = vs_prog_data,
98 };
99
100 const unsigned *kernel = elk_compile_vs(compiler, ¶ms);
101 return (struct blorp_program) {
102 .kernel = kernel,
103 .kernel_size = vs_prog_data->base.base.program_size,
104 .prog_data = vs_prog_data,
105 .prog_data_size = sizeof(*vs_prog_data),
106 };
107 }
108
109 static bool
lower_base_workgroup_id(nir_builder * b,nir_intrinsic_instr * intrin,UNUSED void * data)110 lower_base_workgroup_id(nir_builder *b, nir_intrinsic_instr *intrin,
111 UNUSED void *data)
112 {
113 if (intrin->intrinsic != nir_intrinsic_load_base_workgroup_id)
114 return false;
115
116 b->cursor = nir_instr_remove(&intrin->instr);
117 nir_def_rewrite_uses(&intrin->def, nir_imm_zero(b, 3, 32));
118 return true;
119 }
120
121 static struct blorp_program
blorp_compile_cs_elk(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)122 blorp_compile_cs_elk(struct blorp_context *blorp, void *mem_ctx,
123 struct nir_shader *nir)
124 {
125 const struct elk_compiler *compiler = blorp->compiler->elk;
126
127 nir->options = compiler->nir_options[MESA_SHADER_COMPUTE];
128
129 struct elk_nir_compiler_opts opts = {};
130 elk_preprocess_nir(compiler, nir, &opts);
131 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
132
133 NIR_PASS_V(nir, nir_lower_io, nir_var_uniform, elk_type_size_scalar_bytes,
134 (nir_lower_io_options)0);
135
136 STATIC_ASSERT(offsetof(struct blorp_wm_inputs, subgroup_id) + 4 ==
137 sizeof(struct blorp_wm_inputs));
138 nir->num_uniforms = offsetof(struct blorp_wm_inputs, subgroup_id);
139 unsigned nr_params = nir->num_uniforms / 4;
140
141 struct elk_cs_prog_data *cs_prog_data = rzalloc(mem_ctx, struct elk_cs_prog_data);
142 cs_prog_data->base.nr_params = nr_params;
143 cs_prog_data->base.param = rzalloc_array(NULL, uint32_t, nr_params);
144
145 NIR_PASS_V(nir, elk_nir_lower_cs_intrinsics, compiler->devinfo,
146 cs_prog_data);
147 NIR_PASS_V(nir, nir_shader_intrinsics_pass, lower_base_workgroup_id,
148 nir_metadata_block_index | nir_metadata_dominance, NULL);
149
150 struct elk_cs_prog_key cs_key;
151 memset(&cs_key, 0, sizeof(cs_key));
152
153 struct elk_compile_cs_params params = {
154 .base = {
155 .mem_ctx = mem_ctx,
156 .nir = nir,
157 .log_data = blorp->driver_ctx,
158 .debug_flag = DEBUG_BLORP,
159 },
160 .key = &cs_key,
161 .prog_data = cs_prog_data,
162 };
163
164 const unsigned *kernel = elk_compile_cs(compiler, ¶ms);
165
166 ralloc_free(cs_prog_data->base.param);
167 cs_prog_data->base.param = NULL;
168
169 return (struct blorp_program) {
170 .kernel = kernel,
171 .kernel_size = cs_prog_data->base.program_size,
172 .prog_data = cs_prog_data,
173 .prog_data_size = sizeof(*cs_prog_data),
174 };
175 }
176
177 struct blorp_sf_key {
178 struct blorp_base_key base;
179 struct elk_sf_prog_key key;
180 };
181
182 static bool
blorp_ensure_sf_program_elk(struct blorp_batch * batch,struct blorp_params * params)183 blorp_ensure_sf_program_elk(struct blorp_batch *batch,
184 struct blorp_params *params)
185 {
186 struct blorp_context *blorp = batch->blorp;
187 const struct elk_compiler *compiler = blorp->compiler->elk;
188 const struct elk_wm_prog_data *wm_prog_data = params->wm_prog_data;
189 assert(params->wm_prog_data);
190
191 /* Gfx6+ doesn't need a strips and fans program */
192 if (compiler->devinfo->ver >= 6)
193 return true;
194
195 struct blorp_sf_key key = {
196 .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_GFX4_SF),
197 };
198
199 /* Everything gets compacted in vertex setup, so we just need a
200 * pass-through for the correct number of input varyings.
201 */
202 const uint64_t slots_valid = VARYING_BIT_POS |
203 ((1ull << wm_prog_data->num_varying_inputs) - 1) << VARYING_SLOT_VAR0;
204
205 key.key.attrs = slots_valid;
206 key.key.primitive = ELK_SF_PRIM_TRIANGLES;
207 key.key.contains_flat_varying = wm_prog_data->contains_flat_varying;
208
209 STATIC_ASSERT(sizeof(key.key.interp_mode) ==
210 sizeof(wm_prog_data->interp_mode));
211 memcpy(key.key.interp_mode, wm_prog_data->interp_mode,
212 sizeof(key.key.interp_mode));
213
214 if (blorp->lookup_shader(batch, &key, sizeof(key),
215 ¶ms->sf_prog_kernel, ¶ms->sf_prog_data))
216 return true;
217
218 void *mem_ctx = ralloc_context(NULL);
219
220 const unsigned *program;
221 unsigned program_size;
222
223 struct intel_vue_map vue_map;
224 elk_compute_vue_map(compiler->devinfo, &vue_map, slots_valid, false, 1);
225
226 struct elk_sf_prog_data prog_data_tmp;
227 program = elk_compile_sf(compiler, mem_ctx, &key.key,
228 &prog_data_tmp, &vue_map, &program_size);
229
230 bool result =
231 blorp->upload_shader(batch, MESA_SHADER_NONE,
232 &key, sizeof(key), program, program_size,
233 (void *)&prog_data_tmp, sizeof(prog_data_tmp),
234 ¶ms->sf_prog_kernel, ¶ms->sf_prog_data);
235
236 ralloc_free(mem_ctx);
237
238 return result;
239 }
240
241 #pragma pack(push, 1)
242 struct layer_offset_vs_key {
243 struct blorp_base_key base;
244 unsigned num_inputs;
245 };
246 #pragma pack(pop)
247
248 /* In the case of doing attachment clears, we are using a surface state that
249 * is handed to us so we can't set (and don't even know) the base array layer.
250 * In order to do a layered clear in this scenario, we need some way of adding
251 * the base array layer to the instance id. Unfortunately, our hardware has
252 * no real concept of "base instance", so we have to do it manually in a
253 * vertex shader.
254 */
255 static bool
blorp_params_get_layer_offset_vs_elk(struct blorp_batch * batch,struct blorp_params * params)256 blorp_params_get_layer_offset_vs_elk(struct blorp_batch *batch,
257 struct blorp_params *params)
258 {
259 struct blorp_context *blorp = batch->blorp;
260 struct layer_offset_vs_key blorp_key = {
261 .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_LAYER_OFFSET_VS),
262 };
263
264 struct elk_wm_prog_data *wm_prog_data = params->wm_prog_data;
265 if (wm_prog_data)
266 blorp_key.num_inputs = wm_prog_data->num_varying_inputs;
267
268 if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
269 ¶ms->vs_prog_kernel, ¶ms->vs_prog_data))
270 return true;
271
272 void *mem_ctx = ralloc_context(NULL);
273
274 nir_builder b;
275 blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_VERTEX,
276 blorp_shader_type_to_name(blorp_key.base.shader_type));
277
278 const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
279
280 /* First we deal with the header which has instance and base instance */
281 nir_variable *a_header = nir_variable_create(b.shader, nir_var_shader_in,
282 uvec4_type, "header");
283 a_header->data.location = VERT_ATTRIB_GENERIC0;
284
285 nir_variable *v_layer = nir_variable_create(b.shader, nir_var_shader_out,
286 glsl_int_type(), "layer_id");
287 v_layer->data.location = VARYING_SLOT_LAYER;
288
289 /* Compute the layer id */
290 nir_def *header = nir_load_var(&b, a_header);
291 nir_def *base_layer = nir_channel(&b, header, 0);
292 nir_def *instance = nir_channel(&b, header, 1);
293 nir_store_var(&b, v_layer, nir_iadd(&b, instance, base_layer), 0x1);
294
295 /* Then we copy the vertex from the next slot to VARYING_SLOT_POS */
296 nir_variable *a_vertex = nir_variable_create(b.shader, nir_var_shader_in,
297 glsl_vec4_type(), "a_vertex");
298 a_vertex->data.location = VERT_ATTRIB_GENERIC1;
299
300 nir_variable *v_pos = nir_variable_create(b.shader, nir_var_shader_out,
301 glsl_vec4_type(), "v_pos");
302 v_pos->data.location = VARYING_SLOT_POS;
303
304 nir_copy_var(&b, v_pos, a_vertex);
305
306 /* Then we copy everything else */
307 for (unsigned i = 0; i < blorp_key.num_inputs; i++) {
308 nir_variable *a_in = nir_variable_create(b.shader, nir_var_shader_in,
309 uvec4_type, "input");
310 a_in->data.location = VERT_ATTRIB_GENERIC2 + i;
311
312 nir_variable *v_out = nir_variable_create(b.shader, nir_var_shader_out,
313 uvec4_type, "output");
314 v_out->data.location = VARYING_SLOT_VAR0 + i;
315
316 nir_copy_var(&b, v_out, a_in);
317 }
318
319 const struct blorp_program p =
320 blorp_compile_vs(blorp, mem_ctx, b.shader);
321
322 bool result =
323 blorp->upload_shader(batch, MESA_SHADER_VERTEX,
324 &blorp_key, sizeof(blorp_key),
325 p.kernel, p.kernel_size,
326 p.prog_data, p.prog_data_size,
327 ¶ms->vs_prog_kernel, ¶ms->vs_prog_data);
328
329 ralloc_free(mem_ctx);
330 return result;
331 }
332
333 void
blorp_init_elk(struct blorp_context * blorp,void * driver_ctx,struct isl_device * isl_dev,const struct elk_compiler * elk,const struct blorp_config * config)334 blorp_init_elk(struct blorp_context *blorp, void *driver_ctx,
335 struct isl_device *isl_dev, const struct elk_compiler *elk,
336 const struct blorp_config *config)
337 {
338 blorp_init(blorp, driver_ctx, isl_dev, config);
339 assert(elk);
340
341 blorp->compiler->elk = elk;
342 blorp->compiler->compile_fs = blorp_compile_fs_elk;
343 blorp->compiler->compile_vs = blorp_compile_vs_elk;
344 blorp->compiler->compile_cs = blorp_compile_cs_elk;
345 blorp->compiler->ensure_sf_program = blorp_ensure_sf_program_elk;
346 blorp->compiler->params_get_layer_offset_vs =
347 blorp_params_get_layer_offset_vs_elk;
348 }
349