~mmach/netext73/mesa_2004

« back to all changes in this revision

Viewing changes to src/freedreno/ir3/ir3_disk_cache.c

  • Committer: mmach
  • Date: 2022-09-22 20:00:35 UTC
  • Revision ID: netbit73@gmail.com-20220922200035-j2mt0pv92d002zy3
2022-09-22 21:17:58

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2020 Google, Inc.
 
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 FROM,
 
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
21
 * SOFTWARE.
 
22
 */
 
23
 
 
24
#include "nir_serialize.h"
 
25
 
 
26
#include "ir3_compiler.h"
 
27
#include "ir3_nir.h"
 
28
 
 
29
#define debug 0
 
30
 
 
31
/*
 
32
 * Shader disk-cache implementation.
 
33
 *
 
34
 * Note that at least in the EGL_ANDROID_blob_cache, we should never
 
35
 * rely on inter-dependencies between different cache entries:
 
36
 *
 
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,
 
40
 *    is associated with the key after the set call.  Note that while there are
 
41
 *    no guarantees, the cache implementation should attempt to cache the most
 
42
 *    recently set value for a given key.
 
43
 *
 
44
 * for this reason, because binning pass variants share const_state with
 
45
 * their draw-pass counterpart, both variants are serialized together.
 
46
 */
 
47
 
 
48
void
 
49
ir3_disk_cache_init(struct ir3_compiler *compiler)
 
50
{
 
51
   if (ir3_shader_debug & IR3_DBG_NOCACHE)
 
52
      return;
 
53
 
 
54
   const char *renderer = fd_dev_name(compiler->dev_id);
 
55
   const struct build_id_note *note =
 
56
      build_id_find_nhdr_for_addr(ir3_disk_cache_init);
 
57
   assert(note && build_id_length(note) == 20); /* sha1 */
 
58
 
 
59
   const uint8_t *id_sha1 = build_id_data(note);
 
60
   assert(id_sha1);
 
61
 
 
62
   char timestamp[41];
 
63
   _mesa_sha1_format(timestamp, id_sha1);
 
64
 
 
65
   uint64_t driver_flags = ir3_shader_debug;
 
66
   if (compiler->robust_buffer_access2)
 
67
      driver_flags |= IR3_DBG_ROBUST_UBO_ACCESS;
 
68
   compiler->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
 
69
}
 
70
 
 
71
void
 
72
ir3_disk_cache_init_shader_key(struct ir3_compiler *compiler,
 
73
                               struct ir3_shader *shader)
 
74
{
 
75
   if (!compiler->disk_cache)
 
76
      return;
 
77
 
 
78
   struct mesa_sha1 ctx;
 
79
 
 
80
   _mesa_sha1_init(&ctx);
 
81
 
 
82
   /* Serialize the NIR to a binary blob that we can hash for the disk
 
83
    * cache.  Drop unnecessary information (like variable names)
 
84
    * so the serialized NIR is smaller, and also to let us detect more
 
85
    * isomorphic shaders when hashing, increasing cache hits.
 
86
    */
 
87
   struct blob blob;
 
88
   blob_init(&blob);
 
89
   nir_serialize(&blob, shader->nir, true);
 
90
   _mesa_sha1_update(&ctx, blob.data, blob.size);
 
91
   blob_finish(&blob);
 
92
 
 
93
   _mesa_sha1_update(&ctx, &shader->api_wavesize,
 
94
                     sizeof(shader->api_wavesize));
 
95
   _mesa_sha1_update(&ctx, &shader->real_wavesize,
 
96
                     sizeof(shader->real_wavesize));
 
97
 
 
98
   /* Note that on some gens stream-out is lowered in ir3 to stg.  For later
 
99
    * gens we maybe don't need to include stream-out in the cache key.
 
100
    */
 
101
   _mesa_sha1_update(&ctx, &shader->stream_output,
 
102
                     sizeof(shader->stream_output));
 
103
 
 
104
   _mesa_sha1_final(&ctx, shader->cache_key);
 
105
}
 
106
 
 
107
static void
 
108
compute_variant_key(struct ir3_shader *shader, struct ir3_shader_variant *v,
 
109
                    cache_key cache_key)
 
110
{
 
111
   struct blob blob;
 
112
   blob_init(&blob);
 
113
 
 
114
   blob_write_bytes(&blob, &shader->cache_key, sizeof(shader->cache_key));
 
115
   blob_write_bytes(&blob, &v->key, sizeof(v->key));
 
116
   blob_write_uint8(&blob, v->binning_pass);
 
117
 
 
118
   disk_cache_compute_key(shader->compiler->disk_cache, blob.data, blob.size,
 
119
                          cache_key);
 
120
 
 
121
   blob_finish(&blob);
 
122
}
 
123
 
 
124
static void
 
125
retrieve_variant(struct blob_reader *blob, struct ir3_shader_variant *v)
 
126
{
 
127
   blob_copy_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);
 
128
 
 
129
   /*
 
130
    * pointers need special handling:
 
131
    */
 
132
 
 
133
   v->bin = rzalloc_size(v, v->info.size);
 
134
   blob_copy_bytes(blob, v->bin, v->info.size);
 
135
 
 
136
   if (!v->binning_pass) {
 
137
      blob_copy_bytes(blob, v->const_state, sizeof(*v->const_state));
 
138
      unsigned immeds_sz = v->const_state->immediates_size *
 
139
                           sizeof(v->const_state->immediates[0]);
 
140
      v->const_state->immediates = ralloc_size(v->const_state, immeds_sz);
 
141
      blob_copy_bytes(blob, v->const_state->immediates, immeds_sz);
 
142
   }
 
