v3dv: handle the case where we fail to allocate a new job gracefully

There are a handful of tests that simulate 'out of memory' situations
during swapchain image creation, and these can lead to failed job
allocations when the driver is running on the prime blit path, as that
involves creating a command buffer. The tests expect us to handle this
scenario gracefully and return an appropriate OOM error as a result.
This make sure we don't try to dereference a job if we failed to allocate
it so we don't crash and can return the OOM error gracefully in the
process.

Fixes:
dEQP-VK.wsi.xlib.swapchain.simulate_oom.*

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga
2020-03-12 11:59:04 +01:00
committed by Marge Bot
parent e5adc33e80
commit 5cfc3b5cc9
3 changed files with 31 additions and 3 deletions
+13 -3
View File
@@ -505,7 +505,14 @@ v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer,
struct v3dv_job *job = vk_zalloc(&cmd_buffer->device->alloc,
sizeof(struct v3dv_job), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
assert(job);
cmd_buffer->state.job = job;
if (!job) {
fprintf(stderr, "Error: failed to allocate CPU memory for job\n");
cmd_buffer->state.oom = true;
return NULL;
}
job->cmd_buffer = cmd_buffer;
@@ -532,8 +539,6 @@ v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer,
if (cmd_buffer->state.pass)
job->first_subpass = subpass_idx;
cmd_buffer->state.job = job;
return job;
}
@@ -1486,6 +1491,8 @@ subpass_start(struct v3dv_cmd_buffer *cmd_buffer, uint32_t subpass_idx)
* the new job.
*/
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, subpass_idx);
if (!job)
return;
state->subpass_idx = subpass_idx;
@@ -1551,6 +1558,9 @@ v3dv_EndCommandBuffer(VkCommandBuffer commandBuffer)
{
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
if (cmd_buffer->state.oom)
return VK_ERROR_OUT_OF_HOST_MEMORY;
cmd_buffer->status = V3DV_CMD_BUFFER_STATUS_EXECUTABLE;
struct v3dv_job *job = cmd_buffer->state.job;
+15
View File
@@ -644,6 +644,8 @@ copy_image_to_buffer_tlb(struct v3dv_cmd_buffer *cmd_buffer,
assert(num_layers > 0);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return;
v3dv_cmd_buffer_start_frame(cmd_buffer,
region->imageExtent.width,
@@ -785,6 +787,8 @@ copy_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
assert(num_layers > 0);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return;
v3dv_cmd_buffer_start_frame(cmd_buffer,
region->extent.width,
@@ -928,6 +932,8 @@ clear_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t height = u_minify(image->extent.height, level);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return;
v3dv_cmd_buffer_start_frame(cmd_buffer, width, height, 1,
1, internal_bpp);
@@ -1131,6 +1137,8 @@ copy_buffer(struct v3dv_cmd_buffer *cmd_buffer,
uint32_t dst_offset = region->dstOffset;
while (num_items > 0) {
job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return NULL;
uint32_t width, height;
framebuffer_size_for_pixel_count(num_items, &width, &height);
@@ -1209,6 +1217,8 @@ v3dv_CmdUpdateBuffer(VkCommandBuffer commandBuffer,
};
struct v3dv_job *copy_job =
copy_buffer(cmd_buffer, dst_buffer->mem->bo, src_bo, &region);
if (!copy_job)
return;
/* Make sure we add the BO to the list of extra BOs so it is not leaked.
* If the copy job was split into multiple jobs, we just bind it to the last
@@ -1299,6 +1309,8 @@ fill_buffer(struct v3dv_cmd_buffer *cmd_buffer,
while (num_items > 0) {
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return;
uint32_t width, height;
framebuffer_size_for_pixel_count(num_items, &width, &height);
@@ -1487,6 +1499,9 @@ copy_buffer_to_image_tlb(struct v3dv_cmd_buffer *cmd_buffer,
assert(num_layers > 0);
struct v3dv_job *job = v3dv_cmd_buffer_start_job(cmd_buffer, -1);
if (!job)
return;
v3dv_cmd_buffer_start_frame(cmd_buffer,
region->imageExtent.width,
region->imageExtent.height,
+3
View File
@@ -612,6 +612,9 @@ struct v3dv_cmd_buffer_state {
struct v3dv_vertex_binding vertex_bindings[MAX_VBS];
uint8_t index_size;
/* Used to flag OOM conditions during command buffer recording */
bool oom;
};
struct v3dv_descriptor {