1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #ifdef ENABLE_SHADER_CACHE
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include <ctype.h>
27*61046927SAndroid Build Coastguard Worker #include <ftw.h>
28*61046927SAndroid Build Coastguard Worker #include <string.h>
29*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
30*61046927SAndroid Build Coastguard Worker #include <stdio.h>
31*61046927SAndroid Build Coastguard Worker #include <sys/file.h>
32*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
33*61046927SAndroid Build Coastguard Worker #include <sys/stat.h>
34*61046927SAndroid Build Coastguard Worker #include <sys/mman.h>
35*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
36*61046927SAndroid Build Coastguard Worker #include <errno.h>
37*61046927SAndroid Build Coastguard Worker #include <dirent.h>
38*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker #include "util/compress.h"
41*61046927SAndroid Build Coastguard Worker #include "util/crc32.h"
42*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
43*61046927SAndroid Build Coastguard Worker #include "util/rand_xor.h"
44*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
45*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
46*61046927SAndroid Build Coastguard Worker #include "util/perf/cpu_trace.h"
47*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
48*61046927SAndroid Build Coastguard Worker #include "util/compiler.h"
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker #include "disk_cache.h"
51*61046927SAndroid Build Coastguard Worker #include "disk_cache_os.h"
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker /* The cache version should be bumped whenever a change is made to the
54*61046927SAndroid Build Coastguard Worker * structure of cache entries or the index. This will give any 3rd party
55*61046927SAndroid Build Coastguard Worker * applications reading the cache entries a chance to adjust to the changes.
56*61046927SAndroid Build Coastguard Worker *
57*61046927SAndroid Build Coastguard Worker * - The cache version is checked internally when reading a cache entry. If we
58*61046927SAndroid Build Coastguard Worker * ever have a mismatch we are in big trouble as this means we had a cache
59*61046927SAndroid Build Coastguard Worker * collision. In case of such an event please check the skys for giant
60*61046927SAndroid Build Coastguard Worker * asteroids and that the entire Mesa team hasn't been eaten by wolves.
61*61046927SAndroid Build Coastguard Worker *
62*61046927SAndroid Build Coastguard Worker * - There is no strict requirement that cache versions be backwards
63*61046927SAndroid Build Coastguard Worker * compatible but effort should be taken to limit disruption where possible.
64*61046927SAndroid Build Coastguard Worker */
65*61046927SAndroid Build Coastguard Worker #define CACHE_VERSION 1
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker #define DRV_KEY_CPY(_dst, _src, _src_size) \
68*61046927SAndroid Build Coastguard Worker do { \
69*61046927SAndroid Build Coastguard Worker memcpy(_dst, _src, _src_size); \
70*61046927SAndroid Build Coastguard Worker _dst += _src_size; \
71*61046927SAndroid Build Coastguard Worker } while (0);
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker static bool
disk_cache_init_queue(struct disk_cache * cache)74*61046927SAndroid Build Coastguard Worker disk_cache_init_queue(struct disk_cache *cache)
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker if (util_queue_is_initialized(&cache->cache_queue))
77*61046927SAndroid Build Coastguard Worker return true;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /* 4 threads were chosen below because just about all modern CPUs currently
80*61046927SAndroid Build Coastguard Worker * available that run Mesa have *at least* 4 cores. For these CPUs allowing
81*61046927SAndroid Build Coastguard Worker * more threads can result in the queue being processed faster, thus
82*61046927SAndroid Build Coastguard Worker * avoiding excessive memory use due to a backlog of cache entrys building
83*61046927SAndroid Build Coastguard Worker * up in the queue. Since we set the UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY
84*61046927SAndroid Build Coastguard Worker * flag this should have little negative impact on low core systems.
85*61046927SAndroid Build Coastguard Worker *
86*61046927SAndroid Build Coastguard Worker * The queue will resize automatically when it's full, so adding new jobs
87*61046927SAndroid Build Coastguard Worker * doesn't stall.
88*61046927SAndroid Build Coastguard Worker */
89*61046927SAndroid Build Coastguard Worker return util_queue_init(&cache->cache_queue, "disk$", 32, 4,
90*61046927SAndroid Build Coastguard Worker UTIL_QUEUE_INIT_RESIZE_IF_FULL |
91*61046927SAndroid Build Coastguard Worker UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY |
92*61046927SAndroid Build Coastguard Worker UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY, NULL);
93*61046927SAndroid Build Coastguard Worker }
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker static struct disk_cache *
disk_cache_type_create(const char * gpu_name,const char * driver_id,uint64_t driver_flags,enum disk_cache_type cache_type)96*61046927SAndroid Build Coastguard Worker disk_cache_type_create(const char *gpu_name,
97*61046927SAndroid Build Coastguard Worker const char *driver_id,
98*61046927SAndroid Build Coastguard Worker uint64_t driver_flags,
99*61046927SAndroid Build Coastguard Worker enum disk_cache_type cache_type)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker void *local;
102*61046927SAndroid Build Coastguard Worker struct disk_cache *cache = NULL;
103*61046927SAndroid Build Coastguard Worker char *max_size_str;
104*61046927SAndroid Build Coastguard Worker uint64_t max_size;
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker uint8_t cache_version = CACHE_VERSION;
107*61046927SAndroid Build Coastguard Worker size_t cv_size = sizeof(cache_version);
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker /* A ralloc context for transient data during this invocation. */
110*61046927SAndroid Build Coastguard Worker local = ralloc_context(NULL);
111*61046927SAndroid Build Coastguard Worker if (local == NULL)
112*61046927SAndroid Build Coastguard Worker goto fail;
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker cache = rzalloc(NULL, struct disk_cache);
115*61046927SAndroid Build Coastguard Worker if (cache == NULL)
116*61046927SAndroid Build Coastguard Worker goto fail;
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker /* Assume failure. */
119*61046927SAndroid Build Coastguard Worker cache->path_init_failed = true;
120*61046927SAndroid Build Coastguard Worker cache->type = DISK_CACHE_NONE;
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker if (!disk_cache_enabled())
123*61046927SAndroid Build Coastguard Worker goto path_fail;
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker char *path = disk_cache_generate_cache_dir(local, gpu_name, driver_id,
126*61046927SAndroid Build Coastguard Worker cache_type);
127*61046927SAndroid Build Coastguard Worker if (!path)
128*61046927SAndroid Build Coastguard Worker goto path_fail;
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker cache->path = ralloc_strdup(cache, path);
131*61046927SAndroid Build Coastguard Worker if (cache->path == NULL)
132*61046927SAndroid Build Coastguard Worker goto path_fail;
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker /* Cache tests that want to have a disabled cache compression are using
135*61046927SAndroid Build Coastguard Worker * the "make_check_uncompressed" for the driver_id name. Hence here we
136*61046927SAndroid Build Coastguard Worker * disable disk cache compression when mesa's build tests require it.
137*61046927SAndroid Build Coastguard Worker */
138*61046927SAndroid Build Coastguard Worker if (strcmp(driver_id, "make_check_uncompressed") == 0)
139*61046927SAndroid Build Coastguard Worker cache->compression_disabled = true;
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker if (cache_type == DISK_CACHE_SINGLE_FILE) {
142*61046927SAndroid Build Coastguard Worker if (!disk_cache_load_cache_index_foz(local, cache))
143*61046927SAndroid Build Coastguard Worker goto path_fail;
144*61046927SAndroid Build Coastguard Worker } else if (cache_type == DISK_CACHE_DATABASE) {
145*61046927SAndroid Build Coastguard Worker if (!disk_cache_db_load_cache_index(local, cache))
146*61046927SAndroid Build Coastguard Worker goto path_fail;
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker if (!getenv("MESA_SHADER_CACHE_DIR") && !getenv("MESA_GLSL_CACHE_DIR"))
150*61046927SAndroid Build Coastguard Worker disk_cache_touch_cache_user_marker(cache->path);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker cache->type = cache_type;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker cache->stats.enabled = debug_get_bool_option("MESA_SHADER_CACHE_SHOW_STATS",
155*61046927SAndroid Build Coastguard Worker false);
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker if (!disk_cache_mmap_cache_index(local, cache, path))
158*61046927SAndroid Build Coastguard Worker goto path_fail;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker max_size = 0;
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker max_size_str = getenv("MESA_SHADER_CACHE_MAX_SIZE");
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker if (!max_size_str) {
165*61046927SAndroid Build Coastguard Worker max_size_str = getenv("MESA_GLSL_CACHE_MAX_SIZE");
166*61046927SAndroid Build Coastguard Worker if (max_size_str)
167*61046927SAndroid Build Coastguard Worker fprintf(stderr,
168*61046927SAndroid Build Coastguard Worker "*** MESA_GLSL_CACHE_MAX_SIZE is deprecated; "
169*61046927SAndroid Build Coastguard Worker "use MESA_SHADER_CACHE_MAX_SIZE instead ***\n");
170*61046927SAndroid Build Coastguard Worker }
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker #ifdef MESA_SHADER_CACHE_MAX_SIZE
173*61046927SAndroid Build Coastguard Worker if( !max_size_str ) {
174*61046927SAndroid Build Coastguard Worker max_size_str = MESA_SHADER_CACHE_MAX_SIZE;
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker #endif
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker if (max_size_str) {
179*61046927SAndroid Build Coastguard Worker char *end;
180*61046927SAndroid Build Coastguard Worker max_size = strtoul(max_size_str, &end, 10);
181*61046927SAndroid Build Coastguard Worker if (end == max_size_str) {
182*61046927SAndroid Build Coastguard Worker max_size = 0;
183*61046927SAndroid Build Coastguard Worker } else {
184*61046927SAndroid Build Coastguard Worker switch (*end) {
185*61046927SAndroid Build Coastguard Worker case 'K':
186*61046927SAndroid Build Coastguard Worker case 'k':
187*61046927SAndroid Build Coastguard Worker max_size *= 1024;
188*61046927SAndroid Build Coastguard Worker break;
189*61046927SAndroid Build Coastguard Worker case 'M':
190*61046927SAndroid Build Coastguard Worker case 'm':
191*61046927SAndroid Build Coastguard Worker max_size *= 1024*1024;
192*61046927SAndroid Build Coastguard Worker break;
193*61046927SAndroid Build Coastguard Worker case '\0':
194*61046927SAndroid Build Coastguard Worker case 'G':
195*61046927SAndroid Build Coastguard Worker case 'g':
196*61046927SAndroid Build Coastguard Worker default:
197*61046927SAndroid Build Coastguard Worker max_size *= 1024*1024*1024;
198*61046927SAndroid Build Coastguard Worker break;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker }
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker /* Default to 1GB for maximum cache size. */
204*61046927SAndroid Build Coastguard Worker if (max_size == 0) {
205*61046927SAndroid Build Coastguard Worker max_size = 1024*1024*1024;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker cache->max_size = max_size;
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker if (cache->type == DISK_CACHE_DATABASE)
211*61046927SAndroid Build Coastguard Worker mesa_cache_db_multipart_set_size_limit(&cache->cache_db, cache->max_size);
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker if (!disk_cache_init_queue(cache))
214*61046927SAndroid Build Coastguard Worker goto fail;
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker cache->path_init_failed = false;
217*61046927SAndroid Build Coastguard Worker
218*61046927SAndroid Build Coastguard Worker path_fail:
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size = cv_size;
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker /* Create driver id keys */
223*61046927SAndroid Build Coastguard Worker size_t id_size = strlen(driver_id) + 1;
224*61046927SAndroid Build Coastguard Worker size_t gpu_name_size = strlen(gpu_name) + 1;
225*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size += id_size;
226*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size += gpu_name_size;
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker /* We sometimes store entire structs that contains a pointers in the cache,
229*61046927SAndroid Build Coastguard Worker * use pointer size as a key to avoid hard to debug issues.
230*61046927SAndroid Build Coastguard Worker */
231*61046927SAndroid Build Coastguard Worker uint8_t ptr_size = sizeof(void *);
232*61046927SAndroid Build Coastguard Worker size_t ptr_size_size = sizeof(ptr_size);
233*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size += ptr_size_size;
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker size_t driver_flags_size = sizeof(driver_flags);
236*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size += driver_flags_size;
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob =
239*61046927SAndroid Build Coastguard Worker ralloc_size(cache, cache->driver_keys_blob_size);
240*61046927SAndroid Build Coastguard Worker if (!cache->driver_keys_blob)
241*61046927SAndroid Build Coastguard Worker goto fail;
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker uint8_t *drv_key_blob = cache->driver_keys_blob;
244*61046927SAndroid Build Coastguard Worker DRV_KEY_CPY(drv_key_blob, &cache_version, cv_size)
245*61046927SAndroid Build Coastguard Worker DRV_KEY_CPY(drv_key_blob, driver_id, id_size)
246*61046927SAndroid Build Coastguard Worker DRV_KEY_CPY(drv_key_blob, gpu_name, gpu_name_size)
247*61046927SAndroid Build Coastguard Worker DRV_KEY_CPY(drv_key_blob, &ptr_size, ptr_size_size)
248*61046927SAndroid Build Coastguard Worker DRV_KEY_CPY(drv_key_blob, &driver_flags, driver_flags_size)
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker /* Seed our rand function */
251*61046927SAndroid Build Coastguard Worker s_rand_xorshift128plus(cache->seed_xorshift128plus, true);
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker ralloc_free(local);
254*61046927SAndroid Build Coastguard Worker
255*61046927SAndroid Build Coastguard Worker return cache;
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker fail:
258*61046927SAndroid Build Coastguard Worker if (cache)
259*61046927SAndroid Build Coastguard Worker ralloc_free(cache);
260*61046927SAndroid Build Coastguard Worker ralloc_free(local);
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker return NULL;
263*61046927SAndroid Build Coastguard Worker }
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker struct disk_cache *
disk_cache_create(const char * gpu_name,const char * driver_id,uint64_t driver_flags)266*61046927SAndroid Build Coastguard Worker disk_cache_create(const char *gpu_name, const char *driver_id,
267*61046927SAndroid Build Coastguard Worker uint64_t driver_flags)
268*61046927SAndroid Build Coastguard Worker {
269*61046927SAndroid Build Coastguard Worker enum disk_cache_type cache_type;
270*61046927SAndroid Build Coastguard Worker struct disk_cache *cache;
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker if (debug_get_bool_option("MESA_DISK_CACHE_SINGLE_FILE", false))
273*61046927SAndroid Build Coastguard Worker cache_type = DISK_CACHE_SINGLE_FILE;
274*61046927SAndroid Build Coastguard Worker else if (debug_get_bool_option("MESA_DISK_CACHE_MULTI_FILE", false))
275*61046927SAndroid Build Coastguard Worker cache_type = DISK_CACHE_MULTI_FILE;
276*61046927SAndroid Build Coastguard Worker else {
277*61046927SAndroid Build Coastguard Worker cache_type = DISK_CACHE_DATABASE;
278*61046927SAndroid Build Coastguard Worker /* Since switching the default cache to <mesa_shader_cache_db>, remove the
279*61046927SAndroid Build Coastguard Worker * old cache folder if it hasn't been modified for more than 7 days.
280*61046927SAndroid Build Coastguard Worker */
281*61046927SAndroid Build Coastguard Worker if (!getenv("MESA_SHADER_CACHE_DIR") && !getenv("MESA_GLSL_CACHE_DIR"))
282*61046927SAndroid Build Coastguard Worker disk_cache_delete_old_cache();
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker /* Create main writable cache. */
286*61046927SAndroid Build Coastguard Worker cache = disk_cache_type_create(gpu_name, driver_id, driver_flags,
287*61046927SAndroid Build Coastguard Worker cache_type);
288*61046927SAndroid Build Coastguard Worker if (!cache)
289*61046927SAndroid Build Coastguard Worker return NULL;
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker /* If MESA_DISK_CACHE_SINGLE_FILE is unset and MESA_DISK_CACHE_COMBINE_RW_WITH_RO_FOZ
292*61046927SAndroid Build Coastguard Worker * is set, then enable additional Fossilize RO caches together with the RW
293*61046927SAndroid Build Coastguard Worker * cache. At first we will check cache entry presence in the RO caches and
294*61046927SAndroid Build Coastguard Worker * if entry isn't found there, then we'll fall back to the RW cache.
295*61046927SAndroid Build Coastguard Worker */
296*61046927SAndroid Build Coastguard Worker if (cache_type != DISK_CACHE_SINGLE_FILE && !cache->path_init_failed &&
297*61046927SAndroid Build Coastguard Worker debug_get_bool_option("MESA_DISK_CACHE_COMBINE_RW_WITH_RO_FOZ", false)) {
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker /* Create read-only cache used for sharing prebuilt shaders.
300*61046927SAndroid Build Coastguard Worker * If cache entry will be found in this cache, then the main cache
301*61046927SAndroid Build Coastguard Worker * will be bypassed.
302*61046927SAndroid Build Coastguard Worker */
303*61046927SAndroid Build Coastguard Worker cache->foz_ro_cache = disk_cache_type_create(gpu_name, driver_id,
304*61046927SAndroid Build Coastguard Worker driver_flags,
305*61046927SAndroid Build Coastguard Worker DISK_CACHE_SINGLE_FILE);
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker
308*61046927SAndroid Build Coastguard Worker return cache;
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker void
disk_cache_destroy(struct disk_cache * cache)312*61046927SAndroid Build Coastguard Worker disk_cache_destroy(struct disk_cache *cache)
313*61046927SAndroid Build Coastguard Worker {
314*61046927SAndroid Build Coastguard Worker if (unlikely(cache && cache->stats.enabled)) {
315*61046927SAndroid Build Coastguard Worker printf("disk shader cache: hits = %u, misses = %u\n",
316*61046927SAndroid Build Coastguard Worker cache->stats.hits,
317*61046927SAndroid Build Coastguard Worker cache->stats.misses);
318*61046927SAndroid Build Coastguard Worker }
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker if (cache && util_queue_is_initialized(&cache->cache_queue)) {
321*61046927SAndroid Build Coastguard Worker util_queue_finish(&cache->cache_queue);
322*61046927SAndroid Build Coastguard Worker util_queue_destroy(&cache->cache_queue);
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker if (cache->foz_ro_cache)
325*61046927SAndroid Build Coastguard Worker disk_cache_destroy(cache->foz_ro_cache);
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker if (cache->type == DISK_CACHE_SINGLE_FILE)
328*61046927SAndroid Build Coastguard Worker foz_destroy(&cache->foz_db);
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker if (cache->type == DISK_CACHE_DATABASE)
331*61046927SAndroid Build Coastguard Worker mesa_cache_db_multipart_close(&cache->cache_db);
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker disk_cache_destroy_mmap(cache);
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker ralloc_free(cache);
337*61046927SAndroid Build Coastguard Worker }
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker void
disk_cache_wait_for_idle(struct disk_cache * cache)340*61046927SAndroid Build Coastguard Worker disk_cache_wait_for_idle(struct disk_cache *cache)
341*61046927SAndroid Build Coastguard Worker {
342*61046927SAndroid Build Coastguard Worker util_queue_finish(&cache->cache_queue);
343*61046927SAndroid Build Coastguard Worker }
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker void
disk_cache_remove(struct disk_cache * cache,const cache_key key)346*61046927SAndroid Build Coastguard Worker disk_cache_remove(struct disk_cache *cache, const cache_key key)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker if (cache->type == DISK_CACHE_DATABASE) {
349*61046927SAndroid Build Coastguard Worker mesa_cache_db_multipart_entry_remove(&cache->cache_db, key);
350*61046927SAndroid Build Coastguard Worker return;
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker char *filename = disk_cache_get_cache_filename(cache, key);
354*61046927SAndroid Build Coastguard Worker if (filename == NULL) {
355*61046927SAndroid Build Coastguard Worker return;
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker disk_cache_evict_item(cache, filename);
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker static struct disk_cache_put_job *
create_put_job(struct disk_cache * cache,const cache_key key,void * data,size_t size,struct cache_item_metadata * cache_item_metadata,bool take_ownership)362*61046927SAndroid Build Coastguard Worker create_put_job(struct disk_cache *cache, const cache_key key,
363*61046927SAndroid Build Coastguard Worker void *data, size_t size,
364*61046927SAndroid Build Coastguard Worker struct cache_item_metadata *cache_item_metadata,
365*61046927SAndroid Build Coastguard Worker bool take_ownership)
366*61046927SAndroid Build Coastguard Worker {
367*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *)
368*61046927SAndroid Build Coastguard Worker malloc(sizeof(struct disk_cache_put_job) + (take_ownership ? 0 : size));
369*61046927SAndroid Build Coastguard Worker
370*61046927SAndroid Build Coastguard Worker if (dc_job) {
371*61046927SAndroid Build Coastguard Worker dc_job->cache = cache;
372*61046927SAndroid Build Coastguard Worker memcpy(dc_job->key, key, sizeof(cache_key));
373*61046927SAndroid Build Coastguard Worker if (take_ownership) {
374*61046927SAndroid Build Coastguard Worker dc_job->data = data;
375*61046927SAndroid Build Coastguard Worker } else {
376*61046927SAndroid Build Coastguard Worker dc_job->data = dc_job + 1;
377*61046927SAndroid Build Coastguard Worker memcpy(dc_job->data, data, size);
378*61046927SAndroid Build Coastguard Worker }
379*61046927SAndroid Build Coastguard Worker dc_job->size = size;
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker /* Copy the cache item metadata */
382*61046927SAndroid Build Coastguard Worker if (cache_item_metadata) {
383*61046927SAndroid Build Coastguard Worker dc_job->cache_item_metadata.type = cache_item_metadata->type;
384*61046927SAndroid Build Coastguard Worker if (cache_item_metadata->type == CACHE_ITEM_TYPE_GLSL) {
385*61046927SAndroid Build Coastguard Worker dc_job->cache_item_metadata.num_keys =
386*61046927SAndroid Build Coastguard Worker cache_item_metadata->num_keys;
387*61046927SAndroid Build Coastguard Worker dc_job->cache_item_metadata.keys = (cache_key *)
388*61046927SAndroid Build Coastguard Worker malloc(cache_item_metadata->num_keys * sizeof(cache_key));
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker if (!dc_job->cache_item_metadata.keys)
391*61046927SAndroid Build Coastguard Worker goto fail;
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker memcpy(dc_job->cache_item_metadata.keys,
394*61046927SAndroid Build Coastguard Worker cache_item_metadata->keys,
395*61046927SAndroid Build Coastguard Worker sizeof(cache_key) * cache_item_metadata->num_keys);
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker } else {
398*61046927SAndroid Build Coastguard Worker dc_job->cache_item_metadata.type = CACHE_ITEM_TYPE_UNKNOWN;
399*61046927SAndroid Build Coastguard Worker dc_job->cache_item_metadata.keys = NULL;
400*61046927SAndroid Build Coastguard Worker }
401*61046927SAndroid Build Coastguard Worker }
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker return dc_job;
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker fail:
406*61046927SAndroid Build Coastguard Worker free(dc_job);
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker return NULL;
409*61046927SAndroid Build Coastguard Worker }
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker static void
destroy_put_job(void * job,void * gdata,int thread_index)412*61046927SAndroid Build Coastguard Worker destroy_put_job(void *job, void *gdata, int thread_index)
413*61046927SAndroid Build Coastguard Worker {
414*61046927SAndroid Build Coastguard Worker if (job) {
415*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job;
416*61046927SAndroid Build Coastguard Worker free(dc_job->cache_item_metadata.keys);
417*61046927SAndroid Build Coastguard Worker free(job);
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker
421*61046927SAndroid Build Coastguard Worker static void
destroy_put_job_nocopy(void * job,void * gdata,int thread_index)422*61046927SAndroid Build Coastguard Worker destroy_put_job_nocopy(void *job, void *gdata, int thread_index)
423*61046927SAndroid Build Coastguard Worker {
424*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job;
425*61046927SAndroid Build Coastguard Worker free(dc_job->data);
426*61046927SAndroid Build Coastguard Worker destroy_put_job(job, gdata, thread_index);
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker
429*61046927SAndroid Build Coastguard Worker static void
430*61046927SAndroid Build Coastguard Worker blob_put_compressed(struct disk_cache *cache, const cache_key key,
431*61046927SAndroid Build Coastguard Worker const void *data, size_t size);
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker static void
cache_put(void * job,void * gdata,int thread_index)434*61046927SAndroid Build Coastguard Worker cache_put(void *job, void *gdata, int thread_index)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker assert(job);
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker unsigned i = 0;
439*61046927SAndroid Build Coastguard Worker char *filename = NULL;
440*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job;
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker if (dc_job->cache->blob_put_cb) {
443*61046927SAndroid Build Coastguard Worker blob_put_compressed(dc_job->cache, dc_job->key, dc_job->data, dc_job->size);
444*61046927SAndroid Build Coastguard Worker } else if (dc_job->cache->type == DISK_CACHE_SINGLE_FILE) {
445*61046927SAndroid Build Coastguard Worker disk_cache_write_item_to_disk_foz(dc_job);
446*61046927SAndroid Build Coastguard Worker } else if (dc_job->cache->type == DISK_CACHE_DATABASE) {
447*61046927SAndroid Build Coastguard Worker disk_cache_db_write_item_to_disk(dc_job);
448*61046927SAndroid Build Coastguard Worker } else if (dc_job->cache->type == DISK_CACHE_MULTI_FILE) {
449*61046927SAndroid Build Coastguard Worker filename = disk_cache_get_cache_filename(dc_job->cache, dc_job->key);
450*61046927SAndroid Build Coastguard Worker if (filename == NULL)
451*61046927SAndroid Build Coastguard Worker goto done;
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker /* If the cache is too large, evict something else first. */
454*61046927SAndroid Build Coastguard Worker while (p_atomic_read_relaxed(&dc_job->cache->size->value) + dc_job->size > dc_job->cache->max_size &&
455*61046927SAndroid Build Coastguard Worker i < 8) {
456*61046927SAndroid Build Coastguard Worker disk_cache_evict_lru_item(dc_job->cache);
457*61046927SAndroid Build Coastguard Worker i++;
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker disk_cache_write_item_to_disk(dc_job, filename);
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker done:
463*61046927SAndroid Build Coastguard Worker free(filename);
464*61046927SAndroid Build Coastguard Worker }
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker struct blob_cache_entry {
468*61046927SAndroid Build Coastguard Worker uint32_t uncompressed_size;
469*61046927SAndroid Build Coastguard Worker uint8_t compressed_data[];
470*61046927SAndroid Build Coastguard Worker };
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker static void
blob_put_compressed(struct disk_cache * cache,const cache_key key,const void * data,size_t size)473*61046927SAndroid Build Coastguard Worker blob_put_compressed(struct disk_cache *cache, const cache_key key,
474*61046927SAndroid Build Coastguard Worker const void *data, size_t size)
475*61046927SAndroid Build Coastguard Worker {
476*61046927SAndroid Build Coastguard Worker MESA_TRACE_FUNC();
477*61046927SAndroid Build Coastguard Worker
478*61046927SAndroid Build Coastguard Worker size_t max_buf = util_compress_max_compressed_len(size);
479*61046927SAndroid Build Coastguard Worker struct blob_cache_entry *entry = malloc(max_buf + sizeof(*entry));
480*61046927SAndroid Build Coastguard Worker if (!entry)
481*61046927SAndroid Build Coastguard Worker goto out;
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker entry->uncompressed_size = size;
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker size_t compressed_size =
486*61046927SAndroid Build Coastguard Worker util_compress_deflate(data, size, entry->compressed_data, max_buf);
487*61046927SAndroid Build Coastguard Worker if (!compressed_size)
488*61046927SAndroid Build Coastguard Worker goto out;
489*61046927SAndroid Build Coastguard Worker
490*61046927SAndroid Build Coastguard Worker unsigned entry_size = compressed_size + sizeof(*entry);
491*61046927SAndroid Build Coastguard Worker // The curly brackets are here to only trace the blob_put_cb call
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker MESA_TRACE_SCOPE("blob_put");
494*61046927SAndroid Build Coastguard Worker cache->blob_put_cb(key, CACHE_KEY_SIZE, entry, entry_size);
495*61046927SAndroid Build Coastguard Worker }
496*61046927SAndroid Build Coastguard Worker
497*61046927SAndroid Build Coastguard Worker out:
498*61046927SAndroid Build Coastguard Worker free(entry);
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker static void *
blob_get_compressed(struct disk_cache * cache,const cache_key key,size_t * size)502*61046927SAndroid Build Coastguard Worker blob_get_compressed(struct disk_cache *cache, const cache_key key,
503*61046927SAndroid Build Coastguard Worker size_t *size)
504*61046927SAndroid Build Coastguard Worker {
505*61046927SAndroid Build Coastguard Worker MESA_TRACE_FUNC();
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker /* This is what Android EGL defines as the maxValueSize in egl_cache_t
508*61046927SAndroid Build Coastguard Worker * class implementation.
509*61046927SAndroid Build Coastguard Worker */
510*61046927SAndroid Build Coastguard Worker const signed long max_blob_size = 64 * 1024;
511*61046927SAndroid Build Coastguard Worker struct blob_cache_entry *entry = malloc(max_blob_size);
512*61046927SAndroid Build Coastguard Worker if (!entry)
513*61046927SAndroid Build Coastguard Worker return NULL;
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker signed long entry_size;
516*61046927SAndroid Build Coastguard Worker // The curly brackets are here to only trace the blob_get_cb call
517*61046927SAndroid Build Coastguard Worker {
518*61046927SAndroid Build Coastguard Worker MESA_TRACE_SCOPE("blob_get");
519*61046927SAndroid Build Coastguard Worker entry_size = cache->blob_get_cb(key, CACHE_KEY_SIZE, entry, max_blob_size);
520*61046927SAndroid Build Coastguard Worker }
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker if (!entry_size) {
523*61046927SAndroid Build Coastguard Worker free(entry);
524*61046927SAndroid Build Coastguard Worker return NULL;
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker void *data = malloc(entry->uncompressed_size);
528*61046927SAndroid Build Coastguard Worker if (!data) {
529*61046927SAndroid Build Coastguard Worker free(entry);
530*61046927SAndroid Build Coastguard Worker return NULL;
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker
533*61046927SAndroid Build Coastguard Worker unsigned compressed_size = entry_size - sizeof(*entry);
534*61046927SAndroid Build Coastguard Worker bool ret = util_compress_inflate(entry->compressed_data, compressed_size,
535*61046927SAndroid Build Coastguard Worker data, entry->uncompressed_size);
536*61046927SAndroid Build Coastguard Worker if (!ret) {
537*61046927SAndroid Build Coastguard Worker free(data);
538*61046927SAndroid Build Coastguard Worker free(entry);
539*61046927SAndroid Build Coastguard Worker return NULL;
540*61046927SAndroid Build Coastguard Worker }
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker if (size)
543*61046927SAndroid Build Coastguard Worker *size = entry->uncompressed_size;
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker free(entry);
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker return data;
548*61046927SAndroid Build Coastguard Worker }
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker void
disk_cache_put(struct disk_cache * cache,const cache_key key,const void * data,size_t size,struct cache_item_metadata * cache_item_metadata)551*61046927SAndroid Build Coastguard Worker disk_cache_put(struct disk_cache *cache, const cache_key key,
552*61046927SAndroid Build Coastguard Worker const void *data, size_t size,
553*61046927SAndroid Build Coastguard Worker struct cache_item_metadata *cache_item_metadata)
554*61046927SAndroid Build Coastguard Worker {
555*61046927SAndroid Build Coastguard Worker if (!util_queue_is_initialized(&cache->cache_queue))
556*61046927SAndroid Build Coastguard Worker return;
557*61046927SAndroid Build Coastguard Worker
558*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job =
559*61046927SAndroid Build Coastguard Worker create_put_job(cache, key, (void*)data, size, cache_item_metadata, false);
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker if (dc_job) {
562*61046927SAndroid Build Coastguard Worker util_queue_fence_init(&dc_job->fence);
563*61046927SAndroid Build Coastguard Worker util_queue_add_job(&cache->cache_queue, dc_job, &dc_job->fence,
564*61046927SAndroid Build Coastguard Worker cache_put, destroy_put_job, dc_job->size);
565*61046927SAndroid Build Coastguard Worker }
566*61046927SAndroid Build Coastguard Worker }
567*61046927SAndroid Build Coastguard Worker
568*61046927SAndroid Build Coastguard Worker void
disk_cache_put_nocopy(struct disk_cache * cache,const cache_key key,void * data,size_t size,struct cache_item_metadata * cache_item_metadata)569*61046927SAndroid Build Coastguard Worker disk_cache_put_nocopy(struct disk_cache *cache, const cache_key key,
570*61046927SAndroid Build Coastguard Worker void *data, size_t size,
571*61046927SAndroid Build Coastguard Worker struct cache_item_metadata *cache_item_metadata)
572*61046927SAndroid Build Coastguard Worker {
573*61046927SAndroid Build Coastguard Worker if (!util_queue_is_initialized(&cache->cache_queue)) {
574*61046927SAndroid Build Coastguard Worker free(data);
575*61046927SAndroid Build Coastguard Worker return;
576*61046927SAndroid Build Coastguard Worker }
577*61046927SAndroid Build Coastguard Worker
578*61046927SAndroid Build Coastguard Worker struct disk_cache_put_job *dc_job =
579*61046927SAndroid Build Coastguard Worker create_put_job(cache, key, data, size, cache_item_metadata, true);
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker if (dc_job) {
582*61046927SAndroid Build Coastguard Worker util_queue_fence_init(&dc_job->fence);
583*61046927SAndroid Build Coastguard Worker util_queue_add_job(&cache->cache_queue, dc_job, &dc_job->fence,
584*61046927SAndroid Build Coastguard Worker cache_put, destroy_put_job_nocopy, dc_job->size);
585*61046927SAndroid Build Coastguard Worker }
586*61046927SAndroid Build Coastguard Worker }
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker void *
disk_cache_get(struct disk_cache * cache,const cache_key key,size_t * size)589*61046927SAndroid Build Coastguard Worker disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size)
590*61046927SAndroid Build Coastguard Worker {
591*61046927SAndroid Build Coastguard Worker void *buf = NULL;
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker if (size)
594*61046927SAndroid Build Coastguard Worker *size = 0;
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker if (cache->foz_ro_cache)
597*61046927SAndroid Build Coastguard Worker buf = disk_cache_load_item_foz(cache->foz_ro_cache, key, size);
598*61046927SAndroid Build Coastguard Worker
599*61046927SAndroid Build Coastguard Worker if (!buf) {
600*61046927SAndroid Build Coastguard Worker if (cache->blob_get_cb) {
601*61046927SAndroid Build Coastguard Worker buf = blob_get_compressed(cache, key, size);
602*61046927SAndroid Build Coastguard Worker } else if (cache->type == DISK_CACHE_SINGLE_FILE) {
603*61046927SAndroid Build Coastguard Worker buf = disk_cache_load_item_foz(cache, key, size);
604*61046927SAndroid Build Coastguard Worker } else if (cache->type == DISK_CACHE_DATABASE) {
605*61046927SAndroid Build Coastguard Worker buf = disk_cache_db_load_item(cache, key, size);
606*61046927SAndroid Build Coastguard Worker } else if (cache->type == DISK_CACHE_MULTI_FILE) {
607*61046927SAndroid Build Coastguard Worker char *filename = disk_cache_get_cache_filename(cache, key);
608*61046927SAndroid Build Coastguard Worker if (filename)
609*61046927SAndroid Build Coastguard Worker buf = disk_cache_load_item(cache, filename, size);
610*61046927SAndroid Build Coastguard Worker }
611*61046927SAndroid Build Coastguard Worker }
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker if (unlikely(cache->stats.enabled)) {
614*61046927SAndroid Build Coastguard Worker if (buf)
615*61046927SAndroid Build Coastguard Worker p_atomic_inc(&cache->stats.hits);
616*61046927SAndroid Build Coastguard Worker else
617*61046927SAndroid Build Coastguard Worker p_atomic_inc(&cache->stats.misses);
618*61046927SAndroid Build Coastguard Worker }
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker return buf;
621*61046927SAndroid Build Coastguard Worker }
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker void
disk_cache_put_key(struct disk_cache * cache,const cache_key key)624*61046927SAndroid Build Coastguard Worker disk_cache_put_key(struct disk_cache *cache, const cache_key key)
625*61046927SAndroid Build Coastguard Worker {
626*61046927SAndroid Build Coastguard Worker const uint32_t *key_chunk = (const uint32_t *) key;
627*61046927SAndroid Build Coastguard Worker int i = CPU_TO_LE32(*key_chunk) & CACHE_INDEX_KEY_MASK;
628*61046927SAndroid Build Coastguard Worker unsigned char *entry;
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker if (cache->blob_put_cb) {
631*61046927SAndroid Build Coastguard Worker cache->blob_put_cb(key, CACHE_KEY_SIZE, key_chunk, sizeof(uint32_t));
632*61046927SAndroid Build Coastguard Worker return;
633*61046927SAndroid Build Coastguard Worker }
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker if (cache->path_init_failed)
636*61046927SAndroid Build Coastguard Worker return;
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker entry = &cache->stored_keys[i * CACHE_KEY_SIZE];
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker memcpy(entry, key, CACHE_KEY_SIZE);
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker /* This function lets us test whether a given key was previously
644*61046927SAndroid Build Coastguard Worker * stored in the cache with disk_cache_put_key(). The implement is
645*61046927SAndroid Build Coastguard Worker * efficient by not using syscalls or hitting the disk. It's not
646*61046927SAndroid Build Coastguard Worker * race-free, but the races are benign. If we race with someone else
647*61046927SAndroid Build Coastguard Worker * calling disk_cache_put_key, then that's just an extra cache miss and an
648*61046927SAndroid Build Coastguard Worker * extra recompile.
649*61046927SAndroid Build Coastguard Worker */
650*61046927SAndroid Build Coastguard Worker bool
disk_cache_has_key(struct disk_cache * cache,const cache_key key)651*61046927SAndroid Build Coastguard Worker disk_cache_has_key(struct disk_cache *cache, const cache_key key)
652*61046927SAndroid Build Coastguard Worker {
653*61046927SAndroid Build Coastguard Worker const uint32_t *key_chunk = (const uint32_t *) key;
654*61046927SAndroid Build Coastguard Worker int i = CPU_TO_LE32(*key_chunk) & CACHE_INDEX_KEY_MASK;
655*61046927SAndroid Build Coastguard Worker unsigned char *entry;
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker if (cache->blob_get_cb) {
658*61046927SAndroid Build Coastguard Worker uint32_t blob;
659*61046927SAndroid Build Coastguard Worker return cache->blob_get_cb(key, CACHE_KEY_SIZE, &blob, sizeof(uint32_t));
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker if (cache->path_init_failed)
663*61046927SAndroid Build Coastguard Worker return false;
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker entry = &cache->stored_keys[i * CACHE_KEY_SIZE];
666*61046927SAndroid Build Coastguard Worker
667*61046927SAndroid Build Coastguard Worker return memcmp(entry, key, CACHE_KEY_SIZE) == 0;
668*61046927SAndroid Build Coastguard Worker }
669*61046927SAndroid Build Coastguard Worker
670*61046927SAndroid Build Coastguard Worker void
disk_cache_compute_key(struct disk_cache * cache,const void * data,size_t size,cache_key key)671*61046927SAndroid Build Coastguard Worker disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
672*61046927SAndroid Build Coastguard Worker cache_key key)
673*61046927SAndroid Build Coastguard Worker {
674*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
675*61046927SAndroid Build Coastguard Worker
676*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
677*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, cache->driver_keys_blob,
678*61046927SAndroid Build Coastguard Worker cache->driver_keys_blob_size);
679*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, data, size);
680*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, key);
681*61046927SAndroid Build Coastguard Worker }
682*61046927SAndroid Build Coastguard Worker
683*61046927SAndroid Build Coastguard Worker void
disk_cache_set_callbacks(struct disk_cache * cache,disk_cache_put_cb put,disk_cache_get_cb get)684*61046927SAndroid Build Coastguard Worker disk_cache_set_callbacks(struct disk_cache *cache, disk_cache_put_cb put,
685*61046927SAndroid Build Coastguard Worker disk_cache_get_cb get)
686*61046927SAndroid Build Coastguard Worker {
687*61046927SAndroid Build Coastguard Worker cache->blob_put_cb = put;
688*61046927SAndroid Build Coastguard Worker cache->blob_get_cb = get;
689*61046927SAndroid Build Coastguard Worker disk_cache_init_queue(cache);
690*61046927SAndroid Build Coastguard Worker }
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker #endif /* ENABLE_SHADER_CACHE */
693