143
}
 
144
 
 
145
static void
 
146
store_variant(struct blob *blob, struct ir3_shader_variant *v)
 
147
{
 
148
   blob_write_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);
 
149
 
 
150
   /*
 
151
    * pointers need special handling:
 
152
    */
 
153
 
 
154
   blob_write_bytes(blob, v->bin, v->info.size);
 
155
 
 
156
   /* No saving constant_data, it's already baked into bin at this point. */
 
157
 
 
158
   if (!v->binning_pass) {
 
159
      blob_write_bytes(blob, v->const_state, sizeof(*v->const_state));
 
160
      unsigned immeds_sz = v->const_state->immediates_size *
 
161
                           sizeof(v->const_state->immediates[0]);
 
162
      blob_write_bytes(blob, v->const_state->immediates, immeds_sz);
 
163
   }
 
164
}
 
165
 
 
166
struct ir3_shader_variant *
 
167
ir3_retrieve_variant(struct blob_reader *blob, struct ir3_compiler *compiler,
 
168
                     void *mem_ctx)
 
169
{
 
170
   struct ir3_shader_variant *v = rzalloc_size(mem_ctx, sizeof(*v));
 
171
 
 
172
   v->id = 0;
 
173
   v->compiler = compiler;
 
174
   v->binning_pass = false;
 
175
   v->nonbinning = NULL;
 
176
   v->binning = NULL;
 
177
   blob_copy_bytes(blob, &v->key, sizeof(v->key));
 
178
   v->type = blob_read_uint32(blob);
 
179
   v->mergedregs = blob_read_uint32(blob);
 
180
   v->const_state = rzalloc_size(v, sizeof(*v->const_state));
 
181
 
 
182
   retrieve_variant(blob, v);
 
183
 
 
184
   if (v->type == MESA_SHADER_VERTEX && ir3_has_binning_vs(&v->key)) {
 
185
      v->binning = rzalloc_size(v, sizeof(*v->binning));
 
186
      v->binning->id = 0;
 
187
      v->binning->compiler = compiler;
 
188
      v->binning->binning_pass = true;
 
189
      v->binning->nonbinning = v;
 
190
      v->binning->key = v->key;
 
191
      v->binning->type = MESA_SHADER_VERTEX;
 
192
      v->binning->mergedregs = v->mergedregs;
 
193
      v->binning->const_state = v->const_state;
 
194
 
 
195
      retrieve_variant(blob, v->binning);
 
196
   }
 
197
   
 
198
   return v;
 
199
}
 
200
 
 
201
void
 
202
ir3_store_variant(struct blob *blob, struct ir3_shader_variant *v)
 
203
{
 
204
   blob_write_bytes(blob, &v->key, sizeof(v->key));
 
205
   blob_write_uint32(blob, v->type);
 
206
   blob_write_uint32(blob, v->mergedregs);
 
207
 
 
208
   store_variant(blob, v);
 
209
 
 
210
   if (v->type == MESA_SHADER_VERTEX && ir3_has_binning_vs(&v->key)) {
 
211
      store_variant(blob, v->binning);
 
212
   }
 
213
}
 
214
 
 
215
bool
 
216
ir3_disk_cache_retrieve(struct ir3_shader *shader,
 
217
                        struct ir3_shader_variant *v)
 
218
{
 
219
   if (!shader->compiler->disk_cache)
 
220
      return false;
 
221
 
 
222
   cache_key cache_key;
 
223
 
 
224
   compute_variant_key(shader, v, cache_key);
 
225
 
 
226
   if (debug) {
 
227
      char sha1[41];
 
228
      _mesa_sha1_format(sha1, cache_key);
 
229
      fprintf(stderr, "[mesa disk cache] retrieving variant %s: ", sha1);
 
230
   }
 
231
 
 
232
   size_t size;
 
233
   void *buffer = disk_cache_get(shader->compiler->disk_cache, cache_key, &size);
 
234
 
 
235
   if (debug)
 
236
      fprintf(stderr, "%s\n", buffer ? "found" : "missing");
 
237
 
 
238
   if (!buffer)
 
239
      return false;
 
240
 
 
241
   struct blob_reader blob;
 
242
   blob_reader_init(&blob, buffer, size);
 
243
 
 
244
   retrieve_variant(&blob, v);
 
245
 
 
246
   if (v->binning)
 
247
      retrieve_variant(&blob, v->binning);
 
248
 
 
249
   free(buffer);
 
250
 
 
251
   return true;
 
252
}
 
253
 
 
254
void
 
255
ir3_disk_cache_store(struct ir3_shader *shader,
 
256
                     struct ir3_shader_variant *v)
 
257
{
 
258
   if (!shader->compiler->disk_cache)
 
259
      return;
 
260
 
 
261
   cache_key cache_key;
 
262
 
 
263
   compute_variant_key(shader, v, cache_key);
 
264
 
 
265
   if (debug) {
 
266
      char sha1[41];
 
267
      _mesa_sha1_format(sha1, cache_key);
 
268
      fprintf(stderr, "[mesa disk cache] storing variant %s\n", sha1);
 
269
   }
 
270
 
 
271
   struct blob blob;
 
272
   blob_init(&blob);
 
273
 
 
274
   store_variant(&blob, v);
 
275
 
 
276
   if (v->binning)
 
277
      store_variant(&blob, v->binning);
 
278
 
 
279
   disk_cache_put(shader->compiler->disk_cache, cache_key, blob.data, blob.size, NULL);
 
280
   blob_finish(&blob);
 
281
}