Path: blob/21.2-virgl/src/gallium/drivers/etnaviv/etnaviv_disk_cache.c
4570 views
/*1* Copyright © 2020 Google, Inc.2* Copyright (c) 2020 Etnaviv Project3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sub license,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the12* next paragraph) shall be included in all copies or substantial portions13* of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21* DEALINGS IN THE SOFTWARE.22*23* Authors:24* Christian Gmeiner <[email protected]>25*/2627#include "etnaviv_debug.h"28#include "etnaviv_disk_cache.h"29#include "nir_serialize.h"3031#define debug 03233void34etna_disk_cache_init(struct etna_compiler *compiler, const char *renderer)35{36if (!(etna_mesa_debug & ETNA_DBG_NIR))37return;3839if (etna_mesa_debug & ETNA_DBG_NOCACHE)40return;4142const struct build_id_note *note =43build_id_find_nhdr_for_addr(etna_disk_cache_init);44assert(note && build_id_length(note) == 20); /* sha1 */4546const uint8_t *id_sha1 = build_id_data(note);47assert(id_sha1);4849char timestamp[41];50_mesa_sha1_format(timestamp, id_sha1);5152compiler->disk_cache = disk_cache_create(renderer, timestamp, etna_mesa_debug);53}5455void56etna_disk_cache_init_shader_key(struct etna_compiler *compiler, struct etna_shader *shader)57{58if (!compiler->disk_cache)59return;6061struct mesa_sha1 ctx;6263_mesa_sha1_init(&ctx);6465/* Serialize the NIR to a binary blob that we can hash for the disk66* cache. Drop unnecessary information (like variable names)67* so the serialized NIR is smaller, and also to let us detect more68* isomorphic shaders when hashing, increasing cache hits.69*/70struct blob blob;7172blob_init(&blob);73nir_serialize(&blob, shader->nir, true);74_mesa_sha1_update(&ctx, blob.data, blob.size);75blob_finish(&blob);7677_mesa_sha1_final(&ctx, shader->cache_key);78}7980static void81compute_variant_key(struct etna_compiler *compiler, struct etna_shader_variant *v,82cache_key cache_key)83{84struct blob blob;8586blob_init(&blob);8788blob_write_bytes(&blob, &v->shader->cache_key, sizeof(v->shader->cache_key));89blob_write_bytes(&blob, &v->key, sizeof(v->key));9091disk_cache_compute_key(compiler->disk_cache, blob.data, blob.size, cache_key);9293blob_finish(&blob);94}9596static void97retrieve_variant(struct blob_reader *blob, struct etna_shader_variant *v)98{99blob_copy_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);100101v->code = malloc(4 * v->code_size);102blob_copy_bytes(blob, v->code, 4 * v->code_size);103104blob_copy_bytes(blob, &v->uniforms.count, sizeof(v->uniforms.count));105v->uniforms.contents = malloc(v->uniforms.count * sizeof(v->uniforms.contents));106v->uniforms.data = malloc(v->uniforms.count * sizeof(v->uniforms.data));107108blob_copy_bytes(blob, v->uniforms.contents, v->uniforms.count * sizeof(v->uniforms.contents));109blob_copy_bytes(blob, v->uniforms.data, v->uniforms.count * sizeof(v->uniforms.data));110}111112static void113store_variant(struct blob *blob, const struct etna_shader_variant *v)114{115const uint32_t imm_count = v->uniforms.count;116117blob_write_bytes(blob, VARIANT_CACHE_PTR(v), VARIANT_CACHE_SIZE);118blob_write_bytes(blob, v->code, 4 * v->code_size);119120blob_write_bytes(blob, &v->uniforms.count, sizeof(v->uniforms.count));121blob_write_bytes(blob, v->uniforms.contents, imm_count * sizeof(v->uniforms.contents));122blob_write_bytes(blob, v->uniforms.data, imm_count * sizeof(v->uniforms.data));123}124125bool126etna_disk_cache_retrieve(struct etna_compiler *compiler, struct etna_shader_variant *v)127{128if (!compiler->disk_cache)129return false;130131cache_key cache_key;132133compute_variant_key(compiler, v, cache_key);134135if (debug) {136char sha1[41];137138_mesa_sha1_format(sha1, cache_key);139fprintf(stderr, "[mesa disk cache] retrieving variant %s: ", sha1);140}141142size_t size;143void *buffer = disk_cache_get(compiler->disk_cache, cache_key, &size);144145if (debug)146fprintf(stderr, "%s\n", buffer ? "found" : "missing");147148if (!buffer)149return false;150151struct blob_reader blob;152blob_reader_init(&blob, buffer, size);153154retrieve_variant(&blob, v);155156free(buffer);157158return true;159}160161void162etna_disk_cache_store(struct etna_compiler *compiler, struct etna_shader_variant *v)163{164if (!compiler->disk_cache)165return;166167cache_key cache_key;168169compute_variant_key(compiler, v, cache_key);170171if (debug) {172char sha1[41];173174_mesa_sha1_format(sha1, cache_key);175fprintf(stderr, "[mesa disk cache] storing variant %s\n", sha1);176}177178struct blob blob;179blob_init(&blob);180181store_variant(&blob, v);182183disk_cache_put(compiler->disk_cache, cache_key, blob.data, blob.size, NULL);184blob_finish(&blob);185}186187188