1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * based in part on anv driver which is: 5bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 8bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 9bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 10bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 12bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 16bf215546Sopenharmony_ci * Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24bf215546Sopenharmony_ci * SOFTWARE. 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include <string.h> 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pvr_device_info.h" 30bf215546Sopenharmony_ci#include "pvr_private.h" 31bf215546Sopenharmony_ci#include "util/blob.h" 32bf215546Sopenharmony_ci#include "vk_log.h" 33bf215546Sopenharmony_ci#include "vk_object.h" 34bf215546Sopenharmony_ci#include "vulkan/util/vk_util.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistatic void pvr_pipeline_cache_load(struct pvr_pipeline_cache *cache, 37bf215546Sopenharmony_ci const void *data, 38bf215546Sopenharmony_ci size_t size) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci struct pvr_device *device = cache->device; 41bf215546Sopenharmony_ci struct pvr_physical_device *pdevice = device->pdevice; 42bf215546Sopenharmony_ci struct vk_pipeline_cache_header header; 43bf215546Sopenharmony_ci struct blob_reader blob; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci blob_reader_init(&blob, data, size); 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci blob_copy_bytes(&blob, &header, sizeof(header)); 48bf215546Sopenharmony_ci if (blob.overrun) 49bf215546Sopenharmony_ci return; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci if (header.header_size < sizeof(header)) 52bf215546Sopenharmony_ci return; 53bf215546Sopenharmony_ci if (header.header_version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) 54bf215546Sopenharmony_ci return; 55bf215546Sopenharmony_ci if (header.vendor_id != VK_VENDOR_ID_IMAGINATION) 56bf215546Sopenharmony_ci return; 57bf215546Sopenharmony_ci if (header.device_id != pdevice->dev_info.ident.device_id) 58bf215546Sopenharmony_ci return; 59bf215546Sopenharmony_ci if (memcmp(header.uuid, pdevice->pipeline_cache_uuid, VK_UUID_SIZE) != 0) 60bf215546Sopenharmony_ci return; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci /* TODO: There isn't currently any cached data so there's nothing to load 63bf215546Sopenharmony_ci * at this point. Once there is something to load then load it now. 64bf215546Sopenharmony_ci */ 65bf215546Sopenharmony_ci} 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ciVkResult pvr_CreatePipelineCache(VkDevice _device, 68bf215546Sopenharmony_ci const VkPipelineCacheCreateInfo *pCreateInfo, 69bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 70bf215546Sopenharmony_ci VkPipelineCache *pPipelineCache) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci PVR_FROM_HANDLE(pvr_device, device, _device); 73bf215546Sopenharmony_ci struct pvr_pipeline_cache *cache; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); 76bf215546Sopenharmony_ci assert(pCreateInfo->flags == 0); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci cache = vk_object_alloc(&device->vk, 79bf215546Sopenharmony_ci pAllocator, 80bf215546Sopenharmony_ci sizeof(*cache), 81bf215546Sopenharmony_ci VK_OBJECT_TYPE_PIPELINE_CACHE); 82bf215546Sopenharmony_ci if (!cache) 83bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci cache->device = device; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci if (pCreateInfo->initialDataSize > 0) { 88bf215546Sopenharmony_ci pvr_pipeline_cache_load(cache, 89bf215546Sopenharmony_ci pCreateInfo->pInitialData, 90bf215546Sopenharmony_ci pCreateInfo->initialDataSize); 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci *pPipelineCache = pvr_pipeline_cache_to_handle(cache); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci return VK_SUCCESS; 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_civoid pvr_DestroyPipelineCache(VkDevice _device, 99bf215546Sopenharmony_ci VkPipelineCache _cache, 100bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci PVR_FROM_HANDLE(pvr_device, device, _device); 103bf215546Sopenharmony_ci PVR_FROM_HANDLE(pvr_pipeline_cache, cache, _cache); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci if (!cache) 106bf215546Sopenharmony_ci return; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci vk_object_free(&device->vk, pAllocator, cache); 109bf215546Sopenharmony_ci} 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ciVkResult pvr_GetPipelineCacheData(VkDevice _device, 112bf215546Sopenharmony_ci VkPipelineCache _cache, 113bf215546Sopenharmony_ci size_t *pDataSize, 114bf215546Sopenharmony_ci void *pData) 115bf215546Sopenharmony_ci{ 116bf215546Sopenharmony_ci PVR_FROM_HANDLE(pvr_device, device, _device); 117bf215546Sopenharmony_ci struct pvr_physical_device *pdevice = device->pdevice; 118bf215546Sopenharmony_ci struct blob blob; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci if (pData) 121bf215546Sopenharmony_ci blob_init_fixed(&blob, pData, *pDataSize); 122bf215546Sopenharmony_ci else 123bf215546Sopenharmony_ci blob_init_fixed(&blob, NULL, SIZE_MAX); 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci struct vk_pipeline_cache_header header = { 126bf215546Sopenharmony_ci .header_size = sizeof(struct vk_pipeline_cache_header), 127bf215546Sopenharmony_ci .header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE, 128bf215546Sopenharmony_ci .vendor_id = VK_VENDOR_ID_IMAGINATION, 129bf215546Sopenharmony_ci .device_id = pdevice->dev_info.ident.device_id, 130bf215546Sopenharmony_ci }; 131bf215546Sopenharmony_ci memcpy(header.uuid, pdevice->pipeline_cache_uuid, VK_UUID_SIZE); 132bf215546Sopenharmony_ci blob_write_bytes(&blob, &header, sizeof(header)); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci /* TODO: Once there's some data to cache then this should be written to 135bf215546Sopenharmony_ci * 'blob'. 136bf215546Sopenharmony_ci */ 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci *pDataSize = blob.size; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci blob_finish(&blob); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci return VK_SUCCESS; 143bf215546Sopenharmony_ci} 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ciVkResult pvr_MergePipelineCaches(VkDevice _device, 146bf215546Sopenharmony_ci VkPipelineCache destCache, 147bf215546Sopenharmony_ci uint32_t srcCacheCount, 148bf215546Sopenharmony_ci const VkPipelineCache *pSrcCaches) 149bf215546Sopenharmony_ci{ 150bf215546Sopenharmony_ci /* TODO: Once there's some data to cache then this will need to be able to 151bf215546Sopenharmony_ci * merge caches together. 152bf215546Sopenharmony_ci */ 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci return VK_SUCCESS; 155bf215546Sopenharmony_ci} 156