[vulkan] Add AHB support functions
bug: 122080810
This CL adds support functions for use with AHardwareBuffer
for getting buffer info and
acquiring/importing/creating buffers.
This is inspired by / based on Intel ANV
https://github.com/mesa3d/mesa/blob/master/src/intel/vulkan/anv_android.c
which has a similar layering between implementation-specific Vulkan
and AHardwareBuffer.
No new entry points are exposed yet.
Test: Builds
Change-Id: Ieb5bfcb8b65b87650cd4a2658668efac99f9105c
diff --git a/system/vulkan_enc/Android.mk b/system/vulkan_enc/Android.mk
index efa2799..d59336f 100644
--- a/system/vulkan_enc/Android.mk
+++ b/system/vulkan_enc/Android.mk
@@ -42,7 +42,8 @@
-DVK_USE_PLATFORM_ANDROID_KHR \
-DVK_NO_PROTOTYPES \
-LOCAL_SRC_FILES := HostVisibleMemoryVirtualization.cpp \
+LOCAL_SRC_FILES := AndroidHardwareBuffer.cpp \
+ HostVisibleMemoryVirtualization.cpp \
Resources.cpp \
Validation.cpp \
VulkanStream.cpp \
@@ -57,6 +58,7 @@
ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
+LOCAL_CFLAGS += -D__ANDROID_API__=28
$(call emugl-export,SHARED_LIBRARIES,libgui)
else
$(call emugl-export,SHARED_LIBRARIES,libsync libnativewindow)
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
new file mode 100644
index 0000000..70ff6cc
--- /dev/null
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -0,0 +1,242 @@
+/// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2019 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "AndroidHardwareBuffer.h"
+
+#include "Resources.h"
+
+#include "gralloc_cb.h"
+#include "vk_format_info.h"
+
+namespace goldfish_vk {
+
+// From Intel ANV implementation.
+/* Construct ahw usage mask from image usage bits, see
+ * 'AHardwareBuffer Usage Equivalence' in Vulkan spec.
+ */
+static uint64_t
+goldfish_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create,
+ const VkImageUsageFlags vk_usage)
+{
+ uint64_t ahw_usage = 0;
+
+ if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
+ ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+
+ if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
+ ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+
+ if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
+ ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
+
+ if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
+ ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
+
+ if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
+ ahw_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
+
+ /* No usage bits set - set at least one GPU usage. */
+ if (ahw_usage == 0)
+ ahw_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+
+ return ahw_usage;
+}
+
+VkResult getAndroidHardwareBufferPropertiesANDROID(
+ const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
+ VkDevice,
+ const AHardwareBuffer* buffer,
+ VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
+
+ VkAndroidHardwareBufferFormatPropertiesANDROID* ahbFormatProps =
+ (VkAndroidHardwareBufferFormatPropertiesANDROID*)vk_find_struct(
+ (vk_struct*)pProperties->pNext,
+ VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
+
+ if (ahbFormatProps) {
+ AHardwareBuffer_Desc desc;
+ AHardwareBuffer_describe(buffer, &desc);
+
+ uint64_t gpu_usage =
+ AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
+ AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
+ AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+
+ if (!(desc.usage & (gpu_usage))) {
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
+ ahbFormatProps->format =
+ vk_format_from_android(desc.format);
+
+ // Just don't, for now
+ ahbFormatProps->externalFormat = 0;
+
+ // The formatFeatures member must include
+ // VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
+ // VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
+ // VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, and should include
+ // VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT and
+ // VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT.
+
+ ahbFormatProps->formatFeatures =
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
+
+ // "Implementations may not always be able to determine the color model,
+ // numerical range, or chroma offsets of the image contents, so the values in
+ // VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
+ // Applications should treat these values as sensible defaults to use in the
+ // absence of more reliable information obtained through some other means."
+
+ ahbFormatProps->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ahbFormatProps->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ahbFormatProps->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ahbFormatProps->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+
+ ahbFormatProps->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
+ ahbFormatProps->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
+
+ ahbFormatProps->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+ ahbFormatProps->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
+ }
+
+ const native_handle_t *handle =
+ AHardwareBuffer_getNativeHandle(buffer);
+ const cb_handle_t* cb_handle =
+ reinterpret_cast<const cb_handle_t*>(handle);
+ uint32_t colorBufferHandle = cb_handle->hostHandle;
+
+ if (!colorBufferHandle) {
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
+ // Disallow host visible heaps for now
+ // (hard to make actual dedicated allocs)
+ uint32_t memoryTypeBits = 0;
+ for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
+ memoryTypeBits |=
+ (!isHostVisibleMemoryTypeIndexForGuest(
+ hostMemVirtInfo, i)) << i;
+ }
+
+ pProperties->memoryTypeBits = memoryTypeBits;
+ pProperties->allocationSize =
+ cb_handle->ashmemBase ? cb_handle->ashmemSize : 0;
+
+ return VK_SUCCESS;
+}
+
+// Based on Intel ANV implementation.
+VkResult getMemoryAndroidHardwareBufferANDROID(struct AHardwareBuffer **pBuffer) {
+
+ /* Some quotes from Vulkan spec:
+ *
+ * "If the device memory was created by importing an Android hardware
+ * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
+ * Android hardware buffer object."
+ *
+ * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
+ * have been included in VkExportMemoryAllocateInfo::handleTypes when
+ * memory was created."
+ */
+
+ if (!pBuffer) return VK_ERROR_OUT_OF_HOST_MEMORY;
+ if (!(*pBuffer)) return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ AHardwareBuffer_acquire(*pBuffer);
+ return VK_SUCCESS;
+}
+
+VkResult importAndroidHardwareBuffer(
+ const VkImportAndroidHardwareBufferInfoANDROID* info,
+ struct AHardwareBuffer **importOut) {
+
+ if (!info || !info->buffer) {
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
+ const native_handle_t *handle =
+ AHardwareBuffer_getNativeHandle(info->buffer);
+ const cb_handle_t* cb_handle =
+ reinterpret_cast<const cb_handle_t*>(handle);
+ uint32_t colorBufferHandle = cb_handle->hostHandle;
+
+ if (!colorBufferHandle) {
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+
+ auto ahb = info->buffer;
+
+ AHardwareBuffer_acquire(ahb);
+ *importOut = ahb;
+ return VK_SUCCESS;
+}
+
+VkResult createAndroidHardwareBuffer(
+ bool hasDedicatedImage,
+ bool hasDedicatedBuffer,
+ const VkExtent3D& imageExtent,
+ uint32_t imageLayers,
+ VkFormat imageFormat,
+ VkImageUsageFlags imageUsage,
+ VkImageCreateFlags imageCreateFlags,
+ VkDeviceSize bufferSize,
+ VkDeviceSize allocationInfoAllocSize,
+ struct AHardwareBuffer **out) {
+
+ uint32_t w = 0;
+ uint32_t h = 1;
+ uint32_t layers = 1;
+ uint32_t format = 0;
+ uint64_t usage = 0;
+
+ /* If caller passed dedicated information. */
+ if (hasDedicatedImage) {
+ w = imageExtent.width;
+ h = imageExtent.height;
+ layers = imageLayers;
+ format = android_format_from_vk(imageFormat);
+ usage = goldfish_ahw_usage_from_vk_usage(imageCreateFlags, imageUsage);
+ } else if (hasDedicatedBuffer) {
+ w = bufferSize;
+ format = AHARDWAREBUFFER_FORMAT_BLOB;
+ usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+ } else {
+ w = allocationInfoAllocSize;
+ format = AHARDWAREBUFFER_FORMAT_BLOB;
+ usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+ }
+
+ struct AHardwareBuffer *ahw = NULL;
+ struct AHardwareBuffer_Desc desc = {
+ .width = w,
+ .height = h,
+ .layers = layers,
+ .format = format,
+ .usage = usage,
+ };
+
+ if (AHardwareBuffer_allocate(&desc, &ahw) != 0) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ *out = ahw;
+
+ return VK_SUCCESS;
+}
+
+} // namespace goldfish_vk
\ No newline at end of file
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.h b/system/vulkan_enc/AndroidHardwareBuffer.h
new file mode 100644
index 0000000..fc6a27e
--- /dev/null
+++ b/system/vulkan_enc/AndroidHardwareBuffer.h
@@ -0,0 +1,52 @@
+/// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2019 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#pragma once
+
+#include "HostVisibleMemoryVirtualization.h"
+
+#include <vulkan/vulkan.h>
+#include <vndk/hardware_buffer.h>
+
+// Structure similar to
+// https://github.com/mesa3d/mesa/blob/master/src/intel/vulkan/anv_android.c
+
+namespace goldfish_vk {
+
+VkResult getAndroidHardwareBufferPropertiesANDROID(
+ const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
+ VkDevice device,
+ const AHardwareBuffer* buffer,
+ VkAndroidHardwareBufferPropertiesANDROID* pProperties);
+
+VkResult getMemoryAndroidHardwareBufferANDROID(
+ struct AHardwareBuffer **pBuffer);
+
+VkResult importAndroidHardwareBuffer(
+ const VkImportAndroidHardwareBufferInfoANDROID* info,
+ struct AHardwareBuffer **importOut);
+
+VkResult createAndroidHardwareBuffer(
+ bool hasDedicatedImage,
+ bool hasDedicatedBuffer,
+ const VkExtent3D& imageExtent,
+ uint32_t imageLayers,
+ VkFormat imageFormat,
+ VkImageUsageFlags imageUsage,
+ VkImageCreateFlags imageCreateFlags,
+ VkDeviceSize bufferSize,
+ VkDeviceSize allocationInfoAllocSize,
+ struct AHardwareBuffer **out);
+
+} // namespace goldfish_vk
\ No newline at end of file
diff --git a/system/vulkan_enc/CMakeLists.txt b/system/vulkan_enc/CMakeLists.txt
index 20c5d40..3b91d56 100644
--- a/system/vulkan_enc/CMakeLists.txt
+++ b/system/vulkan_enc/CMakeLists.txt
@@ -1,10 +1,10 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "f2375abceb5cd867632f063c8cd8234c2cce414d155831a2c851bd7c2607416c")
-set(vulkan_enc_src HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStream.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "8d27c26a3f061872b902d8c89030638903e53faf8467a9e17c13580e71a86452")
+set(vulkan_enc_src AndroidHardwareBuffer.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStream.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp)
android_add_shared_library(vulkan_enc)
target_include_directories(vulkan_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include/vulkan)
-target_compile_definitions(vulkan_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"goldfish_vulkan\"" "-DVK_ANDROID_native_buffer" "-DVK_GOOGLE_address_space" "-DVK_USE_PLATFORM_ANDROID_KHR" "-DVK_NO_PROTOTYPES")
+target_compile_definitions(vulkan_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"goldfish_vulkan\"" "-DVK_ANDROID_native_buffer" "-DVK_GOOGLE_address_space" "-DVK_USE_PLATFORM_ANDROID_KHR" "-DVK_NO_PROTOTYPES" "-D__ANDROID_API__=28")
target_compile_options(vulkan_enc PRIVATE "-fvisibility=default" "-Wno-missing-field-initializers" "-Werror" "-fstrict-aliasing")
target_link_libraries(vulkan_enc PRIVATE gui cutils utils log OpenglCodecCommon_host android-emu-shared)
\ No newline at end of file
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.h b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
index 10afc46..30ab2f6 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.h
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
@@ -109,4 +109,4 @@
void subFreeHostMemory(SubAlloc* toFree);
-} // namespace goldfish_vk
+} // namespace goldfish_vk
\ No newline at end of file
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 980f4bf..df75721 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -16,6 +16,7 @@
#include "ResourceTracker.h"
#include "../OpenglSystemCommon/EmulatorFeatureInfo.h"
+#include "AndroidHardwareBuffer.h"
#include "HostVisibleMemoryVirtualization.h"
#include "Resources.h"
#include "VkEncoder.h"
@@ -139,6 +140,7 @@
GoldfishAddressSpaceBlock*
goldfishAddressSpaceBlock = nullptr;
SubAlloc subAlloc;
+ AHardwareBuffer** ahbHandle = nullptr;
};
#define HANDLE_REGISTER_IMPL_IMPL(type) \
@@ -694,6 +696,49 @@
}
}
+ VkResult on_vkGetAndroidHardwareBufferPropertiesANDROID(
+ VkDevice device,
+ const AHardwareBuffer* buffer,
+ VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
+ return getAndroidHardwareBufferPropertiesANDROID(
+ &mHostVisibleMemoryVirtInfo,
+ device, buffer, pProperties);
+ }
+
+ VkResult on_vkGetMemoryAndroidHardwareBufferANDROID(
+ VkDevice device,
+ const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
+ struct AHardwareBuffer** pBuffer) {
+
+ if (!pInfo) return VK_ERROR_INITIALIZATION_FAILED;
+ if (!pInfo->memory) return VK_ERROR_INITIALIZATION_FAILED;
+
+ AutoLock lock(mLock);
+
+ auto deviceIt = info_VkDevice.find(device);
+
+ if (deviceIt == info_VkDevice.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto memoryIt = info_VkDeviceMemory.find(pInfo->memory);
+
+ if (memoryIt == info_VkDeviceMemory.end()) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ auto& info = memoryIt->second;
+
+ VkResult queryRes =
+ getMemoryAndroidHardwareBufferANDROID(info.ahbHandle);
+
+ if (queryRes != VK_SUCCESS) return queryRes;
+
+ *pBuffer = *(info.ahbHandle);
+
+ return queryRes;
+ }
+
VkResult on_vkAllocateMemory(
void* context,
VkResult input_result,
diff --git a/system/vulkan_enc/Resources.h b/system/vulkan_enc/Resources.h
index 0948df6..0726aac 100644
--- a/system/vulkan_enc/Resources.h
+++ b/system/vulkan_enc/Resources.h
@@ -72,4 +72,18 @@
GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_U64_DECL)
GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_TRIVIAL_NON_DISPATCHABLE_HANDLE_STRUCT)
+// From vkd3d: utility function to search for extension structs
+struct vk_struct {
+ VkStructureType sType;
+ struct vk_struct *pNext;
+};
+
+static const void *vk_find_struct(struct vk_struct *chain, VkStructureType type) {
+ while (chain) {
+ if (chain->sType == type) return chain;
+ chain = chain->pNext;
+ }
+ return nullptr;
+}
+
} // extern "C"
diff --git a/system/vulkan_enc/vk_format_info.h b/system/vulkan_enc/vk_format_info.h
new file mode 100644
index 0000000..c0548a0
--- /dev/null
+++ b/system/vulkan_enc/vk_format_info.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ * Copyright © 2019 The Android Open Source Project
+ * Copyright © 2019 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef VK_FORMAT_INFO_H
+#define VK_FORMAT_INFO_H
+
+#include <stdbool.h>
+#include <vulkan/vulkan.h>
+#include <vndk/hardware_buffer.h>
+
+/* See i915_private_android_types.h in minigbm. */
+#define HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL 0x100
+
+static inline VkFormat
+vk_format_from_android(unsigned android_format)
+{
+ switch (android_format) {
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ return VK_FORMAT_R8G8B8A8_UNORM;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ return VK_FORMAT_R8G8B8_UNORM;
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ return VK_FORMAT_R5G6B5_UNORM_PACK16;
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ return VK_FORMAT_R16G16B16A16_SFLOAT;
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+ case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+ return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ case AHARDWAREBUFFER_FORMAT_BLOB:
+ default:
+ return VK_FORMAT_UNDEFINED;
+ }
+}
+
+static inline unsigned
+android_format_from_vk(unsigned vk_format)
+{
+ switch (vk_format) {
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ case VK_FORMAT_R8G8B8_UNORM:
+ return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
+ case VK_FORMAT_R5G6B5_UNORM_PACK16:
+ return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+ case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+ return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL;
+ default:
+ return AHARDWAREBUFFER_FORMAT_BLOB;
+ }
+}
+
+static inline VkImageAspectFlags
+vk_format_aspects(VkFormat format)
+{
+ switch (format) {
+ case VK_FORMAT_UNDEFINED:
+ return 0;
+
+ case VK_FORMAT_S8_UINT:
+ return VK_IMAGE_ASPECT_STENCIL_BIT;
+
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ case VK_FORMAT_D32_SFLOAT:
+ return VK_IMAGE_ASPECT_DEPTH_BIT;
+
+ case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
+ case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
+ case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
+ case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
+ case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
+ case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
+ case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
+ case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
+ return (VK_IMAGE_ASPECT_PLANE_0_BIT |
+ VK_IMAGE_ASPECT_PLANE_1_BIT |
+ VK_IMAGE_ASPECT_PLANE_2_BIT);
+
+ case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
+ case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
+ case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
+ case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
+ case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
+ case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
+ case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
+ case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
+ return (VK_IMAGE_ASPECT_PLANE_0_BIT |
+ VK_IMAGE_ASPECT_PLANE_1_BIT);
+
+ default:
+ return VK_IMAGE_ASPECT_COLOR_BIT;
+ }
+}
+
+static inline bool
+vk_format_is_color(VkFormat format)
+{
+ return vk_format_aspects(format) == VK_IMAGE_ASPECT_COLOR_BIT;
+}
+
+static inline bool
+vk_format_is_depth_or_stencil(VkFormat format)
+{
+ const VkImageAspectFlags aspects = vk_format_aspects(format);
+ return aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
+}
+
+static inline bool
+vk_format_has_depth(VkFormat format)
+{
+ const VkImageAspectFlags aspects = vk_format_aspects(format);
+ return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
+}
+
+#endif /* VK_FORMAT_INFO_H */
\ No newline at end of file