2 * Copyright © 2018 Intel Corporation
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:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
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.
24 * @file iris_disk_cache.c
26 * Functions for interacting with the on-disk shader cache.
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"
40 #include "iris_context.h"
42 static bool debug
= false;
45 * Compute a disk cache key for the given uncompiled shader and NOS key.
48 iris_disk_cache_compute_key(struct disk_cache
*cache
,
49 const struct iris_uncompiled_shader
*ish
,
50 const void *orig_prog_key
,
51 uint32_t prog_key_size
,
54 /* Create a copy of the program key with program_string_id zeroed out.
55 * It's essentially random data which we don't want to include in our
56 * hashing and comparisons. We'll set a proper value on a cache hit.
58 union brw_any_prog_key prog_key
;
59 memcpy(&prog_key
, orig_prog_key
, prog_key_size
);
60 prog_key
.base
.program_string_id
= 0;
62 uint8_t data
[sizeof(prog_key
) + sizeof(ish
->nir_sha1
)];
63 uint32_t data_size
= prog_key_size
+ sizeof(ish
->nir_sha1
);
65 memcpy(data
, ish
->nir_sha1
, sizeof(ish
->nir_sha1
));
66 memcpy(data
+ sizeof(ish
->nir_sha1
), &prog_key
, prog_key_size
);
68 disk_cache_compute_key(cache
, data
, data_size
, cache_key
);
72 * Store the given compiled shader in the disk cache.
74 * This should only be called on newly compiled shaders. No checking is
75 * done to prevent repeated stores of the same shader.
78 iris_disk_cache_store(struct disk_cache
*cache
,
79 const struct iris_uncompiled_shader
*ish
,
80 const struct iris_compiled_shader
*shader
,
82 uint32_t prog_key_size
)
84 #ifdef ENABLE_SHADER_CACHE
88 gl_shader_stage stage
= ish
->nir
->info
.stage
;
89 const struct brw_stage_prog_data
*prog_data
= shader
->prog_data
;
92 iris_disk_cache_compute_key(cache
, ish
, prog_key
, prog_key_size
, cache_key
);
96 _mesa_sha1_format(sha1
, cache_key
);
97 fprintf(stderr
, "[mesa disk cache] storing %s\n", sha1
);
103 /* We write the following data to the cache blob:
105 * 1. Prog data (must come first because it has the assembly size)
107 * 3. Number of entries in the system value array
108 * 4. System value array
109 * 5. Size (in bytes) of kernel inputs
110 * 6. Shader relocations
111 * 7. Legacy param array (only used for compute workgroup ID)
114 blob_write_bytes(&blob
, shader
->prog_data
, brw_prog_data_size(stage
));
115 blob_write_bytes(&blob
, shader
->map
, shader
->prog_data
->program_size
);
116 blob_write_uint32(&blob
, shader
->num_system_values
);
117 blob_write_bytes(&blob
, shader
->system_values
,
118 shader
->num_system_values
* sizeof(enum brw_param_builtin
));
119 blob_write_uint32(&blob
, shader
->kernel_input_size
);
120 blob_write_bytes(&blob
, prog_data
->relocs
,
121 prog_data
->num_relocs
* sizeof(struct brw_shader_reloc
));
122 blob_write_bytes(&blob
, prog_data
->param
,
123 prog_data
->nr_params
* sizeof(uint32_t));
124 blob_write_bytes(&blob
, &shader
->bt
, sizeof(shader
->bt
));
126 disk_cache_put(cache
, cache_key
, blob
.data
, blob
.size
, NULL
);
131 static const enum iris_program_cache_id cache_id_for_stage
[] = {
132 [MESA_SHADER_VERTEX
] = IRIS_CACHE_VS
,
133 [MESA_SHADER_TESS_CTRL
] = IRIS_CACHE_TCS
,
134 [MESA_SHADER_TESS_EVAL
] = IRIS_CACHE_TES
,
135 [MESA_SHADER_GEOMETRY
] = IRIS_CACHE_GS
,
136 [MESA_SHADER_FRAGMENT
] = IRIS_CACHE_FS
,
137 [MESA_SHADER_COMPUTE
] = IRIS_CACHE_CS
,
141 * Search for a compiled shader in the disk cache. If found, upload it
142 * to the in-memory program cache so we can use it.
144 struct iris_compiled_shader
*
145 iris_disk_cache_retrieve(struct iris_context
*ice
,
146 const struct iris_uncompiled_shader
*ish
,
147 const void *prog_key
,
150 #ifdef ENABLE_SHADER_CACHE
151 struct iris_screen
*screen
= (void *) ice
->ctx
.screen
;
152 struct disk_cache
*cache
= screen
->disk_cache
;
153 gl_shader_stage stage
= ish
->nir
->info
.stage
;
159 iris_disk_cache_compute_key(cache
, ish
, prog_key
, key_size
, cache_key
);
163 _mesa_sha1_format(sha1
, cache_key
);
164 fprintf(stderr
, "[mesa disk cache] retrieving %s: ", sha1
);
168 void *buffer
= disk_cache_get(screen
->disk_cache
, cache_key
, &size
);
171 fprintf(stderr
, "%s\n", buffer
? "found" : "missing");
176 const uint32_t prog_data_size
= brw_prog_data_size(stage
);
178 struct brw_stage_prog_data
*prog_data
= ralloc_size(NULL
, prog_data_size
);
179 const void *assembly
;
180 uint32_t num_system_values
;
181 uint32_t kernel_input_size
;
182 uint32_t *system_values
= NULL
;
183 uint32_t *so_decls
= NULL
;
185 struct blob_reader blob
;
186 blob_reader_init(&blob
, buffer
, size
);
187 blob_copy_bytes(&blob
, prog_data
, prog_data_size
);
188 assembly
= blob_read_bytes(&blob
, prog_data
->program_size
);
189 num_system_values
= blob_read_uint32(&blob
);
190 if (num_system_values
) {
192 ralloc_array(NULL
, enum brw_param_builtin
, num_system_values
);
193 blob_copy_bytes(&blob
, system_values
,
194 num_system_values
* sizeof(enum brw_param_builtin
));
197 kernel_input_size
= blob_read_uint32(&blob
);
199 prog_data
->relocs
= NULL
;
200 if (prog_data
->num_relocs
) {
201 struct brw_shader_reloc
*relocs
=
202 ralloc_array(NULL
, struct brw_shader_reloc
, prog_data
->num_relocs
);
203 blob_copy_bytes(&blob
, relocs
,
204 prog_data
->num_relocs
* sizeof(struct brw_shader_reloc
));
205 prog_data
->relocs
= relocs
;
208 prog_data
->param
= NULL
;
209 prog_data
->pull_param
= NULL
;
210 assert(prog_data
->nr_pull_params
== 0);
212 if (prog_data
->nr_params
) {
213 prog_data
->param
= ralloc_array(NULL
, uint32_t, prog_data
->nr_params
);
214 blob_copy_bytes(&blob
, prog_data
->param
,
215 prog_data
->nr_params
* sizeof(uint32_t));
218 struct iris_binding_table bt
;
219 blob_copy_bytes(&blob
, &bt
, sizeof(bt
));
221 if (stage
== MESA_SHADER_VERTEX
||
222 stage
== MESA_SHADER_TESS_EVAL
||
223 stage
== MESA_SHADER_GEOMETRY
) {
224 struct brw_vue_prog_data
*vue_prog_data
= (void *) prog_data
;
225 so_decls
= screen
->vtbl
.create_so_decl_list(&ish
->stream_output
,
226 &vue_prog_data
->vue_map
);
229 /* System values and uniforms are stored in constant buffer 0, the
230 * user-facing UBOs are indexed by one. So if any constant buffer is
231 * needed, the constant buffer 0 will be needed, so account for it.
233 unsigned num_cbufs
= ish
->nir
->info
.num_ubos
;
235 if (num_cbufs
|| ish
->nir
->num_uniforms
)
238 if (num_system_values
|| kernel_input_size
)
241 assert(stage
< ARRAY_SIZE(cache_id_for_stage
));
242 enum iris_program_cache_id cache_id
= cache_id_for_stage
[stage
];
244 /* Upload our newly read shader to the in-memory program cache and
245 * return it to the caller.
247 struct iris_compiled_shader
*shader
=
248 iris_upload_shader(ice
, cache_id
, key_size
, prog_key
, assembly
,
249 prog_data
, so_decls
, system_values
,
250 num_system_values
, kernel_input_size
, num_cbufs
, &bt
);
261 * Initialize the on-disk shader cache.
264 iris_disk_cache_init(struct iris_screen
*screen
)
266 #ifdef ENABLE_SHADER_CACHE
267 if (INTEL_DEBUG
& DEBUG_DISK_CACHE_DISABLE_MASK
)
270 /* array length = print length + nul char + 1 extra to verify it's unused */
273 snprintf(renderer
, sizeof(renderer
), "iris_%04x", screen
->pci_id
);
274 assert(len
== sizeof(renderer
) - 2);
276 const struct build_id_note
*note
=
277 build_id_find_nhdr_for_addr(iris_disk_cache_init
);
278 assert(note
&& build_id_length(note
) == 20); /* sha1 */
280 const uint8_t *id_sha1
= build_id_data(note
);
284 _mesa_sha1_format(timestamp
, id_sha1
);
286 const uint64_t driver_flags
=
287 brw_get_compiler_config_value(screen
->compiler
);
288 screen
->disk_cache
= disk_cache_create(renderer
, timestamp
, driver_flags
);