2 * Copyright © 2017 Timothy Arceri
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
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"
34 write_stream_out_to_cache(struct blob
*blob
,
35 struct pipe_shader_state
*tgsi
)
37 blob_write_bytes(blob
, &tgsi
->stream_output
,
38 sizeof(tgsi
->stream_output
));
42 write_tgsi_to_cache(struct blob
*blob
, struct pipe_shader_state
*tgsi
,
43 struct st_context
*st
, unsigned char *sha1
,
46 blob_write_uint32(blob
, num_tokens
);
47 blob_write_bytes(blob
, tgsi
->tokens
,
48 num_tokens
* sizeof(struct tgsi_token
));
50 disk_cache_put(st
->ctx
->Cache
, sha1
, blob
->data
, blob
->size
);
54 * Store tgsi and any other required state in on-disk shader cache.
57 st_store_tgsi_in_disk_cache(struct st_context
*st
, struct gl_program
*prog
,
58 struct pipe_shader_state
*out_state
,
64 /* Exit early when we are dealing with a ff shader with no source file to
65 * generate a source from.
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)
72 struct blob
*blob
= blob_create();
74 switch (prog
->info
.stage
) {
75 case MESA_SHADER_VERTEX
: {
76 struct st_vertex_program
*stvp
= (struct st_vertex_program
*) prog
;
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
));
85 write_stream_out_to_cache(blob
, &stvp
->tgsi
);
86 write_tgsi_to_cache(blob
, &stvp
->tgsi
, st
, sha1
, num_tokens
);
89 case MESA_SHADER_TESS_CTRL
: {
90 struct st_tessctrl_program
*stcp
= (struct st_tessctrl_program
*) prog
;
93 write_stream_out_to_cache(blob
, out_state
);
94 write_tgsi_to_cache(blob
, out_state
, st
, sha1
, num_tokens
);
97 case MESA_SHADER_TESS_EVAL
: {
98 struct st_tesseval_program
*step
= (struct st_tesseval_program
*) prog
;
101 write_stream_out_to_cache(blob
, out_state
);
102 write_tgsi_to_cache(blob
, out_state
, st
, sha1
, num_tokens
);
105 case MESA_SHADER_GEOMETRY
: {
106 struct st_geometry_program
*stgp
= (struct st_geometry_program
*) prog
;
109 write_stream_out_to_cache(blob
, out_state
);
110 write_tgsi_to_cache(blob
, out_state
, st
, sha1
, num_tokens
);
113 case MESA_SHADER_FRAGMENT
: {
114 struct st_fragment_program
*stfp
= (struct st_fragment_program
*) prog
;
117 write_tgsi_to_cache(blob
, &stfp
->tgsi
, st
, sha1
, num_tokens
);
120 case MESA_SHADER_COMPUTE
: {
121 struct st_compute_program
*stcp
= (struct st_compute_program
*) prog
;
124 write_tgsi_to_cache(blob
, out_state
, st
, sha1
, num_tokens
);
128 unreachable("Unsupported stage");
131 if (st
->ctx
->_Shader
->Flags
& GLSL_CACHE_INFO
) {
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
);
142 read_stream_out_from_cache(struct blob_reader
*blob_reader
,
143 struct pipe_shader_state
*tgsi
)
145 blob_copy_bytes(blob_reader
, (uint8_t *) &tgsi
->stream_output
,
146 sizeof(tgsi
->stream_output
));
150 read_tgsi_from_cache(struct blob_reader
*blob_reader
,
151 const struct tgsi_token
**tokens
)
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
);
160 st_load_tgsi_from_disk_cache(struct gl_context
*ctx
,
161 struct gl_shader_program
*prog
)
166 unsigned char *stage_sha1
[MESA_SHADER_STAGES
];
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.
172 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
173 if (prog
->_LinkedShaders
[i
] == NULL
)
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
);
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
]);
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
]);
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
]);
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
]);
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
]);
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
]);
231 unreachable("Unsupported stage");
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.
242 if (prog
->data
->LinkStatus
!= linking_skipped
)
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
)
251 unsigned char *sha1
= stage_sha1
[i
];
253 buffer
= (uint8_t *) disk_cache_get(ctx
->Cache
, sha1
, &size
);
255 struct blob_reader blob_reader
;
256 blob_reader_init(&blob_reader
, buffer
, size
);
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
;
264 st_release_vp_variants(st
, stvp
);
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
));
272 read_stream_out_from_cache(&blob_reader
, &stvp
->tgsi
);
273 read_tgsi_from_cache(&blob_reader
, &stvp
->tgsi
.tokens
);
276 st
->dirty
|= ST_NEW_VERTEX_PROGRAM(st
, stvp
);
280 case MESA_SHADER_TESS_CTRL
: {
281 struct st_tessctrl_program
*sttcp
=
282 (struct st_tessctrl_program
*) glprog
;
284 st_release_basic_variants(st
, sttcp
->Base
.Target
,
285 &sttcp
->variants
, &sttcp
->tgsi
);
287 read_stream_out_from_cache(&blob_reader
, &sttcp
->tgsi
);
288 read_tgsi_from_cache(&blob_reader
, &sttcp
->tgsi
.tokens
);
290 if (st
->tcp
== sttcp
)
291 st
->dirty
|= sttcp
->affected_states
;
295 case MESA_SHADER_TESS_EVAL
: {
296 struct st_tesseval_program
*sttep
=
297 (struct st_tesseval_program
*) glprog
;
299 st_release_basic_variants(st
, sttep
->Base
.Target
,
300 &sttep
->variants
, &sttep
->tgsi
);
302 read_stream_out_from_cache(&blob_reader
, &sttep
->tgsi
);
303 read_tgsi_from_cache(&blob_reader
, &sttep
->tgsi
.tokens
);
305 if (st
->tep
== sttep
)
306 st
->dirty
|= sttep
->affected_states
;
310 case MESA_SHADER_GEOMETRY
: {
311 struct st_geometry_program
*stgp
=
312 (struct st_geometry_program
*) glprog
;
314 st_release_basic_variants(st
, stgp
->Base
.Target
, &stgp
->variants
,
317 read_stream_out_from_cache(&blob_reader
, &stgp
->tgsi
);
318 read_tgsi_from_cache(&blob_reader
, &stgp
->tgsi
.tokens
);
321 st
->dirty
|= stgp
->affected_states
;
325 case MESA_SHADER_FRAGMENT
: {
326 struct st_fragment_program
*stfp
=
327 (struct st_fragment_program
*) glprog
;
329 st_release_fp_variants(st
, stfp
);
331 read_tgsi_from_cache(&blob_reader
, &stfp
->tgsi
.tokens
);
334 st
->dirty
|= stfp
->affected_states
;
338 case MESA_SHADER_COMPUTE
: {
339 struct st_compute_program
*stcp
=
340 (struct st_compute_program
*) glprog
;
342 st_release_cp_variants(st
, stcp
);
344 read_tgsi_from_cache(&blob_reader
,
345 (const struct tgsi_token
**) &stcp
->tgsi
.prog
);
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;
352 st
->dirty
|= stcp
->affected_states
;
357 unreachable("Unsupported stage");
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.
364 assert(!"Invalid TGSI shader disk cache item!");
366 if (ctx
->_Shader
->Flags
& GLSL_CACHE_INFO
) {
367 fprintf(stderr
, "Error reading program from cache (invalid "
368 "TGSI cache item)\n");
371 disk_cache_remove(ctx
->Cache
, sha1
);
373 goto fallback_recompile
;
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
);
382 st_set_prog_affected_state_flags(glprog
);
383 _mesa_associate_uniform_storage(ctx
, prog
, glprog
->Parameters
,
388 /* Failed to find a matching cached shader so fallback to recompile.
390 if (ctx
->_Shader
->Flags
& GLSL_CACHE_INFO
) {
391 fprintf(stderr
, "TGSI cache item not found falling back to "
395 goto fallback_recompile
;
404 for (unsigned i
= 0; i
< prog
->NumShaders
; i
++) {
405 _mesa_glsl_compile_shader(ctx
, prog
->Shaders
[i
], false, false, true);
408 prog
->data
->cache_fallback
= true;
409 _mesa_glsl_link_shader(ctx
, prog
);