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