Mesa (main): vulkan/wsi: untangle buffer-images from prime
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Feb 22 10:54:58 UTC 2022
Module: Mesa
Branch: main
Commit: 25a37fabb7a3aa0aff9880ec172efafe6ad190d7
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=25a37fabb7a3aa0aff9880ec172efafe6ad190d7
Author: Erik Faye-Lund <kusmabite at gmail.com>
Date: Thu Feb 3 10:57:16 2022 +0100
vulkan/wsi: untangle buffer-images from prime
Not all Vulkan implementations allows rendering to linear images, so in
order to support scanning out from these on Windows we might have to copy
through a buffer like we do in the PRIME path.
To avoid reimplementing the same, let's instead generalize the code a
bit so it doesn't have to specfy any PRIME-specific details.
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12210>
---
src/amd/vulkan/radv_image.c | 2 +-
src/amd/vulkan/radv_wsi.c | 2 +-
src/broadcom/vulkan/v3dv_image.c | 2 +-
src/virtio/vulkan/vn_wsi.c | 2 +-
src/vulkan/wsi/wsi_common.c | 246 +++++++++++++++++++++++++++++++-----
src/vulkan/wsi/wsi_common.h | 8 +-
src/vulkan/wsi/wsi_common_drm.c | 170 ++++---------------------
src/vulkan/wsi/wsi_common_private.h | 41 ++++--
src/vulkan/wsi/wsi_common_x11.c | 8 +-
9 files changed, 279 insertions(+), 202 deletions(-)
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,
More information about the mesa-commit
mailing list