• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2018 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_disk_cache.c
25  *
26  * Functions for interacting with the on-disk shader cache.
27  */
28 
29 #include <stdio.h>
30 #include <stdint.h>
31 #include <assert.h>
32 #include <string.h>
33 
34 #include "compiler/nir/nir.h"
35 #include "util/blob.h"
36 #include "util/build_id.h"
37 #include "util/disk_cache.h"
38 #include "util/mesa-sha1.h"
39 #include "intel/compiler/brw_compiler.h"
40 #ifdef INTEL_USE_ELK
41 #include "intel/compiler/elk/elk_compiler.h"
42 #endif
43 
44 #include "iris_context.h"
45 
46 static bool debug = false;
47 
48 /**
49  * Compute a disk cache key for the given uncompiled shader and NOS key.
50  */
51 static void
iris_disk_cache_compute_key(struct disk_cache * cache,const struct iris_uncompiled_shader * ish,const void * orig_prog_key,uint32_t prog_key_size,cache_key cache_key)52 iris_disk_cache_compute_key(struct disk_cache *cache,
53                             const struct iris_uncompiled_shader *ish,
54                             const void *orig_prog_key,
55                             uint32_t prog_key_size,
56                             cache_key cache_key)
57 {
58    /* Create a copy of the program key with program_string_id zeroed out.
59     * It's essentially random data which we don't want to include in our
60     * hashing and comparisons.  We'll set a proper value on a cache hit.
61     */
62    union brw_any_prog_key prog_key;
63    memcpy(&prog_key, orig_prog_key, prog_key_size);
64    prog_key.base.program_string_id = 0;
65 
66    uint8_t data[sizeof(prog_key) + sizeof(ish->nir_sha1)];
67    uint32_t data_size = prog_key_size + sizeof(ish->nir_sha1);
68 
69    memcpy(data, ish->nir_sha1, sizeof(ish->nir_sha1));
70    memcpy(data + sizeof(ish->nir_sha1), &prog_key, prog_key_size);
71 
72    disk_cache_compute_key(cache, data, data_size, cache_key);
73 }
74 
75 /**
76  * Store the given compiled shader in the disk cache.
77  *
78  * This should only be called on newly compiled shaders.  No checking is
79  * done to prevent repeated stores of the same shader.
80  */
81 void
iris_disk_cache_store(struct disk_cache * cache,const struct iris_uncompiled_shader * ish,const struct iris_compiled_shader * shader,const void * prog_key,uint32_t prog_key_size)82 iris_disk_cache_store(struct disk_cache *cache,
83                       const struct iris_uncompiled_shader *ish,
84                       const struct iris_compiled_shader *shader,
85                       const void *prog_key,
86                       uint32_t prog_key_size)
87 {
88 #ifdef ENABLE_SHADER_CACHE
89    if (!cache)
90       return;
91 
92    gl_shader_stage stage = ish->nir->info.stage;
93    const struct brw_stage_prog_data *brw = shader->brw_prog_data;
94 #ifdef INTEL_USE_ELK
95    const struct elk_stage_prog_data *elk = shader->elk_prog_data;
96    assert((brw == NULL) != (elk == NULL));
97 #else
98    assert(brw);
99 #endif
100 
101    cache_key cache_key;
102    iris_disk_cache_compute_key(cache, ish, prog_key, prog_key_size, cache_key);
103 
104    if (debug) {
105       char sha1[41];
106       _mesa_sha1_format(sha1, cache_key);
107       fprintf(stderr, "[mesa disk cache] storing %s\n", sha1);
108    }
109 
110    struct blob blob;
111    blob_init(&blob);
112 
113    /* We write the following data to the cache blob:
114     *
115     * 1. Prog data (must come first because it has the assembly size)
116     *   - Zero out pointer values in prog data, so cache entries will be
117     *     consistent.
118     * 2. Assembly code
119     * 3. Number of entries in the system value array
120     * 4. System value array
121     * 5. Size (in bytes) of kernel inputs
122     * 6. Shader relocations
123     * 7. Legacy param array (only used for compute workgroup ID)
124     * 8. Binding table
125     */
126    if (brw) {
127       size_t prog_data_s = brw_prog_data_size(stage);
128       union brw_any_prog_data serializable;
129       assert(prog_data_s <= sizeof(serializable));
130       memcpy(&serializable, shader->brw_prog_data, prog_data_s);
131       serializable.base.param = NULL;
132       serializable.base.relocs = NULL;
133       blob_write_bytes(&blob, &serializable, prog_data_s);
134    } else {
135 #ifdef INTEL_USE_ELK
136       size_t prog_data_s = elk_prog_data_size(stage);
137       union elk_any_prog_data serializable;
138       assert(prog_data_s <= sizeof(serializable));
139       memcpy(&serializable, shader->elk_prog_data, prog_data_s);
140       serializable.base.param = NULL;
141       serializable.base.relocs = NULL;
142       blob_write_bytes(&blob, &serializable, prog_data_s);
143 #else
144       unreachable("no elk support");
145 #endif
146    }
147 
148    blob_write_bytes(&blob, shader->map, shader->program_size);
149    blob_write_uint32(&blob, shader->num_system_values);
150    blob_write_bytes(&blob, shader->system_values,
151                     shader->num_system_values * sizeof(uint32_t));
152    blob_write_uint32(&blob, shader->kernel_input_size);
153    if (brw) {
154       blob_write_bytes(&blob, brw->relocs,
155                        brw->num_relocs * sizeof(struct brw_shader_reloc));
156       blob_write_bytes(&blob, brw->param,
157                        brw->nr_params * sizeof(uint32_t));
158    } else {
159 #ifdef INTEL_USE_ELK
160       blob_write_bytes(&blob, elk->relocs,
161                        elk->num_relocs * sizeof(struct elk_shader_reloc));
162       blob_write_bytes(&blob, elk->param,
163                        elk->nr_params * sizeof(uint32_t));
164 #else
165       unreachable("no elk support");
166 #endif
167    }
168    blob_write_bytes(&blob, &shader->bt, sizeof(shader->bt));
169 
170    disk_cache_put(cache, cache_key, blob.data, blob.size, NULL);
171    blob_finish(&blob);
172 #endif
173 }
174 
175 static const enum iris_program_cache_id cache_id_for_stage[] = {
176    [MESA_SHADER_VERTEX]    = IRIS_CACHE_VS,
177    [MESA_SHADER_TESS_CTRL] = IRIS_CACHE_TCS,
178    [MESA_SHADER_TESS_EVAL] = IRIS_CACHE_TES,
179    [MESA_SHADER_GEOMETRY]  = IRIS_CACHE_GS,
180    [MESA_SHADER_FRAGMENT]  = IRIS_CACHE_FS,
181    [MESA_SHADER_COMPUTE]   = IRIS_CACHE_CS,
182 };
183 
184 /**
185  * Search for a compiled shader in the disk cache.  If found, upload it
186  * to the in-memory program cache so we can use it.
187  */
188 bool
iris_disk_cache_retrieve(struct iris_screen * screen,struct u_upload_mgr * uploader,struct iris_uncompiled_shader * ish,struct iris_compiled_shader * shader,const void * prog_key,uint32_t key_size)189 iris_disk_cache_retrieve(struct iris_screen *screen,
190                          struct u_upload_mgr *uploader,
191                          struct iris_uncompiled_shader *ish,
192                          struct iris_compiled_shader *shader,
193                          const void *prog_key,
194                          uint32_t key_size)
195 {
196 #ifdef ENABLE_SHADER_CACHE
197    struct disk_cache *cache = screen->disk_cache;
198    gl_shader_stage stage = ish->nir->info.stage;
199 
200    if (!cache)
201       return false;
202 
203    cache_key cache_key;
204    iris_disk_cache_compute_key(cache, ish, prog_key, key_size, cache_key);
205 
206    if (debug) {
207       char sha1[41];
208       _mesa_sha1_format(sha1, cache_key);
209       fprintf(stderr, "[mesa disk cache] retrieving %s: ", sha1);
210    }
211 
212    size_t size;
213    void *buffer = disk_cache_get(screen->disk_cache, cache_key, &size);
214 
215    if (debug)
216       fprintf(stderr, "%s\n", buffer ? "found" : "missing");
217 
218    if (!buffer)
219       return false;
220 
221    const uint32_t prog_data_size =
222 #ifdef INTEL_USE_ELK
223       screen->elk ? elk_prog_data_size(stage) :
224 #endif
225       brw_prog_data_size(stage);
226 
227    void *prog_data = ralloc_size(NULL, prog_data_size);
228    const void *assembly;
229    uint32_t num_system_values;
230    uint32_t kernel_input_size;
231    uint32_t *system_values = NULL;
232    uint32_t *so_decls = NULL;
233 
234    struct brw_stage_prog_data *brw = screen->brw ? prog_data : NULL;
235 #ifdef INTEL_USE_ELK
236    struct elk_stage_prog_data *elk = screen->elk ? prog_data : NULL;
237    assert((brw == NULL) != (elk == NULL));
238 #else
239    assert(brw);
240 #endif
241 
242    struct blob_reader blob;
243    blob_reader_init(&blob, buffer, size);
244    blob_copy_bytes(&blob, prog_data, prog_data_size);
245 
246    const unsigned program_size =
247 #ifdef INTEL_USE_ELK
248       elk ? elk->program_size :
249 #endif
250       brw->program_size;
251 
252    assembly = blob_read_bytes(&blob, program_size);
253    num_system_values = blob_read_uint32(&blob);
254    if (num_system_values) {
255       system_values =
256          ralloc_array(NULL, uint32_t, num_system_values);
257       blob_copy_bytes(&blob, system_values,
258                       num_system_values * sizeof(uint32_t));
259    }
260 
261    kernel_input_size = blob_read_uint32(&blob);
262 
263    if (brw) {
264       brw->relocs = NULL;
265       if (brw->num_relocs) {
266          struct brw_shader_reloc *relocs =
267             ralloc_array(NULL, struct brw_shader_reloc, brw->num_relocs);
268          blob_copy_bytes(&blob, relocs,
269                          brw->num_relocs * sizeof(struct brw_shader_reloc));
270          brw->relocs = relocs;
271       }
272 
273       brw->param = NULL;
274       if (brw->nr_params) {
275          brw->param = ralloc_array(NULL, uint32_t, brw->nr_params);
276          blob_copy_bytes(&blob, brw->param, brw->nr_params * sizeof(uint32_t));
277       }
278    } else {
279 #ifdef INTEL_USE_ELK
280       elk->relocs = NULL;
281       if (elk->num_relocs) {
282          struct elk_shader_reloc *relocs =
283             ralloc_array(NULL, struct elk_shader_reloc, elk->num_relocs);
284          blob_copy_bytes(&blob, relocs,
285                          elk->num_relocs * sizeof(struct elk_shader_reloc));
286          elk->relocs = relocs;
287       }
288 
289       elk->param = NULL;
290       if (elk->nr_params) {
291          elk->param = ralloc_array(NULL, uint32_t, elk->nr_params);
292          blob_copy_bytes(&blob, elk->param,
293                          elk->nr_params * sizeof(uint32_t));
294       }
295 #else
296       unreachable("no elk support");
297 #endif
298    }
299 
300    struct iris_binding_table bt;
301    blob_copy_bytes(&blob, &bt, sizeof(bt));
302 
303    if (stage == MESA_SHADER_VERTEX ||
304        stage == MESA_SHADER_TESS_EVAL ||
305        stage == MESA_SHADER_GEOMETRY) {
306       struct intel_vue_map *vue_map =
307 #ifdef INTEL_USE_ELK
308          screen->elk ? &elk_vue_prog_data(prog_data)->vue_map :
309 #endif
310          &brw_vue_prog_data(prog_data)->vue_map;
311       so_decls = screen->vtbl.create_so_decl_list(&ish->stream_output, vue_map);
312    }
313 
314    /* System values and uniforms are stored in constant buffer 0, the
315     * user-facing UBOs are indexed by one.  So if any constant buffer is
316     * needed, the constant buffer 0 will be needed, so account for it.
317     */
318    unsigned num_cbufs = ish->nir->info.num_ubos;
319 
320    if (num_cbufs || ish->nir->num_uniforms)
321       num_cbufs++;
322 
323    if (num_system_values || kernel_input_size)
324       num_cbufs++;
325 
326    if (brw)
327       iris_apply_brw_prog_data(shader, brw);
328    else
329 #ifdef INTEL_USE_ELK
330       iris_apply_elk_prog_data(shader, elk);
331 #else
332       unreachable("no elk support");
333 #endif
334 
335    iris_finalize_program(shader, so_decls, system_values,
336                          num_system_values, kernel_input_size, num_cbufs,
337                          &bt);
338 
339    assert(stage < ARRAY_SIZE(cache_id_for_stage));
340    enum iris_program_cache_id cache_id = cache_id_for_stage[stage];
341 
342    /* Upload our newly read shader to the in-memory program cache. */
343    iris_upload_shader(screen, ish, shader, NULL, uploader,
344                       cache_id, key_size, prog_key, assembly);
345 
346    free(buffer);
347 
348    return true;
349 #else
350    return false;
351 #endif
352 }
353 
354 /**
355  * Initialize the on-disk shader cache.
356  */
357 void
iris_disk_cache_init(struct iris_screen * screen)358 iris_disk_cache_init(struct iris_screen *screen)
359 {
360 #ifdef ENABLE_SHADER_CACHE
361    if (INTEL_DEBUG(DEBUG_DISK_CACHE_DISABLE_MASK))
362       return;
363 
364    /* array length = strlen("iris_") + sha + nul char */
365    char renderer[5 + 40 + 1] = {0};
366 
367    if (screen->brw) {
368       char device_info_sha[41];
369       brw_device_sha1(device_info_sha, screen->devinfo);
370       memcpy(renderer, "iris_", 5);
371       memcpy(renderer + 5, device_info_sha, 40);
372    } else {
373       /* For Gfx8, just use PCI ID. */
374       ASSERTED int len = snprintf(renderer, sizeof(renderer),
375                                   "iris_%04x", screen->devinfo->pci_device_id);
376       assert(len < ARRAY_SIZE(renderer) - 1);
377    }
378 
379    const struct build_id_note *note =
380       build_id_find_nhdr_for_addr(iris_disk_cache_init);
381    assert(note && build_id_length(note) == 20); /* sha1 */
382 
383    const uint8_t *id_sha1 = build_id_data(note);
384    assert(id_sha1);
385 
386    char timestamp[41];
387    _mesa_sha1_format(timestamp, id_sha1);
388 
389    const uint64_t driver_flags =
390 #ifdef INTEL_USE_ELK
391       screen->elk ? elk_get_compiler_config_value(screen->elk) :
392 #endif
393       brw_get_compiler_config_value(screen->brw);
394 
395    screen->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
396 #endif
397 }
398