vulkan/wsi/drm: Break create_prime_image in pieces

This is similar to the previous two commits that we did for DRM native
images.  It breaks it into configure/create/bind/finish and calls
wsi_create_image to walk through the process.  The primary difference is
that prime images need fifth step in the process to set up the blit
command buffer.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12031>
This commit is contained in:
Jason Ekstrand
2021-07-22 18:24:02 -05:00
committed by Marge Bot
parent 830d9967db
commit 579578f10a
3 changed files with 110 additions and 89 deletions

View File

@@ -402,7 +402,6 @@ wsi_configure_image(const struct wsi_swapchain *chain,
info->wsi = (struct wsi_image_create_info) {
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
.scanout = true,
};
__vk_append_struct(&info->create, &info->wsi);
@@ -482,6 +481,12 @@ wsi_create_image(const struct wsi_swapchain *chain,
if (result != VK_SUCCESS)
goto fail;
if (info->finish_create) {
result = info->finish_create(chain, info, image);
if (result != VK_SUCCESS)
goto fail;
}
return VK_SUCCESS;
fail:

View File

@@ -454,22 +454,15 @@ align_u32(uint32_t v, uint32_t a)
#define WSI_PRIME_LINEAR_STRIDE_ALIGN 256
VkResult
wsi_create_prime_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
bool use_modifier,
struct wsi_image *image)
static VkResult
wsi_create_prime_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result;
memset(image, 0, sizeof(*image));
const uint32_t cpp = vk_format_size(pCreateInfo->imageFormat);
const uint32_t linear_stride = align_u32(pCreateInfo->imageExtent.width * cpp,
WSI_PRIME_LINEAR_STRIDE_ALIGN);
uint32_t linear_size = linear_stride * pCreateInfo->imageExtent.height;
uint32_t linear_size = info->linear_stride * info->create.extent.height;
linear_size = align_u32(linear_size, 4096);
const VkExternalMemoryBufferCreateInfo prime_buffer_external_info = {
@@ -487,7 +480,7 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
result = wsi->CreateBuffer(chain->device, &prime_buffer_info,
&chain->alloc, &image->prime.buffer);
if (result != VK_SUCCESS)
goto fail;
return result;
VkMemoryRequirements reqs;
wsi->GetBufferMemoryRequirements(chain->device, image->prime.buffer, &reqs);
@@ -518,46 +511,12 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
result = wsi->AllocateMemory(chain->device, &prime_memory_info,
&chain->alloc, &image->prime.memory);
if (result != VK_SUCCESS)
goto fail;
return result;
result = wsi->BindBufferMemory(chain->device, image->prime.buffer,
image->prime.memory, 0);
if (result != VK_SUCCESS)
goto fail;
const struct wsi_image_create_info image_wsi_info = {
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
.prime_blit_src = true,
};
VkImageCreateInfo image_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.pNext = &image_wsi_info,
.flags = 0,
.imageType = VK_IMAGE_TYPE_2D,
.format = pCreateInfo->imageFormat,
.extent = {
.width = pCreateInfo->imageExtent.width,
.height = pCreateInfo->imageExtent.height,
.depth = 1,
},
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = pCreateInfo->imageUsage | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
.sharingMode = pCreateInfo->imageSharingMode,
.queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount,
.pQueueFamilyIndices = pCreateInfo->pQueueFamilyIndices,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) {
image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR;
}
result = wsi->CreateImage(chain->device, &image_info,
&chain->alloc, &image->image);
if (result != VK_SUCCESS)
goto fail;
return result;
wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
@@ -576,21 +535,44 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
result = wsi->AllocateMemory(chain->device, &memory_info,
&chain->alloc, &image->memory);
if (result != VK_SUCCESS)
goto fail;
return result;
result = wsi->BindImageMemory(chain->device, image->image,
image->memory, 0);
const VkMemoryGetFdInfoKHR linear_memory_get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.pNext = NULL,
.memory = image->prime.memory,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
int fd;
result = wsi->GetMemoryFdKHR(chain->device, &linear_memory_get_fd_info, &fd);
if (result != VK_SUCCESS)
goto fail;
return result;
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) {
result = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
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++) {
@@ -604,7 +586,7 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info,
&image->prime.blit_cmd_buffers[i]);
if (result != VK_SUCCESS)
goto fail;
return result;
const VkCommandBufferBeginInfo begin_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
@@ -613,7 +595,8 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
struct VkBufferImageCopy buffer_image_copy = {
.bufferOffset = 0,
.bufferRowLength = linear_stride / cpp,
.bufferRowLength = info->linear_stride /
vk_format_size(info->create.format),
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
@@ -622,11 +605,7 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
.layerCount = 1,
},
.imageOffset = { .x = 0, .y = 0, .z = 0 },
.imageExtent = {
.width = pCreateInfo->imageExtent.width,
.height = pCreateInfo->imageExtent.height,
.depth = 1,
},
.imageExtent = info->create.extent,
};
wsi->CmdCopyImageToBuffer(image->prime.blit_cmd_buffers[i],
image->image,
@@ -636,32 +615,55 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
result = wsi->EndCommandBuffer(image->prime.blit_cmd_buffers[i]);
if (result != VK_SUCCESS)
goto fail;
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);
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_size(info->create.format);
info->linear_stride = align_u32(info->create.extent.width * cpp,
WSI_PRIME_LINEAR_STRIDE_ALIGN);
info->create_mem = wsi_create_prime_image_mem;
info->finish_create = wsi_finish_create_prime_image;
return VK_SUCCESS;
}
VkResult
wsi_create_prime_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
bool use_modifier,
struct wsi_image *image)
{
struct wsi_image_info info;
VkResult result = wsi_configure_prime_image(chain, pCreateInfo,
use_modifier, &info);
if (result != VK_SUCCESS)
return result;
result = wsi_create_image(chain, &info, image);
if (result != VK_SUCCESS) {
wsi_destroy_image_info(chain, &info);
return result;
}
const VkMemoryGetFdInfoKHR linear_memory_get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.pNext = NULL,
.memory = image->prime.memory,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
int fd;
result = wsi->GetMemoryFdKHR(chain->device, &linear_memory_get_fd_info, &fd);
if (result != VK_SUCCESS)
goto fail;
image->drm_modifier = use_modifier ? DRM_FORMAT_MOD_LINEAR : DRM_FORMAT_MOD_INVALID;
image->num_planes = 1;
image->sizes[0] = linear_size;
image->row_pitches[0] = linear_stride;
image->offsets[0] = 0;
image->fds[0] = fd;
return VK_SUCCESS;
fail:
wsi_destroy_image(chain, image);
return result;
}

View File

@@ -36,17 +36,26 @@ struct wsi_image_info {
VkImageFormatListCreateInfoKHR format_list;
VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list;
bool prime_use_linear_modifier;
/* Not really part of VkImageCreateInfo but needed to figure out the
* number of planes we need to bind.
*/
uint32_t modifier_prop_count;
struct VkDrmFormatModifierPropertiesEXT *modifier_props;
/* For prime blit images, the linear stride in bytes */
uint32_t linear_stride;
uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size);
VkResult (*create_mem)(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image);
VkResult (*finish_create)(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image);
};
struct wsi_image {
@@ -139,6 +148,11 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
struct wsi_image *image);
VkResult
wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
bool use_modifier,
struct wsi_image_info *info);
VkResult
wsi_create_prime_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
bool use_modifier,