iris: Upload kernel inputs with system values
[mesa.git] / src / gallium / drivers / iris / iris_disk_cache.c
1 /*
2 * Copyright © 2018 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 shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 /**
24 * @file iris_disk_cache.c
25 *
26 * Functions for interacting with the on-disk shader cache.
27 */
28
29 #include <stdio.h>
30 #include <stdint.h>
31 #include <assert.h>
32 #include <string.h>
33
34 #include "compiler/nir/nir.h"
35 #include "util/blob.h"
36 #include "util/build_id.h"
37 #include "util/disk_cache.h"
38 #include "util/mesa-sha1.h"
39
40 #include "iris_context.h"
41
42 static bool debug = false;
43
44 /**
45 * Compute a disk cache key for the given uncompiled shader and NOS key.
46 */
47 static void
48 iris_disk_cache_compute_key(struct disk_cache *cache,
49 const struct iris_uncompiled_shader *ish,
50 const void *orig_prog_key,
51 uint32_t prog_key_size,
52 cache_key cache_key)
53 {
54 /* Create a copy of the program key with program_string_id zeroed out.
55 * It's essentially random data which we don't want to include in our
56 * hashing and comparisons. We'll set a proper value on a cache hit.
57 */
58 union brw_any_prog_key prog_key;
59 memcpy(&prog_key, orig_prog_key, prog_key_size);
60 prog_key.base.program_string_id = 0;
61
62 uint8_t data[sizeof(prog_key) + sizeof(ish->nir_sha1)];
63 uint32_t data_size = prog_key_size + sizeof(ish->nir_sha1);
64
65 memcpy(data, ish->nir_sha1, sizeof(ish->nir_sha1));
66 memcpy(data + sizeof(ish->nir_sha1), &prog_key, prog_key_size);
67
68 disk_cache_compute_key(cache, data, data_size, cache_key);
69 }
70
71 /**
72 * Store the given compiled shader in the disk cache.
73 *
74 * This should only be called on newly compiled shaders. No checking is
75 * done to prevent repeated stores of the same shader.
76 */
77 void
78 iris_disk_cache_store(struct disk_cache *cache,
79 const struct iris_uncompiled_shader *ish,
80 const struct iris_compiled_shader *shader,
81 const void *prog_key,
82 uint32_t prog_key_size)
83 {
84 #ifdef ENABLE_SHADER_CACHE
85 if (!cache)
86 return;
87
88 gl_shader_stage stage = ish->nir->info.stage;
89 const struct brw_stage_prog_data *prog_data = shader->prog_data;
90
91 cache_key cache_key;
92 iris_disk_cache_compute_key(cache, ish, prog_key, prog_key_size, cache_key);
93
94 if (debug) {
95 char sha1[41];
96 _mesa_sha1_format(sha1, cache_key);
97 fprintf(stderr, "[mesa disk cache] storing %s\n", sha1);
98 }
99
100 struct blob blob;
101 blob_init(&blob);
102
103 /* We write the following data to the cache blob:
104 *
105 * 1. Prog data (must come first because it has the assembly size)
106 * 2. Assembly code
107 * 3. Number of entries in the system value array
108 * 4. System value array
109 * 5. Size (in bytes) of kernel inputs
110 * 6. Legacy param array (only used for compute workgroup ID)
111 * 7. Binding table
112 */
113 blob_write_bytes(&blob, shader->prog_data, brw_prog_data_size(stage));
114 blob_write_bytes(&blob, shader->map, shader->prog_data->program_size);
115 blob_write_uint32(&blob, shader->num_system_values);
116 blob_write_bytes(&blob, shader->system_values,
117 shader->num_system_values * sizeof(enum brw_param_builtin));
118 blob_write_uint32(&blob, shader->kernel_input_size);
119 blob_write_bytes(&blob, prog_data->param,
120 prog_data->nr_params * sizeof(uint32_t));
121 blob_write_bytes(&blob, &shader->bt, sizeof(shader->bt));
122
123 disk_cache_put(cache, cache_key, blob.data, blob.size, NULL);
124 blob_finish(&blob);
125 #endif
126 }
127
128 static const enum iris_program_cache_id cache_id_for_stage[] = {
129 [MESA_SHADER_VERTEX] = IRIS_CACHE_VS,
130 [MESA_SHADER_TESS_CTRL] = IRIS_CACHE_TCS,
131 [MESA_SHADER_TESS_EVAL] = IRIS_CACHE_TES,
132 [MESA_SHADER_GEOMETRY] = IRIS_CACHE_GS,
133 [MESA_SHADER_FRAGMENT] = IRIS_CACHE_FS,
134 [MESA_SHADER_COMPUTE] = IRIS_CACHE_CS,
135 };
136
137 /**
138 * Search for a compiled shader in the disk cache. If found, upload it
139 * to the in-memory program cache so we can use it.
140 */
141 struct iris_compiled_shader *
142 iris_disk_cache_retrieve(struct iris_context *ice,
143 const struct iris_uncompiled_shader *ish,
144 const void *prog_key,
145 uint32_t key_size)
146 {
147 #ifdef ENABLE_SHADER_CACHE
148 struct iris_screen *screen = (void *) ice->ctx.screen;
149 struct disk_cache *cache = screen->disk_cache;
150 gl_shader_stage stage = ish->nir->info.stage;
151
152 if (!cache)
153 return NULL;
154
155 cache_key cache_key;
156 iris_disk_cache_compute_key(cache, ish, prog_key, key_size, cache_key);
157
158 if (debug) {
159 char sha1[41];
160 _mesa_sha1_format(sha1, cache_key);
161 fprintf(stderr, "[mesa disk cache] retrieving %s: ", sha1);
162 }
163
164 size_t size;
165 void *buffer = disk_cache_get(screen->disk_cache, cache_key, &size);
166
167 if (debug)
168 fprintf(stderr, "%s\n", buffer ? "found" : "missing");
169
170 if (!buffer)
171 return NULL;
172
173 const uint32_t prog_data_size = brw_prog_data_size(stage);
174
175 struct brw_stage_prog_data *prog_data = ralloc_size(NULL, prog_data_size);
176 const void *assembly;
177 uint32_t num_system_values;
178 uint32_t kernel_input_size;
179 uint32_t *system_values = NULL;
180 uint32_t *so_decls = NULL;
181
182 struct blob_reader blob;
183 blob_reader_init(&blob, buffer, size);
184 blob_copy_bytes(&blob, prog_data, prog_data_size);
185 assembly = blob_read_bytes(&blob, prog_data->program_size);
186 num_system_values = blob_read_uint32(&blob);
187 if (num_system_values) {
188 system_values =
189 ralloc_array(NULL, enum brw_param_builtin, num_system_values);
190 blob_copy_bytes(&blob, system_values,
191 num_system_values * sizeof(enum brw_param_builtin));
192 }
193
194 kernel_input_size = blob_read_uint32(&blob);
195
196 prog_data->param = NULL;
197 prog_data->pull_param = NULL;
198 assert(prog_data->nr_pull_params == 0);
199
200 if (prog_data->nr_params) {
201 prog_data->param = ralloc_array(NULL, uint32_t, prog_data->nr_params);
202 blob_copy_bytes(&blob, prog_data->param,
203 prog_data->nr_params * sizeof(uint32_t));
204 }
205
206 struct iris_binding_table bt;
207 blob_copy_bytes(&blob, &bt, sizeof(bt));
208
209 if (stage == MESA_SHADER_VERTEX ||
210 stage == MESA_SHADER_TESS_EVAL ||
211 stage == MESA_SHADER_GEOMETRY) {
212 struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
213 so_decls = screen->vtbl.create_so_decl_list(&ish->stream_output,
214 &vue_prog_data->vue_map);
215 }
216
217 /* System values and uniforms are stored in constant buffer 0, the
218 * user-facing UBOs are indexed by one. So if any constant buffer is
219 * needed, the constant buffer 0 will be needed, so account for it.
220 */
221 unsigned num_cbufs = ish->nir->info.num_ubos;
222
223 if (num_cbufs || ish->nir->num_uniforms)
224 num_cbufs++;
225
226 if (num_system_values || kernel_input_size)
227 num_cbufs++;
228
229 assert(stage < ARRAY_SIZE(cache_id_for_stage));
230 enum iris_program_cache_id cache_id = cache_id_for_stage[stage];
231
232 /* Upload our newly read shader to the in-memory program cache and
233 * return it to the caller.
234 */
235 struct iris_compiled_shader *shader =
236 iris_upload_shader(ice, cache_id, key_size, prog_key, assembly,
237 prog_data, so_decls, system_values,
238 num_system_values, kernel_input_size, num_cbufs, &bt);
239
240 free(buffer);
241
242 return shader;
243 #else
244 return NULL;
245 #endif
246 }
247
248 /**
249 * Initialize the on-disk shader cache.
250 */
251 void
252 iris_disk_cache_init(struct iris_screen *screen)
253 {
254 #ifdef ENABLE_SHADER_CACHE
255 if (INTEL_DEBUG & DEBUG_DISK_CACHE_DISABLE_MASK)
256 return;
257
258 /* array length = print length + nul char + 1 extra to verify it's unused */
259 char renderer[11];
260 UNUSED int len =
261 snprintf(renderer, sizeof(renderer), "iris_%04x", screen->pci_id);
262 assert(len == sizeof(renderer) - 2);
263
264 const struct build_id_note *note =
265 build_id_find_nhdr_for_addr(iris_disk_cache_init);
266 assert(note && build_id_length(note) == 20); /* sha1 */
267
268 const uint8_t *id_sha1 = build_id_data(note);
269 assert(id_sha1);
270
271 char timestamp[41];
272 _mesa_sha1_format(timestamp, id_sha1);
273
274 const uint64_t driver_flags =
275 brw_get_compiler_config_value(screen->compiler);
276 screen->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
277 #endif
278 }