2 * Copyright © 2015 Intel Corporation
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 DEALINGS
24 #include "util/mesa-sha1.h"
25 #include "util/hash_table.h"
26 #include "util/debug.h"
27 #include "anv_private.h"
30 anv_shader_bin_size(uint32_t prog_data_size
, uint32_t key_size
,
31 uint32_t surface_count
, uint32_t sampler_count
)
33 const uint32_t binding_data_size
=
34 (surface_count
+ sampler_count
) * sizeof(struct anv_pipeline_binding
);
36 return align_u32(sizeof(struct anv_shader_bin
), 8) +
37 align_u32(prog_data_size
, 8) +
38 align_u32(sizeof(uint32_t) + key_size
, 8) +
39 align_u32(binding_data_size
, 8);
42 struct anv_shader_bin
*
43 anv_shader_bin_create(struct anv_device
*device
,
44 const void *key_data
, uint32_t key_size
,
45 const void *kernel_data
, uint32_t kernel_size
,
46 const struct brw_stage_prog_data
*prog_data
,
47 uint32_t prog_data_size
,
48 const struct anv_pipeline_bind_map
*bind_map
)
51 anv_shader_bin_size(prog_data_size
, key_size
,
52 bind_map
->surface_count
, bind_map
->sampler_count
);
54 struct anv_shader_bin
*shader
=
55 vk_alloc(&device
->alloc
, size
, 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
);
62 anv_state_pool_alloc(&device
->instruction_state_pool
, kernel_size
, 64);
63 memcpy(shader
->kernel
.map
, kernel_data
, kernel_size
);
64 shader
->kernel_size
= kernel_size
;
65 shader
->bind_map
= *bind_map
;
66 shader
->prog_data_size
= prog_data_size
;
68 /* Now we fill out the floating data at the end */
70 data
+= align_u32(sizeof(struct anv_shader_bin
), 8);
72 shader
->prog_data
= data
;
73 memcpy(data
, prog_data
, prog_data_size
);
74 data
+= align_u32(prog_data_size
, 8);
77 struct anv_shader_bin_key
*key
= data
;
79 memcpy(key
->data
, key_data
, key_size
);
80 data
+= align_u32(sizeof(*key
) + key_size
, 8);
82 shader
->bind_map
.surface_to_descriptor
= data
;
83 memcpy(data
, bind_map
->surface_to_descriptor
,
84 bind_map
->surface_count
* sizeof(struct anv_pipeline_binding
));
85 data
+= bind_map
->surface_count
* sizeof(struct anv_pipeline_binding
);
87 shader
->bind_map
.sampler_to_descriptor
= data
;
88 memcpy(data
, bind_map
->sampler_to_descriptor
,
89 bind_map
->sampler_count
* sizeof(struct anv_pipeline_binding
));
95 anv_shader_bin_destroy(struct anv_device
*device
,
96 struct anv_shader_bin
*shader
)
98 assert(shader
->ref_cnt
== 0);
99 anv_state_pool_free(&device
->instruction_state_pool
, shader
->kernel
);
100 vk_free(&device
->alloc
, shader
);
104 anv_shader_bin_data_size(const struct anv_shader_bin
*shader
)
106 return anv_shader_bin_size(shader
->prog_data_size
,
108 shader
->bind_map
.surface_count
,
109 shader
->bind_map
.sampler_count
) +
110 align_u32(shader
->kernel_size
, 8);
114 anv_shader_bin_write_data(const struct anv_shader_bin
*shader
, void *data
)
117 anv_shader_bin_size(shader
->prog_data_size
,
119 shader
->bind_map
.surface_count
,
120 shader
->bind_map
.sampler_count
);
122 memcpy(data
, shader
, struct_size
);
125 memcpy(data
, shader
->kernel
.map
, shader
->kernel_size
);
130 * - Compact binding table layout so it's tight and not dependent on
131 * descriptor set layout.
133 * - Review prog_data struct for size and cacheability: struct
134 * brw_stage_prog_data has binding_table which uses a lot of uint32_t for 8
135 * bit quantities etc; param, pull_param, and image_params are pointers, we
136 * just need the compation map. use bit fields for all bools, eg
141 shader_bin_key_hash_func(const void *void_key
)
143 const struct anv_shader_bin_key
*key
= void_key
;
144 return _mesa_hash_data(key
->data
, key
->size
);
148 shader_bin_key_compare_func(const void *void_a
, const void *void_b
)
150 const struct anv_shader_bin_key
*a
= void_a
, *b
= void_b
;
151 if (a
->size
!= b
->size
)
154 return memcmp(a
->data
, b
->data
, a
->size
) == 0;
158 anv_pipeline_cache_init(struct anv_pipeline_cache
*cache
,
159 struct anv_device
*device
,
162 cache
->device
= device
;
163 pthread_mutex_init(&cache
->mutex
, NULL
);
166 cache
->cache
= _mesa_hash_table_create(NULL
, shader_bin_key_hash_func
,
167 shader_bin_key_compare_func
);
174 anv_pipeline_cache_finish(struct anv_pipeline_cache
*cache
)
176 pthread_mutex_destroy(&cache
->mutex
);
179 /* This is a bit unfortunate. In order to keep things from randomly
180 * going away, the shader cache has to hold a reference to all shader
181 * binaries it contains. We unref them when we destroy the cache.
183 struct hash_entry
*entry
;
184 hash_table_foreach(cache
->cache
, entry
)
185 anv_shader_bin_unref(cache
->device
, entry
->data
);
187 _mesa_hash_table_destroy(cache
->cache
, NULL
);
192 anv_hash_shader(unsigned char *hash
, const void *key
, size_t key_size
,
193 struct anv_shader_module
*module
,
194 const char *entrypoint
,
195 const struct anv_pipeline_layout
*pipeline_layout
,
196 const VkSpecializationInfo
*spec_info
)
198 struct mesa_sha1
*ctx
;
200 ctx
= _mesa_sha1_init();
201 _mesa_sha1_update(ctx
, key
, key_size
);
202 _mesa_sha1_update(ctx
, module
->sha1
, sizeof(module
->sha1
));
203 _mesa_sha1_update(ctx
, entrypoint
, strlen(entrypoint
));
204 if (pipeline_layout
) {
205 _mesa_sha1_update(ctx
, pipeline_layout
->sha1
,
206 sizeof(pipeline_layout
->sha1
));
208 /* hash in shader stage, pipeline layout? */
210 _mesa_sha1_update(ctx
, spec_info
->pMapEntries
,
211 spec_info
->mapEntryCount
* sizeof spec_info
->pMapEntries
[0]);
212 _mesa_sha1_update(ctx
, spec_info
->pData
, spec_info
->dataSize
);
214 _mesa_sha1_final(ctx
, hash
);
217 static struct anv_shader_bin
*
218 anv_pipeline_cache_search_locked(struct anv_pipeline_cache
*cache
,
219 const void *key_data
, uint32_t key_size
)
221 uint32_t vla
[1 + DIV_ROUND_UP(key_size
, sizeof(uint32_t))];
222 struct anv_shader_bin_key
*key
= (void *)vla
;
223 key
->size
= key_size
;
224 memcpy(key
->data
, key_data
, key_size
);
226 struct hash_entry
*entry
= _mesa_hash_table_search(cache
->cache
, key
);
233 struct anv_shader_bin
*
234 anv_pipeline_cache_search(struct anv_pipeline_cache
*cache
,
235 const void *key_data
, uint32_t key_size
)
240 pthread_mutex_lock(&cache
->mutex
);
242 struct anv_shader_bin
*shader
=
243 anv_pipeline_cache_search_locked(cache
, key_data
, key_size
);
245 pthread_mutex_unlock(&cache
->mutex
);
247 /* We increment refcount before handing it to the caller */
249 anv_shader_bin_ref(shader
);
254 static struct anv_shader_bin
*
255 anv_pipeline_cache_add_shader(struct anv_pipeline_cache
*cache
,
256 const void *key_data
, uint32_t key_size
,
257 const void *kernel_data
, uint32_t kernel_size
,
258 const void *prog_data
, uint32_t prog_data_size
,
259 const struct anv_pipeline_bind_map
*bind_map
)
261 struct anv_shader_bin
*shader
=
262 anv_pipeline_cache_search_locked(cache
, key_data
, key_size
);
266 struct anv_shader_bin
*bin
=
267 anv_shader_bin_create(cache
->device
, key_data
, key_size
,
268 kernel_data
, kernel_size
,
269 prog_data
, prog_data_size
, bind_map
);
273 _mesa_hash_table_insert(cache
->cache
, bin
->key
, bin
);
278 struct anv_shader_bin
*
279 anv_pipeline_cache_upload_kernel(struct anv_pipeline_cache
*cache
,
280 const void *key_data
, uint32_t key_size
,
281 const void *kernel_data
, uint32_t kernel_size
,
282 const struct brw_stage_prog_data
*prog_data
,
283 uint32_t prog_data_size
,
284 const struct anv_pipeline_bind_map
*bind_map
)
287 pthread_mutex_lock(&cache
->mutex
);
289 struct anv_shader_bin
*bin
=
290 anv_pipeline_cache_add_shader(cache
, key_data
, key_size
,
291 kernel_data
, kernel_size
,
292 prog_data
, prog_data_size
, bind_map
);
294 pthread_mutex_unlock(&cache
->mutex
);
296 /* We increment refcount before handing it to the caller */
297 anv_shader_bin_ref(bin
);
301 /* In this case, we're not caching it so the caller owns it entirely */
302 return anv_shader_bin_create(cache
->device
, key_data
, key_size
,
303 kernel_data
, kernel_size
,
304 prog_data
, prog_data_size
, bind_map
);
308 struct cache_header
{
309 uint32_t header_size
;
310 uint32_t header_version
;
313 uint8_t uuid
[VK_UUID_SIZE
];
317 anv_pipeline_cache_load(struct anv_pipeline_cache
*cache
,
318 const void *data
, size_t size
)
320 struct anv_device
*device
= cache
->device
;
321 struct cache_header header
;
322 uint8_t uuid
[VK_UUID_SIZE
];
324 if (cache
->cache
== NULL
)
327 if (size
< sizeof(header
))
329 memcpy(&header
, data
, sizeof(header
));
330 if (header
.header_size
< sizeof(header
))
332 if (header
.header_version
!= VK_PIPELINE_CACHE_HEADER_VERSION_ONE
)
334 if (header
.vendor_id
!= 0x8086)
336 if (header
.device_id
!= device
->chipset_id
)
338 anv_device_get_cache_uuid(uuid
);
339 if (memcmp(header
.uuid
, uuid
, VK_UUID_SIZE
) != 0)
342 const void *end
= data
+ size
;
343 const void *p
= data
+ header
.header_size
;
345 /* Count is the total number of valid entries */
347 if (p
+ sizeof(count
) >= end
)
349 memcpy(&count
, p
, sizeof(count
));
350 p
+= align_u32(sizeof(count
), 8);
352 for (uint32_t i
= 0; i
< count
; i
++) {
353 struct anv_shader_bin bin
;
354 if (p
+ sizeof(bin
) > end
)
356 memcpy(&bin
, p
, sizeof(bin
));
357 p
+= align_u32(sizeof(struct anv_shader_bin
), 8);
359 const void *prog_data
= p
;
360 p
+= align_u32(bin
.prog_data_size
, 8);
362 struct anv_shader_bin_key key
;
363 if (p
+ sizeof(key
) > end
)
365 memcpy(&key
, p
, sizeof(key
));
366 const void *key_data
= p
+ sizeof(key
);
367 p
+= align_u32(sizeof(key
) + key
.size
, 8);
369 /* We're going to memcpy this so getting rid of const is fine */
370 struct anv_pipeline_binding
*bindings
= (void *)p
;
371 p
+= align_u32((bin
.bind_map
.surface_count
+ bin
.bind_map
.sampler_count
) *
372 sizeof(struct anv_pipeline_binding
), 8);
373 bin
.bind_map
.surface_to_descriptor
= bindings
;
374 bin
.bind_map
.sampler_to_descriptor
= bindings
+ bin
.bind_map
.surface_count
;
376 const void *kernel_data
= p
;
377 p
+= align_u32(bin
.kernel_size
, 8);
382 anv_pipeline_cache_add_shader(cache
, key_data
, key
.size
,
383 kernel_data
, bin
.kernel_size
,
384 prog_data
, bin
.prog_data_size
,
390 pipeline_cache_enabled()
392 static int enabled
= -1;
394 enabled
= env_var_as_boolean("ANV_ENABLE_PIPELINE_CACHE", true);
398 VkResult
anv_CreatePipelineCache(
400 const VkPipelineCacheCreateInfo
* pCreateInfo
,
401 const VkAllocationCallbacks
* pAllocator
,
402 VkPipelineCache
* pPipelineCache
)
404 ANV_FROM_HANDLE(anv_device
, device
, _device
);
405 struct anv_pipeline_cache
*cache
;
407 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO
);
408 assert(pCreateInfo
->flags
== 0);
410 cache
= vk_alloc2(&device
->alloc
, pAllocator
,
412 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
414 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
416 anv_pipeline_cache_init(cache
, device
, pipeline_cache_enabled());
418 if (pCreateInfo
->initialDataSize
> 0)
419 anv_pipeline_cache_load(cache
,
420 pCreateInfo
->pInitialData
,
421 pCreateInfo
->initialDataSize
);
423 *pPipelineCache
= anv_pipeline_cache_to_handle(cache
);
428 void anv_DestroyPipelineCache(
430 VkPipelineCache _cache
,
431 const VkAllocationCallbacks
* pAllocator
)
433 ANV_FROM_HANDLE(anv_device
, device
, _device
);
434 ANV_FROM_HANDLE(anv_pipeline_cache
, cache
, _cache
);
436 anv_pipeline_cache_finish(cache
);
438 vk_free2(&device
->alloc
, pAllocator
, cache
);
441 VkResult
anv_GetPipelineCacheData(
443 VkPipelineCache _cache
,
447 ANV_FROM_HANDLE(anv_device
, device
, _device
);
448 ANV_FROM_HANDLE(anv_pipeline_cache
, cache
, _cache
);
449 struct cache_header
*header
;
452 size_t size
= align_u32(sizeof(*header
), 8) +
453 align_u32(sizeof(uint32_t), 8);
456 struct hash_entry
*entry
;
457 hash_table_foreach(cache
->cache
, entry
)
458 size
+= anv_shader_bin_data_size(entry
->data
);
465 if (*pDataSize
< sizeof(*header
)) {
467 return VK_INCOMPLETE
;
470 void *p
= pData
, *end
= pData
+ *pDataSize
;
472 header
->header_size
= sizeof(*header
);
473 header
->header_version
= VK_PIPELINE_CACHE_HEADER_VERSION_ONE
;
474 header
->vendor_id
= 0x8086;
475 header
->device_id
= device
->chipset_id
;
476 anv_device_get_cache_uuid(header
->uuid
);
477 p
+= align_u32(header
->header_size
, 8);
480 p
+= align_u32(sizeof(*count
), 8);
483 VkResult result
= VK_SUCCESS
;
485 struct hash_entry
*entry
;
486 hash_table_foreach(cache
->cache
, entry
) {
487 struct anv_shader_bin
*shader
= entry
->data
;
488 size_t data_size
= anv_shader_bin_data_size(entry
->data
);
489 if (p
+ data_size
> end
) {
490 result
= VK_INCOMPLETE
;
494 anv_shader_bin_write_data(shader
, p
);
501 *pDataSize
= p
- pData
;
506 VkResult
anv_MergePipelineCaches(
508 VkPipelineCache destCache
,
509 uint32_t srcCacheCount
,
510 const VkPipelineCache
* pSrcCaches
)
512 ANV_FROM_HANDLE(anv_pipeline_cache
, dst
, destCache
);
517 for (uint32_t i
= 0; i
< srcCacheCount
; i
++) {
518 ANV_FROM_HANDLE(anv_pipeline_cache
, src
, pSrcCaches
[i
]);
522 struct hash_entry
*entry
;
523 hash_table_foreach(src
->cache
, entry
) {
524 struct anv_shader_bin
*bin
= entry
->data
;
525 if (_mesa_hash_table_search(dst
->cache
, bin
->key
))
528 anv_shader_bin_ref(bin
);
529 _mesa_hash_table_insert(dst
->cache
, bin
->key
, bin
);