summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYiwei Zhang <zzyiwei@chromium.org>2024-04-26 06:10:37 +0000
committerMarge Bot <emma+marge@anholt.net>2024-04-26 17:35:29 +0000
commit4ec84adbed1e7cc0b78af754294c4a2b254bc317 (patch)
tree959403950061e1fcb1cd782a058c285573552a7d
parentc3be21f1778ff3e3de4d6506bb20a0ffd11f5003 (diff)
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>
-rw-r--r--src/virtio/vulkan/vn_pipeline.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/virtio/vulkan/vn_pipeline.c b/src/virtio/vulkan/vn_pipeline.c
index fa75fa3bd55..039effc5f7a 100644
--- a/src/virtio/vulkan/vn_pipeline.c
+++ b/src/virtio/vulkan/vn_pipeline.c
@@ -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,