• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params);
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, &params);
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, &params);
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                             &params->sf_prog_kernel, &params->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                            &params->sf_prog_kernel, &params->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                             &params->vs_prog_kernel, &params->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                            &params->vs_prog_kernel, &params->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