glsl, st/shader_cache: check the whole sha1 for zero
[mesa.git] / src / mesa / state_tracker / st_shader_cache.c
1 /*
2 * Copyright © 2017 Timothy Arceri
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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <stdio.h>
25
26 #include "st_program.h"
27 #include "st_shader_cache.h"
28 #include "compiler/glsl/program.h"
29 #include "pipe/p_shader_tokens.h"
30 #include "program/ir_to_mesa.h"
31 #include "util/u_memory.h"
32
33 static void
34 write_stream_out_to_cache(struct blob *blob,
35 struct pipe_shader_state *tgsi)
36 {
37 blob_write_bytes(blob, &tgsi->stream_output,
38 sizeof(tgsi->stream_output));
39 }
40
41 static void
42 write_tgsi_to_cache(struct blob *blob, struct pipe_shader_state *tgsi,
43 struct st_context *st, unsigned char *sha1,
44 unsigned num_tokens)
45 {
46 blob_write_uint32(blob, num_tokens);
47 blob_write_bytes(blob, tgsi->tokens,
48 num_tokens * sizeof(struct tgsi_token));
49
50 disk_cache_put(st->ctx->Cache, sha1, blob->data, blob->size);
51 }
52
53 /**
54 * Store tgsi and any other required state in on-disk shader cache.
55 */
56 void
57 st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog,
58 struct pipe_shader_state *out_state,
59 unsigned num_tokens)
60 {
61 if (!st->ctx->Cache)
62 return;
63
64 /* Exit early when we are dealing with a ff shader with no source file to
65 * generate a source from.
66 */
67 static const char zero[sizeof(prog->sh.data->sha1)] = {0};
68 if (memcmp(prog->sh.data->sha1, zero, sizeof(prog->sh.data->sha1)) == 0)
69 return;
70
71 unsigned char *sha1;
72 struct blob *blob = blob_create();
73
74 switch (prog->info.stage) {
75 case MESA_SHADER_VERTEX: {
76 struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
77 sha1 = stvp->sha1;
78
79 blob_write_uint32(blob, stvp->num_inputs);
80 blob_write_bytes(blob, stvp->index_to_input,
81 sizeof(stvp->index_to_input));
82 blob_write_bytes(blob, stvp->result_to_output,
83 sizeof(stvp->result_to_output));
84
85 write_stream_out_to_cache(blob, &stvp->tgsi);
86 write_tgsi_to_cache(blob, &stvp->tgsi, st, sha1, num_tokens);
87 break;
88 }
89 case MESA_SHADER_TESS_CTRL: {
90 struct st_tessctrl_program *stcp = (struct st_tessctrl_program *) prog;
91 sha1 = stcp->sha1;
92
93 write_stream_out_to_cache(blob, out_state);
94 write_tgsi_to_cache(blob, out_state, st, sha1, num_tokens);
95 break;
96 }
97 case MESA_SHADER_TESS_EVAL: {
98 struct st_tesseval_program *step = (struct st_tesseval_program *) prog;
99 sha1 = step->sha1;
100
101 write_stream_out_to_cache(blob, out_state);
102 write_tgsi_to_cache(blob, out_state, st, sha1, num_tokens);
103 break;
104 }
105 case MESA_SHADER_GEOMETRY: {
106 struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
107 sha1 = stgp->sha1;
108
109 write_stream_out_to_cache(blob, out_state);
110 write_tgsi_to_cache(blob, out_state, st, sha1, num_tokens);
111 break;
112 }
113 case MESA_SHADER_FRAGMENT: {
114 struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
115 sha1 = stfp->sha1;
116
117 write_tgsi_to_cache(blob, &stfp->tgsi, st, sha1, num_tokens);
118 break;
119 }
120 case MESA_SHADER_COMPUTE: {
121 struct st_compute_program *stcp = (struct st_compute_program *) prog;
122 sha1 = stcp->sha1;
123
124 write_tgsi_to_cache(blob, out_state, st, sha1, num_tokens);
125 break;
126 }
127 default:
128 unreachable("Unsupported stage");
129 }
130
131 if (st->ctx->_Shader->Flags & GLSL_CACHE_INFO) {
132 char sha1_buf[41];
133 _mesa_sha1_format(sha1_buf, sha1);
134 fprintf(stderr, "putting %s tgsi_tokens in cache: %s\n",
135 _mesa_shader_stage_to_string(prog->info.stage), sha1_buf);
136 }
137
138 free(blob);
139 }
140
141 static void
142 read_stream_out_from_cache(struct blob_reader *blob_reader,
143 struct pipe_shader_state *tgsi)
144 {
145 blob_copy_bytes(blob_reader, (uint8_t *) &tgsi->stream_output,
146 sizeof(tgsi->stream_output));
147 }
148
149 static void
150 read_tgsi_from_cache(struct blob_reader *blob_reader,
151 const struct tgsi_token **tokens)
152 {
153 uint32_t num_tokens = blob_read_uint32(blob_reader);
154 unsigned tokens_size = num_tokens * sizeof(struct tgsi_token);
155 *tokens = (const struct tgsi_token*) MALLOC(tokens_size);
156 blob_copy_bytes(blob_reader, (uint8_t *) *tokens, tokens_size);
157 }
158
159 bool
160 st_load_tgsi_from_disk_cache(struct gl_context *ctx,
161 struct gl_shader_program *prog)
162 {
163 if (!ctx->Cache)
164 return false;
165
166 unsigned char *stage_sha1[MESA_SHADER_STAGES];
167 char sha1_buf[41];
168
169 /* Compute and store sha1 for each stage. These will be reused by the
170 * cache store pass if we fail to find the cached tgsi.
171 */
172 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
173 if (prog->_LinkedShaders[i] == NULL)
174 continue;
175
176 char *buf = ralloc_strdup(NULL, "tgsi_tokens ");
177 _mesa_sha1_format(sha1_buf,
178 prog->_LinkedShaders[i]->Program->sh.data->sha1);
179 ralloc_strcat(&buf, sha1_buf);
180
181 struct gl_program *glprog = prog->_LinkedShaders[i]->Program;
182 switch (glprog->info.stage) {
183 case MESA_SHADER_VERTEX: {
184 struct st_vertex_program *stvp = (struct st_vertex_program *) glprog;
185 stage_sha1[i] = stvp->sha1;
186 ralloc_strcat(&buf, " vs");
187 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
188 break;
189 }
190 case MESA_SHADER_TESS_CTRL: {
191 struct st_tessctrl_program *stcp =
192 (struct st_tessctrl_program *) glprog;
193 stage_sha1[i] = stcp->sha1;
194 ralloc_strcat(&buf, " tcs");
195 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
196 break;
197 }
198 case MESA_SHADER_TESS_EVAL: {
199 struct st_tesseval_program *step =
200 (struct st_tesseval_program *) glprog;
201 stage_sha1[i] = step->sha1;
202 ralloc_strcat(&buf, " tes");
203 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
204 break;
205 }
206 case MESA_SHADER_GEOMETRY: {
207 struct st_geometry_program *stgp =
208 (struct st_geometry_program *) glprog;
209 stage_sha1[i] = stgp->sha1;
210 ralloc_strcat(&buf, " gs");
211 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
212 break;
213 }
214 case MESA_SHADER_FRAGMENT: {
215 struct st_fragment_program *stfp =
216 (struct st_fragment_program *) glprog;
217 stage_sha1[i] = stfp->sha1;
218 ralloc_strcat(&buf, " fs");
219 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
220 break;
221 }
222 case MESA_SHADER_COMPUTE: {
223 struct st_compute_program *stcp =
224 (struct st_compute_program *) glprog;
225 stage_sha1[i] = stcp->sha1;
226 ralloc_strcat(&buf, " cs");
227 disk_cache_compute_key(ctx->Cache, buf, strlen(buf), stage_sha1[i]);
228 break;
229 }
230 default:
231 unreachable("Unsupported stage");
232 }
233
234 ralloc_free(buf);
235 }
236
237 /* Now that we have created the sha1 keys that will be used for writting to
238 * the tgsi cache fallback to the regular glsl to tgsi path if we didn't
239 * load the GLSL IR from cache. We do this as glsl to tgsi can alter things
240 * such as gl_program_parameter_list which holds things like uniforms.
241 */
242 if (prog->data->LinkStatus != linking_skipped)
243 return false;
244
245 struct st_context *st = st_context(ctx);
246 uint8_t *buffer = NULL;
247 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
248 if (prog->_LinkedShaders[i] == NULL)
249 continue;
250
251 unsigned char *sha1 = stage_sha1[i];
252 size_t size;
253 buffer = (uint8_t *) disk_cache_get(ctx->Cache, sha1, &size);
254 if (buffer) {
255 struct blob_reader blob_reader;
256 blob_reader_init(&blob_reader, buffer, size);
257
258 struct gl_program *glprog = prog->_LinkedShaders[i]->Program;
259 switch (glprog->info.stage) {
260 case MESA_SHADER_VERTEX: {
261 struct st_vertex_program *stvp =
262 (struct st_vertex_program *) glprog;
263
264 st_release_vp_variants(st, stvp);
265
266 stvp->num_inputs = blob_read_uint32(&blob_reader);
267 blob_copy_bytes(&blob_reader, (uint8_t *) stvp->index_to_input,
268 sizeof(stvp->index_to_input));
269 blob_copy_bytes(&blob_reader, (uint8_t *) stvp->result_to_output,
270 sizeof(stvp->result_to_output));
271
272 read_stream_out_from_cache(&blob_reader, &stvp->tgsi);
273 read_tgsi_from_cache(&blob_reader, &stvp->tgsi.tokens);
274
275 if (st->vp == stvp)
276 st->dirty |= ST_NEW_VERTEX_PROGRAM(st, stvp);
277
278 break;
279 }
280 case MESA_SHADER_TESS_CTRL: {
281 struct st_tessctrl_program *sttcp =
282 (struct st_tessctrl_program *) glprog;
283
284 st_release_basic_variants(st, sttcp->Base.Target,
285 &sttcp->variants, &sttcp->tgsi);
286
287 read_stream_out_from_cache(&blob_reader, &sttcp->tgsi);
288 read_tgsi_from_cache(&blob_reader, &sttcp->tgsi.tokens);
289
290 if (st->tcp == sttcp)
291 st->dirty |= sttcp->affected_states;
292
293 break;
294 }
295 case MESA_SHADER_TESS_EVAL: {
296 struct st_tesseval_program *sttep =
297 (struct st_tesseval_program *) glprog;
298
299 st_release_basic_variants(st, sttep->Base.Target,
300 &sttep->variants, &sttep->tgsi);
301
302 read_stream_out_from_cache(&blob_reader, &sttep->tgsi);
303 read_tgsi_from_cache(&blob_reader, &sttep->tgsi.tokens);
304
305 if (st->tep == sttep)
306 st->dirty |= sttep->affected_states;
307
308 break;
309 }
310 case MESA_SHADER_GEOMETRY: {
311 struct st_geometry_program *stgp =
312 (struct st_geometry_program *) glprog;
313
314 st_release_basic_variants(st, stgp->Base.Target, &stgp->variants,
315 &stgp->tgsi);
316
317 read_stream_out_from_cache(&blob_reader, &stgp->tgsi);
318 read_tgsi_from_cache(&blob_reader, &stgp->tgsi.tokens);
319
320 if (st->gp == stgp)
321 st->dirty |= stgp->affected_states;
322
323 break;
324 }
325 case MESA_SHADER_FRAGMENT: {
326 struct st_fragment_program *stfp =
327 (struct st_fragment_program *) glprog;
328
329 st_release_fp_variants(st, stfp);
330
331 read_tgsi_from_cache(&blob_reader, &stfp->tgsi.tokens);
332
333 if (st->fp == stfp)
334 st->dirty |= stfp->affected_states;
335
336 break;
337 }
338 case MESA_SHADER_COMPUTE: {
339 struct st_compute_program *stcp =
340 (struct st_compute_program *) glprog;
341
342 st_release_cp_variants(st, stcp);
343
344 read_tgsi_from_cache(&blob_reader,
345 (const struct tgsi_token**) &stcp->tgsi.prog);
346
347 stcp->tgsi.req_local_mem = stcp->Base.info.cs.shared_size;
348 stcp->tgsi.req_private_mem = 0;
349 stcp->tgsi.req_input_mem = 0;
350
351 if (st->cp == stcp)
352 st->dirty |= stcp->affected_states;
353
354 break;
355 }
356 default:
357 unreachable("Unsupported stage");
358 }
359
360 if (blob_reader.current != blob_reader.end || blob_reader.overrun) {
361 /* Something very bad has gone wrong discard the item from the
362 * cache and rebuild/link from source.
363 */
364 assert(!"Invalid TGSI shader disk cache item!");
365
366 if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
367 fprintf(stderr, "Error reading program from cache (invalid "
368 "TGSI cache item)\n");
369 }
370
371 disk_cache_remove(ctx->Cache, sha1);
372
373 goto fallback_recompile;
374 }
375
376 if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
377 _mesa_sha1_format(sha1_buf, sha1);
378 fprintf(stderr, "%s tgsi_tokens retrieved from cache: %s\n",
379 _mesa_shader_stage_to_string(i), sha1_buf);
380 }
381
382 st_set_prog_affected_state_flags(glprog);
383 _mesa_associate_uniform_storage(ctx, prog, glprog->Parameters,
384 false);
385
386 free(buffer);
387 } else {
388 /* Failed to find a matching cached shader so fallback to recompile.
389 */
390 if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
391 fprintf(stderr, "TGSI cache item not found falling back to "
392 "compile.\n");
393 }
394
395 goto fallback_recompile;
396 }
397 }
398
399 return true;
400
401 fallback_recompile:
402 free(buffer);
403
404 for (unsigned i = 0; i < prog->NumShaders; i++) {
405 _mesa_glsl_compile_shader(ctx, prog->Shaders[i], false, false, true);
406 }
407
408 prog->data->cache_fallback = true;
409 _mesa_glsl_link_shader(ctx, prog);
410
411 return true;
412 }