vk: Handle allocation failures in meta init paths

Fixes dEQP-VK.api.object_management.alloc_callback_fail.* failures.
This commit is contained in:
Kristian Høgsberg Kristensen 2016-01-03 22:43:47 -08:00
parent b2ad2a20b6
commit 5526c1782a
5 changed files with 134 additions and 37 deletions

View 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(

View 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

View 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);
VkResult result;
struct anv_meta_state *state = &device->meta_state;
device->meta_state.clear.stencil_only_pipeline =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT);
result =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT,
&state->clear.depth_only_pipeline);
if (result != VK_SUCCESS)
goto fail;
device->meta_state.clear.depthstencil_pipeline =
create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT);
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

View 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

View 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);