2 * Copyright © 2020 Google, Inc.
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 (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 #include "nir_serialize.h"
26 #include "ir3_compiler.h"
32 * Shader disk-cache implementation.
34 * Note that at least in the EGL_ANDROID_blob_cache, we should never
35 * rely on inter-dependencies between different cache entries:
37 * No guarantees are made as to whether a given key/value pair is present in
38 * the cache after the set call. If a different value has been associated
39 * with the given key in the past then it is undefined which value, if any, is
40 * associated with the key after the set call. Note that while there are no
41 * guarantees, the cache implementation should attempt to cache the most
42 * recently set value for a given key.
44 * for this reason, because binning pass variants share const_state with
45 * their draw-pass counterpart, both variants are serialized together.
49 ir3_disk_cache_init(struct ir3_compiler
*compiler
)
51 if (ir3_shader_debug
& IR3_DBG_NOCACHE
)
54 /* array length = print length + nul char + 1 extra to verify it's unused */
57 snprintf(renderer
, sizeof(renderer
), "FD%03d", compiler
->gpu_id
);
58 assert(len
== sizeof(renderer
) - 2);
60 const struct build_id_note
*note
=
61 build_id_find_nhdr_for_addr(ir3_disk_cache_init
);
62 assert(note
&& build_id_length(note
) == 20); /* sha1 */
64 const uint8_t *id_sha1
= build_id_data(note
);
68 _mesa_sha1_format(timestamp
, id_sha1
);
70 const uint64_t driver_flags
= ir3_shader_debug
;
71 compiler
->disk_cache
= disk_cache_create(renderer
, timestamp
, driver_flags
);
75 ir3_disk_cache_init_shader_key(struct ir3_compiler
*compiler
,
76 struct ir3_shader
*shader
)
78 if (!compiler
->disk_cache
)
83 _mesa_sha1_init(&ctx
);
85 /* Serialize the NIR to a binary blob that we can hash for the disk
86 * cache. Drop unnecessary information (like variable names)
87 * so the serialized NIR is smaller, and also to let us detect more
88 * isomorphic shaders when hashing, increasing cache hits.
92 nir_serialize(&blob
, shader
->nir
, true);
93 _mesa_sha1_update(&ctx
, blob
.data
, blob
.size
);
96 /* Note that on some gens stream-out is lowered in ir3 to stg. For later
97 * gens we maybe don't need to include stream-out in the cache key.
99 _mesa_sha1_update(&ctx
, &shader
->stream_output
, sizeof(shader
->stream_output
));
101 _mesa_sha1_final(&ctx
, shader
->cache_key
);
105 compute_variant_key(struct ir3_compiler
*compiler
,
106 struct ir3_shader_variant
*v
, cache_key cache_key
)
111 blob_write_bytes(&blob
, &v
->shader
->cache_key
, sizeof(v
->shader
->cache_key
));
112 blob_write_bytes(&blob
, &v
->key
, sizeof(v
->key
));
113 blob_write_uint8(&blob
, v
->binning_pass
);
115 disk_cache_compute_key(compiler
->disk_cache
, blob
.data
, blob
.size
, cache_key
);
121 retrieve_variant(struct blob_reader
*blob
, struct ir3_shader_variant
*v
)
123 blob_copy_bytes(blob
, VARIANT_CACHE_PTR(v
), VARIANT_CACHE_SIZE
);
126 * pointers need special handling:
129 v
->bin
= malloc(4 * v
->info
.sizedwords
);
130 blob_copy_bytes(blob
, v
->bin
, 4 * v
->info
.sizedwords
);
132 if (!v
->binning_pass
) {
133 blob_copy_bytes(blob
, v
->const_state
, sizeof(*v
->const_state
));
134 unsigned immeds_sz
= v
->const_state
->immediates_size
*
135 sizeof(v
->const_state
->immediates
[0]);
136 v
->const_state
->immediates
= ralloc_size(v
->const_state
, immeds_sz
);
137 blob_copy_bytes(blob
, v
->const_state
->immediates
, immeds_sz
);
142 store_variant(struct blob
*blob
, struct ir3_shader_variant
*v
)
144 blob_write_bytes(blob
, VARIANT_CACHE_PTR(v
), VARIANT_CACHE_SIZE
);
147 * pointers need special handling:
150 blob_write_bytes(blob
, v
->bin
, 4 * v
->info
.sizedwords
);
152 if (!v
->binning_pass
) {
153 blob_write_bytes(blob
, v
->const_state
, sizeof(*v
->const_state
));
154 unsigned immeds_sz
= v
->const_state
->immediates_size
*
155 sizeof(v
->const_state
->immediates
[0]);
156 blob_write_bytes(blob
, v
->const_state
->immediates
, immeds_sz
);
161 ir3_disk_cache_retrieve(struct ir3_compiler
*compiler
,
162 struct ir3_shader_variant
*v
)
164 if (!compiler
->disk_cache
)
169 compute_variant_key(compiler
, v
, cache_key
);
173 _mesa_sha1_format(sha1
, cache_key
);
174 fprintf(stderr
, "[mesa disk cache] retrieving variant %s: ", sha1
);
178 void *buffer
= disk_cache_get(compiler
->disk_cache
, cache_key
, &size
);
181 fprintf(stderr
, "%s\n", buffer
? "found" : "missing");
186 struct blob_reader blob
;
187 blob_reader_init(&blob
, buffer
, size
);
189 retrieve_variant(&blob
, v
);
192 retrieve_variant(&blob
, v
->binning
);
200 ir3_disk_cache_store(struct ir3_compiler
*compiler
,
201 struct ir3_shader_variant
*v
)
203 if (!compiler
->disk_cache
)
208 compute_variant_key(compiler
, v
, cache_key
);
212 _mesa_sha1_format(sha1
, cache_key
);
213 fprintf(stderr
, "[mesa disk cache] storing variant %s\n", sha1
);
219 store_variant(&blob
, v
);
222 store_variant(&blob
, v
->binning
);
224 disk_cache_put(compiler
->disk_cache
, cache_key
, blob
.data
, blob
.size
, NULL
);