[Mesa-dev] [RFC v2 21/22] RFC: vulkan/wsi: Add modifiers to WSI image creation
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Thu Aug 31 04:24:35 UTC 2017
From: Daniel Stone <daniels at collabora.com>
Allow the WSI to provide a set of modifiers to be used along with the
format.
For now, no winsys provides any modifier support. Add a fallback to the
previous default (X-tiling) inside ANV.
RADV remains somewhat broken in the presence of a winsys which will
suggest modifiers, but with a Vulkan driver which is not modifier-aware.
Currently none of the AMD tiling modes have modifier tokens defined, and
forcing to linear would be an unacceptable performance penalty. For now,
just stick our head in the sand.
---
src/amd/vulkan/radv_wsi.c | 9 ++++++++-
src/intel/vulkan/anv_wsi.c | 33 +++++++++++++++++++++++++++------
src/vulkan/wsi/wsi_common.h | 5 ++++-
src/vulkan/wsi/wsi_common_wayland.c | 6 +++++-
src/vulkan/wsi/wsi_common_x11.c | 15 ++++++++++++---
5 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index aa44b7d78a..2f62fda582 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -141,13 +141,15 @@ static VkResult
radv_wsi_image_create(VkDevice device_h,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks* pAllocator,
+ uint64_t *modifiers,
+ int num_modifiers,
bool needs_linear_copy,
bool linear,
VkImage *image_p,
VkDeviceMemory *memory_p,
uint32_t *size,
uint32_t *offset,
- uint32_t *row_pitch, int *fd_p)
+ uint32_t *row_pitch, int *fd_p, uint64_t *modifier)
{
VkResult result = VK_SUCCESS;
struct radeon_surf *surface;
@@ -156,6 +158,10 @@ radv_wsi_image_create(VkDevice device_h,
int fd;
RADV_FROM_HANDLE(radv_device, device, device_h);
+ /* FIXME: Square the circle. */
+ assert(!modifiers ||
+ (num_modifiers == 1 && modifiers[0] == DRM_FORMAT_MOD_LINEAR));
+
result = radv_image_create(device_h,
&(struct radv_image_create_info) {
.vk_info =
@@ -224,6 +230,7 @@ radv_wsi_image_create(VkDevice device_h,
*memory_p = memory_h;
*size = image->size;
*offset = image->offset;
+ *modifier = DRM_FORMAT_MOD_INVALID;
if (device->physical_device->rad_info.chip_class >= GFX9)
*row_pitch = surface->u.gfx9.surf_pitch * surface->bpe;
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 8f01f62e8a..88e2d7abc5 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -172,17 +172,38 @@ static VkResult
anv_wsi_image_create(VkDevice device_h,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks* pAllocator,
+ uint64_t *modifiers,
+ int num_modifiers,
bool different_gpu,
bool linear,
VkImage *image_p,
VkDeviceMemory *memory_p,
uint32_t *size,
uint32_t *offset,
- uint32_t *row_pitch, int *fd_p)
+ uint32_t *row_pitch, int *fd_p, uint64_t *modifier)
{
struct anv_device *device = anv_device_from_handle(device_h);
VkImage image_h;
struct anv_image *image;
+ VkImageTiling vk_tiling = VK_IMAGE_TILING_LINEAR;
+ int i;
+
+ uint64_t modifiers_fallback[] = { I915_FORMAT_MOD_X_TILED };
+ if (num_modifiers == 0) {
+ modifiers = modifiers_fallback;
+ num_modifiers = ARRAY_SIZE(modifiers_fallback);
+ }
+
+ /* XXX: Retconning the VkImageTiling from modifiers is a bit hairy, because
+ * the actual ISL tiling/aux selection happens further down, which may
+ * filter the modes out and return linear even though we suggest a
+ * tiling mode. */
+ for (i = 0; i < num_modifiers; i++) {
+ enum isl_tiling t;
+ enum isl_aux_usage a;
+ if (isl_tiling_from_drm_format_mod(modifiers[i], &t, &a))
+ vk_tiling = VK_IMAGE_TILING_OPTIMAL;
+ }
VkResult result;
result = anv_CreateImage(anv_device_to_handle(device),
@@ -199,7 +220,7 @@ anv_wsi_image_create(VkDevice device_h,
.arrayLayers = 1,
.samples = 1,
/* FIXME: Need a way to use X tiling to allow scanout */
- .tiling = VK_IMAGE_TILING_OPTIMAL,
+ .tiling = vk_tiling,
.usage = (pCreateInfo->imageUsage |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
.flags = 0,
@@ -210,10 +231,8 @@ anv_wsi_image_create(VkDevice device_h,
.pNext =
&(VkExportImageDmaBufInfoMESAX) {
.sType = VK_STRUCTURE_TYPE_EXPORT_IMAGE_DMA_BUF_INFO_MESAX,
- .drmFormatModifierCount = 1,
- .pDrmFormatModifiers = (uint64_t[]) {
- I915_FORMAT_MOD_X_TILED,
- },
+ .drmFormatModifierCount = ARRAY_SIZE(modifiers),
+ .pDrmFormatModifiers = modifiers,
}}},
NULL,
&image_h);
@@ -273,6 +292,8 @@ anv_wsi_image_create(VkDevice device_h,
*fd_p = fd;
*size = image->size;
*offset = image->offset;
+ *modifier = isl_tiling_to_drm_format_mod(image->color_surface.isl.tiling,
+ image->aux_usage);
return VK_SUCCESS;
fail_alloc_memory:
anv_FreeMemory(device_h, memory_h, pAllocator);
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 8166b7dd34..eb1b5a1063 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -35,6 +35,8 @@ struct wsi_image_fns {
VkResult (*create_wsi_image)(VkDevice device_h,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
+ uint64_t *modifiers,
+ int num_modifiers,
bool needs_linear_copy,
bool linear,
VkImage *image_p,
@@ -42,7 +44,8 @@ struct wsi_image_fns {
uint32_t *size_p,
uint32_t *offset_p,
uint32_t *row_pitch_p,
- int *fd_p);
+ int *fd_p,
+ uint64_t *modifier_p);
void (*free_wsi_image)(VkDevice device,
const VkAllocationCallbacks *pAllocator,
VkImage image_h,
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index dd283a1211..80300dc81a 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -698,9 +698,12 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
uint32_t size;
uint32_t row_pitch;
uint32_t offset;
+ uint64_t modifier;
result = chain->base.image_fns->create_wsi_image(vk_device,
pCreateInfo,
pAllocator,
+ NULL,
+ 0,
false,
false,
&image->image,
@@ -708,7 +711,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
&size,
&offset,
&row_pitch,
- &fd);
+ &fd,
+ &modifier);
if (result != VK_SUCCESS)
return result;
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index ecdaf91434..f12583db13 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -955,6 +955,8 @@ static VkResult
x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
const VkAllocationCallbacks* pAllocator,
+ uint64_t *modifiers,
+ int num_modifiers,
struct x11_image *image)
{
xcb_void_cookie_t cookie;
@@ -964,10 +966,13 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
uint32_t bpp = 32;
int fd;
uint32_t size;
+ uint64_t modifier;
result = chain->base.image_fns->create_wsi_image(device_h,
pCreateInfo,
pAllocator,
+ modifiers,
+ num_modifiers,
chain->base.needs_linear_copy,
false,
&image->image,
@@ -975,7 +980,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
&size,
&offset,
&row_pitch,
- &fd);
+ &fd,
+ &modifier);
if (result != VK_SUCCESS)
return result;
@@ -983,6 +989,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
result = chain->base.image_fns->create_wsi_image(device_h,
pCreateInfo,
pAllocator,
+ modifiers,
+ num_modifiers,
chain->base.needs_linear_copy,
true,
&image->linear_image,
@@ -990,7 +998,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
&size,
&offset,
&row_pitch,
- &fd);
+ &fd,
+ &modifier);
if (result != VK_SUCCESS) {
chain->base.image_fns->free_wsi_image(device_h, pAllocator,
image->image, image->memory);
@@ -1186,7 +1195,7 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
uint32_t image = 0;
for (; image < chain->base.image_count; image++) {
result = x11_image_init(device, chain, pCreateInfo, pAllocator,
- &chain->images[image]);
+ NULL, 0, &chain->images[image]);
if (result != VK_SUCCESS)
goto fail_init_images;
}
--
2.13.0
More information about the mesa-dev
mailing list