• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 /**
24  * @file iris_program_cache.c
25  *
26  * The in-memory program cache.  This is basically a hash table mapping
27  * API-specified shaders and a state key to a compiled variant.  It also
28  * takes care of uploading shader assembly into a BO for use on the GPU.
29  */
30 
31 #include <stdio.h>
32 #include <errno.h>
33 #include "pipe/p_defines.h"
34 #include "pipe/p_state.h"
35 #include "pipe/p_context.h"
36 #include "pipe/p_screen.h"
37 #include "util/u_atomic.h"
38 #include "util/u_upload_mgr.h"
39 #include "compiler/nir/nir.h"
40 #include "compiler/nir/nir_builder.h"
41 #include "intel/compiler/brw_compiler.h"
42 #include "intel/compiler/brw_nir.h"
43 #ifdef INTEL_USE_ELK
44 #include "intel/compiler/elk/elk_compiler.h"
45 #include "intel/compiler/elk/elk_nir.h"
46 #endif
47 #include "iris_context.h"
48 #include "iris_resource.h"
49 
50 struct keybox {
51    uint16_t size;
52    enum iris_program_cache_id cache_id;
53    uint8_t data[0];
54 };
55 
56 static struct keybox *
make_keybox(void * mem_ctx,enum iris_program_cache_id cache_id,const void * key,uint32_t key_size)57 make_keybox(void *mem_ctx,
58             enum iris_program_cache_id cache_id,
59             const void *key,
60             uint32_t key_size)
61 {
62    struct keybox *keybox =
63       ralloc_size(mem_ctx, sizeof(struct keybox) + key_size);
64 
65    keybox->cache_id = cache_id;
66    keybox->size = key_size;
67    memcpy(keybox->data, key, key_size);
68 
69    return keybox;
70 }
71 
72 static uint32_t
keybox_hash(const void * void_key)73 keybox_hash(const void *void_key)
74 {
75    const struct keybox *key = void_key;
76    return _mesa_hash_data(&key->cache_id, key->size + sizeof(key->cache_id));
77 }
78 
79 static bool
keybox_equals(const void * void_a,const void * void_b)80 keybox_equals(const void *void_a, const void *void_b)
81 {
82    const struct keybox *a = void_a, *b = void_b;
83    if (a->size != b->size)
84       return false;
85 
86    return memcmp(a->data, b->data, a->size) == 0;
87 }
88 
89 struct iris_compiled_shader *
iris_find_cached_shader(struct iris_context * ice,enum iris_program_cache_id cache_id,uint32_t key_size,const void * key)90 iris_find_cached_shader(struct iris_context *ice,
91                         enum iris_program_cache_id cache_id,
92                         uint32_t key_size,
93                         const void *key)
94 {
95    struct keybox *keybox = make_keybox(NULL, cache_id, key, key_size);
96    struct hash_entry *entry =
97       _mesa_hash_table_search(ice->shaders.cache, keybox);
98 
99    ralloc_free(keybox);
100 
101    return entry ? entry->data : NULL;
102 }
103 
104 void
iris_delete_shader_variant(struct iris_compiled_shader * shader)105 iris_delete_shader_variant(struct iris_compiled_shader *shader)
106 {
107    pipe_resource_reference(&shader->assembly.res, NULL);
108    util_queue_fence_destroy(&shader->ready);
109    ralloc_free(shader);
110 }
111 
112 struct iris_compiled_shader *
iris_create_shader_variant(const struct iris_screen * screen,void * mem_ctx,gl_shader_stage stage,enum iris_program_cache_id cache_id,uint32_t key_size,const void * key)113 iris_create_shader_variant(const struct iris_screen *screen,
114                            void *mem_ctx,
115                            gl_shader_stage stage,
116                            enum iris_program_cache_id cache_id,
117                            uint32_t key_size,
118                            const void *key)
119 {
120 #ifndef NDEBUG
121    if (cache_id == IRIS_CACHE_BLORP) {
122       /* Blorp shader must have a mem_ctx. */
123       assert(mem_ctx != NULL);
124    } else if (cache_id == IRIS_CACHE_TCS) {
125       /* Pass-through tessellation control shaders (generated by the driver)
126        * will have a mem_ctx, and other tessellation control shaders will not.
127        */
128    } else {
129       /* Shaders that are neither blorp nor tessellation control must not have
130        * a mem_ctx.
131        */
132       assert(mem_ctx == NULL);
133    }
134 #endif
135 
136    struct iris_compiled_shader *shader =
137       rzalloc_size(mem_ctx, sizeof(struct iris_compiled_shader) +
138                    screen->vtbl.derived_program_state_size(cache_id));
139 
140    pipe_reference_init(&shader->ref, 1);
141    util_queue_fence_init(&shader->ready);
142    util_queue_fence_reset(&shader->ready);
143 
144    if (cache_id != IRIS_CACHE_BLORP) {
145       assert(key_size <= sizeof(union iris_any_prog_key));
146       memcpy(&shader->key, key, key_size);
147    }
148 
149    shader->stage = stage;
150 
151    return shader;
152 }
153 
154 void
iris_upload_shader(struct iris_screen * screen,struct iris_uncompiled_shader * ish,struct iris_compiled_shader * shader,struct hash_table * driver_shaders,struct u_upload_mgr * uploader,enum iris_program_cache_id cache_id,uint32_t key_size,const void * key,const void * assembly)155 iris_upload_shader(struct iris_screen *screen,
156                    struct iris_uncompiled_shader *ish,
157                    struct iris_compiled_shader *shader,
158                    struct hash_table *driver_shaders,
159                    struct u_upload_mgr *uploader,
160                    enum iris_program_cache_id cache_id,
161                    uint32_t key_size,
162                    const void *key,
163                    const void *assembly)
164 {
165    const struct intel_device_info *devinfo = screen->devinfo;
166 
167    u_upload_alloc(uploader, 0, shader->program_size, 64,
168                   &shader->assembly.offset, &shader->assembly.res,
169                   &shader->map);
170    memcpy(shader->map, assembly, shader->program_size);
171 
172    struct iris_resource *res = (void *) shader->assembly.res;
173    uint64_t shader_data_addr = res->bo->address +
174                                shader->assembly.offset +
175                                shader->const_data_offset;
176 
177    if (screen->brw) {
178       struct brw_shader_reloc_value reloc_values[] = {
179          {
180             .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW,
181             .value = shader_data_addr,
182          },
183          {
184             .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH,
185             .value = shader_data_addr >> 32,
186          },
187       };
188       brw_write_shader_relocs(&screen->brw->isa, shader->map,
189                               shader->brw_prog_data, reloc_values,
190                               ARRAY_SIZE(reloc_values));
191    } else {
192 #ifdef INTEL_USE_ELK
193       struct elk_shader_reloc_value reloc_values[] = {
194          {
195             .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW,
196             .value = shader_data_addr,
197          },
198          {
199             .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH,
200             .value = shader_data_addr >> 32,
201          },
202       };
203       elk_write_shader_relocs(&screen->elk->isa, shader->map,
204                               shader->elk_prog_data, reloc_values,
205                               ARRAY_SIZE(reloc_values));
206 #else
207       unreachable("no elk support");
208 #endif
209    }
210 
211    /* Store the 3DSTATE shader packets and other derived state. */
212    screen->vtbl.store_derived_program_state(devinfo, cache_id, shader);
213 
214    util_queue_fence_signal(&shader->ready);
215 
216    if (!ish) {
217       struct keybox *keybox = make_keybox(shader, cache_id, key, key_size);
218       _mesa_hash_table_insert(driver_shaders, keybox, shader);
219    }
220 }
221 
222 bool
iris_blorp_lookup_shader(struct blorp_batch * blorp_batch,const void * key,uint32_t key_size,uint32_t * kernel_out,void * prog_data_out)223 iris_blorp_lookup_shader(struct blorp_batch *blorp_batch,
224                          const void *key, uint32_t key_size,
225                          uint32_t *kernel_out, void *prog_data_out)
226 {
227    struct blorp_context *blorp = blorp_batch->blorp;
228    struct iris_context *ice = blorp->driver_ctx;
229    struct iris_batch *batch = blorp_batch->driver_batch;
230    struct iris_compiled_shader *shader =
231       iris_find_cached_shader(ice, IRIS_CACHE_BLORP, key_size, key);
232 
233    if (!shader)
234       return false;
235 
236    struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
237    *kernel_out =
238       iris_bo_offset_from_base_address(bo) + shader->assembly.offset;
239    *((void **) prog_data_out) =
240 #ifdef INTEL_USE_ELK
241       batch->screen->elk ? (void *)shader->elk_prog_data :
242 #endif
243       (void *)shader->brw_prog_data;
244 
245    iris_use_pinned_bo(batch, bo, false, IRIS_DOMAIN_NONE);
246 
247    return true;
248 }
249 
250 bool
iris_blorp_upload_shader(struct blorp_batch * blorp_batch,uint32_t stage,const void * key,uint32_t key_size,const void * kernel,UNUSED uint32_t kernel_size,const void * prog_data_templ,UNUSED uint32_t prog_data_size,uint32_t * kernel_out,void * prog_data_out)251 iris_blorp_upload_shader(struct blorp_batch *blorp_batch, uint32_t stage,
252                          const void *key, uint32_t key_size,
253                          const void *kernel, UNUSED uint32_t kernel_size,
254                          const void *prog_data_templ,
255                          UNUSED uint32_t prog_data_size,
256                          uint32_t *kernel_out, void *prog_data_out)
257 {
258    struct blorp_context *blorp = blorp_batch->blorp;
259    struct iris_context *ice = blorp->driver_ctx;
260    struct iris_batch *batch = blorp_batch->driver_batch;
261    struct iris_screen *screen = batch->screen;
262 
263    struct iris_binding_table bt;
264    memset(&bt, 0, sizeof(bt));
265 
266    struct iris_compiled_shader *shader =
267       iris_create_shader_variant(screen, ice->shaders.cache, stage,
268                                  IRIS_CACHE_BLORP, key_size, key);
269 
270    void *prog_data = ralloc_size(NULL, prog_data_size);
271    memcpy(prog_data, prog_data_templ, prog_data_size);
272 
273    if (screen->brw) {
274       iris_apply_brw_prog_data(shader, prog_data);
275    } else {
276 #ifdef INTEL_USE_ELK
277       assert(screen->elk);
278       iris_apply_elk_prog_data(shader, prog_data);
279 #else
280       unreachable("no elk support");
281 #endif
282    }
283 
284    iris_finalize_program(shader, NULL, NULL, 0, 0, 0, &bt);
285 
286    iris_upload_shader(screen, NULL, shader, ice->shaders.cache,
287                       ice->shaders.uploader_driver,
288                       IRIS_CACHE_BLORP, key_size, key, kernel);
289 
290    struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
291    *kernel_out =
292       iris_bo_offset_from_base_address(bo) + shader->assembly.offset;
293    *((void **) prog_data_out) =
294 #ifdef INTEL_USE_ELK
295       screen->elk ? (void *)shader->elk_prog_data :
296 #endif
297       (void*)shader->brw_prog_data;
298 
299    iris_use_pinned_bo(batch, bo, false, IRIS_DOMAIN_NONE);
300 
301    return true;
302 }
303 
304 void
iris_init_program_cache(struct iris_context * ice)305 iris_init_program_cache(struct iris_context *ice)
306 {
307    ice->shaders.cache =
308       _mesa_hash_table_create(ice, keybox_hash, keybox_equals);
309 
310    ice->shaders.uploader_driver =
311       u_upload_create(&ice->ctx, 64 * 1024,
312                       PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE,
313                       IRIS_RESOURCE_FLAG_SHADER_MEMZONE |
314                       IRIS_RESOURCE_FLAG_DEVICE_MEM);
315    ice->shaders.uploader_unsync =
316       u_upload_create(&ice->ctx, 64 * 1024,
317                       PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE,
318                       IRIS_RESOURCE_FLAG_SHADER_MEMZONE |
319                       IRIS_RESOURCE_FLAG_DEVICE_MEM);
320 }
321 
322 void
iris_destroy_program_cache(struct iris_context * ice)323 iris_destroy_program_cache(struct iris_context *ice)
324 {
325    for (int i = 0; i < MESA_SHADER_STAGES; i++) {
326       iris_shader_variant_reference(&ice->shaders.prog[i], NULL);
327    }
328    iris_shader_variant_reference(&ice->shaders.last_vue_shader, NULL);
329 
330    hash_table_foreach(ice->shaders.cache, entry) {
331       struct iris_compiled_shader *shader = entry->data;
332       iris_delete_shader_variant(shader);
333    }
334 
335    u_upload_destroy(ice->shaders.uploader_driver);
336    u_upload_destroy(ice->shaders.uploader_unsync);
337 
338    ralloc_free(ice->shaders.cache);
339 }
340 
341 static void
link_libintel_shaders(nir_shader * nir,const uint32_t * spv_code,uint32_t spv_size)342 link_libintel_shaders(nir_shader *nir,
343                       const uint32_t *spv_code, uint32_t spv_size)
344 {
345    nir_shader *libintel = brw_nir_from_spirv(nir, spv_code, spv_size);
346 
347    nir_link_shader_functions(nir, libintel);
348    NIR_PASS_V(nir, nir_inline_functions);
349    NIR_PASS_V(nir, nir_remove_non_entrypoints);
350    NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_function_temp,
351               glsl_get_cl_type_size_align);
352    NIR_PASS_V(nir, nir_opt_deref);
353    NIR_PASS_V(nir, nir_lower_vars_to_ssa);
354    NIR_PASS_V(nir, nir_lower_explicit_io,
355               nir_var_shader_temp | nir_var_function_temp | nir_var_mem_shared |
356                  nir_var_mem_global,
357               nir_address_format_62bit_generic);
358    NIR_PASS_V(nir, nir_lower_scratch_to_var);
359 }
360 
361 void
iris_ensure_indirect_generation_shader(struct iris_batch * batch)362 iris_ensure_indirect_generation_shader(struct iris_batch *batch)
363 {
364    struct iris_context *ice = batch->ice;
365    if (ice->draw.generation.shader)
366       return;
367 
368    struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
369    const struct {
370       char name[40];
371    } key = {
372       .name = "iris-generation-shader",
373    };
374    ice->draw.generation.shader =
375       iris_find_cached_shader(ice, IRIS_CACHE_BLORP, sizeof(key), &key);
376    if (ice->draw.generation.shader != NULL)
377       return;
378 
379    const nir_shader_compiler_options *nir_options =
380 #ifdef INTEL_USE_ELK
381       screen->elk ? screen->elk->nir_options[MESA_SHADER_COMPUTE] :
382 #endif
383       screen->brw->nir_options[MESA_SHADER_COMPUTE];
384 
385    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
386                                                   nir_options,
387                                                   "iris-indirect-generate");
388 
389    uint32_t uniform_size =
390       screen->vtbl.call_generation_shader(screen, &b);
391 
392    uint32_t spv_size;
393    const uint32_t *spv_code = screen->vtbl.load_shader_lib_spv(&spv_size);
394 
395    nir_shader *nir = b.shader;
396 
397    link_libintel_shaders(nir, spv_code, spv_size);
398 
399    NIR_PASS_V(nir, nir_lower_vars_to_ssa);
400    NIR_PASS_V(nir, nir_opt_cse);
401    NIR_PASS_V(nir, nir_opt_gcm, true);
402    NIR_PASS_V(nir, nir_opt_peephole_select, 1, false, false);
403 
404    NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
405 
406    NIR_PASS_V(nir, nir_split_var_copies);
407    NIR_PASS_V(nir, nir_split_per_member_structs);
408 
409    if (screen->brw) {
410       struct brw_nir_compiler_opts opts = {};
411       brw_preprocess_nir(screen->brw, nir, &opts);
412    } else {
413 #ifdef INTEL_USE_ELK
414       assert(screen->elk);
415       struct elk_nir_compiler_opts opts = {};
416       elk_preprocess_nir(screen->elk, nir, &opts);
417 #else
418       unreachable("no elk support");
419 #endif
420    }
421 
422    NIR_PASS_V(nir, nir_propagate_invariant, false);
423 
424    NIR_PASS_V(nir, nir_lower_input_attachments,
425               &(nir_input_attachment_options) {
426                  .use_fragcoord_sysval = true,
427                  .use_layer_id_sysval = true,
428               });
429 
430    /* Reset sizes before gathering information */
431    nir->global_mem_size = 0;
432    nir->scratch_size = 0;
433    nir->info.shared_size = 0;
434    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
435 
436    NIR_PASS_V(nir, nir_copy_prop);
437    NIR_PASS_V(nir, nir_opt_constant_folding);
438    NIR_PASS_V(nir, nir_opt_dce);
439 
440    /* Do vectorizing here. For some reason when trying to do it in the back
441     * this just isn't working.
442     */
443    nir_load_store_vectorize_options options = {
444       .modes = nir_var_mem_ubo | nir_var_mem_ssbo | nir_var_mem_global,
445       .callback = brw_nir_should_vectorize_mem,
446       .robust_modes = (nir_variable_mode)0,
447    };
448    NIR_PASS_V(nir, nir_opt_load_store_vectorize, &options);
449 
450    nir->num_uniforms = uniform_size;
451 
452    struct iris_compiled_shader *shader =
453       iris_create_shader_variant(screen, ice->shaders.cache,
454                                  MESA_SHADER_FRAGMENT,
455                                  IRIS_CACHE_BLORP,
456                                  sizeof(key), &key);
457 
458    const unsigned *program;
459    if (screen->brw) {
460       union brw_any_prog_key prog_key;
461       memset(&prog_key, 0, sizeof(prog_key));
462 
463       struct brw_wm_prog_data *prog_data = ralloc_size(NULL, sizeof(*prog_data));
464       memset(prog_data, 0, sizeof(*prog_data));
465       prog_data->base.nr_params = nir->num_uniforms / 4;
466 
467       brw_nir_analyze_ubo_ranges(screen->brw, nir, prog_data->base.ubo_ranges);
468 
469       struct brw_compile_stats stats[3];
470       struct brw_compile_fs_params params = {
471          .base = {
472             .nir = nir,
473             .log_data = &ice->dbg,
474             .debug_flag = DEBUG_WM,
475             .stats = stats,
476             .mem_ctx = nir,
477          },
478          .key = &prog_key.wm,
479          .prog_data = prog_data,
480       };
481       program = brw_compile_fs(screen->brw, &params);
482       assert(program);
483       iris_apply_brw_prog_data(shader, &prog_data->base);
484    } else {
485 #ifdef INTEL_USE_ELK
486       union elk_any_prog_key prog_key;
487       memset(&prog_key, 0, sizeof(prog_key));
488 
489       struct elk_wm_prog_data *prog_data = ralloc_size(NULL, sizeof(*prog_data));
490       memset(prog_data, 0, sizeof(*prog_data));
491       prog_data->base.nr_params = nir->num_uniforms / 4;
492 
493       elk_nir_analyze_ubo_ranges(screen->elk, nir, prog_data->base.ubo_ranges);
494 
495       struct elk_compile_stats stats[3];
496       struct elk_compile_fs_params params = {
497          .base = {
498             .nir = nir,
499             .log_data = &ice->dbg,
500             .debug_flag = DEBUG_WM,
501             .stats = stats,
502             .mem_ctx = nir,
503          },
504          .key = &prog_key.wm,
505          .prog_data = prog_data,
506       };
507       program = elk_compile_fs(screen->elk, &params);
508       assert(program);
509       iris_apply_elk_prog_data(shader, &prog_data->base);
510 #else
511       unreachable("no elk support");
512 #endif
513    }
514 
515    struct iris_binding_table bt;
516    memset(&bt, 0, sizeof(bt));
517 
518    iris_finalize_program(shader, NULL, NULL, 0, 0, 0, &bt);
519 
520    iris_upload_shader(screen, NULL, shader, ice->shaders.cache,
521                       ice->shaders.uploader_driver,
522                       IRIS_CACHE_BLORP, sizeof(key), &key, program);
523 
524    ralloc_free(nir);
525 
526    struct iris_bo *bo = iris_resource_bo(shader->assembly.res);
527    iris_use_pinned_bo(batch, bo, false, IRIS_DOMAIN_NONE);
528 
529    ice->draw.generation.shader = shader;
530 }
531