diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 712dfe3c81b..c90f016e755 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -2327,7 +2327,7 @@ 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; + bool prime_blit_src = wsi_info && wsi_info->buffer_blit_src; return radv_image_create(device, &(struct radv_image_create_info){ diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index 9793653b326..57743ac0e2c 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -95,7 +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.get_buffer_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; diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index e0ee210afa4..cb0880370ff 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -257,7 +257,7 @@ create_image(struct v3dv_device *device, /* When using the simulator the WSI common code will see that our * driver wsi device doesn't match the display device and because of that * it will not attempt to present directly from the swapchain images, - * instead it will use the prime blit path (use_prime_blit flag in + * instead it will use the prime blit path (use_buffer_blit flag in * struct wsi_swapchain), where it copies the contents of the swapchain * images to a linear buffer with appropriate row stride for presentation. * As a result, on that path, swapchain images do not have any special diff --git a/src/virtio/vulkan/vn_wsi.c b/src/virtio/vulkan/vn_wsi.c index 7419b587ea8..7f0ed9dbc37 100644 --- a/src/virtio/vulkan/vn_wsi.c +++ b/src/virtio/vulkan/vn_wsi.c @@ -133,7 +133,7 @@ vn_wsi_create_image(struct vn_device *dev, return result; img->wsi.is_wsi = true; - img->wsi.is_prime_blit_src = wsi_info->prime_blit_src; + img->wsi.is_prime_blit_src = wsi_info->buffer_blit_src; img->wsi.tiling_override = create_info->tiling; if (create_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index ecd4a4b3b54..e755d76d3bb 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -28,6 +28,7 @@ #include "util/xmlconfig.h" #include "vk_device.h" #include "vk_fence.h" +#include "vk_format.h" #include "vk_instance.h" #include "vk_physical_device.h" #include "vk_queue.h" @@ -223,7 +224,7 @@ wsi_swapchain_init(const struct wsi_device *wsi, VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, - bool use_prime_blit) + bool use_buffer_blit) { VkResult result; @@ -234,12 +235,12 @@ wsi_swapchain_init(const struct wsi_device *wsi, chain->wsi = wsi; chain->device = device; chain->alloc = *pAllocator; - chain->use_prime_blit = use_prime_blit; - chain->prime_blit_queue = VK_NULL_HANDLE; - if (use_prime_blit && wsi->get_prime_blit_queue) - chain->prime_blit_queue = wsi->get_prime_blit_queue(device); + chain->use_buffer_blit = use_buffer_blit; + chain->buffer_blit_queue = VK_NULL_HANDLE; + if (use_buffer_blit && wsi->get_buffer_blit_queue) + chain->buffer_blit_queue = wsi->get_buffer_blit_queue(device); - int cmd_pools_count = chain->prime_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; + int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; chain->cmd_pools = vk_zalloc(pAllocator, sizeof(VkCommandPool) * cmd_pools_count, 8, @@ -250,8 +251,8 @@ wsi_swapchain_init(const struct wsi_device *wsi, for (uint32_t i = 0; i < cmd_pools_count; i++) { int queue_family_index = i; - if (chain->prime_blit_queue != VK_NULL_HANDLE) { - VK_FROM_HANDLE(vk_queue, queue, chain->prime_blit_queue); + if (chain->buffer_blit_queue != VK_NULL_HANDLE) { + VK_FROM_HANDLE(vk_queue, queue, chain->buffer_blit_queue); queue_family_index = queue->queue_family_index; } const VkCommandPoolCreateInfo cmd_pool_info = { @@ -335,14 +336,14 @@ wsi_swapchain_finish(struct wsi_swapchain *chain) vk_free(&chain->alloc, chain->fences); } - if (chain->prime_blit_semaphores) { + if (chain->buffer_blit_semaphores) { for (unsigned i = 0; i < chain->image_count; i++) - chain->wsi->DestroySemaphore(chain->device, chain->prime_blit_semaphores[i], &chain->alloc); + chain->wsi->DestroySemaphore(chain->device, chain->buffer_blit_semaphores[i], &chain->alloc); - vk_free(&chain->alloc, chain->prime_blit_semaphores); + vk_free(&chain->alloc, chain->buffer_blit_semaphores); } - int cmd_pools_count = chain->prime_blit_queue != VK_NULL_HANDLE ? + int cmd_pools_count = chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : chain->wsi->queue_family_count; for (uint32_t i = 0; i < cmd_pools_count; i++) { chain->wsi->DestroyCommandPool(chain->device, chain->cmd_pools[i], @@ -500,18 +501,18 @@ wsi_destroy_image(const struct wsi_swapchain *chain, { const struct wsi_device *wsi = chain->wsi; - if (image->prime.blit_cmd_buffers) { + if (image->buffer.blit_cmd_buffers) { for (uint32_t i = 0; i < wsi->queue_family_count; i++) { wsi->FreeCommandBuffers(chain->device, chain->cmd_pools[i], - 1, &image->prime.blit_cmd_buffers[i]); + 1, &image->buffer.blit_cmd_buffers[i]); } - vk_free(&chain->alloc, image->prime.blit_cmd_buffers); + vk_free(&chain->alloc, image->buffer.blit_cmd_buffers); } wsi->FreeMemory(chain->device, image->memory, &chain->alloc); wsi->DestroyImage(chain->device, image->image, &chain->alloc); - wsi->FreeMemory(chain->device, image->prime.memory, &chain->alloc); - wsi->DestroyBuffer(chain->device, image->prime.buffer, &chain->alloc); + wsi->FreeMemory(chain->device, image->buffer.memory, &chain->alloc); + wsi->DestroyBuffer(chain->device, image->buffer.buffer, &chain->alloc); } VKAPI_ATTR VkResult VKAPI_CALL @@ -707,12 +708,12 @@ wsi_CreateSwapchainKHR(VkDevice _device, return VK_ERROR_OUT_OF_HOST_MEMORY; } - if (swapchain->prime_blit_queue != VK_NULL_HANDLE) { - swapchain->prime_blit_semaphores = vk_zalloc(alloc, - sizeof (*swapchain->prime_blit_semaphores) * swapchain->image_count, - sizeof (*swapchain->prime_blit_semaphores), + if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) { + swapchain->buffer_blit_semaphores = vk_zalloc(alloc, + sizeof (*swapchain->buffer_blit_semaphores) * swapchain->image_count, + sizeof (*swapchain->buffer_blit_semaphores), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!swapchain->prime_blit_semaphores) { + if (!swapchain->buffer_blit_semaphores) { swapchain->destroy(swapchain, alloc); return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -894,7 +895,7 @@ wsi_common_queue_present(const struct wsi_device *wsi, if (result != VK_SUCCESS) goto fail_present; - if (swapchain->use_prime_blit && swapchain->prime_blit_queue != VK_NULL_HANDLE) { + if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) { const VkSemaphoreCreateInfo sem_info = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .pNext = NULL, @@ -902,7 +903,7 @@ wsi_common_queue_present(const struct wsi_device *wsi, }; result = wsi->CreateSemaphore(device, &sem_info, &swapchain->alloc, - &swapchain->prime_blit_semaphores[image_index]); + &swapchain->buffer_blit_semaphores[image_index]); if (result != VK_SUCCESS) goto fail_present; } @@ -958,22 +959,22 @@ wsi_common_queue_present(const struct wsi_device *wsi, } VkFence fence = swapchain->fences[image_index]; - if (swapchain->use_prime_blit) { - if (swapchain->prime_blit_queue == VK_NULL_HANDLE) { - /* If we are using default prime blits, we need to perform the blit now. The + if (swapchain->use_buffer_blit) { + if (swapchain->buffer_blit_queue == VK_NULL_HANDLE) { + /* If we are using default buffer blits, we need to perform the blit now. The * command buffer is attached to the image. */ submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = - &image->prime.blit_cmd_buffers[queue_family_index]; - mem_signal.memory = image->prime.memory; + &image->buffer.blit_cmd_buffers[queue_family_index]; + mem_signal.memory = image->buffer.memory; } else { /* If we are using a blit using the driver's private queue, then do an empty * submit signalling a semaphore, and then submit the blit. */ fence = VK_NULL_HANDLE; submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = &swapchain->prime_blit_semaphores[image_index]; + submit_info.pSignalSemaphores = &swapchain->buffer_blit_semaphores[image_index]; } } @@ -982,22 +983,22 @@ wsi_common_queue_present(const struct wsi_device *wsi, if (result != VK_SUCCESS) goto fail_present; - if (swapchain->use_prime_blit && swapchain->prime_blit_queue != VK_NULL_HANDLE) { + if (swapchain->use_buffer_blit && swapchain->buffer_blit_queue != VK_NULL_HANDLE) { submit_info.commandBufferCount = 1; - if (swapchain->prime_blit_queue != VK_NULL_HANDLE) { - submit_info.pCommandBuffers = &image->prime.blit_cmd_buffers[0]; + if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) { + submit_info.pCommandBuffers = &image->buffer.blit_cmd_buffers[0]; submit_info.waitSemaphoreCount = 1; submit_info.pWaitSemaphores = submit_info.pSignalSemaphores; submit_info.signalSemaphoreCount = 0; submit_info.pSignalSemaphores = NULL; /* Submit the copy to the private transfer queue */ - result = wsi->QueueSubmit(swapchain->prime_blit_queue, + result = wsi->QueueSubmit(swapchain->buffer_blit_queue, 1, &submit_info, swapchain->fences[image_index]); } - mem_signal.memory = image->prime.memory; + mem_signal.memory = image->buffer.memory; } if (wsi->sw) @@ -1130,3 +1131,178 @@ wsi_common_bind_swapchain_image(const struct wsi_device *wsi, return wsi->BindImageMemory(chain->device, vk_image, image->memory, 0); } + +VkResult +wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image, + VkExternalMemoryHandleTypeFlags handle_types, + bool implicit_sync) +{ + const struct wsi_device *wsi = chain->wsi; + VkResult result; + + uint32_t linear_size = info->linear_stride * info->create.extent.height; + linear_size = ALIGN_POT(linear_size, info->size_align); + + const VkExternalMemoryBufferCreateInfo buffer_external_info = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + .pNext = NULL, + .handleTypes = handle_types, + }; + const VkBufferCreateInfo buffer_info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = &buffer_external_info, + .size = linear_size, + .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + result = wsi->CreateBuffer(chain->device, &buffer_info, + &chain->alloc, &image->buffer.buffer); + if (result != VK_SUCCESS) + return result; + + VkMemoryRequirements reqs; + wsi->GetBufferMemoryRequirements(chain->device, image->buffer.buffer, &reqs); + assert(reqs.size <= linear_size); + + const struct wsi_memory_allocate_info memory_wsi_info = { + .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA, + .pNext = NULL, + .implicit_sync = implicit_sync, + }; + const VkExportMemoryAllocateInfo memory_export_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + .pNext = &memory_wsi_info, + .handleTypes = handle_types, + }; + const VkMemoryDedicatedAllocateInfo buf_mem_dedicated_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = &memory_export_info, + .image = VK_NULL_HANDLE, + .buffer = image->buffer.buffer, + }; + const VkMemoryAllocateInfo buf_mem_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = &buf_mem_dedicated_info, + .allocationSize = linear_size, + .memoryTypeIndex = + info->select_buffer_memory_type(wsi, reqs.memoryTypeBits), + }; + result = wsi->AllocateMemory(chain->device, &buf_mem_info, + &chain->alloc, &image->buffer.memory); + if (result != VK_SUCCESS) + return result; + + result = wsi->BindBufferMemory(chain->device, image->buffer.buffer, + image->buffer.memory, 0); + if (result != VK_SUCCESS) + return result; + + wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); + + const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = NULL, + .image = image->image, + .buffer = VK_NULL_HANDLE, + }; + const VkMemoryAllocateInfo memory_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = &memory_dedicated_info, + .allocationSize = reqs.size, + .memoryTypeIndex = + info->select_image_memory_type(wsi, reqs.memoryTypeBits), + }; + + result = wsi->AllocateMemory(chain->device, &memory_info, + &chain->alloc, &image->memory); + if (result != VK_SUCCESS) + return result; + + image->num_planes = 1; + image->sizes[0] = linear_size; + image->row_pitches[0] = info->linear_stride; + image->offsets[0] = 0; + + return VK_SUCCESS; +} + +VkResult +wsi_finish_create_buffer_image(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image) +{ + const struct wsi_device *wsi = chain->wsi; + VkResult result; + + int cmd_buffer_count = + chain->buffer_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; + image->buffer.blit_cmd_buffers = + vk_zalloc(&chain->alloc, + sizeof(VkCommandBuffer) * cmd_buffer_count, 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!image->buffer.blit_cmd_buffers) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + for (uint32_t i = 0; i < cmd_buffer_count; i++) { + const VkCommandBufferAllocateInfo cmd_buffer_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = NULL, + .commandPool = chain->cmd_pools[i], + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info, + &image->buffer.blit_cmd_buffers[i]); + if (result != VK_SUCCESS) + return result; + + const VkCommandBufferBeginInfo begin_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + }; + wsi->BeginCommandBuffer(image->buffer.blit_cmd_buffers[i], &begin_info); + struct VkBufferImageCopy buffer_image_copy = { + .bufferOffset = 0, + .bufferRowLength = info->linear_stride / + vk_format_get_blocksize(info->create.format), + .bufferImageHeight = 0, + .imageSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .imageOffset = { .x = 0, .y = 0, .z = 0 }, + .imageExtent = info->create.extent, + }; + wsi->CmdCopyImageToBuffer(image->buffer.blit_cmd_buffers[i], + image->image, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + image->buffer.buffer, + 1, &buffer_image_copy); + + result = wsi->EndCommandBuffer(image->buffer.blit_cmd_buffers[i]); + if (result != VK_SUCCESS) + return result; + } + + return VK_SUCCESS; +} + +VkResult +wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + struct wsi_image_info *info) +{ + VkResult result = wsi_configure_image(chain, pCreateInfo, + 0 /* handle_types */, info); + if (result != VK_SUCCESS) + return result; + + info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + info->wsi.buffer_blit_src = true; + info->finish_create = wsi_finish_create_buffer_image; + + return VK_SUCCESS; +} diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 696f6b40bac..52411a0a604 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -60,8 +60,8 @@ struct wsi_image_create_info { const void *pNext; bool scanout; - /* if true, the image is a prime blit source */ - bool prime_blit_src; + /* if true, the image is a buffer blit source */ + bool buffer_blit_src; }; struct wsi_memory_allocate_info { @@ -176,9 +176,9 @@ struct wsi_device { /* * A driver can implement this callback to return a special queue to execute - * prime blits. + * buffer blits. */ - VkQueue (*get_prime_blit_queue)(VkDevice device); + VkQueue (*get_buffer_blit_queue)(VkDevice device); #define WSI_CB(cb) PFN_vk##cb cb WSI_CB(AllocateMemory); diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c index 8982ba225f2..72af5b2c820 100644 --- a/src/vulkan/wsi/wsi_common_drm.c +++ b/src/vulkan/wsi/wsi_common_drm.c @@ -115,6 +115,20 @@ select_memory_type(const struct wsi_device *wsi, unreachable("No memory type found"); } +static uint32_t +prime_select_buffer_memory_type(const struct wsi_device *wsi, + uint32_t type_bits) +{ + return select_memory_type(wsi, false, type_bits); +} + +static uint32_t +prime_select_image_memory_type(const struct wsi_device *wsi, + uint32_t type_bits) +{ + return select_memory_type(wsi, true, type_bits); +} + static const struct VkDrmFormatModifierPropertiesEXT * get_modifier_props(const struct wsi_image_info *info, uint64_t modifier) { @@ -416,87 +430,17 @@ wsi_create_prime_image_mem(const struct wsi_swapchain *chain, struct wsi_image *image) { const struct wsi_device *wsi = chain->wsi; - VkResult result; - - uint32_t linear_size = info->linear_stride * info->create.extent.height; - linear_size = ALIGN_POT(linear_size, 4096); - - const VkExternalMemoryBufferCreateInfo prime_buffer_external_info = { - .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, - .pNext = NULL, - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - }; - const VkBufferCreateInfo prime_buffer_info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = &prime_buffer_external_info, - .size = linear_size, - .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - result = wsi->CreateBuffer(chain->device, &prime_buffer_info, - &chain->alloc, &image->prime.buffer); - if (result != VK_SUCCESS) - return result; - - VkMemoryRequirements reqs; - wsi->GetBufferMemoryRequirements(chain->device, image->prime.buffer, &reqs); - assert(reqs.size <= linear_size); - - const struct wsi_memory_allocate_info memory_wsi_info = { - .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA, - .pNext = NULL, - .implicit_sync = true, - }; - const VkExportMemoryAllocateInfo prime_memory_export_info = { - .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, - .pNext = &memory_wsi_info, - .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, - }; - const VkMemoryDedicatedAllocateInfo prime_memory_dedicated_info = { - .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, - .pNext = &prime_memory_export_info, - .image = VK_NULL_HANDLE, - .buffer = image->prime.buffer, - }; - const VkMemoryAllocateInfo prime_memory_info = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = &prime_memory_dedicated_info, - .allocationSize = linear_size, - .memoryTypeIndex = select_memory_type(wsi, false, reqs.memoryTypeBits), - }; - result = wsi->AllocateMemory(chain->device, &prime_memory_info, - &chain->alloc, &image->prime.memory); - if (result != VK_SUCCESS) - return result; - - result = wsi->BindBufferMemory(chain->device, image->prime.buffer, - image->prime.memory, 0); - if (result != VK_SUCCESS) - return result; - - wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); - - const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { - .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, - .pNext = NULL, - .image = image->image, - .buffer = VK_NULL_HANDLE, - }; - const VkMemoryAllocateInfo memory_info = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = &memory_dedicated_info, - .allocationSize = reqs.size, - .memoryTypeIndex = select_memory_type(wsi, true, reqs.memoryTypeBits), - }; - result = wsi->AllocateMemory(chain->device, &memory_info, - &chain->alloc, &image->memory); + VkResult result = + wsi_create_buffer_image_mem(chain, info, image, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + true); if (result != VK_SUCCESS) return result; const VkMemoryGetFdInfoKHR linear_memory_get_fd_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, .pNext = NULL, - .memory = image->prime.memory, + .memory = image->buffer.memory, .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, }; int fd; @@ -506,98 +450,32 @@ wsi_create_prime_image_mem(const struct wsi_swapchain *chain, image->drm_modifier = info->prime_use_linear_modifier ? DRM_FORMAT_MOD_LINEAR : DRM_FORMAT_MOD_INVALID; - image->num_planes = 1; - image->sizes[0] = linear_size; - image->row_pitches[0] = info->linear_stride; - image->offsets[0] = 0; image->fds[0] = fd; return VK_SUCCESS; } -static VkResult -wsi_finish_create_prime_image(const struct wsi_swapchain *chain, - const struct wsi_image_info *info, - struct wsi_image *image) -{ - const struct wsi_device *wsi = chain->wsi; - VkResult result; - - image->prime.blit_cmd_buffers = - vk_zalloc(&chain->alloc, - sizeof(VkCommandBuffer) * wsi->queue_family_count, 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (!image->prime.blit_cmd_buffers) - return VK_ERROR_OUT_OF_HOST_MEMORY; - - int cmd_buffer_count = chain->prime_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count; - for (uint32_t i = 0; i < cmd_buffer_count; i++) { - const VkCommandBufferAllocateInfo cmd_buffer_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .pNext = NULL, - .commandPool = chain->cmd_pools[i], - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = 1, - }; - result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info, - &image->prime.blit_cmd_buffers[i]); - if (result != VK_SUCCESS) - return result; - - const VkCommandBufferBeginInfo begin_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - }; - wsi->BeginCommandBuffer(image->prime.blit_cmd_buffers[i], &begin_info); - - struct VkBufferImageCopy buffer_image_copy = { - .bufferOffset = 0, - .bufferRowLength = info->linear_stride / - vk_format_get_blocksize(info->create.format), - .bufferImageHeight = 0, - .imageSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }, - .imageOffset = { .x = 0, .y = 0, .z = 0 }, - .imageExtent = info->create.extent, - }; - wsi->CmdCopyImageToBuffer(image->prime.blit_cmd_buffers[i], - image->image, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - image->prime.buffer, - 1, &buffer_image_copy); - - result = wsi->EndCommandBuffer(image->prime.blit_cmd_buffers[i]); - if (result != VK_SUCCESS) - return result; - } - - return VK_SUCCESS; -} - VkResult wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, bool use_modifier, struct wsi_image_info *info) { - VkResult result = wsi_configure_image(chain, pCreateInfo, - 0 /* handle_types */, info); + VkResult result = + wsi_configure_buffer_image(chain, pCreateInfo, info); if (result != VK_SUCCESS) return result; - info->create.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - info->wsi.prime_blit_src = true, info->prime_use_linear_modifier = use_modifier; const uint32_t cpp = vk_format_get_blocksize(info->create.format); info->linear_stride = ALIGN_POT(info->create.extent.width * cpp, WSI_PRIME_LINEAR_STRIDE_ALIGN); + info->size_align = 4096; info->create_mem = wsi_create_prime_image_mem; - info->finish_create = wsi_finish_create_prime_image; + info->select_buffer_memory_type = prime_select_buffer_memory_type; + info->select_image_memory_type = prime_select_image_memory_type; return VK_SUCCESS; } diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index b41cd16a96a..af190ce501b 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -44,8 +44,14 @@ struct wsi_image_info { uint32_t modifier_prop_count; struct VkDrmFormatModifierPropertiesEXT *modifier_props; - /* For prime blit images, the linear stride in bytes */ + /* For buffer blit images, the linear stride in bytes */ uint32_t linear_stride; + uint32_t size_align; + + uint32_t (*select_image_memory_type)(const struct wsi_device *wsi, + uint32_t type_bits); + uint32_t (*select_buffer_memory_type)(const struct wsi_device *wsi, + uint32_t type_bits); uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size); @@ -66,7 +72,7 @@ struct wsi_image { VkBuffer buffer; VkDeviceMemory memory; VkCommandBuffer *blit_cmd_buffers; - } prime; + } buffer; uint64_t drm_modifier; int num_planes; @@ -84,20 +90,20 @@ struct wsi_swapchain { VkDevice device; VkAllocationCallbacks alloc; VkFence* fences; - VkSemaphore* prime_blit_semaphores; + VkSemaphore* buffer_blit_semaphores; VkPresentModeKHR present_mode; struct wsi_image_info image_info; uint32_t image_count; - bool use_prime_blit; + bool use_buffer_blit; - /* If the driver wants to use a special queue to execute the prime blit, - * it'll implement the wsi_device::get_prime_blit_queue callback. + /* If the driver wants to use a special queue to execute the buffer blit, + * it'll implement the wsi_device::get_buffer_blit_queue callback. * The created queue will be stored here and will be used to execute the - * prime blit instead of using the present queue. + * buffer blit instead of using the present queue. */ - VkQueue prime_blit_queue; + VkQueue buffer_blit_queue; /* Command pools, one per queue family */ VkCommandPool *cmd_pools; @@ -123,7 +129,7 @@ wsi_swapchain_init(const struct wsi_device *wsi, VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, - bool use_prime_blit); + bool use_buffer_blit); enum VkPresentModeKHR wsi_swapchain_get_present_mode(struct wsi_device *wsi, @@ -147,6 +153,23 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain, bool use_modifier, struct wsi_image_info *info); +VkResult +wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image, + VkExternalMemoryHandleTypeFlags handle_types, + bool implicit_sync); + +VkResult +wsi_finish_create_buffer_image(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image); + +VkResult +wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + struct wsi_image_info *info); + VkResult wsi_configure_image(const struct wsi_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 6faecb636bd..85a66a95dab 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -1858,13 +1858,13 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, /* When our local device is not compatible with the DRI3 device provided by * the X server we assume this is a PRIME system. */ - bool use_prime_blit = false; + bool use_buffer_blit = false; if (!wsi_device->sw) if (!wsi_x11_check_dri3_compatible(wsi_device, conn)) - use_prime_blit = true; + use_buffer_blit = true; result = wsi_swapchain_init(wsi_device, &chain->base, device, - pCreateInfo, pAllocator, use_prime_blit); + pCreateInfo, pAllocator, use_buffer_blit); if (result != VK_SUCCESS) goto fail_alloc; @@ -1957,7 +1957,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, modifiers, num_modifiers, &num_tranches, pAllocator); - if (chain->base.use_prime_blit) { + if (chain->base.use_buffer_blit) { bool use_modifier = num_tranches > 0; result = wsi_configure_prime_image(&chain->base, pCreateInfo, use_modifier,