diff options
Diffstat (limited to 'src/freedreno/vulkan/tu_pipeline.c')
-rw-r--r-- | src/freedreno/vulkan/tu_pipeline.c | 127 |
1 files changed, 107 insertions, 20 deletions
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index b7598960748..9df7c20b455 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -37,42 +37,114 @@ #include "vk_format.h" #include "vk_util.h" -VkResult -tu_graphics_pipeline_create( - VkDevice _device, - VkPipelineCache _cache, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const struct tu_graphics_pipeline_create_info *extra, - const VkAllocationCallbacks *pAllocator, - VkPipeline *pPipeline) +#include "tu_cs.h" + +struct tu_pipeline_builder +{ + struct tu_device *device; + struct tu_pipeline_cache *cache; + const VkAllocationCallbacks *alloc; + const VkGraphicsPipelineCreateInfo *create_info; +}; + +static VkResult +tu_pipeline_builder_create_pipeline(struct tu_pipeline_builder *builder, + struct tu_pipeline **out_pipeline) { + struct tu_device *dev = builder->device; + + struct tu_pipeline *pipeline = + vk_zalloc2(&dev->alloc, builder->alloc, sizeof(*pipeline), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!pipeline) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + tu_cs_init(&pipeline->cs, TU_CS_MODE_SUB_STREAM, 2048); + + /* reserve the space now such that tu_cs_begin_sub_stream never fails */ + VkResult result = tu_cs_reserve_space(dev, &pipeline->cs, 2048); + if (result != VK_SUCCESS) { + vk_free2(&dev->alloc, builder->alloc, pipeline); + return result; + } + + *out_pipeline = pipeline; return VK_SUCCESS; } +static void +tu_pipeline_finish(struct tu_pipeline *pipeline, + struct tu_device *dev, + const VkAllocationCallbacks *alloc) +{ + tu_cs_finish(dev, &pipeline->cs); +} + +static VkResult +tu_pipeline_builder_build(struct tu_pipeline_builder *builder, + struct tu_pipeline **pipeline) +{ + VkResult result = tu_pipeline_builder_create_pipeline(builder, pipeline); + if (result != VK_SUCCESS) + return result; + + /* we should have reserved enough space upfront such that the CS never + * grows + */ + assert((*pipeline)->cs.bo_count == 1); + + return VK_SUCCESS; +} + +static void +tu_pipeline_builder_init_graphics( + struct tu_pipeline_builder *builder, + struct tu_device *dev, + struct tu_pipeline_cache *cache, + const VkGraphicsPipelineCreateInfo *create_info, + const VkAllocationCallbacks *alloc) +{ + *builder = (struct tu_pipeline_builder) { + .device = dev, + .cache = cache, + .create_info = create_info, + .alloc = alloc, + }; +} + VkResult -tu_CreateGraphicsPipelines(VkDevice _device, +tu_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) { - VkResult result = VK_SUCCESS; - unsigned i = 0; + TU_FROM_HANDLE(tu_device, dev, device); + TU_FROM_HANDLE(tu_pipeline_cache, cache, pipelineCache); - for (; i < count; i++) { - VkResult r; - r = - tu_graphics_pipeline_create(_device, pipelineCache, &pCreateInfos[i], - NULL, pAllocator, &pPipelines[i]); - if (r != VK_SUCCESS) { - result = r; - pPipelines[i] = VK_NULL_HANDLE; + for (uint32_t i = 0; i < count; i++) { + struct tu_pipeline_builder builder; + tu_pipeline_builder_init_graphics(&builder, dev, cache, + &pCreateInfos[i], pAllocator); + + struct tu_pipeline *pipeline; + VkResult result = tu_pipeline_builder_build(&builder, &pipeline); + + if (result != VK_SUCCESS) { + for (uint32_t j = 0; j < i; j++) { + tu_DestroyPipeline(device, pPipelines[j], pAllocator); + pPipelines[j] = VK_NULL_HANDLE; + } + + return result; } + + pPipelines[i] = tu_pipeline_to_handle(pipeline); } - return result; + return VK_SUCCESS; } static VkResult @@ -108,3 +180,18 @@ tu_CreateComputePipelines(VkDevice _device, return result; } + +void +tu_DestroyPipeline(VkDevice _device, + VkPipeline _pipeline, + const VkAllocationCallbacks *pAllocator) +{ + TU_FROM_HANDLE(tu_device, dev, _device); + TU_FROM_HANDLE(tu_pipeline, pipeline, _pipeline); + + if (!_pipeline) + return; + + tu_pipeline_finish(pipeline, dev, pAllocator); + vk_free2(&dev->alloc, pAllocator, pipeline); +} |