[Mesa-dev] [RFC v5 16/19] vulkan/wsi: Add wsi_image_create_with_modifiers
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Mon Nov 6 22:02:46 UTC 2017
Allow the winsys to provide a set of acceptable modifiers to the driver
when creating WSI images.
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
src/amd/vulkan/radv_wsi.c | 3 ++
src/intel/vulkan/anv_image.c | 9 +++-
src/intel/vulkan/anv_private.h | 3 ++
src/intel/vulkan/anv_wsi.c | 101 ++++++++++++++++++++++++++++++++++++-----
src/vulkan/wsi/wsi_common.h | 11 +++++
5 files changed, 114 insertions(+), 13 deletions(-)
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c
index c4c6ff9736..a1881eaa35 100644
--- a/src/amd/vulkan/radv_wsi.c
+++ b/src/amd/vulkan/radv_wsi.c
@@ -223,6 +223,8 @@ radv_wsi_image_create(VkDevice device_h,
wsi_image->image = image_h;
wsi_image->memory = memory_h;
+ wsi_image->linear_image = VK_NULL_HANDLE;
+ wsi_image->linear_memory = VK_NULL_HANDLE;
wsi_image->num_planes = 1;
wsi_image->drm_modifier = DRM_FORMAT_MOD_INVALID;
wsi_image->sizes[0] = image->size;
@@ -256,6 +258,7 @@ radv_wsi_image_free(VkDevice device,
static const struct wsi_image_fns radv_wsi_image_fns = {
.create_wsi_image = radv_wsi_image_create,
+ .create_wsi_image_with_modifiers = NULL,
.free_wsi_image = radv_wsi_image_free,
};
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index cd96bfd0d6..262f6805dc 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -274,12 +274,16 @@ make_surface(const struct anv_device *dev,
/* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the
* result with an optionally provided ISL tiling argument.
*/
- isl_tiling_flags_t tiling_flags =
+ isl_tiling_flags_t mask =
(vk_info->tiling == VK_IMAGE_TILING_LINEAR) ?
ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK;
+ isl_tiling_flags_t tiling_flags = mask;
+ isl_tiling_flags_t suboptimal_tiling_flags = 0;
if (anv_info->isl_tiling_flags)
tiling_flags &= anv_info->isl_tiling_flags;
+ if (anv_info->isl_suboptimal_tiling_flags)
+ suboptimal_tiling_flags = anv_info->isl_suboptimal_tiling_flags & mask;
assert(tiling_flags);
@@ -322,7 +326,8 @@ make_surface(const struct anv_device *dev,
.min_alignment = 0,
.row_pitch = anv_info->stride,
.usage = usage,
- .tiling_flags = tiling_flags);
+ .tiling_flags = tiling_flags,
+ .suboptimal_tiling_flags = suboptimal_tiling_flags);
/* isl_surf_init() will fail only if provided invalid input. Invalid input
* is illegal in Vulkan.
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 8de5103453..5e5010fde9 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2630,6 +2630,9 @@ struct anv_image_create_info {
/** An opt-in bitmask which filters an ISL-mapping of the Vulkan tiling. */
isl_tiling_flags_t isl_tiling_flags;
+ /** Set of possible but suboptimal tiling flags. */
+ isl_tiling_flags_t isl_suboptimal_tiling_flags;
+
/** These flags will be added to any derived from VkImageCreateInfo. */
isl_surf_usage_flags_t isl_extra_usage_flags;
diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c
index 740bbff9d3..f41db86f12 100644
--- a/src/intel/vulkan/anv_wsi.c
+++ b/src/intel/vulkan/anv_wsi.c
@@ -169,12 +169,13 @@ VkResult anv_GetPhysicalDeviceSurfacePresentModesKHR(
static VkResult
-anv_wsi_image_create(VkDevice device_h,
- const VkSwapchainCreateInfoKHR *pCreateInfo,
- const VkAllocationCallbacks* pAllocator,
- bool should_export,
- bool different_gpu,
- struct wsi_image_base *wsi_image)
+anv_wsi_image_alloc(VkDevice device_h,
+ const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ bool should_export,
+ isl_tiling_flags_t *isl_tiling,
+ VkImageTiling vk_tiling,
+ struct wsi_image_base *wsi_image)
{
struct anv_device *device = anv_device_from_handle(device_h);
VkImage image_h;
@@ -183,7 +184,8 @@ anv_wsi_image_create(VkDevice device_h,
VkResult result;
result = anv_image_create(anv_device_to_handle(device),
&(struct anv_image_create_info) {
- .isl_tiling_flags = ISL_TILING_X_BIT,
+ .isl_tiling_flags = isl_tiling[0],
+ .isl_suboptimal_tiling_flags = isl_tiling[1],
.stride = 0,
.vk_info =
&(VkImageCreateInfo) {
@@ -198,8 +200,7 @@ anv_wsi_image_create(VkDevice device_h,
.mipLevels = 1,
.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,
@@ -238,10 +239,11 @@ anv_wsi_image_create(VkDevice device_h,
assert(image->planes[0].offset == 0);
struct anv_surface *surface = &image->planes[0].surface;
- assert(surface->isl.tiling == ISL_TILING_X);
+ assert((isl_tiling[0] | isl_tiling[1]) & (1 << surface->isl.tiling));
int ret = anv_gem_set_tiling(device, memory->bo->gem_handle,
- surface->isl.row_pitch, I915_TILING_X);
+ surface->isl.row_pitch,
+ isl_tiling_to_i915_tiling(surface->isl.tiling));
if (ret) {
/* FINISHME: Choose a better error. */
result = vk_errorf(device->instance, device,
@@ -266,6 +268,8 @@ anv_wsi_image_create(VkDevice device_h,
wsi_image->image = image_h;
wsi_image->memory = memory_h;
+ wsi_image->linear_image = VK_NULL_HANDLE;
+ wsi_image->linear_memory = VK_NULL_HANDLE;
/* We don't yet allow sharing of aux planes with the winsys. Doing so
* would require a separate external_aux_usage member in the anv_image,
@@ -289,6 +293,80 @@ fail_create_image:
return result;
}
+static VkResult
+anv_wsi_image_create(VkDevice device_h,
+ const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ bool should_export,
+ bool different_gpu,
+ struct wsi_image_base *wsi_image)
+{
+ isl_tiling_flags_t isl_tiling[2] = {ISL_TILING_X_BIT, 0};
+ VkImageTiling vk_tiling = VK_IMAGE_TILING_OPTIMAL;
+
+ return anv_wsi_image_alloc(device_h,
+ pCreateInfo,
+ pAllocator,
+ should_export,
+ isl_tiling,
+ vk_tiling,
+ wsi_image);
+}
+
+static VkResult
+anv_wsi_image_create_with_modifiers(VkDevice device_h,
+ const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ bool different_gpu,
+ uint64_t **modifiers,
+ int *num_modifiers,
+ int num_tranches,
+ struct wsi_image_base *wsi_image)
+{
+ isl_tiling_flags_t isl_tiling[2] = {0,};
+ VkImageTiling vk_tiling = VK_IMAGE_TILING_OPTIMAL;
+
+ assert(num_tranches >= 0 && num_tranches <= 2);
+
+ /* If we haven't been provided any modifiers, fall back to our previous
+ * default of X-tiling, which the other side can infer through the BO
+ * get_tiling ioctl. */
+ if (num_tranches == 0) {
+ isl_tiling[0] = ISL_TILING_X_BIT;
+ } else {
+ for (int i = 0; i < num_tranches; i++) {
+ for (int j = 0; j < num_modifiers[i]; j++) {
+ const struct isl_drm_modifier_info *info =
+ isl_drm_modifier_get_info(modifiers[i][j]);
+ if (!info || info->aux_usage != ISL_AUX_USAGE_NONE)
+ continue;
+ isl_tiling[i] |= (1 << info->tiling);
+ }
+ }
+ }
+
+ /* This isn't strictly correct; really we want something more like
+ * SURFACE_LOST, because we'll never be able to render to it in these
+ * conditions.
+ */
+ if (isl_tiling[0] == 0)
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
+ if (isl_tiling[0] & ISL_TILING_NON_LINEAR_MASK ||
+ isl_tiling[1] & ISL_TILING_NON_LINEAR_MASK)
+ vk_tiling = VK_IMAGE_TILING_OPTIMAL;
+ else
+ vk_tiling = VK_IMAGE_TILING_LINEAR;
+
+ return anv_wsi_image_alloc(device_h,
+ pCreateInfo,
+ pAllocator,
+ true,
+ isl_tiling,
+ vk_tiling,
+ wsi_image);
+}
+
static void
anv_wsi_image_free(VkDevice device,
const VkAllocationCallbacks* pAllocator,
@@ -301,6 +379,7 @@ anv_wsi_image_free(VkDevice device,
static const struct wsi_image_fns anv_wsi_image_fns = {
.create_wsi_image = anv_wsi_image_create,
+ .create_wsi_image_with_modifiers = anv_wsi_image_create_with_modifiers,
.free_wsi_image = anv_wsi_image_free,
};
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index d808a4cfdc..0741e59875 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -33,6 +33,8 @@
struct wsi_image_base {
VkImage image;
VkDeviceMemory memory;
+ VkImage linear_image;
+ VkDeviceMemory linear_memory;
uint64_t drm_modifier;
int num_planes;
@@ -50,6 +52,15 @@ struct wsi_image_fns {
bool should_export,
bool different_gpu,
struct wsi_image_base *image_p);
+
+ VkResult (*create_wsi_image_with_modifiers)(VkDevice device_h,
+ const VkSwapchainCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ bool different_gpu,
+ uint64_t **modifiers,
+ int *num_modifiers,
+ int num_tranches,
+ struct wsi_image_base *image_p);
void (*free_wsi_image)(VkDevice device,
const VkAllocationCallbacks *pAllocator,
struct wsi_image_base *image);
--
2.13.0
More information about the mesa-dev
mailing list