diff --git a/src/nouveau/vulkan/nvk_device.c b/src/nouveau/vulkan/nvk_device.c index f64abc55fa1..e164b4921fa 100644 --- a/src/nouveau/vulkan/nvk_device.c +++ b/src/nouveau/vulkan/nvk_device.c @@ -166,11 +166,15 @@ nvk_CreateDevice(VkPhysicalDevice physicalDevice, dev->vk.command_buffer_ops = &nvk_cmd_buffer_ops; dev->pdev = pdev; + result = nvk_upload_queue_init(dev, &dev->upload); + if (result != VK_SUCCESS) + goto fail_ws_dev; + result = nvk_descriptor_table_init(dev, &dev->images, 8 * 4 /* tic entry size */, 1024, 1024 * 1024); if (result != VK_SUCCESS) - goto fail_ws_dev; + goto fail_upload; /* Reserve the descriptor at offset 0 to be the null descriptor */ uint32_t null_image[8] = { 0, }; @@ -268,6 +272,8 @@ fail_samplers: nvk_descriptor_table_finish(dev, &dev->samplers); fail_images: nvk_descriptor_table_finish(dev, &dev->images); +fail_upload: + nvk_upload_queue_finish(dev, &dev->upload); fail_ws_dev: nouveau_ws_device_destroy(dev->ws_dev); fail_init: @@ -293,11 +299,16 @@ nvk_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) nouveau_ws_bo_destroy(dev->vab_memory); nouveau_ws_bo_destroy(dev->zero_page); vk_device_finish(&dev->vk); + + /* Idle the upload queue before we tear down heaps */ + nvk_upload_queue_sync(dev, &dev->upload); + nvk_slm_area_finish(&dev->slm); nvk_heap_finish(dev, &dev->event_heap); nvk_heap_finish(dev, &dev->shader_heap); nvk_descriptor_table_finish(dev, &dev->samplers); nvk_descriptor_table_finish(dev, &dev->images); + nvk_upload_queue_finish(dev, &dev->upload); nouveau_ws_device_destroy(dev->ws_dev); vk_free(&dev->vk.alloc, dev); } diff --git a/src/nouveau/vulkan/nvk_device.h b/src/nouveau/vulkan/nvk_device.h index ae36d875837..91bda76b061 100644 --- a/src/nouveau/vulkan/nvk_device.h +++ b/src/nouveau/vulkan/nvk_device.h @@ -10,6 +10,7 @@ #include "nvk_descriptor_table.h" #include "nvk_heap.h" #include "nvk_queue.h" +#include "nvk_upload_queue.h" #include "vk_device.h" #include "vk_meta.h" #include "vk_queue.h" @@ -35,6 +36,8 @@ struct nvk_device { struct nouveau_ws_device *ws_dev; + struct nvk_upload_queue upload; + struct nvk_descriptor_table images; struct nvk_descriptor_table samplers; struct nvk_heap shader_heap; diff --git a/src/nouveau/vulkan/nvk_queue_drm_nouveau.c b/src/nouveau/vulkan/nvk_queue_drm_nouveau.c index 6ea7b2f5ac9..8881d51b3ae 100644 --- a/src/nouveau/vulkan/nvk_queue_drm_nouveau.c +++ b/src/nouveau/vulkan/nvk_queue_drm_nouveau.c @@ -65,19 +65,27 @@ push_builder_init(struct nvk_queue *queue, pb->is_vmbind = is_vmbind; } +static void +push_add_syncobj_wait(struct push_builder *pb, + uint32_t syncobj, + uint64_t wait_value) +{ + assert(pb->req.wait_count < NVK_PUSH_MAX_SYNCS); + pb->req_wait[pb->req.wait_count++] = (struct drm_nouveau_sync) { + .flags = wait_value ? DRM_NOUVEAU_SYNC_TIMELINE_SYNCOBJ : + DRM_NOUVEAU_SYNC_SYNCOBJ, + .handle = syncobj, + .timeline_value = wait_value, + }; +} + static void push_add_sync_wait(struct push_builder *pb, struct vk_sync_wait *wait) { - struct vk_drm_syncobj *sync = vk_sync_as_drm_syncobj(wait->sync); - assert(sync); - assert(pb->req.wait_count < NVK_PUSH_MAX_SYNCS); - pb->req_wait[pb->req.wait_count++] = (struct drm_nouveau_sync) { - .flags = wait->wait_value ? DRM_NOUVEAU_SYNC_TIMELINE_SYNCOBJ : - DRM_NOUVEAU_SYNC_SYNCOBJ, - .handle = sync->syncobj, - .timeline_value = wait->wait_value, - }; + struct vk_drm_syncobj *sync = vk_sync_as_drm_syncobj(wait->sync); + assert(sync != NULL); + push_add_syncobj_wait(pb, sync->syncobj, wait->wait_value); } static void @@ -363,12 +371,22 @@ nvk_queue_submit_drm_nouveau(struct nvk_queue *queue, struct vk_queue_submit *submit, bool sync) { + struct nvk_device *dev = nvk_queue_device(queue); struct push_builder pb; + VkResult result; + + uint64_t upload_time_point; + result = nvk_upload_queue_flush(dev, &dev->upload, &upload_time_point); + if (result != VK_SUCCESS) + return result; const bool is_vmbind = submit->buffer_bind_count > 0 || submit->image_opaque_bind_count > 0; push_builder_init(queue, &pb, is_vmbind); + if (!is_vmbind && upload_time_point > 0) + push_add_syncobj_wait(&pb, dev->upload.drm.syncobj, upload_time_point); + for (uint32_t i = 0; i < submit->wait_count; i++) push_add_sync_wait(&pb, &submit->waits[i]); @@ -395,7 +413,7 @@ nvk_queue_submit_drm_nouveau(struct nvk_queue *queue, continue; if (pb.req.push_count >= pb.max_push) { - VkResult result = push_submit(queue, &pb, sync); + result = push_submit(queue, &pb, sync); if (result != VK_SUCCESS) return result;