diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 91ae1932def..3640f715ca1 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -2635,9 +2635,9 @@ radv_get_queue_global_priority(const VkDeviceQueueGlobalPriorityCreateInfoEXT *p } } -static int -radv_queue_init(struct radv_device *device, struct radv_queue *queue, - int idx, const VkDeviceQueueCreateInfo *create_info, +int +radv_queue_init(struct radv_device *device, struct radv_queue *queue, int idx, + const VkDeviceQueueCreateInfo *create_info, const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority) { queue->device = device; @@ -3105,6 +3105,7 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr goto fail; } } + device->private_sdma_queue = VK_NULL_HANDLE; device->pbb_allowed = device->physical_device->rad_info.chip_class >= GFX9 && !(device->instance->debug_flags & RADV_DEBUG_NOBINNING); @@ -3331,6 +3332,10 @@ radv_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator) if (device->queue_count[i]) vk_free(&device->vk.alloc, device->queues[i]); } + if (device->private_sdma_queue != VK_NULL_HANDLE) { + radv_queue_finish(device->private_sdma_queue); + vk_free(&device->vk.alloc, device->private_sdma_queue); + } for (unsigned i = 0; i < RADV_NUM_HW_CTX; i++) { if (device->hw_ctx[i]) diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 53d52d79de4..d74dc6a7bf3 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -531,6 +531,11 @@ radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image * image->info.surf_index = NULL; } + + if (create_info->prime_blit_src && device->physical_device->rad_info.chip_class == GFX9) { + /* Older SDMA hw can't handle DCC */ + image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC; + } } return VK_SUCCESS; } @@ -2310,11 +2315,13 @@ radv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, const struct wsi_image_create_info *wsi_info = vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA); bool scanout = wsi_info && wsi_info->scanout; + bool prime_blit_src = wsi_info && wsi_info->prime_blit_src; return radv_image_create(device, &(struct radv_image_create_info){ .vk_info = pCreateInfo, .scanout = scanout, + .prime_blit_src = prime_blit_src, }, pAllocator, pImage); } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index ff44ff28695..c49d4d2e449 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -858,6 +858,9 @@ struct radv_device { struct u_rwlock vs_prologs_lock; struct hash_table *vs_prologs; + /* Prime blit sdma queue */ + struct radv_queue *private_sdma_queue; + struct radv_shader_prolog *simple_vs_prologs[MAX_VERTEX_ATTRIBS]; struct radv_shader_prolog *instance_rate_vs_prologs[816]; }; @@ -2329,6 +2332,7 @@ struct radv_image_create_info { const VkImageCreateInfo *vk_info; bool scanout; bool no_metadata_planes; + bool prime_blit_src; const struct radeon_bo_metadata *bo_metadata; }; @@ -2541,6 +2545,10 @@ struct radv_query_pool { bool radv_queue_internal_submit(struct radv_queue *queue, struct radeon_cmdbuf *cs); +int radv_queue_init(struct radv_device *device, struct radv_queue *queue, int idx, + const VkDeviceQueueCreateInfo *create_info, + const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority); + void radv_set_descriptor_set(struct radv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point, struct radv_descriptor_set *set, unsigned idx); diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index d8bdde9faa7..9793653b326 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -24,6 +24,7 @@ */ #include "util/macros.h" +#include "radv_debug.h" #include "radv_meta.h" #include "radv_private.h" #include "vk_fence.h" @@ -49,6 +50,39 @@ radv_wsi_set_memory_ownership(VkDevice _device, VkDeviceMemory _mem, VkBool32 ow } } +static VkQueue +radv_wsi_get_prime_blit_queue(VkDevice _device) +{ + RADV_FROM_HANDLE(radv_device, device, _device); + + if (device->private_sdma_queue != VK_NULL_HANDLE) + return vk_queue_to_handle(&device->private_sdma_queue->vk); + + if (device->physical_device->rad_info.chip_class >= GFX9 && + !(device->physical_device->instance->debug_flags & RADV_DEBUG_NO_DMA_BLIT)) { + const VkDeviceQueueCreateInfo queue_create = { + .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + .queueFamilyIndex = RADV_QUEUE_TRANSFER, + .queueCount = 1, + }; + device->private_sdma_queue = vk_zalloc(&device->vk.alloc, sizeof(struct radv_queue), 8, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + + VkResult result = radv_queue_init(device, device->private_sdma_queue, 0, &queue_create, NULL); + if (result == VK_SUCCESS) { + /* Remove the queue from our queue list because it'll be cleared manually + * in radv_DestroyDevice. + */ + list_delinit(&device->private_sdma_queue->vk.link); + return vk_queue_to_handle(&device->private_sdma_queue->vk); + } else { + vk_free(&device->vk.alloc, device->private_sdma_queue); + device->private_sdma_queue = VK_NULL_HANDLE; + } + } + return VK_NULL_HANDLE; +} + VkResult radv_init_wsi(struct radv_physical_device *physical_device) { @@ -61,6 +95,7 @@ radv_init_wsi(struct radv_physical_device *physical_device) physical_device->wsi_device.supports_modifiers = physical_device->rad_info.chip_class >= GFX9; physical_device->wsi_device.set_memory_ownership = radv_wsi_set_memory_ownership; + physical_device->wsi_device.get_prime_blit_queue = radv_wsi_get_prime_blit_queue; physical_device->wsi_device.signal_semaphore_with_memory = true; physical_device->wsi_device.signal_fence_with_memory = true;