1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2019 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv and radv which are: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 8bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vn_pipeline.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_pipeline.h" 14bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_pipeline_cache.h" 15bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_pipeline_layout.h" 16bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_shader_module.h" 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#include "vn_device.h" 19bf215546Sopenharmony_ci#include "vn_physical_device.h" 20bf215546Sopenharmony_ci 21bf215546Sopenharmony_ci/* shader module commands */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ciVkResult 24bf215546Sopenharmony_civn_CreateShaderModule(VkDevice device, 25bf215546Sopenharmony_ci const VkShaderModuleCreateInfo *pCreateInfo, 26bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 27bf215546Sopenharmony_ci VkShaderModule *pShaderModule) 28bf215546Sopenharmony_ci{ 29bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 30bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 31bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci struct vn_shader_module *mod = 34bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*mod), VN_DEFAULT_ALIGN, 35bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 36bf215546Sopenharmony_ci if (!mod) 37bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci vn_object_base_init(&mod->base, VK_OBJECT_TYPE_SHADER_MODULE, &dev->base); 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci VkShaderModule mod_handle = vn_shader_module_to_handle(mod); 42bf215546Sopenharmony_ci vn_async_vkCreateShaderModule(dev->instance, device, pCreateInfo, NULL, 43bf215546Sopenharmony_ci &mod_handle); 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci *pShaderModule = mod_handle; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci return VK_SUCCESS; 48bf215546Sopenharmony_ci} 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_civoid 51bf215546Sopenharmony_civn_DestroyShaderModule(VkDevice device, 52bf215546Sopenharmony_ci VkShaderModule shaderModule, 53bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 56bf215546Sopenharmony_ci struct vn_shader_module *mod = vn_shader_module_from_handle(shaderModule); 57bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 58bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci if (!mod) 61bf215546Sopenharmony_ci return; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci vn_async_vkDestroyShaderModule(dev->instance, device, shaderModule, NULL); 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci vn_object_base_fini(&mod->base); 66bf215546Sopenharmony_ci vk_free(alloc, mod); 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci/* pipeline layout commands */ 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ciVkResult 72bf215546Sopenharmony_civn_CreatePipelineLayout(VkDevice device, 73bf215546Sopenharmony_ci const VkPipelineLayoutCreateInfo *pCreateInfo, 74bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 75bf215546Sopenharmony_ci VkPipelineLayout *pPipelineLayout) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 78bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 79bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci struct vn_pipeline_layout *layout = 82bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*layout), VN_DEFAULT_ALIGN, 83bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 84bf215546Sopenharmony_ci if (!layout) 85bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci vn_object_base_init(&layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT, 88bf215546Sopenharmony_ci &dev->base); 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci VkPipelineLayout layout_handle = vn_pipeline_layout_to_handle(layout); 91bf215546Sopenharmony_ci vn_async_vkCreatePipelineLayout(dev->instance, device, pCreateInfo, NULL, 92bf215546Sopenharmony_ci &layout_handle); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci *pPipelineLayout = layout_handle; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci return VK_SUCCESS; 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_civoid 100bf215546Sopenharmony_civn_DestroyPipelineLayout(VkDevice device, 101bf215546Sopenharmony_ci VkPipelineLayout pipelineLayout, 102bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 103bf215546Sopenharmony_ci{ 104bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 105bf215546Sopenharmony_ci struct vn_pipeline_layout *layout = 106bf215546Sopenharmony_ci vn_pipeline_layout_from_handle(pipelineLayout); 107bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 108bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci if (!layout) 111bf215546Sopenharmony_ci return; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci vn_async_vkDestroyPipelineLayout(dev->instance, device, pipelineLayout, 114bf215546Sopenharmony_ci NULL); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci vn_object_base_fini(&layout->base); 117bf215546Sopenharmony_ci vk_free(alloc, layout); 118bf215546Sopenharmony_ci} 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci/* pipeline cache commands */ 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ciVkResult 123bf215546Sopenharmony_civn_CreatePipelineCache(VkDevice device, 124bf215546Sopenharmony_ci const VkPipelineCacheCreateInfo *pCreateInfo, 125bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 126bf215546Sopenharmony_ci VkPipelineCache *pPipelineCache) 127bf215546Sopenharmony_ci{ 128bf215546Sopenharmony_ci VN_TRACE_FUNC(); 129bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 130bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 131bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci struct vn_pipeline_cache *cache = 134bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*cache), VN_DEFAULT_ALIGN, 135bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 136bf215546Sopenharmony_ci if (!cache) 137bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci vn_object_base_init(&cache->base, VK_OBJECT_TYPE_PIPELINE_CACHE, 140bf215546Sopenharmony_ci &dev->base); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci VkPipelineCacheCreateInfo local_create_info; 143bf215546Sopenharmony_ci if (pCreateInfo->initialDataSize) { 144bf215546Sopenharmony_ci const struct vk_pipeline_cache_header *header = 145bf215546Sopenharmony_ci pCreateInfo->pInitialData; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci local_create_info = *pCreateInfo; 148bf215546Sopenharmony_ci local_create_info.initialDataSize -= header->header_size; 149bf215546Sopenharmony_ci local_create_info.pInitialData += header->header_size; 150bf215546Sopenharmony_ci pCreateInfo = &local_create_info; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci VkPipelineCache cache_handle = vn_pipeline_cache_to_handle(cache); 154bf215546Sopenharmony_ci vn_async_vkCreatePipelineCache(dev->instance, device, pCreateInfo, NULL, 155bf215546Sopenharmony_ci &cache_handle); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci *pPipelineCache = cache_handle; 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci return VK_SUCCESS; 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_civoid 163bf215546Sopenharmony_civn_DestroyPipelineCache(VkDevice device, 164bf215546Sopenharmony_ci VkPipelineCache pipelineCache, 165bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 166bf215546Sopenharmony_ci{ 167bf215546Sopenharmony_ci VN_TRACE_FUNC(); 168bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 169bf215546Sopenharmony_ci struct vn_pipeline_cache *cache = 170bf215546Sopenharmony_ci vn_pipeline_cache_from_handle(pipelineCache); 171bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 172bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (!cache) 175bf215546Sopenharmony_ci return; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci vn_async_vkDestroyPipelineCache(dev->instance, device, pipelineCache, 178bf215546Sopenharmony_ci NULL); 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci vn_object_base_fini(&cache->base); 181bf215546Sopenharmony_ci vk_free(alloc, cache); 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ciVkResult 185bf215546Sopenharmony_civn_GetPipelineCacheData(VkDevice device, 186bf215546Sopenharmony_ci VkPipelineCache pipelineCache, 187bf215546Sopenharmony_ci size_t *pDataSize, 188bf215546Sopenharmony_ci void *pData) 189bf215546Sopenharmony_ci{ 190bf215546Sopenharmony_ci VN_TRACE_FUNC(); 191bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 192bf215546Sopenharmony_ci struct vn_physical_device *physical_dev = dev->physical_device; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci struct vk_pipeline_cache_header *header = pData; 195bf215546Sopenharmony_ci VkResult result; 196bf215546Sopenharmony_ci if (!pData) { 197bf215546Sopenharmony_ci result = vn_call_vkGetPipelineCacheData(dev->instance, device, 198bf215546Sopenharmony_ci pipelineCache, pDataSize, NULL); 199bf215546Sopenharmony_ci if (result != VK_SUCCESS) 200bf215546Sopenharmony_ci return vn_error(dev->instance, result); 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci *pDataSize += sizeof(*header); 203bf215546Sopenharmony_ci return VK_SUCCESS; 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci if (*pDataSize <= sizeof(*header)) { 207bf215546Sopenharmony_ci *pDataSize = 0; 208bf215546Sopenharmony_ci return VK_INCOMPLETE; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci const VkPhysicalDeviceProperties *props = 212bf215546Sopenharmony_ci &physical_dev->properties.vulkan_1_0; 213bf215546Sopenharmony_ci header->header_size = sizeof(*header); 214bf215546Sopenharmony_ci header->header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE; 215bf215546Sopenharmony_ci header->vendor_id = props->vendorID; 216bf215546Sopenharmony_ci header->device_id = props->deviceID; 217bf215546Sopenharmony_ci memcpy(header->uuid, props->pipelineCacheUUID, VK_UUID_SIZE); 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci *pDataSize -= header->header_size; 220bf215546Sopenharmony_ci result = 221bf215546Sopenharmony_ci vn_call_vkGetPipelineCacheData(dev->instance, device, pipelineCache, 222bf215546Sopenharmony_ci pDataSize, pData + header->header_size); 223bf215546Sopenharmony_ci if (result < VK_SUCCESS) 224bf215546Sopenharmony_ci return vn_error(dev->instance, result); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci *pDataSize += header->header_size; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci return result; 229bf215546Sopenharmony_ci} 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ciVkResult 232bf215546Sopenharmony_civn_MergePipelineCaches(VkDevice device, 233bf215546Sopenharmony_ci VkPipelineCache dstCache, 234bf215546Sopenharmony_ci uint32_t srcCacheCount, 235bf215546Sopenharmony_ci const VkPipelineCache *pSrcCaches) 236bf215546Sopenharmony_ci{ 237bf215546Sopenharmony_ci VN_TRACE_FUNC(); 238bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci vn_async_vkMergePipelineCaches(dev->instance, device, dstCache, 241bf215546Sopenharmony_ci srcCacheCount, pSrcCaches); 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci return VK_SUCCESS; 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci/* pipeline commands */ 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_cistruct vn_graphics_pipeline_create_info_fix { 249bf215546Sopenharmony_ci bool ignore_tessellation_state; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci /* Ignore the following: 252bf215546Sopenharmony_ci * pViewportState 253bf215546Sopenharmony_ci * pMultisampleState 254bf215546Sopenharmony_ci * pDepthStencilState 255bf215546Sopenharmony_ci * pColorBlendState 256bf215546Sopenharmony_ci */ 257bf215546Sopenharmony_ci bool ignore_raster_dedicated_states; 258bf215546Sopenharmony_ci}; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_cistatic const VkGraphicsPipelineCreateInfo * 261bf215546Sopenharmony_civn_fix_graphics_pipeline_create_info( 262bf215546Sopenharmony_ci struct vn_device *dev, 263bf215546Sopenharmony_ci uint32_t create_info_count, 264bf215546Sopenharmony_ci const VkGraphicsPipelineCreateInfo *create_infos, 265bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 266bf215546Sopenharmony_ci VkGraphicsPipelineCreateInfo **out) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci VN_TRACE_FUNC(); 269bf215546Sopenharmony_ci VkGraphicsPipelineCreateInfo *infos = NULL; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* Defer allocation until we find a needed fix. */ 272bf215546Sopenharmony_ci struct vn_graphics_pipeline_create_info_fix *fixes = NULL; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci for (uint32_t i = 0; i < create_info_count; i++) { 275bf215546Sopenharmony_ci const VkGraphicsPipelineCreateInfo *info = &create_infos[i]; 276bf215546Sopenharmony_ci struct vn_graphics_pipeline_create_info_fix fix = { 0 }; 277bf215546Sopenharmony_ci bool any_fix = false; 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci VkShaderStageFlags stages = 0; 280bf215546Sopenharmony_ci for (uint32_t j = 0; j < info->stageCount; j++) { 281bf215546Sopenharmony_ci stages |= info->pStages[j].stage; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci /* Fix pTessellationState? 285bf215546Sopenharmony_ci * VUID-VkGraphicsPipelineCreateInfo-pStages-00731 286bf215546Sopenharmony_ci */ 287bf215546Sopenharmony_ci if (info->pTessellationState && 288bf215546Sopenharmony_ci (!(stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) || 289bf215546Sopenharmony_ci !(stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))) { 290bf215546Sopenharmony_ci fix.ignore_tessellation_state = true; 291bf215546Sopenharmony_ci any_fix = true; 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci bool ignore_raster_dedicated_states = 295bf215546Sopenharmony_ci !info->pRasterizationState || 296bf215546Sopenharmony_ci info->pRasterizationState->rasterizerDiscardEnable == VK_TRUE; 297bf215546Sopenharmony_ci if (ignore_raster_dedicated_states && info->pDynamicState) { 298bf215546Sopenharmony_ci for (uint32_t j = 0; j < info->pDynamicState->dynamicStateCount; 299bf215546Sopenharmony_ci j++) { 300bf215546Sopenharmony_ci if (info->pDynamicState->pDynamicStates[j] == 301bf215546Sopenharmony_ci VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE) { 302bf215546Sopenharmony_ci ignore_raster_dedicated_states = false; 303bf215546Sopenharmony_ci break; 304bf215546Sopenharmony_ci } 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci /* FIXME: Conditions for ignoring pDepthStencilState and 309bf215546Sopenharmony_ci * pColorBlendState miss some cases that depend on the render pass. Make 310bf215546Sopenharmony_ci * them agree with the VUIDs. 311bf215546Sopenharmony_ci */ 312bf215546Sopenharmony_ci if (ignore_raster_dedicated_states && 313bf215546Sopenharmony_ci (info->pViewportState || info->pMultisampleState || 314bf215546Sopenharmony_ci info->pDepthStencilState || info->pColorBlendState)) { 315bf215546Sopenharmony_ci fix.ignore_raster_dedicated_states = true; 316bf215546Sopenharmony_ci any_fix = true; 317bf215546Sopenharmony_ci } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if (any_fix) { 320bf215546Sopenharmony_ci if (!fixes) { 321bf215546Sopenharmony_ci fixes = vk_zalloc(alloc, create_info_count * sizeof(fixes[0]), 322bf215546Sopenharmony_ci VN_DEFAULT_ALIGN, 323bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 324bf215546Sopenharmony_ci if (!fixes) 325bf215546Sopenharmony_ci return NULL; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci fixes[i] = fix; 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci if (!fixes) 333bf215546Sopenharmony_ci return create_infos; 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci infos = vk_alloc(alloc, sizeof(*infos) * create_info_count, 336bf215546Sopenharmony_ci VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 337bf215546Sopenharmony_ci if (!infos) { 338bf215546Sopenharmony_ci vk_free(alloc, fixes); 339bf215546Sopenharmony_ci return NULL; 340bf215546Sopenharmony_ci } 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci memcpy(infos, create_infos, sizeof(*infos) * create_info_count); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci for (uint32_t i = 0; i < create_info_count; i++) { 345bf215546Sopenharmony_ci VkGraphicsPipelineCreateInfo *info = &infos[i]; 346bf215546Sopenharmony_ci struct vn_graphics_pipeline_create_info_fix fix = fixes[i]; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci if (fix.ignore_tessellation_state) 349bf215546Sopenharmony_ci info->pTessellationState = NULL; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (fix.ignore_raster_dedicated_states) { 352bf215546Sopenharmony_ci info->pViewportState = NULL; 353bf215546Sopenharmony_ci info->pMultisampleState = NULL; 354bf215546Sopenharmony_ci info->pDepthStencilState = NULL; 355bf215546Sopenharmony_ci info->pColorBlendState = NULL; 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci vk_free(alloc, fixes); 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci *out = infos; 362bf215546Sopenharmony_ci return infos; 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ciVkResult 366bf215546Sopenharmony_civn_CreateGraphicsPipelines(VkDevice device, 367bf215546Sopenharmony_ci VkPipelineCache pipelineCache, 368bf215546Sopenharmony_ci uint32_t createInfoCount, 369bf215546Sopenharmony_ci const VkGraphicsPipelineCreateInfo *pCreateInfos, 370bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 371bf215546Sopenharmony_ci VkPipeline *pPipelines) 372bf215546Sopenharmony_ci{ 373bf215546Sopenharmony_ci VN_TRACE_FUNC(); 374bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 375bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 376bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 377bf215546Sopenharmony_ci VkGraphicsPipelineCreateInfo *local_infos = NULL; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci pCreateInfos = vn_fix_graphics_pipeline_create_info( 380bf215546Sopenharmony_ci dev, createInfoCount, pCreateInfos, alloc, &local_infos); 381bf215546Sopenharmony_ci if (!pCreateInfos) 382bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci for (uint32_t i = 0; i < createInfoCount; i++) { 385bf215546Sopenharmony_ci struct vn_pipeline *pipeline = 386bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*pipeline), VN_DEFAULT_ALIGN, 387bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 388bf215546Sopenharmony_ci if (!pipeline) { 389bf215546Sopenharmony_ci for (uint32_t j = 0; j < i; j++) 390bf215546Sopenharmony_ci vk_free(alloc, vn_pipeline_from_handle(pPipelines[j])); 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci if (local_infos) 393bf215546Sopenharmony_ci vk_free(alloc, local_infos); 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci memset(pPipelines, 0, sizeof(*pPipelines) * createInfoCount); 396bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci vn_object_base_init(&pipeline->base, VK_OBJECT_TYPE_PIPELINE, 400bf215546Sopenharmony_ci &dev->base); 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci VkPipeline pipeline_handle = vn_pipeline_to_handle(pipeline); 403bf215546Sopenharmony_ci pPipelines[i] = pipeline_handle; 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci vn_async_vkCreateGraphicsPipelines(dev->instance, device, pipelineCache, 407bf215546Sopenharmony_ci createInfoCount, pCreateInfos, NULL, 408bf215546Sopenharmony_ci pPipelines); 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci if (local_infos) 411bf215546Sopenharmony_ci vk_free(alloc, local_infos); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci return VK_SUCCESS; 414bf215546Sopenharmony_ci} 415bf215546Sopenharmony_ci 416bf215546Sopenharmony_ciVkResult 417bf215546Sopenharmony_civn_CreateComputePipelines(VkDevice device, 418bf215546Sopenharmony_ci VkPipelineCache pipelineCache, 419bf215546Sopenharmony_ci uint32_t createInfoCount, 420bf215546Sopenharmony_ci const VkComputePipelineCreateInfo *pCreateInfos, 421bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 422bf215546Sopenharmony_ci VkPipeline *pPipelines) 423bf215546Sopenharmony_ci{ 424bf215546Sopenharmony_ci VN_TRACE_FUNC(); 425bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 426bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 427bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci for (uint32_t i = 0; i < createInfoCount; i++) { 430bf215546Sopenharmony_ci struct vn_pipeline *pipeline = 431bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*pipeline), VN_DEFAULT_ALIGN, 432bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 433bf215546Sopenharmony_ci if (!pipeline) { 434bf215546Sopenharmony_ci for (uint32_t j = 0; j < i; j++) 435bf215546Sopenharmony_ci vk_free(alloc, vn_pipeline_from_handle(pPipelines[j])); 436bf215546Sopenharmony_ci memset(pPipelines, 0, sizeof(*pPipelines) * createInfoCount); 437bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci vn_object_base_init(&pipeline->base, VK_OBJECT_TYPE_PIPELINE, 441bf215546Sopenharmony_ci &dev->base); 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci VkPipeline pipeline_handle = vn_pipeline_to_handle(pipeline); 444bf215546Sopenharmony_ci pPipelines[i] = pipeline_handle; 445bf215546Sopenharmony_ci } 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci vn_async_vkCreateComputePipelines(dev->instance, device, pipelineCache, 448bf215546Sopenharmony_ci createInfoCount, pCreateInfos, NULL, 449bf215546Sopenharmony_ci pPipelines); 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci return VK_SUCCESS; 452bf215546Sopenharmony_ci} 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_civoid 455bf215546Sopenharmony_civn_DestroyPipeline(VkDevice device, 456bf215546Sopenharmony_ci VkPipeline _pipeline, 457bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 458bf215546Sopenharmony_ci{ 459bf215546Sopenharmony_ci VN_TRACE_FUNC(); 460bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 461bf215546Sopenharmony_ci struct vn_pipeline *pipeline = vn_pipeline_from_handle(_pipeline); 462bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 463bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci if (!pipeline) 466bf215546Sopenharmony_ci return; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci vn_async_vkDestroyPipeline(dev->instance, device, _pipeline, NULL); 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci vn_object_base_fini(&pipeline->base); 471bf215546Sopenharmony_ci vk_free(alloc, pipeline); 472bf215546Sopenharmony_ci} 473