Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/util/disk_cache.h
4545 views
1
/*
2
* Copyright © 2014 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 (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#ifndef DISK_CACHE_H
25
#define DISK_CACHE_H
26
27
#ifdef HAVE_DLFCN_H
28
#include <dlfcn.h>
29
#include <stdio.h>
30
#include "util/build_id.h"
31
#endif
32
#include <assert.h>
33
#include <stdint.h>
34
#include <stdbool.h>
35
#include <sys/stat.h>
36
#include "util/mesa-sha1.h"
37
38
#ifdef __cplusplus
39
extern "C" {
40
#endif
41
42
/* Size of cache keys in bytes. */
43
#define CACHE_KEY_SIZE 20
44
45
#define CACHE_DIR_NAME "mesa_shader_cache"
46
#define CACHE_DIR_NAME_SF "mesa_shader_cache_sf"
47
48
typedef uint8_t cache_key[CACHE_KEY_SIZE];
49
50
/* WARNING: 3rd party applications might be reading the cache item metadata.
51
* Do not change these values without making the change widely known.
52
* Please contact Valve developers and make them aware of this change.
53
*/
54
#define CACHE_ITEM_TYPE_UNKNOWN 0x0
55
#define CACHE_ITEM_TYPE_GLSL 0x1
56
57
typedef void
58
(*disk_cache_put_cb) (const void *key, signed long keySize,
59
const void *value, signed long valueSize);
60
61
typedef signed long
62
(*disk_cache_get_cb) (const void *key, signed long keySize,
63
void *value, signed long valueSize);
64
65
struct cache_item_metadata {
66
/**
67
* The cache item type. This could be used to identify a GLSL cache item,
68
* a certain type of IR (tgsi, nir, etc), or signal that it is the final
69
* binary form of the shader.
70
*/
71
uint32_t type;
72
73
/** GLSL cache item metadata */
74
cache_key *keys; /* sha1 list of shaders that make up the cache item */
75
uint32_t num_keys;
76
};
77
78
struct disk_cache;
79
80
static inline char *
81
disk_cache_format_hex_id(char *buf, const uint8_t *hex_id, unsigned size)
82
{
83
static const char hex_digits[] = "0123456789abcdef";
84
unsigned i;
85
86
for (i = 0; i < size; i += 2) {
87
buf[i] = hex_digits[hex_id[i >> 1] >> 4];
88
buf[i + 1] = hex_digits[hex_id[i >> 1] & 0x0f];
89
}
90
buf[i] = '\0';
91
92
return buf;
93
}
94
95
#ifdef HAVE_DLADDR
96
static inline bool
97
disk_cache_get_function_timestamp(void *ptr, uint32_t* timestamp)
98
{
99
Dl_info info;
100
struct stat st;
101
if (!dladdr(ptr, &info) || !info.dli_fname) {
102
return false;
103
}
104
if (stat(info.dli_fname, &st)) {
105
return false;
106
}
107
108
if (!st.st_mtime) {
109
fprintf(stderr, "Mesa: The provided filesystem timestamp for the cache "
110
"is bogus! Disabling On-disk cache.\n");
111
return false;
112
}
113
114
*timestamp = st.st_mtime;
115
116
return true;
117
}
118
119
static inline bool
120
disk_cache_get_function_identifier(void *ptr, struct mesa_sha1 *ctx)
121
{
122
uint32_t timestamp;
123
124
#ifdef HAVE_DL_ITERATE_PHDR
125
const struct build_id_note *note = NULL;
126
if ((note = build_id_find_nhdr_for_addr(ptr))) {
127
_mesa_sha1_update(ctx, build_id_data(note), build_id_length(note));
128
} else
129
#endif
130
if (disk_cache_get_function_timestamp(ptr, &timestamp)) {
131
_mesa_sha1_update(ctx, &timestamp, sizeof(timestamp));
132
} else
133
return false;
134
return true;
135
}
136
#else
137
static inline bool
138
disk_cache_get_function_identifier(void *ptr, struct mesa_sha1 *ctx)
139
{
140
return false;
141
}
142
#endif
143
144
/* Provide inlined stub functions if the shader cache is disabled. */
145
146
#ifdef ENABLE_SHADER_CACHE
147
148
/**
149
* Create a new cache object.
150
*
151
* This function creates the handle necessary for all subsequent cache_*
152
* functions.
153
*
154
* This cache provides two distinct operations:
155
*
156
* o Storage and retrieval of arbitrary objects by cryptographic
157
* name (or "key"). This is provided via disk_cache_put() and
158
* disk_cache_get().
159
*
160
* o The ability to store a key alone and check later whether the
161
* key was previously stored. This is provided via disk_cache_put_key()
162
* and disk_cache_has_key().
163
*
164
* The put_key()/has_key() operations are conceptually identical to
165
* put()/get() with no data, but are provided separately to allow for
166
* a more efficient implementation.
167
*
168
* In all cases, the keys are sequences of 20 bytes. It is anticipated
169
* that callers will compute appropriate SHA-1 signatures for keys,
170
* (though nothing in this implementation directly relies on how the
171
* names are computed). See mesa-sha1.h and _mesa_sha1_compute for
172
* assistance in computing SHA-1 signatures.
173
*/
174
struct disk_cache *
175
disk_cache_create(const char *gpu_name, const char *timestamp,
176
uint64_t driver_flags);
177
178
/**
179
* Destroy a cache object, (freeing all associated resources).
180
*/
181
void
182
disk_cache_destroy(struct disk_cache *cache);
183
184
/* Wait for all previous disk_cache_put() calls to be processed (used for unit
185
* testing).
186
*/
187
void
188
disk_cache_wait_for_idle(struct disk_cache *cache);
189
190
/**
191
* Remove the item in the cache under the name \key.
192
*/
193
void
194
disk_cache_remove(struct disk_cache *cache, const cache_key key);
195
196
/**
197
* Store an item in the cache under the name \key.
198
*
199
* The item can be retrieved later with disk_cache_get(), (unless the item has
200
* been evicted in the interim).
201
*
202
* Any call to disk_cache_put() may cause an existing, random item to be
203
* evicted from the cache.
204
*/
205
void
206
disk_cache_put(struct disk_cache *cache, const cache_key key,
207
const void *data, size_t size,
208
struct cache_item_metadata *cache_item_metadata);
209
210
/**
211
* Store an item in the cache under the name \key without copying the data param.
212
*
213
* The item can be retrieved later with disk_cache_get(), (unless the item has
214
* been evicted in the interim).
215
*
216
* Any call to disk_cache_put() may cause an existing, random item to be
217
* evicted from the cache.
218
*
219
* @p data will be freed
220
*/
221
void
222
disk_cache_put_nocopy(struct disk_cache *cache, const cache_key key,
223
void *data, size_t size,
224
struct cache_item_metadata *cache_item_metadata);
225
226
/**
227
* Retrieve an item previously stored in the cache with the name <key>.
228
*
229
* The item must have been previously stored with a call to disk_cache_put().
230
*
231
* If \size is non-NULL, then, on successful return, it will be set to the
232
* size of the object.
233
*
234
* \return A pointer to the stored object if found. NULL if the object
235
* is not found, or if any error occurs, (memory allocation failure,
236
* filesystem error, etc.). The returned data is malloc'ed so the
237
* caller should call free() it when finished.
238
*/
239
void *
240
disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size);
241
242
/**
243
* Store the name \key within the cache, (without any associated data).
244
*
245
* Later this key can be checked with disk_cache_has_key(), (unless the key
246
* has been evicted in the interim).
247
*
248
* Any call to disk_cache_put_key() may cause an existing, random key to be
249
* evicted from the cache.
250
*/
251
void
252
disk_cache_put_key(struct disk_cache *cache, const cache_key key);
253
254
/**
255
* Test whether the name \key was previously recorded in the cache.
256
*
257
* Return value: True if disk_cache_put_key() was previously called with
258
* \key, (and the key was not evicted in the interim).
259
*
260
* Note: disk_cache_has_key() will only return true for keys passed to
261
* disk_cache_put_key(). Specifically, a call to disk_cache_put() will not cause
262
* disk_cache_has_key() to return true for the same key.
263
*/
264
bool
265
disk_cache_has_key(struct disk_cache *cache, const cache_key key);
266
267
/**
268
* Compute the name \key from \data of given \size.
269
*/
270
void
271
disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
272
cache_key key);
273
274
void
275
disk_cache_set_callbacks(struct disk_cache *cache, disk_cache_put_cb put,
276
disk_cache_get_cb get);
277
278
#else
279
280
static inline struct disk_cache *
281
disk_cache_create(const char *gpu_name, const char *timestamp,
282
uint64_t driver_flags)
283
{
284
return NULL;
285
}
286
287
static inline void
288
disk_cache_destroy(struct disk_cache *cache) {
289
return;
290
}
291
292
static inline void
293
disk_cache_put(struct disk_cache *cache, const cache_key key,
294
const void *data, size_t size,
295
struct cache_item_metadata *cache_item_metadata)
296
{
297
return;
298
}
299
300
static inline void
301
disk_cache_put_nocopy(struct disk_cache *cache, const cache_key key,
302
void *data, size_t size,
303
struct cache_item_metadata *cache_item_metadata)
304
{
305
return;
306
}
307
308
static inline void
309
disk_cache_remove(struct disk_cache *cache, const cache_key key)
310
{
311
return;
312
}
313
314
static inline uint8_t *
315
disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size)
316
{
317
return NULL;
318
}
319
320
static inline void
321
disk_cache_put_key(struct disk_cache *cache, const cache_key key)
322
{
323
return;
324
}
325
326
static inline bool
327
disk_cache_has_key(struct disk_cache *cache, const cache_key key)
328
{
329
return false;
330
}
331
332
static inline void
333
disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
334
const cache_key key)
335
{
336
return;
337
}
338
339
static inline void
340
disk_cache_set_callbacks(struct disk_cache *cache, disk_cache_put_cb put,
341
disk_cache_get_cb get)
342
{
343
return;
344
}
345
346
#endif /* ENABLE_SHADER_CACHE */
347
348
#ifdef __cplusplus
349
}
350
#endif
351
352
#endif /* CACHE_H */
353
354