aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChad Versace <chadversary@chromium.org>2019-01-22 14:40:01 -0800
committerChad Versace <chadversary@chromium.org>2019-02-11 13:38:48 -0800
commit72243cd695e64005ebdc4b81c41b4c96605bc818 (patch)
treea861c18c1d1ae1dd5a4f7b455f436ffc16777457
parentdbb66dc1766245d657922d48e1b661621776d79e (diff)
downloadmesa-wip/tu-drm-format-mod.zip
mesa-wip/tu-drm-format-mod.tar.xz
WIP: turnip: Support VkImageDrmFormatModifier*CreateInfoEXTwip/tu-drm-format-mod
-rw-r--r--src/freedreno/vulkan/tu_image.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/src/freedreno/vulkan/tu_image.c b/src/freedreno/vulkan/tu_image.c
index c0f0c98..4fb4356d 100644
--- a/src/freedreno/vulkan/tu_image.c
+++ b/src/freedreno/vulkan/tu_image.c
@@ -50,7 +50,9 @@ static const struct
};
static void
-setup_slices(struct tu_image *image, const VkImageCreateInfo *pCreateInfo)
+setup_slices(struct tu_image *image,
+ const VkImageCreateInfo *pCreateInfo,
+ const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info)
{
enum vk_format_layout layout =
vk_format_description(pCreateInfo->format)->layout;
@@ -132,9 +134,24 @@ tu_image_create(VkDevice _device,
{
TU_FROM_HANDLE(tu_device, device, _device);
const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
+ const VkImageDrmFormatModifierListCreateInfoEXT *drm_list_info = NULL;
+ const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info = NULL;
struct tu_image *image = NULL;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
+ vk_foreach_struct_const(s, pCreateInfo->pNext) {
+ switch (s->sType) {
+ case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT:
+ drm_list_info = (const void *) s;
+ break;
+ case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT:
+ drm_explicit_info = (const void *) s;
+ break;
+ default:
+ break;
+ }
+ }
+
tu_assert(pCreateInfo->mipLevels > 0);
tu_assert(pCreateInfo->arrayLayers > 0);
tu_assert(pCreateInfo->samples > 0);
@@ -172,13 +189,76 @@ tu_image_create(VkDevice _device,
vk_find_struct_const(pCreateInfo->pNext,
EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL;
- image->tile_mode = pCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ? 3 : 0;
+ switch (pCreateInfo->tiling) {
+ case VK_IMAGE_TILING_LINEAR:
+ image->tile_mode = 0;
+ break;
+ case VK_IMAGE_TILING_OPTIMAL:
+ image->tile_mode = 3;
+ break;
+ case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:
+ /* We currently advertise, through
+ * VkPhysicalDeviceImageDrmFormatModifierInfoEXT, support for only
+ * DRM_FORMAT_MOD_LINEAR.
+ */
+ if (drm_list_info) {
+ assert(drm_list_info->pDrmFormatModifiers[0] == DRM_FORMAT_MOD_LINEAR);
+ } else {
+ assert(drm_explicit_info->drmFormatModifier == DRM_FORMAT_MOD_LINEAR);
+ }
+
+ image->tile_mode = TILE6_LINEAR;
+ }
+
setup_slices(image, pCreateInfo);
image->size = image->layer_size * pCreateInfo->arrayLayers;
+
+ if (drm_explicit_info) {
+ /* Inspect the application-provided memory layout. */
+
+ /* We currently support only simple DRM images. */
+ assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
+ assert(pCreateInfo->mipLevels == 1);
+ assert(pCreateInfo->arrayLayers == 1);
+ assert(pCreateInfo->samples == 1);
+ assert(drm_explicit_info->drmFormatModifierPlaneCount == 1);
+
+ /* We can ignore some params in pPlaneLayouts.
+ *
+ * From the Vulkan 1.1.98 spec:
+ *
+ * * For each element of pPlaneLayouts, size must be 0
+ * * For each element of pPlaneLayouts, arrayPitch must be 0 if
+ * arrayLayers is 1.
+ * * For each element of pPlaneLayouts, depthPitch must be 0 if
+ * extent::depth is 1.
+ */
+ VkSubresourceLayout plane = drm_explicit_info->pPlaneLayouts[0];
+ assert(plane.size == 0);
+ assert(plane.arrayPitch == 0);
+ assert(plane.depthPitch == 0);
+
+ /* For now, let's be excessively strict regarding plane layouts (because
+ * chadv doesn't yet understand the hardware's restrictions0. We reject
+ * the application-requested layout if it differs from the
+ * driver-preferred layout calculated above.
+ */
+ if (plane.offset != image->levels[0].offset ||
+ plane.rowPitch == image->levels[0].pitch) {
+ result = vk_error(device->instance,
+ VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
+ goto fail;
+ }
+ }
+
*pImage = tu_image_to_handle(image);
return VK_SUCCESS;
+
+ fail:
+ vk_free2(&device->alloc, alloc, image);
+ return result;
}
void