From 1d2ae8756f848e6877e3e1c21ff1cb540cc8f9ed Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alejandro=20Pi=C3=B1eiro?= Date: Sat, 4 Jul 2020 13:10:49 +0200 Subject: [PATCH] v3dv/pipeline_cache: bare basic support for pipeline cache And this means providing a proper cache object, and being able to load/retrieve a cache data with a proper header. Not really caching anything yet. That would be tackle on following patches. Note that this no-op cache got all the specific pipeline_cache and pipeline.cache tests passing on the rpi4. The following tests are still crashing when using the simulator: dEQP-VK.synchronization.internally_synchronized_objects.pipeline_cache_compute dEQP-VK.synchronization.internally_synchronized_objects.pipeline_cache_graphics But those are an issue of synchronization tests on the simulator, and not related with the pipeline cache itself. In general synchronization tests should be tested on the rpi4. Part-of: --- src/broadcom/vulkan/v3dv_pipeline_cache.c | 125 +++++++++++++++++++++++++++--- src/broadcom/vulkan/v3dv_private.h | 8 ++ 2 files changed, 121 insertions(+), 12 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_pipeline_cache.c b/src/broadcom/vulkan/v3dv_pipeline_cache.c index f9e2ce0..d7718f8 100644 --- a/src/broadcom/vulkan/v3dv_pipeline_cache.c +++ b/src/broadcom/vulkan/v3dv_pipeline_cache.c @@ -22,14 +22,76 @@ */ #include "v3dv_private.h" +#include "vulkan/util/vk_util.h" + + +static void +pipeline_cache_init(struct v3dv_pipeline_cache *cache, + struct v3dv_device *device) +{ + cache->_loader_data.loaderMagic = ICD_LOADER_MAGIC; + + cache->device = device; + pthread_mutex_init(&cache->mutex, NULL); +} + +static void +pipeline_cache_load(struct v3dv_pipeline_cache *cache, + size_t size, + const void *data) +{ + struct v3dv_device *device = cache->device; + struct v3dv_physical_device *pdevice = &device->instance->physicalDevice; + struct vk_pipeline_cache_header header; + + if (size < sizeof(header)) + return; + memcpy(&header, data, sizeof(header)); + if (header.header_size < sizeof(header)) + return; + if (header.header_version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE) + return; + if (header.vendor_id != v3dv_physical_device_vendor_id(pdevice)) + return; + if (header.device_id != v3dv_physical_device_device_id(pdevice)) + return; + if (memcmp(header.uuid, pdevice->pipeline_cache_uuid, VK_UUID_SIZE) != 0) + return; + + /* FIXME: at this point we only verify the header but we dont really load + * any data. pending to implement serialize/deserialize among other things. + */ +} VkResult v3dv_CreatePipelineCache(VkDevice _device, - const VkPipelineCacheCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkPipelineCache *pPipelineCache) + const VkPipelineCacheCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineCache *pPipelineCache) { - /* FIXME: stub */ + V3DV_FROM_HANDLE(v3dv_device, device, _device); + struct v3dv_pipeline_cache *cache; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); + assert(pCreateInfo->flags == 0); + + cache = vk_alloc2(&device->alloc, pAllocator, + sizeof(*cache), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + if (cache == NULL) + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + pipeline_cache_init(cache, device); + + if (pCreateInfo->initialDataSize > 0) { + pipeline_cache_load(cache, + pCreateInfo->initialDataSize, + pCreateInfo->pInitialData); + } + + *pPipelineCache = v3dv_pipeline_cache_to_handle(cache); + return VK_SUCCESS; } @@ -38,7 +100,15 @@ v3dv_DestroyPipelineCache(VkDevice _device, VkPipelineCache _cache, const VkAllocationCallbacks *pAllocator) { - /* FIXME: stub */ + V3DV_FROM_HANDLE(v3dv_device, device, _device); + V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache); + + if (!cache) + return; + + pthread_mutex_destroy(&cache->mutex); + + vk_free2(&device->alloc, pAllocator, cache); } VkResult @@ -47,15 +117,46 @@ v3dv_MergePipelineCaches(VkDevice device, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) { - unreachable("vkMergePipelineCaches not implemented."); - return VK_ERROR_UNKNOWN; + /* FIXME: at this point there are not other content that the header cache, + * so merging pipeline caches would be always successful + */ + return VK_SUCCESS; } VkResult -v3dv_GetPipelineCacheData(VkDevice device, - VkPipelineCache pipelineCache, - size_t *pDataSize, void *pData) +v3dv_GetPipelineCacheData(VkDevice _device, + VkPipelineCache _cache, + size_t *pDataSize, + void *pData) { - unreachable("vkGetPipelineCacheData not implemented."); - return VK_ERROR_UNKNOWN; + V3DV_FROM_HANDLE(v3dv_device, device, _device); + V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache); + struct v3dv_physical_device *pdevice = &device->instance->physicalDevice; + struct vk_pipeline_cache_header *header; + VkResult result = VK_SUCCESS; + + pthread_mutex_lock(&cache->mutex); + + /* FIXME: at this point the cache data is just the header */ + const size_t size = sizeof(*header); + if (pData == NULL) { + pthread_mutex_unlock(&cache->mutex); + *pDataSize = size; + return VK_SUCCESS; + } + if (*pDataSize < sizeof(*header)) { + pthread_mutex_unlock(&cache->mutex); + *pDataSize = 0; + return VK_INCOMPLETE; + } + + header = pData; + header->header_size = sizeof(*header); + header->header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE; + header->vendor_id = v3dv_physical_device_vendor_id(pdevice); + header->device_id = v3dv_physical_device_device_id(pdevice); + memcpy(header->uuid, pdevice->pipeline_cache_uuid, VK_UUID_SIZE); + + pthread_mutex_unlock(&cache->mutex); + return result; } diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 94cd443..520f6f7 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -261,6 +261,13 @@ struct v3dv_meta_blit_pipeline { #define V3DV_META_BLIT_CACHE_KEY_SIZE (3 * sizeof(uint32_t)) +struct v3dv_pipeline_cache { + VK_LOADER_DATA _loader_data; + + struct v3dv_device *device; + mtx_t mutex; +}; + struct v3dv_device { VK_LOADER_DATA _loader_data; @@ -1782,6 +1789,7 @@ V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_framebuffer, VkFramebuffer) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image, VkImage) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image_view, VkImageView) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline, VkPipeline) +V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline_cache, VkPipelineCache) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline_layout, VkPipelineLayout) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_query_pool, VkQueryPool) V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_render_pass, VkRenderPass) -- 2.7.4