1/* 2 * Copyright © 2018 Intel Corporation 3 * Copyright (c) 2021 Lima Project 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sub license, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 */ 25 26#include "compiler/nir/nir.h" 27#include "util/blob.h" 28#include "util/build_id.h" 29#include "util/disk_cache.h" 30#include "util/mesa-sha1.h" 31 32#include "lima_context.h" 33#include "lima_screen.h" 34#include "lima_disk_cache.h" 35 36void 37lima_vs_disk_cache_store(struct disk_cache *cache, 38 const struct lima_vs_key *key, 39 const struct lima_vs_compiled_shader *shader) 40{ 41 if (!cache) 42 return; 43 44 cache_key cache_key; 45 disk_cache_compute_key(cache, key, sizeof(*key), cache_key); 46 47 if (lima_debug & LIMA_DEBUG_DISK_CACHE) { 48 char sha1[41]; 49 _mesa_sha1_format(sha1, cache_key); 50 fprintf(stderr, "[mesa disk cache] storing %s\n", sha1); 51 } 52 53 struct blob blob; 54 blob_init(&blob); 55 56 blob_write_bytes(&blob, &shader->state, sizeof(shader->state)); 57 blob_write_bytes(&blob, shader->shader, shader->state.shader_size); 58 blob_write_bytes(&blob, shader->constant, shader->state.constant_size); 59 60 disk_cache_put(cache, cache_key, blob.data, blob.size, NULL); 61 blob_finish(&blob); 62} 63 64void 65lima_fs_disk_cache_store(struct disk_cache *cache, 66 const struct lima_fs_key *key, 67 const struct lima_fs_compiled_shader *shader) 68{ 69 if (!cache) 70 return; 71 72 cache_key cache_key; 73 disk_cache_compute_key(cache, key, sizeof(*key), cache_key); 74 75 if (lima_debug & LIMA_DEBUG_DISK_CACHE) { 76 char sha1[41]; 77 _mesa_sha1_format(sha1, cache_key); 78 fprintf(stderr, "[mesa disk cache] storing %s\n", sha1); 79 } 80 81 struct blob blob; 82 blob_init(&blob); 83 84 blob_write_bytes(&blob, &shader->state, sizeof(shader->state)); 85 blob_write_bytes(&blob, shader->shader, shader->state.shader_size); 86 87 disk_cache_put(cache, cache_key, blob.data, blob.size, NULL); 88 blob_finish(&blob); 89} 90 91struct lima_vs_compiled_shader * 92lima_vs_disk_cache_retrieve(struct disk_cache *cache, 93 struct lima_vs_key *key) 94{ 95 struct lima_vs_compiled_shader *shader = NULL; 96 97 if (!cache) 98 return NULL; 99 100 cache_key cache_key; 101 disk_cache_compute_key(cache, key, sizeof(*key), cache_key); 102 103 if (lima_debug & LIMA_DEBUG_DISK_CACHE) { 104 char sha1[41]; 105 _mesa_sha1_format(sha1, cache_key); 106 fprintf(stderr, "[mesa disk cache] retrieving %s: ", sha1); 107 } 108 109 size_t size; 110 void *buffer = disk_cache_get(cache, cache_key, &size); 111 112 if (lima_debug & LIMA_DEBUG_DISK_CACHE) 113 fprintf(stderr, "%s\n", buffer ? "found" : "missing"); 114 115 if (!buffer) 116 return NULL; 117 118 shader = rzalloc(NULL, struct lima_vs_compiled_shader); 119 if (!shader) 120 goto out; 121 122 struct blob_reader blob; 123 blob_reader_init(&blob, buffer, size); 124 blob_copy_bytes(&blob, &shader->state, sizeof(shader->state)); 125 shader->shader = rzalloc_size(shader, shader->state.shader_size); 126 if (!shader->shader) 127 goto err; 128 blob_copy_bytes(&blob, shader->shader, shader->state.shader_size); 129 shader->constant = rzalloc_size(shader, shader->state.constant_size); 130 if (!shader->constant) 131 goto err; 132 blob_copy_bytes(&blob, shader->constant, shader->state.constant_size); 133 134out: 135 free(buffer); 136 return shader; 137 138err: 139 ralloc_free(shader); 140 return NULL; 141} 142 143struct lima_fs_compiled_shader * 144lima_fs_disk_cache_retrieve(struct disk_cache *cache, 145 struct lima_fs_key *key) 146{ 147 struct lima_fs_compiled_shader *shader = NULL; 148 149 if (!cache) 150 return NULL; 151 152 cache_key cache_key; 153 disk_cache_compute_key(cache, key, sizeof(*key), cache_key); 154 155 if (lima_debug & LIMA_DEBUG_DISK_CACHE) { 156 char sha1[41]; 157 _mesa_sha1_format(sha1, cache_key); 158 fprintf(stderr, "[mesa disk cache] retrieving %s: ", sha1); 159 } 160 161 size_t size; 162 void *buffer = disk_cache_get(cache, cache_key, &size); 163 164 if (lima_debug & LIMA_DEBUG_DISK_CACHE) 165 fprintf(stderr, "%s\n", buffer ? "found" : "missing"); 166 167 if (!buffer) 168 return NULL; 169 170 shader = rzalloc(NULL, struct lima_fs_compiled_shader); 171 if (!shader) 172 goto out; 173 174 struct blob_reader blob; 175 blob_reader_init(&blob, buffer, size); 176 blob_copy_bytes(&blob, &shader->state, sizeof(shader->state)); 177 shader->shader = rzalloc_size(shader, shader->state.shader_size); 178 if (!shader->shader) 179 goto err; 180 blob_copy_bytes(&blob, shader->shader, shader->state.shader_size); 181 182out: 183 free(buffer); 184 return shader; 185 186err: 187 ralloc_free(shader); 188 return NULL; 189} 190 191void 192lima_disk_cache_init(struct lima_screen *screen) 193{ 194 const struct build_id_note *note = 195 build_id_find_nhdr_for_addr(lima_disk_cache_init); 196 assert(note && build_id_length(note) == 20); /* sha1 */ 197 198 const uint8_t *id_sha1 = build_id_data(note); 199 assert(id_sha1); 200 201 char timestamp[41]; 202 _mesa_sha1_format(timestamp, id_sha1); 203 204 screen->disk_cache = disk_cache_create(screen->base.get_name(&screen->base), timestamp, 0); 205} 206