diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c index 8c0d68a1e76..5ac8ab2c12f 100644 --- a/src/broadcom/vulkan/v3dv_cmd_buffer.c +++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c @@ -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; diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c index 37988d11e5c..fdc64008aeb 100644 --- a/src/broadcom/vulkan/v3dv_meta_copy.c +++ b/src/broadcom/vulkan/v3dv_meta_copy.c @@ -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, diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 46413a7d079..ec786d70df0 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -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 {