vk: Handle allocation failures in meta init paths
authorKristian Høgsberg Kristensen <krh@owl.jf.intel.com>
Mon, 4 Jan 2016 06:43:47 +0000 (22:43 -0800)
committerKristian Høgsberg Kristensen <krh@owl.jf.intel.com>
Mon, 4 Jan 2016 18:07:08 +0000 (10:07 -0800)
Fixes dEQP-VK.api.object_management.alloc_callback_fail.* failures.

src/vulkan/anv_device.c
src/vulkan/anv_meta.c
src/vulkan/anv_meta_clear.c
src/vulkan/anv_meta_clear.h
src/vulkan/anv_private.h

index c070aaf2125567dad872b4aefc65d7d08756c877..40914aeb1cc60c07a335b0475686cf807046eafe 100644 (file)
@@ -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(
index 5b564eb4dc2b12d0ba7a7e84e7dfa8ae0ae00f19..b72ec48afe23528afa163a2dd34dc3c90d30b2be 100644 (file)
@@ -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
index 8e1470e153199714e0d41ae4b4b6c26e9623d6f0..6a0517a2228da82145343aa6a3d05373fc791f14 100644 (file)
@@ -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
index e53bd979763b97510f188910606726b8371392a7..853d9f241d83751753c998581392389e1062375d 100644 (file)
@@ -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
index cc9e139c034d0dd7987f9f5e026c40b5cbd18609..8b17d9b3546b5c797fc1c8df2fb7d064d2d99056 100644 (file)
@@ -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);