venus: fix to destroy all pipeline handles on early error paths

For early error returns, all pipeline handles have to be destroyed.
Otherwise the caller will treat those valid handles as successfully
created pipeline objects.

Cc: mesa-stable
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28944>
This commit is contained in:
Yiwei Zhang 2024-04-26 06:10:37 +00:00 committed by Marge Bot
parent c3be21f177
commit 4ec84adbed
1 changed files with 37 additions and 14 deletions

View File

@ -584,27 +584,48 @@ vn_create_pipeline_handles(struct vn_device *dev,
return true;
}
/** For vkCreate*Pipelines. */
static void
vn_destroy_failed_pipelines(struct vn_device *dev,
uint32_t create_info_count,
VkPipeline *pipelines,
const VkAllocationCallbacks *alloc)
vn_destroy_pipeline_handles_internal(struct vn_device *dev,
uint32_t pipeline_count,
VkPipeline *pipeline_handles,
const VkAllocationCallbacks *alloc,
bool failed_only)
{
for (uint32_t i = 0; i < create_info_count; i++) {
struct vn_pipeline *pipeline = vn_pipeline_from_handle(pipelines[i]);
for (uint32_t i = 0; i < pipeline_count; i++) {
struct vn_pipeline *pipeline =
vn_pipeline_from_handle(pipeline_handles[i]);
if (pipeline->base.id == 0) {
if (!failed_only || pipeline->base.id == 0) {
if (pipeline->layout) {
vn_pipeline_layout_unref(dev, pipeline->layout);
}
vn_object_base_fini(&pipeline->base);
vk_free(alloc, pipeline);
pipelines[i] = VK_NULL_HANDLE;
pipeline_handles[i] = VK_NULL_HANDLE;
}
}
}
static inline void
vn_destroy_pipeline_handles(struct vn_device *dev,
uint32_t pipeline_count,
VkPipeline *pipeline_handles,
const VkAllocationCallbacks *alloc)
{
vn_destroy_pipeline_handles_internal(dev, pipeline_count, pipeline_handles,
alloc, false);
}
static inline void
vn_destroy_failed_pipeline_handles(struct vn_device *dev,
uint32_t pipeline_count,
VkPipeline *pipeline_handles,
const VkAllocationCallbacks *alloc)
{
vn_destroy_pipeline_handles_internal(dev, pipeline_count, pipeline_handles,
alloc, true);
}
#define VN_PIPELINE_CREATE_SYNC_MASK \
(VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT | \
VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT)
@ -1546,7 +1567,7 @@ vn_CreateGraphicsPipelines(VkDevice device,
pCreateInfos = vn_fix_graphics_pipeline_create_infos(
dev, createInfoCount, pCreateInfos, fix_descs, &fix_tmp, alloc);
if (!pCreateInfos) {
vn_destroy_failed_pipelines(dev, createInfoCount, pPipelines, alloc);
vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
STACK_ARRAY_FINISH(fix_descs);
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
@ -1570,7 +1591,7 @@ vn_CreateGraphicsPipelines(VkDevice device,
struct vn_ring *target_ring = vn_get_target_ring(dev);
if (!target_ring) {
vk_free(alloc, fix_tmp);
vn_destroy_failed_pipelines(dev, createInfoCount, pPipelines, alloc);
vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
STACK_ARRAY_FINISH(fix_descs);
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
@ -1584,7 +1605,8 @@ vn_CreateGraphicsPipelines(VkDevice device,
target_ring, device, pipelineCache, createInfoCount, pCreateInfos,
NULL, pPipelines);
if (result != VK_SUCCESS)
vn_destroy_failed_pipelines(dev, createInfoCount, pPipelines, alloc);
vn_destroy_failed_pipeline_handles(dev, createInfoCount, pPipelines,
alloc);
} else {
vn_async_vkCreateGraphicsPipelines(target_ring, device, pipelineCache,
createInfoCount, pCreateInfos, NULL,
@ -1634,7 +1656,7 @@ vn_CreateComputePipelines(VkDevice device,
struct vn_ring *target_ring = vn_get_target_ring(dev);
if (!target_ring) {
vn_destroy_failed_pipelines(dev, createInfoCount, pPipelines, alloc);
vn_destroy_pipeline_handles(dev, createInfoCount, pPipelines, alloc);
return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
@ -1643,7 +1665,8 @@ vn_CreateComputePipelines(VkDevice device,
target_ring, device, pipelineCache, createInfoCount, pCreateInfos,
NULL, pPipelines);
if (result != VK_SUCCESS)
vn_destroy_failed_pipelines(dev, createInfoCount, pPipelines, alloc);
vn_destroy_failed_pipeline_handles(dev, createInfoCount, pPipelines,
alloc);
} else {
vn_async_vkCreateComputePipelines(target_ring, device, pipelineCache,
createInfoCount, pCreateInfos, NULL,