mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 00:40:10 +01:00
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:
parent
830d9967db
commit
579578f10a
3 changed files with 110 additions and 89 deletions
|
|
@ -402,7 +402,6 @@ wsi_configure_image(const struct wsi_swapchain *chain,
|
||||||
|
|
||||||
info->wsi = (struct wsi_image_create_info) {
|
info->wsi = (struct wsi_image_create_info) {
|
||||||
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
|
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
|
||||||
.scanout = true,
|
|
||||||
};
|
};
|
||||||
__vk_append_struct(&info->create, &info->wsi);
|
__vk_append_struct(&info->create, &info->wsi);
|
||||||
|
|
||||||
|
|
@ -482,6 +481,12 @@ wsi_create_image(const struct wsi_swapchain *chain,
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (info->finish_create) {
|
||||||
|
result = info->finish_create(chain, info, image);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
||||||
|
|
@ -454,22 +454,15 @@ align_u32(uint32_t v, uint32_t a)
|
||||||
|
|
||||||
#define WSI_PRIME_LINEAR_STRIDE_ALIGN 256
|
#define WSI_PRIME_LINEAR_STRIDE_ALIGN 256
|
||||||
|
|
||||||
VkResult
|
static VkResult
|
||||||
wsi_create_prime_image(const struct wsi_swapchain *chain,
|
wsi_create_prime_image_mem(const struct wsi_swapchain *chain,
|
||||||
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
const struct wsi_image_info *info,
|
||||||
bool use_modifier,
|
struct wsi_image *image)
|
||||||
struct wsi_image *image)
|
|
||||||
{
|
{
|
||||||
const struct wsi_device *wsi = chain->wsi;
|
const struct wsi_device *wsi = chain->wsi;
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
memset(image, 0, sizeof(*image));
|
uint32_t linear_size = info->linear_stride * info->create.extent.height;
|
||||||
|
|
||||||
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;
|
|
||||||
linear_size = align_u32(linear_size, 4096);
|
linear_size = align_u32(linear_size, 4096);
|
||||||
|
|
||||||
const VkExternalMemoryBufferCreateInfo prime_buffer_external_info = {
|
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,
|
result = wsi->CreateBuffer(chain->device, &prime_buffer_info,
|
||||||
&chain->alloc, &image->prime.buffer);
|
&chain->alloc, &image->prime.buffer);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
return result;
|
||||||
|
|
||||||
VkMemoryRequirements reqs;
|
VkMemoryRequirements reqs;
|
||||||
wsi->GetBufferMemoryRequirements(chain->device, image->prime.buffer, &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,
|
result = wsi->AllocateMemory(chain->device, &prime_memory_info,
|
||||||
&chain->alloc, &image->prime.memory);
|
&chain->alloc, &image->prime.memory);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
return result;
|
||||||
|
|
||||||
result = wsi->BindBufferMemory(chain->device, image->prime.buffer,
|
result = wsi->BindBufferMemory(chain->device, image->prime.buffer,
|
||||||
image->prime.memory, 0);
|
image->prime.memory, 0);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
return result;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs);
|
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,
|
result = wsi->AllocateMemory(chain->device, &memory_info,
|
||||||
&chain->alloc, &image->memory);
|
&chain->alloc, &image->memory);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
return result;
|
||||||
|
|
||||||
result = wsi->BindImageMemory(chain->device, image->image,
|
const VkMemoryGetFdInfoKHR linear_memory_get_fd_info = {
|
||||||
image->memory, 0);
|
.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)
|
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 =
|
image->prime.blit_cmd_buffers =
|
||||||
vk_zalloc(&chain->alloc,
|
vk_zalloc(&chain->alloc,
|
||||||
sizeof(VkCommandBuffer) * wsi->queue_family_count, 8,
|
sizeof(VkCommandBuffer) * wsi->queue_family_count, 8,
|
||||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||||
if (!image->prime.blit_cmd_buffers) {
|
if (!image->prime.blit_cmd_buffers)
|
||||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmd_buffer_count = chain->prime_blit_queue != VK_NULL_HANDLE ? 1 : wsi->queue_family_count;
|
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++) {
|
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,
|
result = wsi->AllocateCommandBuffers(chain->device, &cmd_buffer_info,
|
||||||
&image->prime.blit_cmd_buffers[i]);
|
&image->prime.blit_cmd_buffers[i]);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
goto fail;
|
return result;
|
||||||
|
|
||||||
const VkCommandBufferBeginInfo begin_info = {
|
const VkCommandBufferBeginInfo begin_info = {
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_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 = {
|
struct VkBufferImageCopy buffer_image_copy = {
|
||||||
.bufferOffset = 0,
|
.bufferOffset = 0,
|
||||||
.bufferRowLength = linear_stride / cpp,
|
.bufferRowLength = info->linear_stride /
|
||||||
|
vk_format_size(info->create.format),
|
||||||
.bufferImageHeight = 0,
|
.bufferImageHeight = 0,
|
||||||
.imageSubresource = {
|
.imageSubresource = {
|
||||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
|
@ -622,11 +605,7 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||||
.layerCount = 1,
|
.layerCount = 1,
|
||||||
},
|
},
|
||||||
.imageOffset = { .x = 0, .y = 0, .z = 0 },
|
.imageOffset = { .x = 0, .y = 0, .z = 0 },
|
||||||
.imageExtent = {
|
.imageExtent = info->create.extent,
|
||||||
.width = pCreateInfo->imageExtent.width,
|
|
||||||
.height = pCreateInfo->imageExtent.height,
|
|
||||||
.depth = 1,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
wsi->CmdCopyImageToBuffer(image->prime.blit_cmd_buffers[i],
|
wsi->CmdCopyImageToBuffer(image->prime.blit_cmd_buffers[i],
|
||||||
image->image,
|
image->image,
|
||||||
|
|
@ -636,32 +615,55 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||||
|
|
||||||
result = wsi->EndCommandBuffer(image->prime.blit_cmd_buffers[i]);
|
result = wsi->EndCommandBuffer(image->prime.blit_cmd_buffers[i]);
|
||||||
if (result != VK_SUCCESS)
|
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;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
fail:
|
|
||||||
wsi_destroy_image(chain, image);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,26 @@ struct wsi_image_info {
|
||||||
VkImageFormatListCreateInfoKHR format_list;
|
VkImageFormatListCreateInfoKHR format_list;
|
||||||
VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list;
|
VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list;
|
||||||
|
|
||||||
|
bool prime_use_linear_modifier;
|
||||||
|
|
||||||
/* Not really part of VkImageCreateInfo but needed to figure out the
|
/* Not really part of VkImageCreateInfo but needed to figure out the
|
||||||
* number of planes we need to bind.
|
* number of planes we need to bind.
|
||||||
*/
|
*/
|
||||||
uint32_t modifier_prop_count;
|
uint32_t modifier_prop_count;
|
||||||
struct VkDrmFormatModifierPropertiesEXT *modifier_props;
|
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);
|
uint8_t *(*alloc_shm)(struct wsi_image *image, unsigned size);
|
||||||
|
|
||||||
VkResult (*create_mem)(const struct wsi_swapchain *chain,
|
VkResult (*create_mem)(const struct wsi_swapchain *chain,
|
||||||
const struct wsi_image_info *info,
|
const struct wsi_image_info *info,
|
||||||
struct wsi_image *image);
|
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 {
|
struct wsi_image {
|
||||||
|
|
@ -139,6 +148,11 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||||
struct wsi_image *image);
|
struct wsi_image *image);
|
||||||
|
|
||||||
VkResult
|
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,
|
wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||||
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
||||||
bool use_modifier,
|
bool use_modifier,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue