101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2015 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 247ec681f3Smrg#include "util/blob.h" 2501e04c3fSmrg#include "util/hash_table.h" 2601e04c3fSmrg#include "util/debug.h" 2701e04c3fSmrg#include "util/disk_cache.h" 2801e04c3fSmrg#include "util/mesa-sha1.h" 299f464c52Smaya#include "nir/nir_serialize.h" 3001e04c3fSmrg#include "anv_private.h" 319f464c52Smaya#include "nir/nir_xfb_info.h" 327ec681f3Smrg#include "vulkan/util/vk_util.h" 3301e04c3fSmrg 3401e04c3fSmrgstruct anv_shader_bin * 3501e04c3fSmrganv_shader_bin_create(struct anv_device *device, 367ec681f3Smrg gl_shader_stage stage, 3701e04c3fSmrg const void *key_data, uint32_t key_size, 3801e04c3fSmrg const void *kernel_data, uint32_t kernel_size, 3901e04c3fSmrg const struct brw_stage_prog_data *prog_data_in, 407ec681f3Smrg uint32_t prog_data_size, 417ec681f3Smrg const struct brw_compile_stats *stats, uint32_t num_stats, 429f464c52Smaya const nir_xfb_info *xfb_info_in, 4301e04c3fSmrg const struct anv_pipeline_bind_map *bind_map) 4401e04c3fSmrg{ 457ec681f3Smrg VK_MULTIALLOC(ma); 467ec681f3Smrg VK_MULTIALLOC_DECL(&ma, struct anv_shader_bin, shader, 1); 477ec681f3Smrg VK_MULTIALLOC_DECL_SIZE(&ma, struct anv_shader_bin_key, key, 487ec681f3Smrg sizeof(*key) + key_size); 497ec681f3Smrg VK_MULTIALLOC_DECL_SIZE(&ma, struct brw_stage_prog_data, prog_data, 507ec681f3Smrg prog_data_size); 517ec681f3Smrg VK_MULTIALLOC_DECL(&ma, struct brw_shader_reloc, prog_data_relocs, 527ec681f3Smrg prog_data_in->num_relocs); 537ec681f3Smrg VK_MULTIALLOC_DECL(&ma, uint32_t, prog_data_param, prog_data_in->nr_params); 547ec681f3Smrg 557ec681f3Smrg VK_MULTIALLOC_DECL_SIZE(&ma, nir_xfb_info, xfb_info, 567ec681f3Smrg xfb_info_in == NULL ? 0 : 577ec681f3Smrg nir_xfb_info_size(xfb_info_in->output_count)); 587ec681f3Smrg 597ec681f3Smrg VK_MULTIALLOC_DECL(&ma, struct anv_pipeline_binding, surface_to_descriptor, 6001e04c3fSmrg bind_map->surface_count); 617ec681f3Smrg VK_MULTIALLOC_DECL(&ma, struct anv_pipeline_binding, sampler_to_descriptor, 6201e04c3fSmrg bind_map->sampler_count); 6301e04c3fSmrg 647ec681f3Smrg if (!vk_multialloc_alloc(&ma, &device->vk.alloc, 657ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_DEVICE)) 6601e04c3fSmrg return NULL; 6701e04c3fSmrg 6801e04c3fSmrg shader->ref_cnt = 1; 6901e04c3fSmrg 707ec681f3Smrg shader->stage = stage; 717ec681f3Smrg 7201e04c3fSmrg key->size = key_size; 7301e04c3fSmrg memcpy(key->data, key_data, key_size); 7401e04c3fSmrg shader->key = key; 7501e04c3fSmrg 7601e04c3fSmrg shader->kernel = 7701e04c3fSmrg anv_state_pool_alloc(&device->instruction_state_pool, kernel_size, 64); 7801e04c3fSmrg memcpy(shader->kernel.map, kernel_data, kernel_size); 7901e04c3fSmrg shader->kernel_size = kernel_size; 8001e04c3fSmrg 817ec681f3Smrg uint64_t shader_data_addr = INSTRUCTION_STATE_POOL_MIN_ADDRESS + 827ec681f3Smrg shader->kernel.offset + 837ec681f3Smrg prog_data_in->const_data_offset; 847ec681f3Smrg 857ec681f3Smrg int rv_count = 0; 867ec681f3Smrg struct brw_shader_reloc_value reloc_values[5]; 877ec681f3Smrg reloc_values[rv_count++] = (struct brw_shader_reloc_value) { 887ec681f3Smrg .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW, 897ec681f3Smrg .value = shader_data_addr, 907ec681f3Smrg }; 917ec681f3Smrg reloc_values[rv_count++] = (struct brw_shader_reloc_value) { 927ec681f3Smrg .id = BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH, 937ec681f3Smrg .value = shader_data_addr >> 32, 947ec681f3Smrg }; 957ec681f3Smrg reloc_values[rv_count++] = (struct brw_shader_reloc_value) { 967ec681f3Smrg .id = BRW_SHADER_RELOC_SHADER_START_OFFSET, 977ec681f3Smrg .value = shader->kernel.offset, 987ec681f3Smrg }; 997ec681f3Smrg if (brw_shader_stage_is_bindless(stage)) { 1007ec681f3Smrg const struct brw_bs_prog_data *bs_prog_data = 1017ec681f3Smrg brw_bs_prog_data_const(prog_data_in); 1027ec681f3Smrg uint64_t resume_sbt_addr = INSTRUCTION_STATE_POOL_MIN_ADDRESS + 1037ec681f3Smrg shader->kernel.offset + 1047ec681f3Smrg bs_prog_data->resume_sbt_offset; 1057ec681f3Smrg reloc_values[rv_count++] = (struct brw_shader_reloc_value) { 1067ec681f3Smrg .id = BRW_SHADER_RELOC_RESUME_SBT_ADDR_LOW, 1077ec681f3Smrg .value = resume_sbt_addr, 1087ec681f3Smrg }; 1097ec681f3Smrg reloc_values[rv_count++] = (struct brw_shader_reloc_value) { 1107ec681f3Smrg .id = BRW_SHADER_RELOC_RESUME_SBT_ADDR_HIGH, 1117ec681f3Smrg .value = resume_sbt_addr >> 32, 1127ec681f3Smrg }; 11301e04c3fSmrg } 1147ec681f3Smrg 1157ec681f3Smrg brw_write_shader_relocs(&device->info, shader->kernel.map, prog_data_in, 1167ec681f3Smrg reloc_values, rv_count); 11701e04c3fSmrg 11801e04c3fSmrg memcpy(prog_data, prog_data_in, prog_data_size); 1197ec681f3Smrg typed_memcpy(prog_data_relocs, prog_data_in->relocs, 1207ec681f3Smrg prog_data_in->num_relocs); 1217ec681f3Smrg prog_data->relocs = prog_data_relocs; 1227ec681f3Smrg memset(prog_data_param, 0, 12301e04c3fSmrg prog_data->nr_params * sizeof(*prog_data_param)); 12401e04c3fSmrg prog_data->param = prog_data_param; 12501e04c3fSmrg shader->prog_data = prog_data; 12601e04c3fSmrg shader->prog_data_size = prog_data_size; 12701e04c3fSmrg 1287ec681f3Smrg assert(num_stats <= ARRAY_SIZE(shader->stats)); 1297ec681f3Smrg typed_memcpy(shader->stats, stats, num_stats); 1307ec681f3Smrg shader->num_stats = num_stats; 1317ec681f3Smrg 1329f464c52Smaya if (xfb_info_in) { 1339f464c52Smaya *xfb_info = *xfb_info_in; 1349f464c52Smaya typed_memcpy(xfb_info->outputs, xfb_info_in->outputs, 1359f464c52Smaya xfb_info_in->output_count); 1369f464c52Smaya shader->xfb_info = xfb_info; 1379f464c52Smaya } else { 1389f464c52Smaya shader->xfb_info = NULL; 1399f464c52Smaya } 1409f464c52Smaya 14101e04c3fSmrg shader->bind_map = *bind_map; 14201e04c3fSmrg typed_memcpy(surface_to_descriptor, bind_map->surface_to_descriptor, 14301e04c3fSmrg bind_map->surface_count); 14401e04c3fSmrg shader->bind_map.surface_to_descriptor = surface_to_descriptor; 14501e04c3fSmrg typed_memcpy(sampler_to_descriptor, bind_map->sampler_to_descriptor, 14601e04c3fSmrg bind_map->sampler_count); 14701e04c3fSmrg shader->bind_map.sampler_to_descriptor = sampler_to_descriptor; 14801e04c3fSmrg 14901e04c3fSmrg return shader; 15001e04c3fSmrg} 15101e04c3fSmrg 15201e04c3fSmrgvoid 15301e04c3fSmrganv_shader_bin_destroy(struct anv_device *device, 15401e04c3fSmrg struct anv_shader_bin *shader) 15501e04c3fSmrg{ 15601e04c3fSmrg assert(shader->ref_cnt == 0); 15701e04c3fSmrg anv_state_pool_free(&device->instruction_state_pool, shader->kernel); 1587ec681f3Smrg vk_free(&device->vk.alloc, shader); 15901e04c3fSmrg} 16001e04c3fSmrg 16101e04c3fSmrgstatic bool 16201e04c3fSmrganv_shader_bin_write_to_blob(const struct anv_shader_bin *shader, 16301e04c3fSmrg struct blob *blob) 16401e04c3fSmrg{ 1657ec681f3Smrg blob_write_uint32(blob, shader->stage); 1667ec681f3Smrg 1679f464c52Smaya blob_write_uint32(blob, shader->key->size); 1689f464c52Smaya blob_write_bytes(blob, shader->key->data, shader->key->size); 1699f464c52Smaya 1709f464c52Smaya blob_write_uint32(blob, shader->kernel_size); 1719f464c52Smaya blob_write_bytes(blob, shader->kernel.map, shader->kernel_size); 1729f464c52Smaya 1739f464c52Smaya blob_write_uint32(blob, shader->prog_data_size); 1749f464c52Smaya blob_write_bytes(blob, shader->prog_data, shader->prog_data_size); 1757ec681f3Smrg blob_write_bytes(blob, shader->prog_data->relocs, 1767ec681f3Smrg shader->prog_data->num_relocs * 1777ec681f3Smrg sizeof(shader->prog_data->relocs[0])); 1787ec681f3Smrg 1797ec681f3Smrg blob_write_uint32(blob, shader->num_stats); 1807ec681f3Smrg blob_write_bytes(blob, shader->stats, 1817ec681f3Smrg shader->num_stats * sizeof(shader->stats[0])); 1829f464c52Smaya 1839f464c52Smaya if (shader->xfb_info) { 1849f464c52Smaya uint32_t xfb_info_size = 1859f464c52Smaya nir_xfb_info_size(shader->xfb_info->output_count); 1869f464c52Smaya blob_write_uint32(blob, xfb_info_size); 1879f464c52Smaya blob_write_bytes(blob, shader->xfb_info, xfb_info_size); 1889f464c52Smaya } else { 1899f464c52Smaya blob_write_uint32(blob, 0); 1909f464c52Smaya } 1919f464c52Smaya 1927ec681f3Smrg blob_write_bytes(blob, shader->bind_map.surface_sha1, 1937ec681f3Smrg sizeof(shader->bind_map.surface_sha1)); 1947ec681f3Smrg blob_write_bytes(blob, shader->bind_map.sampler_sha1, 1957ec681f3Smrg sizeof(shader->bind_map.sampler_sha1)); 1967ec681f3Smrg blob_write_bytes(blob, shader->bind_map.push_sha1, 1977ec681f3Smrg sizeof(shader->bind_map.push_sha1)); 1989f464c52Smaya blob_write_uint32(blob, shader->bind_map.surface_count); 1999f464c52Smaya blob_write_uint32(blob, shader->bind_map.sampler_count); 2009f464c52Smaya blob_write_bytes(blob, shader->bind_map.surface_to_descriptor, 2019f464c52Smaya shader->bind_map.surface_count * 2029f464c52Smaya sizeof(*shader->bind_map.surface_to_descriptor)); 2039f464c52Smaya blob_write_bytes(blob, shader->bind_map.sampler_to_descriptor, 2049f464c52Smaya shader->bind_map.sampler_count * 2059f464c52Smaya sizeof(*shader->bind_map.sampler_to_descriptor)); 2067ec681f3Smrg blob_write_bytes(blob, shader->bind_map.push_ranges, 2077ec681f3Smrg sizeof(shader->bind_map.push_ranges)); 2089f464c52Smaya 2099f464c52Smaya return !blob->out_of_memory; 21001e04c3fSmrg} 21101e04c3fSmrg 21201e04c3fSmrgstatic struct anv_shader_bin * 21301e04c3fSmrganv_shader_bin_create_from_blob(struct anv_device *device, 21401e04c3fSmrg struct blob_reader *blob) 21501e04c3fSmrg{ 2167ec681f3Smrg gl_shader_stage stage = blob_read_uint32(blob); 2177ec681f3Smrg 21801e04c3fSmrg uint32_t key_size = blob_read_uint32(blob); 21901e04c3fSmrg const void *key_data = blob_read_bytes(blob, key_size); 22001e04c3fSmrg 22101e04c3fSmrg uint32_t kernel_size = blob_read_uint32(blob); 22201e04c3fSmrg const void *kernel_data = blob_read_bytes(blob, kernel_size); 22301e04c3fSmrg 22401e04c3fSmrg uint32_t prog_data_size = blob_read_uint32(blob); 2257ec681f3Smrg const void *prog_data_bytes = blob_read_bytes(blob, prog_data_size); 22601e04c3fSmrg if (blob->overrun) 22701e04c3fSmrg return NULL; 2287ec681f3Smrg 2297ec681f3Smrg union brw_any_prog_data prog_data; 2307ec681f3Smrg memcpy(&prog_data, prog_data_bytes, 2317ec681f3Smrg MIN2(sizeof(prog_data), prog_data_size)); 2327ec681f3Smrg prog_data.base.relocs = 2337ec681f3Smrg blob_read_bytes(blob, prog_data.base.num_relocs * 2347ec681f3Smrg sizeof(prog_data.base.relocs[0])); 2357ec681f3Smrg 2367ec681f3Smrg uint32_t num_stats = blob_read_uint32(blob); 2377ec681f3Smrg const struct brw_compile_stats *stats = 2387ec681f3Smrg blob_read_bytes(blob, num_stats * sizeof(stats[0])); 23901e04c3fSmrg 2409f464c52Smaya const nir_xfb_info *xfb_info = NULL; 2419f464c52Smaya uint32_t xfb_size = blob_read_uint32(blob); 2429f464c52Smaya if (xfb_size) 2439f464c52Smaya xfb_info = blob_read_bytes(blob, xfb_size); 2449f464c52Smaya 24501e04c3fSmrg struct anv_pipeline_bind_map bind_map; 2467ec681f3Smrg blob_copy_bytes(blob, bind_map.surface_sha1, sizeof(bind_map.surface_sha1)); 2477ec681f3Smrg blob_copy_bytes(blob, bind_map.sampler_sha1, sizeof(bind_map.sampler_sha1)); 2487ec681f3Smrg blob_copy_bytes(blob, bind_map.push_sha1, sizeof(bind_map.push_sha1)); 24901e04c3fSmrg bind_map.surface_count = blob_read_uint32(blob); 25001e04c3fSmrg bind_map.sampler_count = blob_read_uint32(blob); 25101e04c3fSmrg bind_map.surface_to_descriptor = (void *) 25201e04c3fSmrg blob_read_bytes(blob, bind_map.surface_count * 25301e04c3fSmrg sizeof(*bind_map.surface_to_descriptor)); 25401e04c3fSmrg bind_map.sampler_to_descriptor = (void *) 25501e04c3fSmrg blob_read_bytes(blob, bind_map.sampler_count * 25601e04c3fSmrg sizeof(*bind_map.sampler_to_descriptor)); 2577ec681f3Smrg blob_copy_bytes(blob, bind_map.push_ranges, sizeof(bind_map.push_ranges)); 25801e04c3fSmrg 25901e04c3fSmrg if (blob->overrun) 26001e04c3fSmrg return NULL; 26101e04c3fSmrg 2627ec681f3Smrg return anv_shader_bin_create(device, stage, 26301e04c3fSmrg key_data, key_size, 26401e04c3fSmrg kernel_data, kernel_size, 2657ec681f3Smrg &prog_data.base, prog_data_size, 2667ec681f3Smrg stats, num_stats, xfb_info, &bind_map); 26701e04c3fSmrg} 26801e04c3fSmrg 26901e04c3fSmrg/* Remaining work: 27001e04c3fSmrg * 27101e04c3fSmrg * - Compact binding table layout so it's tight and not dependent on 27201e04c3fSmrg * descriptor set layout. 27301e04c3fSmrg * 27401e04c3fSmrg * - Review prog_data struct for size and cacheability: struct 27501e04c3fSmrg * brw_stage_prog_data has binding_table which uses a lot of uint32_t for 8 27601e04c3fSmrg * bit quantities etc; use bit fields for all bools, eg dual_src_blend. 27701e04c3fSmrg */ 27801e04c3fSmrg 27901e04c3fSmrgstatic uint32_t 28001e04c3fSmrgshader_bin_key_hash_func(const void *void_key) 28101e04c3fSmrg{ 28201e04c3fSmrg const struct anv_shader_bin_key *key = void_key; 28301e04c3fSmrg return _mesa_hash_data(key->data, key->size); 28401e04c3fSmrg} 28501e04c3fSmrg 28601e04c3fSmrgstatic bool 28701e04c3fSmrgshader_bin_key_compare_func(const void *void_a, const void *void_b) 28801e04c3fSmrg{ 28901e04c3fSmrg const struct anv_shader_bin_key *a = void_a, *b = void_b; 29001e04c3fSmrg if (a->size != b->size) 29101e04c3fSmrg return false; 29201e04c3fSmrg 29301e04c3fSmrg return memcmp(a->data, b->data, a->size) == 0; 29401e04c3fSmrg} 29501e04c3fSmrg 2969f464c52Smayastatic uint32_t 2979f464c52Smayasha1_hash_func(const void *sha1) 2989f464c52Smaya{ 2999f464c52Smaya return _mesa_hash_data(sha1, 20); 3009f464c52Smaya} 3019f464c52Smaya 3029f464c52Smayastatic bool 3039f464c52Smayasha1_compare_func(const void *sha1_a, const void *sha1_b) 3049f464c52Smaya{ 3059f464c52Smaya return memcmp(sha1_a, sha1_b, 20) == 0; 3069f464c52Smaya} 3079f464c52Smaya 30801e04c3fSmrgvoid 30901e04c3fSmrganv_pipeline_cache_init(struct anv_pipeline_cache *cache, 31001e04c3fSmrg struct anv_device *device, 3117ec681f3Smrg bool cache_enabled, 3127ec681f3Smrg bool external_sync) 31301e04c3fSmrg{ 3147ec681f3Smrg vk_object_base_init(&device->vk, &cache->base, 3157ec681f3Smrg VK_OBJECT_TYPE_PIPELINE_CACHE); 31601e04c3fSmrg cache->device = device; 3177ec681f3Smrg cache->external_sync = external_sync; 31801e04c3fSmrg pthread_mutex_init(&cache->mutex, NULL); 31901e04c3fSmrg 32001e04c3fSmrg if (cache_enabled) { 32101e04c3fSmrg cache->cache = _mesa_hash_table_create(NULL, shader_bin_key_hash_func, 32201e04c3fSmrg shader_bin_key_compare_func); 3239f464c52Smaya cache->nir_cache = _mesa_hash_table_create(NULL, sha1_hash_func, 3249f464c52Smaya sha1_compare_func); 32501e04c3fSmrg } else { 32601e04c3fSmrg cache->cache = NULL; 3279f464c52Smaya cache->nir_cache = NULL; 32801e04c3fSmrg } 32901e04c3fSmrg} 33001e04c3fSmrg 33101e04c3fSmrgvoid 33201e04c3fSmrganv_pipeline_cache_finish(struct anv_pipeline_cache *cache) 33301e04c3fSmrg{ 33401e04c3fSmrg pthread_mutex_destroy(&cache->mutex); 33501e04c3fSmrg 33601e04c3fSmrg if (cache->cache) { 33701e04c3fSmrg /* This is a bit unfortunate. In order to keep things from randomly 33801e04c3fSmrg * going away, the shader cache has to hold a reference to all shader 33901e04c3fSmrg * binaries it contains. We unref them when we destroy the cache. 34001e04c3fSmrg */ 34101e04c3fSmrg hash_table_foreach(cache->cache, entry) 34201e04c3fSmrg anv_shader_bin_unref(cache->device, entry->data); 34301e04c3fSmrg 34401e04c3fSmrg _mesa_hash_table_destroy(cache->cache, NULL); 34501e04c3fSmrg } 3469f464c52Smaya 3479f464c52Smaya if (cache->nir_cache) { 3489f464c52Smaya hash_table_foreach(cache->nir_cache, entry) 3499f464c52Smaya ralloc_free(entry->data); 3509f464c52Smaya 3519f464c52Smaya _mesa_hash_table_destroy(cache->nir_cache, NULL); 3529f464c52Smaya } 3537ec681f3Smrg 3547ec681f3Smrg vk_object_base_finish(&cache->base); 35501e04c3fSmrg} 35601e04c3fSmrg 35701e04c3fSmrgstatic struct anv_shader_bin * 35801e04c3fSmrganv_pipeline_cache_search_locked(struct anv_pipeline_cache *cache, 35901e04c3fSmrg const void *key_data, uint32_t key_size) 36001e04c3fSmrg{ 36101e04c3fSmrg uint32_t vla[1 + DIV_ROUND_UP(key_size, sizeof(uint32_t))]; 36201e04c3fSmrg struct anv_shader_bin_key *key = (void *)vla; 36301e04c3fSmrg key->size = key_size; 36401e04c3fSmrg memcpy(key->data, key_data, key_size); 36501e04c3fSmrg 36601e04c3fSmrg struct hash_entry *entry = _mesa_hash_table_search(cache->cache, key); 36701e04c3fSmrg if (entry) 36801e04c3fSmrg return entry->data; 36901e04c3fSmrg else 37001e04c3fSmrg return NULL; 37101e04c3fSmrg} 37201e04c3fSmrg 3737ec681f3Smrgstatic inline void 3747ec681f3Smrganv_cache_lock(struct anv_pipeline_cache *cache) 3757ec681f3Smrg{ 3767ec681f3Smrg if (!cache->external_sync) 3777ec681f3Smrg pthread_mutex_lock(&cache->mutex); 3787ec681f3Smrg} 3797ec681f3Smrg 3807ec681f3Smrgstatic inline void 3817ec681f3Smrganv_cache_unlock(struct anv_pipeline_cache *cache) 3827ec681f3Smrg{ 3837ec681f3Smrg if (!cache->external_sync) 3847ec681f3Smrg pthread_mutex_unlock(&cache->mutex); 3857ec681f3Smrg} 3867ec681f3Smrg 38701e04c3fSmrgstruct anv_shader_bin * 38801e04c3fSmrganv_pipeline_cache_search(struct anv_pipeline_cache *cache, 38901e04c3fSmrg const void *key_data, uint32_t key_size) 39001e04c3fSmrg{ 39101e04c3fSmrg if (!cache->cache) 39201e04c3fSmrg return NULL; 39301e04c3fSmrg 3947ec681f3Smrg anv_cache_lock(cache); 39501e04c3fSmrg 39601e04c3fSmrg struct anv_shader_bin *shader = 39701e04c3fSmrg anv_pipeline_cache_search_locked(cache, key_data, key_size); 39801e04c3fSmrg 3997ec681f3Smrg anv_cache_unlock(cache); 40001e04c3fSmrg 40101e04c3fSmrg /* We increment refcount before handing it to the caller */ 40201e04c3fSmrg if (shader) 40301e04c3fSmrg anv_shader_bin_ref(shader); 40401e04c3fSmrg 40501e04c3fSmrg return shader; 40601e04c3fSmrg} 40701e04c3fSmrg 40801e04c3fSmrgstatic void 40901e04c3fSmrganv_pipeline_cache_add_shader_bin(struct anv_pipeline_cache *cache, 41001e04c3fSmrg struct anv_shader_bin *bin) 41101e04c3fSmrg{ 41201e04c3fSmrg if (!cache->cache) 41301e04c3fSmrg return; 41401e04c3fSmrg 4157ec681f3Smrg anv_cache_lock(cache); 41601e04c3fSmrg 41701e04c3fSmrg struct hash_entry *entry = _mesa_hash_table_search(cache->cache, bin->key); 41801e04c3fSmrg if (entry == NULL) { 41901e04c3fSmrg /* Take a reference for the cache */ 42001e04c3fSmrg anv_shader_bin_ref(bin); 42101e04c3fSmrg _mesa_hash_table_insert(cache->cache, bin->key, bin); 42201e04c3fSmrg } 42301e04c3fSmrg 4247ec681f3Smrg anv_cache_unlock(cache); 42501e04c3fSmrg} 42601e04c3fSmrg 42701e04c3fSmrgstatic struct anv_shader_bin * 42801e04c3fSmrganv_pipeline_cache_add_shader_locked(struct anv_pipeline_cache *cache, 4297ec681f3Smrg gl_shader_stage stage, 43001e04c3fSmrg const void *key_data, uint32_t key_size, 43101e04c3fSmrg const void *kernel_data, 43201e04c3fSmrg uint32_t kernel_size, 43301e04c3fSmrg const struct brw_stage_prog_data *prog_data, 43401e04c3fSmrg uint32_t prog_data_size, 4357ec681f3Smrg const struct brw_compile_stats *stats, 4367ec681f3Smrg uint32_t num_stats, 4379f464c52Smaya const nir_xfb_info *xfb_info, 43801e04c3fSmrg const struct anv_pipeline_bind_map *bind_map) 43901e04c3fSmrg{ 44001e04c3fSmrg struct anv_shader_bin *shader = 44101e04c3fSmrg anv_pipeline_cache_search_locked(cache, key_data, key_size); 44201e04c3fSmrg if (shader) 44301e04c3fSmrg return shader; 44401e04c3fSmrg 44501e04c3fSmrg struct anv_shader_bin *bin = 4467ec681f3Smrg anv_shader_bin_create(cache->device, stage, 4477ec681f3Smrg key_data, key_size, 44801e04c3fSmrg kernel_data, kernel_size, 4497ec681f3Smrg prog_data, prog_data_size, 4507ec681f3Smrg stats, num_stats, xfb_info, bind_map); 45101e04c3fSmrg if (!bin) 45201e04c3fSmrg return NULL; 45301e04c3fSmrg 45401e04c3fSmrg _mesa_hash_table_insert(cache->cache, bin->key, bin); 45501e04c3fSmrg 45601e04c3fSmrg return bin; 45701e04c3fSmrg} 45801e04c3fSmrg 45901e04c3fSmrgstruct anv_shader_bin * 46001e04c3fSmrganv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache, 4617ec681f3Smrg gl_shader_stage stage, 46201e04c3fSmrg const void *key_data, uint32_t key_size, 46301e04c3fSmrg const void *kernel_data, uint32_t kernel_size, 46401e04c3fSmrg const struct brw_stage_prog_data *prog_data, 46501e04c3fSmrg uint32_t prog_data_size, 4667ec681f3Smrg const struct brw_compile_stats *stats, 4677ec681f3Smrg uint32_t num_stats, 4689f464c52Smaya const nir_xfb_info *xfb_info, 46901e04c3fSmrg const struct anv_pipeline_bind_map *bind_map) 47001e04c3fSmrg{ 47101e04c3fSmrg if (cache->cache) { 4727ec681f3Smrg anv_cache_lock(cache); 47301e04c3fSmrg 47401e04c3fSmrg struct anv_shader_bin *bin = 4757ec681f3Smrg anv_pipeline_cache_add_shader_locked(cache, stage, key_data, key_size, 47601e04c3fSmrg kernel_data, kernel_size, 47701e04c3fSmrg prog_data, prog_data_size, 4787ec681f3Smrg stats, num_stats, 4799f464c52Smaya xfb_info, bind_map); 48001e04c3fSmrg 4817ec681f3Smrg anv_cache_unlock(cache); 48201e04c3fSmrg 48301e04c3fSmrg /* We increment refcount before handing it to the caller */ 48401e04c3fSmrg if (bin) 48501e04c3fSmrg anv_shader_bin_ref(bin); 48601e04c3fSmrg 48701e04c3fSmrg return bin; 48801e04c3fSmrg } else { 48901e04c3fSmrg /* In this case, we're not caching it so the caller owns it entirely */ 4907ec681f3Smrg return anv_shader_bin_create(cache->device, stage, 4917ec681f3Smrg key_data, key_size, 49201e04c3fSmrg kernel_data, kernel_size, 49301e04c3fSmrg prog_data, prog_data_size, 4947ec681f3Smrg stats, num_stats, 4959f464c52Smaya xfb_info, bind_map); 49601e04c3fSmrg } 49701e04c3fSmrg} 49801e04c3fSmrg 49901e04c3fSmrgstatic void 50001e04c3fSmrganv_pipeline_cache_load(struct anv_pipeline_cache *cache, 50101e04c3fSmrg const void *data, size_t size) 50201e04c3fSmrg{ 50301e04c3fSmrg struct anv_device *device = cache->device; 5047ec681f3Smrg struct anv_physical_device *pdevice = device->physical; 50501e04c3fSmrg 50601e04c3fSmrg if (cache->cache == NULL) 50701e04c3fSmrg return; 50801e04c3fSmrg 50901e04c3fSmrg struct blob_reader blob; 51001e04c3fSmrg blob_reader_init(&blob, data, size); 51101e04c3fSmrg 5127ec681f3Smrg struct vk_pipeline_cache_header header; 51301e04c3fSmrg blob_copy_bytes(&blob, &header, sizeof(header)); 51401e04c3fSmrg uint32_t count = blob_read_uint32(&blob); 51501e04c3fSmrg if (blob.overrun) 51601e04c3fSmrg return; 51701e04c3fSmrg 51801e04c3fSmrg if (header.header_size < sizeof(header)) 51901e04c3fSmrg return; 52001e04c3fSmrg if (header.header_version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) 52101e04c3fSmrg return; 52201e04c3fSmrg if (header.vendor_id != 0x8086) 52301e04c3fSmrg return; 5247ec681f3Smrg if (header.device_id != device->info.chipset_id) 52501e04c3fSmrg return; 52601e04c3fSmrg if (memcmp(header.uuid, pdevice->pipeline_cache_uuid, VK_UUID_SIZE) != 0) 52701e04c3fSmrg return; 52801e04c3fSmrg 52901e04c3fSmrg for (uint32_t i = 0; i < count; i++) { 53001e04c3fSmrg struct anv_shader_bin *bin = 53101e04c3fSmrg anv_shader_bin_create_from_blob(device, &blob); 53201e04c3fSmrg if (!bin) 53301e04c3fSmrg break; 53401e04c3fSmrg _mesa_hash_table_insert(cache->cache, bin->key, bin); 53501e04c3fSmrg } 53601e04c3fSmrg} 53701e04c3fSmrg 53801e04c3fSmrgVkResult anv_CreatePipelineCache( 53901e04c3fSmrg VkDevice _device, 54001e04c3fSmrg const VkPipelineCacheCreateInfo* pCreateInfo, 54101e04c3fSmrg const VkAllocationCallbacks* pAllocator, 54201e04c3fSmrg VkPipelineCache* pPipelineCache) 54301e04c3fSmrg{ 54401e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 54501e04c3fSmrg struct anv_pipeline_cache *cache; 54601e04c3fSmrg 54701e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); 54801e04c3fSmrg 5497ec681f3Smrg cache = vk_alloc2(&device->vk.alloc, pAllocator, 55001e04c3fSmrg sizeof(*cache), 8, 55101e04c3fSmrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 55201e04c3fSmrg if (cache == NULL) 5537ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 55401e04c3fSmrg 55501e04c3fSmrg anv_pipeline_cache_init(cache, device, 5567ec681f3Smrg device->physical->instance->pipeline_cache_enabled, 5577ec681f3Smrg pCreateInfo->flags & VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT); 55801e04c3fSmrg 55901e04c3fSmrg if (pCreateInfo->initialDataSize > 0) 56001e04c3fSmrg anv_pipeline_cache_load(cache, 56101e04c3fSmrg pCreateInfo->pInitialData, 56201e04c3fSmrg pCreateInfo->initialDataSize); 56301e04c3fSmrg 56401e04c3fSmrg *pPipelineCache = anv_pipeline_cache_to_handle(cache); 56501e04c3fSmrg 56601e04c3fSmrg return VK_SUCCESS; 56701e04c3fSmrg} 56801e04c3fSmrg 56901e04c3fSmrgvoid anv_DestroyPipelineCache( 57001e04c3fSmrg VkDevice _device, 57101e04c3fSmrg VkPipelineCache _cache, 57201e04c3fSmrg const VkAllocationCallbacks* pAllocator) 57301e04c3fSmrg{ 57401e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 57501e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_cache, cache, _cache); 57601e04c3fSmrg 57701e04c3fSmrg if (!cache) 57801e04c3fSmrg return; 57901e04c3fSmrg 58001e04c3fSmrg anv_pipeline_cache_finish(cache); 58101e04c3fSmrg 5827ec681f3Smrg vk_free2(&device->vk.alloc, pAllocator, cache); 58301e04c3fSmrg} 58401e04c3fSmrg 58501e04c3fSmrgVkResult anv_GetPipelineCacheData( 58601e04c3fSmrg VkDevice _device, 58701e04c3fSmrg VkPipelineCache _cache, 58801e04c3fSmrg size_t* pDataSize, 58901e04c3fSmrg void* pData) 59001e04c3fSmrg{ 59101e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 59201e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_cache, cache, _cache); 59301e04c3fSmrg 59401e04c3fSmrg struct blob blob; 59501e04c3fSmrg if (pData) { 59601e04c3fSmrg blob_init_fixed(&blob, pData, *pDataSize); 59701e04c3fSmrg } else { 59801e04c3fSmrg blob_init_fixed(&blob, NULL, SIZE_MAX); 59901e04c3fSmrg } 60001e04c3fSmrg 6017ec681f3Smrg struct vk_pipeline_cache_header header = { 6027ec681f3Smrg .header_size = sizeof(struct vk_pipeline_cache_header), 60301e04c3fSmrg .header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, 60401e04c3fSmrg .vendor_id = 0x8086, 6057ec681f3Smrg .device_id = device->info.chipset_id, 60601e04c3fSmrg }; 6077ec681f3Smrg memcpy(header.uuid, device->physical->pipeline_cache_uuid, VK_UUID_SIZE); 60801e04c3fSmrg blob_write_bytes(&blob, &header, sizeof(header)); 60901e04c3fSmrg 61001e04c3fSmrg uint32_t count = 0; 61101e04c3fSmrg intptr_t count_offset = blob_reserve_uint32(&blob); 61201e04c3fSmrg if (count_offset < 0) { 61301e04c3fSmrg *pDataSize = 0; 61401e04c3fSmrg blob_finish(&blob); 61501e04c3fSmrg return VK_INCOMPLETE; 61601e04c3fSmrg } 61701e04c3fSmrg 61801e04c3fSmrg VkResult result = VK_SUCCESS; 61901e04c3fSmrg if (cache->cache) { 62001e04c3fSmrg hash_table_foreach(cache->cache, entry) { 62101e04c3fSmrg struct anv_shader_bin *shader = entry->data; 62201e04c3fSmrg 62301e04c3fSmrg size_t save_size = blob.size; 62401e04c3fSmrg if (!anv_shader_bin_write_to_blob(shader, &blob)) { 62501e04c3fSmrg /* If it fails reset to the previous size and bail */ 62601e04c3fSmrg blob.size = save_size; 62701e04c3fSmrg result = VK_INCOMPLETE; 62801e04c3fSmrg break; 62901e04c3fSmrg } 63001e04c3fSmrg 63101e04c3fSmrg count++; 63201e04c3fSmrg } 63301e04c3fSmrg } 63401e04c3fSmrg 63501e04c3fSmrg blob_overwrite_uint32(&blob, count_offset, count); 63601e04c3fSmrg 63701e04c3fSmrg *pDataSize = blob.size; 63801e04c3fSmrg 63901e04c3fSmrg blob_finish(&blob); 64001e04c3fSmrg 64101e04c3fSmrg return result; 64201e04c3fSmrg} 64301e04c3fSmrg 64401e04c3fSmrgVkResult anv_MergePipelineCaches( 64501e04c3fSmrg VkDevice _device, 64601e04c3fSmrg VkPipelineCache destCache, 64701e04c3fSmrg uint32_t srcCacheCount, 64801e04c3fSmrg const VkPipelineCache* pSrcCaches) 64901e04c3fSmrg{ 65001e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_cache, dst, destCache); 65101e04c3fSmrg 65201e04c3fSmrg if (!dst->cache) 65301e04c3fSmrg return VK_SUCCESS; 65401e04c3fSmrg 65501e04c3fSmrg for (uint32_t i = 0; i < srcCacheCount; i++) { 65601e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_cache, src, pSrcCaches[i]); 65701e04c3fSmrg if (!src->cache) 65801e04c3fSmrg continue; 65901e04c3fSmrg 66001e04c3fSmrg hash_table_foreach(src->cache, entry) { 66101e04c3fSmrg struct anv_shader_bin *bin = entry->data; 66201e04c3fSmrg assert(bin); 66301e04c3fSmrg 66401e04c3fSmrg if (_mesa_hash_table_search(dst->cache, bin->key)) 66501e04c3fSmrg continue; 66601e04c3fSmrg 66701e04c3fSmrg anv_shader_bin_ref(bin); 66801e04c3fSmrg _mesa_hash_table_insert(dst->cache, bin->key, bin); 66901e04c3fSmrg } 67001e04c3fSmrg } 67101e04c3fSmrg 67201e04c3fSmrg return VK_SUCCESS; 67301e04c3fSmrg} 67401e04c3fSmrg 67501e04c3fSmrgstruct anv_shader_bin * 67601e04c3fSmrganv_device_search_for_kernel(struct anv_device *device, 67701e04c3fSmrg struct anv_pipeline_cache *cache, 6789f464c52Smaya const void *key_data, uint32_t key_size, 6799f464c52Smaya bool *user_cache_hit) 68001e04c3fSmrg{ 68101e04c3fSmrg struct anv_shader_bin *bin; 68201e04c3fSmrg 6839f464c52Smaya *user_cache_hit = false; 6849f464c52Smaya 68501e04c3fSmrg if (cache) { 68601e04c3fSmrg bin = anv_pipeline_cache_search(cache, key_data, key_size); 6879f464c52Smaya if (bin) { 6889f464c52Smaya *user_cache_hit = cache != &device->default_pipeline_cache; 68901e04c3fSmrg return bin; 6909f464c52Smaya } 69101e04c3fSmrg } 69201e04c3fSmrg 69301e04c3fSmrg#ifdef ENABLE_SHADER_CACHE 6947ec681f3Smrg struct disk_cache *disk_cache = device->physical->disk_cache; 6957ec681f3Smrg if (disk_cache && device->physical->instance->pipeline_cache_enabled) { 69601e04c3fSmrg cache_key cache_key; 69701e04c3fSmrg disk_cache_compute_key(disk_cache, key_data, key_size, cache_key); 69801e04c3fSmrg 69901e04c3fSmrg size_t buffer_size; 70001e04c3fSmrg uint8_t *buffer = disk_cache_get(disk_cache, cache_key, &buffer_size); 70101e04c3fSmrg if (buffer) { 70201e04c3fSmrg struct blob_reader blob; 70301e04c3fSmrg blob_reader_init(&blob, buffer, buffer_size); 70401e04c3fSmrg bin = anv_shader_bin_create_from_blob(device, &blob); 70501e04c3fSmrg free(buffer); 70601e04c3fSmrg 70701e04c3fSmrg if (bin) { 70801e04c3fSmrg if (cache) 70901e04c3fSmrg anv_pipeline_cache_add_shader_bin(cache, bin); 71001e04c3fSmrg return bin; 71101e04c3fSmrg } 71201e04c3fSmrg } 71301e04c3fSmrg } 71401e04c3fSmrg#endif 71501e04c3fSmrg 71601e04c3fSmrg return NULL; 71701e04c3fSmrg} 71801e04c3fSmrg 71901e04c3fSmrgstruct anv_shader_bin * 72001e04c3fSmrganv_device_upload_kernel(struct anv_device *device, 72101e04c3fSmrg struct anv_pipeline_cache *cache, 7227ec681f3Smrg gl_shader_stage stage, 72301e04c3fSmrg const void *key_data, uint32_t key_size, 72401e04c3fSmrg const void *kernel_data, uint32_t kernel_size, 72501e04c3fSmrg const struct brw_stage_prog_data *prog_data, 72601e04c3fSmrg uint32_t prog_data_size, 7277ec681f3Smrg const struct brw_compile_stats *stats, 7287ec681f3Smrg uint32_t num_stats, 7299f464c52Smaya const nir_xfb_info *xfb_info, 73001e04c3fSmrg const struct anv_pipeline_bind_map *bind_map) 73101e04c3fSmrg{ 73201e04c3fSmrg struct anv_shader_bin *bin; 73301e04c3fSmrg if (cache) { 7347ec681f3Smrg bin = anv_pipeline_cache_upload_kernel(cache, stage, key_data, key_size, 73501e04c3fSmrg kernel_data, kernel_size, 73601e04c3fSmrg prog_data, prog_data_size, 7377ec681f3Smrg stats, num_stats, 7389f464c52Smaya xfb_info, bind_map); 73901e04c3fSmrg } else { 7407ec681f3Smrg bin = anv_shader_bin_create(device, stage, key_data, key_size, 74101e04c3fSmrg kernel_data, kernel_size, 74201e04c3fSmrg prog_data, prog_data_size, 7437ec681f3Smrg stats, num_stats, 7449f464c52Smaya xfb_info, bind_map); 74501e04c3fSmrg } 74601e04c3fSmrg 74701e04c3fSmrg if (bin == NULL) 74801e04c3fSmrg return NULL; 74901e04c3fSmrg 75001e04c3fSmrg#ifdef ENABLE_SHADER_CACHE 7517ec681f3Smrg struct disk_cache *disk_cache = device->physical->disk_cache; 75201e04c3fSmrg if (disk_cache) { 75301e04c3fSmrg struct blob binary; 75401e04c3fSmrg blob_init(&binary); 7559f464c52Smaya if (anv_shader_bin_write_to_blob(bin, &binary)) { 75601e04c3fSmrg cache_key cache_key; 75701e04c3fSmrg disk_cache_compute_key(disk_cache, key_data, key_size, cache_key); 75801e04c3fSmrg 75901e04c3fSmrg disk_cache_put(disk_cache, cache_key, binary.data, binary.size, NULL); 76001e04c3fSmrg } 76101e04c3fSmrg 76201e04c3fSmrg blob_finish(&binary); 76301e04c3fSmrg } 76401e04c3fSmrg#endif 76501e04c3fSmrg 76601e04c3fSmrg return bin; 76701e04c3fSmrg} 7689f464c52Smaya 7699f464c52Smayastruct serialized_nir { 7709f464c52Smaya unsigned char sha1_key[20]; 7719f464c52Smaya size_t size; 7729f464c52Smaya char data[0]; 7739f464c52Smaya}; 7749f464c52Smaya 7759f464c52Smayastruct nir_shader * 7769f464c52Smayaanv_device_search_for_nir(struct anv_device *device, 7779f464c52Smaya struct anv_pipeline_cache *cache, 7789f464c52Smaya const nir_shader_compiler_options *nir_options, 7799f464c52Smaya unsigned char sha1_key[20], 7809f464c52Smaya void *mem_ctx) 7819f464c52Smaya{ 7829f464c52Smaya if (cache && cache->nir_cache) { 7839f464c52Smaya const struct serialized_nir *snir = NULL; 7849f464c52Smaya 7857ec681f3Smrg anv_cache_lock(cache); 7869f464c52Smaya struct hash_entry *entry = 7879f464c52Smaya _mesa_hash_table_search(cache->nir_cache, sha1_key); 7889f464c52Smaya if (entry) 7899f464c52Smaya snir = entry->data; 7907ec681f3Smrg anv_cache_unlock(cache); 7919f464c52Smaya 7929f464c52Smaya if (snir) { 7939f464c52Smaya struct blob_reader blob; 7949f464c52Smaya blob_reader_init(&blob, snir->data, snir->size); 7959f464c52Smaya 7969f464c52Smaya nir_shader *nir = nir_deserialize(mem_ctx, nir_options, &blob); 7979f464c52Smaya if (blob.overrun) { 7989f464c52Smaya ralloc_free(nir); 7999f464c52Smaya } else { 8009f464c52Smaya return nir; 8019f464c52Smaya } 8029f464c52Smaya } 8039f464c52Smaya } 8049f464c52Smaya 8059f464c52Smaya return NULL; 8069f464c52Smaya} 8079f464c52Smaya 8089f464c52Smayavoid 8099f464c52Smayaanv_device_upload_nir(struct anv_device *device, 8109f464c52Smaya struct anv_pipeline_cache *cache, 8119f464c52Smaya const struct nir_shader *nir, 8129f464c52Smaya unsigned char sha1_key[20]) 8139f464c52Smaya{ 8149f464c52Smaya if (cache && cache->nir_cache) { 8157ec681f3Smrg anv_cache_lock(cache); 8169f464c52Smaya struct hash_entry *entry = 8179f464c52Smaya _mesa_hash_table_search(cache->nir_cache, sha1_key); 8187ec681f3Smrg anv_cache_unlock(cache); 8199f464c52Smaya if (entry) 8209f464c52Smaya return; 8219f464c52Smaya 8229f464c52Smaya struct blob blob; 8239f464c52Smaya blob_init(&blob); 8249f464c52Smaya 8257ec681f3Smrg nir_serialize(&blob, nir, false); 8269f464c52Smaya if (blob.out_of_memory) { 8279f464c52Smaya blob_finish(&blob); 8289f464c52Smaya return; 8299f464c52Smaya } 8309f464c52Smaya 8317ec681f3Smrg anv_cache_lock(cache); 8329f464c52Smaya /* Because ralloc isn't thread-safe, we have to do all this inside the 8339f464c52Smaya * lock. We could unlock for the big memcpy but it's probably not worth 8349f464c52Smaya * the hassle. 8359f464c52Smaya */ 8369f464c52Smaya entry = _mesa_hash_table_search(cache->nir_cache, sha1_key); 8379f464c52Smaya if (entry) { 8389f464c52Smaya blob_finish(&blob); 8397ec681f3Smrg anv_cache_unlock(cache); 8409f464c52Smaya return; 8419f464c52Smaya } 8429f464c52Smaya 8439f464c52Smaya struct serialized_nir *snir = 8449f464c52Smaya ralloc_size(cache->nir_cache, sizeof(*snir) + blob.size); 8459f464c52Smaya memcpy(snir->sha1_key, sha1_key, 20); 8469f464c52Smaya snir->size = blob.size; 8479f464c52Smaya memcpy(snir->data, blob.data, blob.size); 8489f464c52Smaya 8499f464c52Smaya blob_finish(&blob); 8509f464c52Smaya 8519f464c52Smaya _mesa_hash_table_insert(cache->nir_cache, snir->sha1_key, snir); 8529f464c52Smaya 8537ec681f3Smrg anv_cache_unlock(cache); 8549f464c52Smaya } 8559f464c52Smaya} 856