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 40#include "iris_context.h" 41 42static bool debug = false; 43 44/** 45 * Compute a disk cache key for the given uncompiled shader and NOS key. 46 */ 47static void 48iris_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, 52 cache_key cache_key) 53{ 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. 57 */ 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; 61 62 uint8_t data[sizeof(prog_key) + sizeof(ish->nir_sha1)]; 63 uint32_t data_size = prog_key_size + sizeof(ish->nir_sha1); 64 65 memcpy(data, ish->nir_sha1, sizeof(ish->nir_sha1)); 66 memcpy(data + sizeof(ish->nir_sha1), &prog_key, prog_key_size); 67 68 disk_cache_compute_key(cache, data, data_size, cache_key); 69} 70 71/** 72 * Store the given compiled shader in the disk cache. 73 * 74 * This should only be called on newly compiled shaders. No checking is 75 * done to prevent repeated stores of the same shader. 76 */ 77void 78iris_disk_cache_store(struct disk_cache *cache, 79 const struct iris_uncompiled_shader *ish, 80 const struct iris_compiled_shader *shader, 81 const void *prog_key, 82 uint32_t prog_key_size) 83{ 84#ifdef ENABLE_SHADER_CACHE 85 if (!cache) 86 return; 87 88 gl_shader_stage stage = ish->nir->info.stage; 89 const struct brw_stage_prog_data *prog_data = shader->prog_data; 90 91 cache_key cache_key; 92 iris_disk_cache_compute_key(cache, ish, prog_key, prog_key_size, cache_key); 93 94 if (debug) { 95 char sha1[41]; 96 _mesa_sha1_format(sha1, cache_key); 97 fprintf(stderr, "[mesa disk cache] storing %s\n", sha1); 98 } 99 100 struct blob blob; 101 blob_init(&blob); 102 103 /* We write the following data to the cache blob: 104 * 105 * 1. Prog data (must come first because it has the assembly size) 106 * 2. Assembly code 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) 112 * 8. Binding table 113 */ 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)); 125 126 disk_cache_put(cache, cache_key, blob.data, blob.size, NULL); 127 blob_finish(&blob); 128#endif 129} 130 131static 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, 138}; 139 140/** 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. 143 */ 144bool 145iris_disk_cache_retrieve(struct iris_screen *screen, 146 struct u_upload_mgr *uploader, 147 struct iris_uncompiled_shader *ish, 148 struct iris_compiled_shader *shader, 149 const void *prog_key, 150 uint32_t key_size) 151{ 152#ifdef ENABLE_SHADER_CACHE 153 struct disk_cache *cache = screen->disk_cache; 154 gl_shader_stage stage = ish->nir->info.stage; 155 156 if (!cache) 157 return false; 158 159 cache_key cache_key; 160 iris_disk_cache_compute_key(cache, ish, prog_key, key_size, cache_key); 161 162 if (debug) { 163 char sha1[41]; 164 _mesa_sha1_format(sha1, cache_key); 165 fprintf(stderr, "[mesa disk cache] retrieving %s: ", sha1); 166 } 167 168 size_t size; 169 void *buffer = disk_cache_get(screen->disk_cache, cache_key, &size); 170 171 if (debug) 172 fprintf(stderr, "%s\n", buffer ? "found" : "missing"); 173 174 if (!buffer) 175 return false; 176 177 const uint32_t prog_data_size = brw_prog_data_size(stage); 178 179 struct brw_stage_prog_data *prog_data = ralloc_size(NULL, prog_data_size); 180 const void *assembly; 181 uint32_t num_system_values; 182 uint32_t kernel_input_size; 183 uint32_t *system_values = NULL; 184 uint32_t *so_decls = NULL; 185 186 struct blob_reader blob; 187 blob_reader_init(&blob, buffer, size); 188 blob_copy_bytes(&blob, prog_data, prog_data_size); 189 assembly = blob_read_bytes(&blob, prog_data->program_size); 190 num_system_values = blob_read_uint32(&blob); 191 if (num_system_values) { 192 system_values = 193 ralloc_array(NULL, enum brw_param_builtin, num_system_values); 194 blob_copy_bytes(&blob, system_values, 195 num_system_values * sizeof(enum brw_param_builtin)); 196 } 197 198 kernel_input_size = blob_read_uint32(&blob); 199 200 prog_data->relocs = NULL; 201 if (prog_data->num_relocs) { 202 struct brw_shader_reloc *relocs = 203 ralloc_array(NULL, struct brw_shader_reloc, prog_data->num_relocs); 204 blob_copy_bytes(&blob, relocs, 205 prog_data->num_relocs * sizeof(struct brw_shader_reloc)); 206 prog_data->relocs = relocs; 207 } 208 209 prog_data->param = NULL; 210 if (prog_data->nr_params) { 211 prog_data->param = ralloc_array(NULL, uint32_t, prog_data->nr_params); 212 blob_copy_bytes(&blob, prog_data->param, 213 prog_data->nr_params * sizeof(uint32_t)); 214 } 215 216 struct iris_binding_table bt; 217 blob_copy_bytes(&blob, &bt, sizeof(bt)); 218 219 if (stage == MESA_SHADER_VERTEX || 220 stage == MESA_SHADER_TESS_EVAL || 221 stage == MESA_SHADER_GEOMETRY) { 222 struct brw_vue_prog_data *vue_prog_data = (void *) prog_data; 223 so_decls = screen->vtbl.create_so_decl_list(&ish->stream_output, 224 &vue_prog_data->vue_map); 225 } 226 227 /* System values and uniforms are stored in constant buffer 0, the 228 * user-facing UBOs are indexed by one. So if any constant buffer is 229 * needed, the constant buffer 0 will be needed, so account for it. 230 */ 231 unsigned num_cbufs = ish->nir->info.num_ubos; 232 233 if (num_cbufs || ish->nir->num_uniforms) 234 num_cbufs++; 235 236 if (num_system_values || kernel_input_size) 237 num_cbufs++; 238 239 iris_finalize_program(shader, prog_data, so_decls, system_values, 240 num_system_values, kernel_input_size, num_cbufs, 241 &bt); 242 243 assert(stage < ARRAY_SIZE(cache_id_for_stage)); 244 enum iris_program_cache_id cache_id = cache_id_for_stage[stage]; 245 246 /* Upload our newly read shader to the in-memory program cache. */ 247 iris_upload_shader(screen, ish, shader, NULL, uploader, 248 cache_id, key_size, prog_key, assembly); 249 250 free(buffer); 251 252 return true; 253#else 254 return false; 255#endif 256} 257 258/** 259 * Initialize the on-disk shader cache. 260 */ 261void 262iris_disk_cache_init(struct iris_screen *screen) 263{ 264#ifdef ENABLE_SHADER_CACHE 265 if (INTEL_DEBUG(DEBUG_DISK_CACHE_DISABLE_MASK)) 266 return; 267 268 /* array length = print length + nul char + 1 extra to verify it's unused */ 269 char renderer[11]; 270 UNUSED int len = 271 snprintf(renderer, sizeof(renderer), "iris_%04x", screen->pci_id); 272 assert(len == sizeof(renderer) - 2); 273 274 const struct build_id_note *note = 275 build_id_find_nhdr_for_addr(iris_disk_cache_init); 276 assert(note && build_id_length(note) == 20); /* sha1 */ 277 278 const uint8_t *id_sha1 = build_id_data(note); 279 assert(id_sha1); 280 281 char timestamp[41]; 282 _mesa_sha1_format(timestamp, id_sha1); 283 284 const uint64_t driver_flags = 285 brw_get_compiler_config_value(screen->compiler); 286 screen->disk_cache = disk_cache_create(renderer, timestamp, driver_flags); 287#endif 288} 289