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:
committed by
Marge Bot
parent
e5adc33e80
commit
5cfc3b5cc9
@@ -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;
|
||||
|
||||
@@ -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, ®ion);
|
||||
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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user