From 5526c1782a01e73d3deac785449456018b53fd65 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg=20Kristensen?= Date: Sun, 3 Jan 2016 22:43:47 -0800 Subject: [PATCH] vk: Handle allocation failures in meta init paths Fixes dEQP-VK.api.object_management.alloc_callback_fail.* failures. --- src/vulkan/anv_device.c | 15 ++++-- src/vulkan/anv_meta.c | 62 ++++++++++++++++++++---- src/vulkan/anv_meta_clear.c | 94 ++++++++++++++++++++++++++++--------- src/vulkan/anv_meta_clear.h | 2 +- src/vulkan/anv_private.h | 2 +- 5 files changed, 136 insertions(+), 39 deletions(-) diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index c070aaf2125..40914aeb1cc 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -664,6 +664,7 @@ VkResult anv_CreateDevice( VkDevice* pDevice) { ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); + VkResult result; struct anv_device *device; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); @@ -699,12 +700,16 @@ VkResult anv_CreateDevice( /* XXX(chadv): Can we dup() physicalDevice->fd here? */ device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC); - if (device->fd == -1) + if (device->fd == -1) { + result = vk_error(VK_ERROR_INITIALIZATION_FAILED); goto fail_device; + } device->context_id = anv_gem_create_context(device); - if (device->context_id == -1) + if (device->context_id == -1) { + result = vk_error(VK_ERROR_INITIALIZATION_FAILED); goto fail_fd; + } device->info = *physical_device->info; device->isl_dev = physical_device->isl_dev; @@ -730,7 +735,9 @@ VkResult anv_CreateDevice( anv_queue_init(device, &device->queue); - anv_device_init_meta(device); + result = anv_device_init_meta(device); + if (result != VK_SUCCESS) + goto fail_fd; anv_device_init_border_colors(device); @@ -743,7 +750,7 @@ VkResult anv_CreateDevice( fail_device: anv_free(&device->alloc, device); - return vk_error(VK_ERROR_INITIALIZATION_FAILED); + return result; } void anv_DestroyDevice( diff --git a/src/vulkan/anv_meta.c b/src/vulkan/anv_meta.c index 5b564eb4dc2..b72ec48afe2 100644 --- a/src/vulkan/anv_meta.c +++ b/src/vulkan/anv_meta.c @@ -178,10 +178,12 @@ meta_blit_get_dest_view_base_array_slice(const struct anv_image *dest_image, } } -static void +static VkResult anv_device_init_meta_blit_state(struct anv_device *device) { - anv_CreateRenderPass(anv_device_to_handle(device), + VkResult result; + + result = anv_CreateRenderPass(anv_device_to_handle(device), &(VkRenderPassCreateInfo) { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, .attachmentCount = 1, @@ -214,6 +216,8 @@ anv_device_init_meta_blit_state(struct anv_device *device) }, .dependencyCount = 0, }, NULL, &device->meta_state.blit.render_pass); + if (result != VK_SUCCESS) + goto fail; /* We don't use a vertex shader for clearing, but instead build and pass * the VUEs directly to the rasterization backend. However, we do need @@ -286,16 +290,21 @@ anv_device_init_meta_blit_state(struct anv_device *device) }, } }; - anv_CreateDescriptorSetLayout(anv_device_to_handle(device), &ds_layout_info, - NULL, &device->meta_state.blit.ds_layout); + result = anv_CreateDescriptorSetLayout(anv_device_to_handle(device), + &ds_layout_info, NULL, + &device->meta_state.blit.ds_layout); + if (result != VK_SUCCESS) + goto fail_render_pass; - anv_CreatePipelineLayout(anv_device_to_handle(device), + result = anv_CreatePipelineLayout(anv_device_to_handle(device), &(VkPipelineLayoutCreateInfo) { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 1, .pSetLayouts = &device->meta_state.blit.ds_layout, }, NULL, &device->meta_state.blit.pipeline_layout); + if (result != VK_SUCCESS) + goto fail_descriptor_set_layout; VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = { { @@ -382,18 +391,43 @@ anv_device_init_meta_blit_state(struct anv_device *device) }; pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_2d); - anv_graphics_pipeline_create(anv_device_to_handle(device), + result = anv_graphics_pipeline_create(anv_device_to_handle(device), &vk_pipeline_info, &anv_pipeline_info, NULL, &device->meta_state.blit.pipeline_2d_src); + if (result != VK_SUCCESS) + goto fail_pipeline_layout; pipeline_shader_stages[1].module = anv_shader_module_to_handle(&fs_3d); - anv_graphics_pipeline_create(anv_device_to_handle(device), + result = anv_graphics_pipeline_create(anv_device_to_handle(device), &vk_pipeline_info, &anv_pipeline_info, NULL, &device->meta_state.blit.pipeline_3d_src); + if (result != VK_SUCCESS) + goto fail_pipeline_2d; ralloc_free(vs.nir); ralloc_free(fs_2d.nir); ralloc_free(fs_3d.nir); + + return VK_SUCCESS; + + fail_pipeline_2d: + anv_DestroyPipeline(anv_device_to_handle(device), + device->meta_state.blit.pipeline_2d_src, NULL); + fail_pipeline_layout: + anv_DestroyPipelineLayout(anv_device_to_handle(device), + device->meta_state.blit.pipeline_layout, NULL); + fail_descriptor_set_layout: + anv_DestroyDescriptorSetLayout(anv_device_to_handle(device), + device->meta_state.blit.ds_layout, NULL); + fail_render_pass: + anv_DestroyRenderPass(anv_device_to_handle(device), + device->meta_state.blit.render_pass, NULL); + + ralloc_free(vs.nir); + ralloc_free(fs_2d.nir); + ralloc_free(fs_3d.nir); + fail: + return result; } static void @@ -1272,11 +1306,19 @@ void anv_CmdResolveImage( stub(); } -void +VkResult anv_device_init_meta(struct anv_device *device) { - anv_device_init_meta_clear_state(device); - anv_device_init_meta_blit_state(device); + VkResult result; + result = anv_device_init_meta_clear_state(device); + if (result != VK_SUCCESS) + return result; + + result = anv_device_init_meta_blit_state(device); + if (result != VK_SUCCESS) + return result; + + return VK_SUCCESS; } void diff --git a/src/vulkan/anv_meta_clear.c b/src/vulkan/anv_meta_clear.c index 8e1470e1531..6a0517a2228 100644 --- a/src/vulkan/anv_meta_clear.c +++ b/src/vulkan/anv_meta_clear.c @@ -112,22 +112,24 @@ build_color_shaders(struct nir_shader **out_vs, *out_fs = fs_b.shader; } -static struct anv_pipeline * +static VkResult create_pipeline(struct anv_device *device, struct nir_shader *vs_nir, struct nir_shader *fs_nir, const VkPipelineVertexInputStateCreateInfo *vi_state, const VkPipelineDepthStencilStateCreateInfo *ds_state, const VkPipelineColorBlendStateCreateInfo *cb_state, - const VkAllocationCallbacks *alloc) + const VkAllocationCallbacks *alloc, + struct anv_pipeline **pipeline) { VkDevice device_h = anv_device_to_handle(device); + VkResult result; struct anv_shader_module vs_m = { .nir = vs_nir }; struct anv_shader_module fs_m = { .nir = fs_nir }; VkPipeline pipeline_h; - anv_graphics_pipeline_create(device_h, + result = anv_graphics_pipeline_create(device_h, &(VkGraphicsPipelineCreateInfo) { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .stageCount = 2, @@ -212,10 +214,12 @@ create_pipeline(struct anv_device *device, ralloc_free(vs_nir); ralloc_free(fs_nir); - return anv_pipeline_from_handle(pipeline_h); + *pipeline = anv_pipeline_from_handle(pipeline_h); + + return result; } -static void +static VkResult init_color_pipeline(struct anv_device *device) { struct nir_shader *vs_nir; @@ -281,9 +285,10 @@ init_color_pipeline(struct anv_device *device) }, }; - device->meta_state.clear.color_pipeline = + return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state, - &cb_state, NULL); + &cb_state, NULL, + &device->meta_state.clear.color_pipeline); } static void @@ -393,9 +398,10 @@ build_depthstencil_shaders(struct nir_shader **out_vs, *out_fs = fs_b.shader; } -static struct anv_pipeline * +static VkResult create_depthstencil_pipeline(struct anv_device *device, - VkImageAspectFlags aspects) + VkImageAspectFlags aspects, + struct anv_pipeline **pipeline) { struct nir_shader *vs_nir; struct nir_shader *fs_nir; @@ -455,7 +461,7 @@ create_depthstencil_pipeline(struct anv_device *device, }; return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state, - &cb_state, NULL); + &cb_state, NULL, pipeline); } static void @@ -553,25 +559,67 @@ emit_load_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer, ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0); } -static void +static VkResult init_depthstencil_pipelines(struct anv_device *device) { - device->meta_state.clear.depth_only_pipeline = - create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT); - - device->meta_state.clear.stencil_only_pipeline = - create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT); - - device->meta_state.clear.depthstencil_pipeline = - create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT | - VK_IMAGE_ASPECT_STENCIL_BIT); + VkResult result; + struct anv_meta_state *state = &device->meta_state; + + result = + create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT, + &state->clear.depth_only_pipeline); + if (result != VK_SUCCESS) + goto fail; + + result = + create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT, + &state->clear.stencil_only_pipeline); + if (result != VK_SUCCESS) + goto fail_depth_only; + + result = + create_depthstencil_pipeline(device, + VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT, + &state->clear.depthstencil_pipeline); + if (result != VK_SUCCESS) + goto fail_stencil_only; + + return result; + + fail_stencil_only: + anv_DestroyPipeline(anv_device_to_handle(device), + anv_pipeline_to_handle(state->clear.stencil_only_pipeline), + NULL); + fail_depth_only: + anv_DestroyPipeline(anv_device_to_handle(device), + anv_pipeline_to_handle(state->clear.depth_only_pipeline), + NULL); + fail: + return result; } -void +VkResult anv_device_init_meta_clear_state(struct anv_device *device) { - init_color_pipeline(device); - init_depthstencil_pipelines(device); + VkResult result; + + result = init_color_pipeline(device); + if (result != VK_SUCCESS) + goto fail; + + result = init_depthstencil_pipelines(device); + if (result != VK_SUCCESS) + goto fail_color_pipeline; + + return VK_SUCCESS; + + fail_color_pipeline: + anv_DestroyPipeline(anv_device_to_handle(device), + anv_pipeline_to_handle(device->meta_state.clear.color_pipeline), + NULL); + fail: + return result; } void diff --git a/src/vulkan/anv_meta_clear.h b/src/vulkan/anv_meta_clear.h index e53bd979763..853d9f241d8 100644 --- a/src/vulkan/anv_meta_clear.h +++ b/src/vulkan/anv_meta_clear.h @@ -29,7 +29,7 @@ extern "C" { struct anv_device; -void anv_device_init_meta_clear_state(struct anv_device *device); +VkResult anv_device_init_meta_clear_state(struct anv_device *device); void anv_device_finish_meta_clear_state(struct anv_device *device); #ifdef __cplusplus diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index cc9e139c034..8b17d9b3546 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -1631,7 +1631,7 @@ struct anv_query_pool { struct anv_bo bo; }; -void anv_device_init_meta(struct anv_device *device); +VkResult anv_device_init_meta(struct anv_device *device); void anv_device_finish_meta(struct anv_device *device); void *anv_lookup_entrypoint(const char *name); -- 2.30.2