1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2014 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg/**
25b8e80941Smrg * \file shader_cache.cpp
26b8e80941Smrg *
27b8e80941Smrg * GLSL shader cache implementation
28b8e80941Smrg *
29b8e80941Smrg * This uses disk_cache.c to write out a serialization of various
30b8e80941Smrg * state that's required in order to successfully load and use a
31b8e80941Smrg * binary written out by a drivers backend, this state is referred to as
32b8e80941Smrg * "metadata" throughout the implementation.
33b8e80941Smrg *
34b8e80941Smrg * The hash key for glsl metadata is a hash of the hashes of each GLSL
35b8e80941Smrg * source string as well as some API settings that change the final program
36b8e80941Smrg * such as SSO, attribute bindings, frag data bindings, etc.
37b8e80941Smrg *
38b8e80941Smrg * In order to avoid caching any actual IR we use the put_key/get_key support
39b8e80941Smrg * in the disk_cache to put the SHA-1 hash for each successfully compiled
40b8e80941Smrg * shader into the cache, and optimisticly return early from glCompileShader
41b8e80941Smrg * (if the identical shader had been successfully compiled in the past),
42b8e80941Smrg * in the hope that the final linked shader will be found in the cache.
43b8e80941Smrg * If anything goes wrong (shader variant not found, backend cache item is
44b8e80941Smrg * corrupt, etc) we will use a fallback path to compile and link the IR.
45b8e80941Smrg */
46b8e80941Smrg
47b8e80941Smrg#include "compiler/shader_info.h"
48b8e80941Smrg#include "glsl_symbol_table.h"
49b8e80941Smrg#include "glsl_parser_extras.h"
50b8e80941Smrg#include "ir.h"
51b8e80941Smrg#include "ir_optimization.h"
52b8e80941Smrg#include "ir_rvalue_visitor.h"
53b8e80941Smrg#include "ir_uniform.h"
54b8e80941Smrg#include "linker.h"
55b8e80941Smrg#include "link_varyings.h"
56b8e80941Smrg#include "nir.h"
57b8e80941Smrg#include "program.h"
58b8e80941Smrg#include "serialize.h"
59b8e80941Smrg#include "shader_cache.h"
60b8e80941Smrg#include "util/mesa-sha1.h"
61b8e80941Smrg#include "string_to_uint_map.h"
62b8e80941Smrg#include "main/mtypes.h"
63b8e80941Smrg
64b8e80941Smrgextern "C" {
65b8e80941Smrg#include "main/enums.h"
66b8e80941Smrg#include "main/shaderobj.h"
67b8e80941Smrg#include "program/program.h"
68b8e80941Smrg}
69b8e80941Smrg
70b8e80941Smrgstatic void
71b8e80941Smrgcompile_shaders(struct gl_context *ctx, struct gl_shader_program *prog) {
72b8e80941Smrg   for (unsigned i = 0; i < prog->NumShaders; i++) {
73b8e80941Smrg      _mesa_glsl_compile_shader(ctx, prog->Shaders[i], false, false, true);
74b8e80941Smrg   }
75b8e80941Smrg}
76b8e80941Smrg
77b8e80941Smrgstatic void
78b8e80941Smrgcreate_binding_str(const char *key, unsigned value, void *closure)
79b8e80941Smrg{
80b8e80941Smrg   char **bindings_str = (char **) closure;
81b8e80941Smrg   ralloc_asprintf_append(bindings_str, "%s:%u,", key, value);
82b8e80941Smrg}
83b8e80941Smrg
84b8e80941Smrgvoid
85b8e80941Smrgshader_cache_write_program_metadata(struct gl_context *ctx,
86b8e80941Smrg                                    struct gl_shader_program *prog)
87b8e80941Smrg{
88b8e80941Smrg   struct disk_cache *cache = ctx->Cache;
89b8e80941Smrg   if (!cache)
90b8e80941Smrg      return;
91b8e80941Smrg
92b8e80941Smrg   /* Exit early when we are dealing with a ff shader with no source file to
93b8e80941Smrg    * generate a source from.
94b8e80941Smrg    *
95b8e80941Smrg    * TODO: In future we should use another method to generate a key for ff
96b8e80941Smrg    * programs.
97b8e80941Smrg    */
98b8e80941Smrg   static const char zero[sizeof(prog->data->sha1)] = {0};
99b8e80941Smrg   if (memcmp(prog->data->sha1, zero, sizeof(prog->data->sha1)) == 0)
100b8e80941Smrg      return;
101b8e80941Smrg
102b8e80941Smrg   struct blob metadata;
103b8e80941Smrg   blob_init(&metadata);
104b8e80941Smrg
105b8e80941Smrg   if (ctx->Driver.ShaderCacheSerializeDriverBlob) {
106b8e80941Smrg      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
107b8e80941Smrg         struct gl_linked_shader *sh = prog->_LinkedShaders[i];
108b8e80941Smrg         if (sh)
109b8e80941Smrg            ctx->Driver.ShaderCacheSerializeDriverBlob(ctx, sh->Program);
110b8e80941Smrg      }
111b8e80941Smrg   }
112b8e80941Smrg
113b8e80941Smrg   serialize_glsl_program(&metadata, ctx, prog);
114b8e80941Smrg
115b8e80941Smrg   struct cache_item_metadata cache_item_metadata;
116b8e80941Smrg   cache_item_metadata.type = CACHE_ITEM_TYPE_GLSL;
117b8e80941Smrg   cache_item_metadata.keys =
118b8e80941Smrg      (cache_key *) malloc(prog->NumShaders * sizeof(cache_key));
119b8e80941Smrg   cache_item_metadata.num_keys = prog->NumShaders;
120b8e80941Smrg
121b8e80941Smrg   if (!cache_item_metadata.keys)
122b8e80941Smrg      goto fail;
123b8e80941Smrg
124b8e80941Smrg   for (unsigned i = 0; i < prog->NumShaders; i++) {
125b8e80941Smrg      memcpy(cache_item_metadata.keys[i], prog->Shaders[i]->sha1,
126b8e80941Smrg             sizeof(cache_key));
127b8e80941Smrg   }
128b8e80941Smrg
129b8e80941Smrg   disk_cache_put(cache, prog->data->sha1, metadata.data, metadata.size,
130b8e80941Smrg                  &cache_item_metadata);
131b8e80941Smrg
132b8e80941Smrg   char sha1_buf[41];
133b8e80941Smrg   if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
134b8e80941Smrg      _mesa_sha1_format(sha1_buf, prog->data->sha1);
135b8e80941Smrg      fprintf(stderr, "putting program metadata in cache: %s\n", sha1_buf);
136b8e80941Smrg   }
137b8e80941Smrg
138b8e80941Smrgfail:
139b8e80941Smrg   free(cache_item_metadata.keys);
140b8e80941Smrg   blob_finish(&metadata);
141b8e80941Smrg}
142b8e80941Smrg
143b8e80941Smrgbool
144b8e80941Smrgshader_cache_read_program_metadata(struct gl_context *ctx,
145b8e80941Smrg                                   struct gl_shader_program *prog)
146b8e80941Smrg{
147b8e80941Smrg   /* Fixed function programs generated by Mesa are not cached. So don't
148b8e80941Smrg    * try to read metadata for them from the cache.
149b8e80941Smrg    */
150b8e80941Smrg   if (prog->Name == 0)
151b8e80941Smrg      return false;
152b8e80941Smrg
153b8e80941Smrg   struct disk_cache *cache = ctx->Cache;
154b8e80941Smrg   if (!cache)
155b8e80941Smrg      return false;
156b8e80941Smrg
157b8e80941Smrg   /* Include bindings when creating sha1. These bindings change the resulting
158b8e80941Smrg    * binary so they are just as important as the shader source.
159b8e80941Smrg    */
160b8e80941Smrg   char *buf = ralloc_strdup(NULL, "vb: ");
161b8e80941Smrg   prog->AttributeBindings->iterate(create_binding_str, &buf);
162b8e80941Smrg   ralloc_strcat(&buf, "fb: ");
163b8e80941Smrg   prog->FragDataBindings->iterate(create_binding_str, &buf);
164b8e80941Smrg   ralloc_strcat(&buf, "fbi: ");
165b8e80941Smrg   prog->FragDataIndexBindings->iterate(create_binding_str, &buf);
166b8e80941Smrg   ralloc_asprintf_append(&buf, "tf: %d ", prog->TransformFeedback.BufferMode);
167b8e80941Smrg   for (unsigned int i = 0; i < prog->TransformFeedback.NumVarying; i++) {
168b8e80941Smrg      ralloc_asprintf_append(&buf, "%s ",
169b8e80941Smrg                             prog->TransformFeedback.VaryingNames[i]);
170b8e80941Smrg   }
171b8e80941Smrg
172b8e80941Smrg   /* SSO has an effect on the linked program so include this when generating
173b8e80941Smrg    * the sha also.
174b8e80941Smrg    */
175b8e80941Smrg   ralloc_asprintf_append(&buf, "sso: %s\n",
176b8e80941Smrg                          prog->SeparateShader ? "T" : "F");
177b8e80941Smrg
178b8e80941Smrg   /* A shader might end up producing different output depending on the glsl
179b8e80941Smrg    * version supported by the compiler. For example a different path might be
180b8e80941Smrg    * taken by the preprocessor, so add the version to the hash input.
181b8e80941Smrg    */
182b8e80941Smrg   ralloc_asprintf_append(&buf, "api: %d glsl: %d fglsl: %d\n",
183b8e80941Smrg                          ctx->API, ctx->Const.GLSLVersion,
184b8e80941Smrg                          ctx->Const.ForceGLSLVersion);
185b8e80941Smrg
186b8e80941Smrg   /* We run the preprocessor on shaders after hashing them, so we need to
187b8e80941Smrg    * add any extension override vars to the hash. If we don't do this the
188b8e80941Smrg    * preprocessor could result in different output and we could load the
189b8e80941Smrg    * wrong shader.
190b8e80941Smrg    */
191b8e80941Smrg   char *ext_override = getenv("MESA_EXTENSION_OVERRIDE");
192b8e80941Smrg   if (ext_override) {
193b8e80941Smrg      ralloc_asprintf_append(&buf, "ext:%s", ext_override);
194b8e80941Smrg   }
195b8e80941Smrg
196b8e80941Smrg   /* DRI config options may also change the output from the compiler so
197b8e80941Smrg    * include them as an input to sha1 creation.
198b8e80941Smrg    */
199b8e80941Smrg   char sha1buf[41];
200b8e80941Smrg   _mesa_sha1_format(sha1buf, ctx->Const.dri_config_options_sha1);
201b8e80941Smrg   ralloc_strcat(&buf, sha1buf);
202b8e80941Smrg
203b8e80941Smrg   for (unsigned i = 0; i < prog->NumShaders; i++) {
204b8e80941Smrg      struct gl_shader *sh = prog->Shaders[i];
205b8e80941Smrg      _mesa_sha1_format(sha1buf, sh->sha1);
206b8e80941Smrg      ralloc_asprintf_append(&buf, "%s: %s\n",
207b8e80941Smrg                             _mesa_shader_stage_to_abbrev(sh->Stage), sha1buf);
208b8e80941Smrg   }
209b8e80941Smrg   disk_cache_compute_key(cache, buf, strlen(buf), prog->data->sha1);
210b8e80941Smrg   ralloc_free(buf);
211b8e80941Smrg
212b8e80941Smrg   size_t size;
213b8e80941Smrg   uint8_t *buffer = (uint8_t *) disk_cache_get(cache, prog->data->sha1,
214b8e80941Smrg                                                &size);
215b8e80941Smrg   if (buffer == NULL) {
216b8e80941Smrg      /* Cached program not found. We may have seen the individual shaders
217b8e80941Smrg       * before and skipped compiling but they may not have been used together
218b8e80941Smrg       * in this combination before. Fall back to linking shaders but first
219b8e80941Smrg       * re-compile the shaders.
220b8e80941Smrg       *
221b8e80941Smrg       * We could probably only compile the shaders which were skipped here
222b8e80941Smrg       * but we need to be careful because the source may also have been
223b8e80941Smrg       * changed since the last compile so for now we just recompile
224b8e80941Smrg       * everything.
225b8e80941Smrg       */
226b8e80941Smrg      compile_shaders(ctx, prog);
227b8e80941Smrg      return false;
228b8e80941Smrg   }
229b8e80941Smrg
230b8e80941Smrg   if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
231b8e80941Smrg      _mesa_sha1_format(sha1buf, prog->data->sha1);
232b8e80941Smrg      fprintf(stderr, "loading shader program meta data from cache: %s\n",
233b8e80941Smrg              sha1buf);
234b8e80941Smrg   }
235b8e80941Smrg
236b8e80941Smrg   struct blob_reader metadata;
237b8e80941Smrg   blob_reader_init(&metadata, buffer, size);
238b8e80941Smrg
239b8e80941Smrg   bool deserialized = deserialize_glsl_program(&metadata, ctx, prog);
240b8e80941Smrg
241b8e80941Smrg   if (!deserialized || metadata.current != metadata.end || metadata.overrun) {
242b8e80941Smrg      /* Something has gone wrong discard the item from the cache and rebuild
243b8e80941Smrg       * from source.
244b8e80941Smrg       */
245b8e80941Smrg      assert(!"Invalid GLSL shader disk cache item!");
246b8e80941Smrg
247b8e80941Smrg      if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
248b8e80941Smrg         fprintf(stderr, "Error reading program from cache (invalid GLSL "
249b8e80941Smrg                 "cache item)\n");
250b8e80941Smrg      }
251b8e80941Smrg
252b8e80941Smrg      disk_cache_remove(cache, prog->data->sha1);
253b8e80941Smrg      compile_shaders(ctx, prog);
254b8e80941Smrg      free(buffer);
255b8e80941Smrg      return false;
256b8e80941Smrg   }
257b8e80941Smrg
258b8e80941Smrg   /* This is used to flag a shader retrieved from cache */
259b8e80941Smrg   prog->data->LinkStatus = LINKING_SKIPPED;
260b8e80941Smrg
261b8e80941Smrg   free (buffer);
262b8e80941Smrg
263b8e80941Smrg   return true;
264b8e80941Smrg}
265