From 23aaa4e179f6b8eff72acd06647f053daa4d2043 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Mon, 30 Jan 2023 20:11:59 -0600 Subject: [PATCH] nvk: Add an nvk_queue_submit wrapper Instead of having the common queue code call into drm_nouveau code directly, add a wrapper layer. This gives us a place to put things like command buffer dumping. Importantly, we move calling `vk_queue_set_error()` to this layer because it may abort if the `VK_ABORT_ON_DEVICE_LOST` is set and we may want to dump before that happens. Part-of: --- src/nouveau/vulkan/nvk_queue.c | 31 +++++++++++++++++++++- src/nouveau/vulkan/nvk_queue.h | 2 +- src/nouveau/vulkan/nvk_queue_drm_nouveau.c | 11 +++----- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/nouveau/vulkan/nvk_queue.c b/src/nouveau/vulkan/nvk_queue.c index dd5a55e2842..14e0fbd0504 100644 --- a/src/nouveau/vulkan/nvk_queue.c +++ b/src/nouveau/vulkan/nvk_queue.c @@ -222,6 +222,30 @@ nvk_queue_state_update(struct nvk_device *dev, return VK_SUCCESS; } +static VkResult +nvk_queue_submit(struct vk_queue *vk_queue, + struct vk_queue_submit *submit) +{ + struct nvk_queue *queue = container_of(vk_queue, struct nvk_queue, vk); + struct nvk_device *dev = nvk_queue_device(queue); + VkResult result; + + if (vk_queue_is_lost(&queue->vk)) + return VK_ERROR_DEVICE_LOST; + + result = nvk_queue_state_update(dev, &queue->state); + if (result != VK_SUCCESS) { + return vk_queue_set_lost(&queue->vk, "Failed to update queue base " + "pointers pushbuf"); + } + + result = nvk_queue_submit_drm_nouveau(queue, submit); + if (result != VK_SUCCESS) + return vk_queue_set_lost(&queue->vk, "Submit failed"); + + return VK_SUCCESS; +} + VkResult nvk_queue_init(struct nvk_device *dev, struct nvk_queue *queue, const VkDeviceQueueCreateInfo *pCreateInfo, @@ -235,7 +259,7 @@ nvk_queue_init(struct nvk_device *dev, struct nvk_queue *queue, nvk_queue_state_init(&queue->state); - queue->vk.driver_submit = nvk_queue_submit_drm_nouveau; + queue->vk.driver_submit = nvk_queue_submit; void *empty_push_map; queue->empty_push = nouveau_ws_bo_new_mapped(dev->pdev->dev, 4096, 0, @@ -288,6 +312,9 @@ nvk_queue_submit_simple(struct nvk_queue *queue, struct nouveau_ws_bo *push_bo; VkResult result; + if (vk_queue_is_lost(&queue->vk)) + return VK_ERROR_DEVICE_LOST; + void *push_map; push_bo = nouveau_ws_bo_new_mapped(dev->pdev->dev, dw_count * 4, 0, NOUVEAU_WS_BO_GART | NOUVEAU_WS_BO_MAP, @@ -299,6 +326,8 @@ nvk_queue_submit_simple(struct nvk_queue *queue, result = nvk_queue_submit_simple_drm_nouveau(queue, push_bo, dw_count, extra_bo); + if (result != VK_SUCCESS) + result = vk_queue_set_lost(&queue->vk, "Submit failed"); nouveau_ws_bo_unmap(push_bo, push_map); nouveau_ws_bo_destroy(push_bo); diff --git a/src/nouveau/vulkan/nvk_queue.h b/src/nouveau/vulkan/nvk_queue.h index 5236f5c6308..953841087e3 100644 --- a/src/nouveau/vulkan/nvk_queue.h +++ b/src/nouveau/vulkan/nvk_queue.h @@ -67,7 +67,7 @@ VkResult nvk_queue_submit_simple_drm_nouveau(struct nvk_queue *queue, uint32_t push_dw_count, struct nouveau_ws_bo *extra_bo); -VkResult nvk_queue_submit_drm_nouveau(struct vk_queue *vkqueue, +VkResult nvk_queue_submit_drm_nouveau(struct nvk_queue *queue, struct vk_queue_submit *submit); #endif diff --git a/src/nouveau/vulkan/nvk_queue_drm_nouveau.c b/src/nouveau/vulkan/nvk_queue_drm_nouveau.c index aabc025792a..0f482bcc26e 100644 --- a/src/nouveau/vulkan/nvk_queue_drm_nouveau.c +++ b/src/nouveau/vulkan/nvk_queue_drm_nouveau.c @@ -90,8 +90,8 @@ push_submit(struct push_builder *pb, struct nvk_queue *queue) DRM_NOUVEAU_GEM_PUSHBUF, &pb->req, sizeof(pb->req)); if (ret != 0) { - return vk_queue_set_lost(&queue->vk, - "DRM_NOUVEAU_GEM_PUSHBUF failed: %m"); + return vk_errorf(queue, VK_ERROR_UNKNOWN, + "DRM_NOUVEAU_GEM_PUSHBUF failed: %m"); } return VK_SUCCESS; @@ -130,18 +130,13 @@ push_add_queue_state(struct push_builder *pb, struct nvk_queue_state *qs) } VkResult -nvk_queue_submit_drm_nouveau(struct vk_queue *vk_queue, +nvk_queue_submit_drm_nouveau(struct nvk_queue *queue, struct vk_queue_submit *submit) { - struct nvk_queue *queue = container_of(vk_queue, struct nvk_queue, vk); struct nvk_device *dev = nvk_queue_device(queue); struct push_builder pb; VkResult result; - result = nvk_queue_state_update(dev, &queue->state); - if (result != VK_SUCCESS) - return result; - push_builder_init(dev, &pb); for (uint32_t i = 0; i < submit->signal_count; i++) {