Implement Android hardware buffer in null driver
authorJesse Hall <jessehall@google.com>
Mon, 7 Aug 2017 05:58:23 +0000 (22:58 -0700)
committerJesse Hall <jessehall@google.com>
Fri, 25 Aug 2017 17:00:01 +0000 (10:00 -0700)
Partially implement these extensions:
* VK_ANDROID_external_memory_android_hardware_buffer
* VK_KHR_external_memory_capabilities
* VK_KHR_external_memory
* VK_KHR_maintenance1
* VK_KHR_sampler_ycbcr_conversion

Components: Framework

Change-Id: If13179c08d46a03efdef4352a4215fa8a2186102

external/vulkancts/framework/vulkan/vkNullDriver.cpp
external/vulkancts/framework/vulkan/vkNullDriverImpl.inl
external/vulkancts/scripts/gen_framework.py

index ccffd8e..d444b11 100644 (file)
 #include "tcuFunctionLibrary.hpp"
 #include "deMemory.h"
 
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+#      include <android/hardware_buffer.h>
+#endif
+
 #include <stdexcept>
 #include <algorithm>
 
@@ -119,11 +123,17 @@ void freeHandle (Handle handle, const VkAllocationCallbacks* pAllocator)
                delete obj;
 }
 
-template<typename Object, typename Handle, typename Parent, typename CreateInfo>
+template<typename Object, typename BaseObject, typename Handle, typename Parent, typename CreateInfo>
 Handle allocateNonDispHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
 {
        Object* const   obj             = allocateHandle<Object, Object*>(parent, pCreateInfo, pAllocator);
-       return Handle((deUint64)(deUintptr)obj);
+       return Handle((deUint64)(deUintptr)static_cast<BaseObject*>(obj));
+}
+
+template<typename Object, typename Handle, typename Parent, typename CreateInfo>
+Handle allocateNonDispHandle (Parent parent, const CreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
+{
+       return allocateNonDispHandle<Object, Object, Handle, Parent, CreateInfo>(parent, pCreateInfo, pAllocator);
 }
 
 template<typename Object, typename Handle>
@@ -240,6 +250,62 @@ public:
        SamplerYcbcrConversionKHR (VkDevice, const VkSamplerYcbcrConversionCreateInfoKHR*) {}
 };
 
+class Buffer
+{
+public:
+                                               Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
+               : m_size (pCreateInfo->size)
+       {
+       }
+
+       VkDeviceSize            getSize         (void) const { return m_size;   }
+
+private:
+       const VkDeviceSize      m_size;
+};
+
+VkExternalMemoryHandleTypeFlagsKHR getExternalHandleTypes (const VkImageCreateInfo* pCreateInfo)
+{
+       const VkExternalMemoryImageCreateInfoKHR* const externalInfo    = findStructure<VkExternalMemoryImageCreateInfoKHR>     (pCreateInfo->pNext);
+
+       return externalInfo ? externalInfo->handleTypes : 0u;
+}
+
+class Image
+{
+public:
+                                                                                               Image                                   (VkDevice, const VkImageCreateInfo* pCreateInfo)
+               : m_imageType                   (pCreateInfo->imageType)
+               , m_format                              (pCreateInfo->format)
+               , m_extent                              (pCreateInfo->extent)
+               , m_arrayLayers                 (pCreateInfo->arrayLayers)
+               , m_samples                             (pCreateInfo->samples)
+               , m_usage                               (pCreateInfo->usage)
+               , m_flags                               (pCreateInfo->flags)
+               , m_externalHandleTypes (::vk::getExternalHandleTypes(pCreateInfo))
+       {
+       }
+
+       VkImageType                                                                     getImageType                    (void) const { return m_imageType;                              }
+       VkFormat                                                                        getFormat                               (void) const { return m_format;                                 }
+       VkExtent3D                                                                      getExtent                               (void) const { return m_extent;                                 }
+       uint32_t                                                                        getArrayLayers                  (void) const { return m_arrayLayers;                    }
+       VkSampleCountFlagBits                                           getSamples                              (void) const { return m_samples;                                }
+       VkImageUsageFlags                                                       getUsage                                (void) const { return m_usage;                                  }
+       VkImageCreateFlags                                                      getFlags                                (void) const { return m_flags;                                  }
+       VkExternalMemoryHandleTypeFlagsKHR                      getExternalHandleTypes  (void) const { return m_externalHandleTypes;    }
+
+private:
+       const VkImageType                                                       m_imageType;
+       const VkFormat                                                          m_format;
+       const VkExtent3D                                                        m_extent;
+       const uint32_t                                                          m_arrayLayers;
+       const VkSampleCountFlagBits                                     m_samples;
+       const VkImageUsageFlags                                         m_usage;
+       const VkImageCreateFlags                                        m_flags;
+       const VkExternalMemoryHandleTypeFlagsKHR        m_externalHandleTypes;
+};
+
 void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
 {
        // \todo [2015-12-03 pyry] Alignment requirements?
@@ -263,59 +329,137 @@ void freeHeap (void* ptr)
 class DeviceMemory
 {
 public:
-                                               DeviceMemory    (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
-                                                       : m_memory(allocateHeap(pAllocInfo))
-                                               {
-                                                       // \todo [2016-08-03 pyry] In some cases leaving data unintialized would help valgrind analysis,
-                                                       //                                                 but currently it mostly hinders it.
-                                                       if (m_memory)
-                                                               deMemset(m_memory, 0xcd, (size_t)pAllocInfo->allocationSize);
-                                               }
-                                               ~DeviceMemory   (void)
-                                               {
-                                                       freeHeap(m_memory);
-                                               }
-
-       void*                           getPtr                  (void) const { return m_memory; }
-
-private:
-       void* const                     m_memory;
+       virtual                 ~DeviceMemory   (void) {}
+       virtual void*   map                             (void) = 0;
+       virtual void    unmap                   (void) = 0;
 };
 
-class Buffer
+class PrivateDeviceMemory : public DeviceMemory
 {
 public:
-                                               Buffer          (VkDevice, const VkBufferCreateInfo* pCreateInfo)
-                                                       : m_size(pCreateInfo->size)
-                                               {}
+                                               PrivateDeviceMemory             (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
+               : m_memory(allocateHeap(pAllocInfo))
+       {
+               // \todo [2016-08-03 pyry] In some cases leaving data unintialized would help valgrind analysis,
+               //                                                 but currently it mostly hinders it.
+               if (m_memory)
+                       deMemset(m_memory, 0xcd, (size_t)pAllocInfo->allocationSize);
+       }
+       virtual                         ~PrivateDeviceMemory    (void)
+       {
+               freeHeap(m_memory);
+       }
 
-       VkDeviceSize            getSize         (void) const { return m_size;   }
+       virtual void*           map                                             (void) /*override*/ { return m_memory; }
+       virtual void            unmap                                   (void) /*override*/ {}
 
 private:
-       const VkDeviceSize      m_size;
+       void* const                     m_memory;
 };
 
-class Image
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+AHardwareBuffer* findOrCreateHwBuffer (const VkMemoryAllocateInfo* pAllocInfo)
+{
+       const VkExportMemoryAllocateInfoKHR* const                              exportInfo              = findStructure<VkExportMemoryAllocateInfoKHR>(pAllocInfo->pNext);
+       const VkImportAndroidHardwareBufferInfoANDROID* const   importInfo              = findStructure<VkImportAndroidHardwareBufferInfoANDROID>(pAllocInfo->pNext);
+       const VkMemoryDedicatedAllocateInfoKHR* const                   dedicatedInfo   = findStructure<VkMemoryDedicatedAllocateInfoKHR>(pAllocInfo->pNext);
+       const Image* const                                                                              image                   = dedicatedInfo && !!dedicatedInfo->image ? reinterpret_cast<const Image*>(dedicatedInfo->image.getInternal()) : DE_NULL;
+       AHardwareBuffer*                                                                                hwbuffer                = DE_NULL;
+
+       // Import and export aren't mutually exclusive; we can have both simultaneously.
+       DE_ASSERT((importInfo && importInfo->buffer.internal) ||
+               (exportInfo && (exportInfo->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0));
+
+       if (importInfo && importInfo->buffer.internal)
+       {
+               hwbuffer = (AHardwareBuffer*)importInfo->buffer.internal;
+               AHardwareBuffer_acquire(hwbuffer);
+       }
+       else if (exportInfo && (exportInfo->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0)
+       {
+               AHardwareBuffer_Desc hwbufferDesc;
+               deMemset(&hwbufferDesc, 0, sizeof(hwbufferDesc));
+
+               if (image)
+               {
+                       hwbufferDesc.width      = image->getExtent().width;
+                       hwbufferDesc.height     = image->getExtent().height;
+                       hwbufferDesc.layers = image->getArrayLayers();
+                       switch (image->getFormat())
+                       {
+                               case VK_FORMAT_R8G8B8A8_UNORM:
+                                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+                                       break;
+                               case VK_FORMAT_R8G8B8_UNORM:
+                                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
+                                       break;
+                               case VK_FORMAT_R5G6B5_UNORM_PACK16:
+                                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+                                       break;
+                               case VK_FORMAT_R16G16B16A16_SFLOAT:
+                                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
+                                       break;
+                               case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+                                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+                                       break;
+                               default:
+                                       DE_FATAL("Unsupported image format for Android hardware buffer export");
+                                       break;
+                       }
+                       if ((image->getUsage() & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
+                               hwbufferDesc.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+                       if ((image->getUsage() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
+                               hwbufferDesc.usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
+                       // if ((image->getFlags() & VK_IMAGE_CREATE_PROTECTED_BIT_KHR) != 0)
+                       //      hwbufferDesc.usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
+
+                       // Make sure we have at least one AHB GPU usage, even if the image doesn't have any
+                       // Vulkan usages with corresponding to AHB GPU usages.
+                       if ((image->getUsage() & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) == 0)
+                               hwbufferDesc.usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+               }
+               else
+               {
+                       hwbufferDesc.width = static_cast<uint32_t>(pAllocInfo->allocationSize);
+                       hwbufferDesc.height = 1,
+                       hwbufferDesc.layers = 1,
+                       hwbufferDesc.format = AHARDWAREBUFFER_FORMAT_BLOB,
+                       hwbufferDesc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
+               }
+
+               AHardwareBuffer_allocate(&hwbufferDesc, &hwbuffer);
+       }
+
+       return hwbuffer;
+}
+
+class ExternalDeviceMemoryAndroid : public DeviceMemory
 {
 public:
-                                                               Image                   (VkDevice, const VkImageCreateInfo* pCreateInfo)
-                                                                       : m_imageType   (pCreateInfo->imageType)
-                                                                       , m_format              (pCreateInfo->format)
-                                                                       , m_extent              (pCreateInfo->extent)
-                                                                       , m_samples             (pCreateInfo->samples)
-                                                               {}
-
-       VkImageType                                     getImageType    (void) const { return m_imageType;      }
-       VkFormat                                        getFormat               (void) const { return m_format;         }
-       VkExtent3D                                      getExtent               (void) const { return m_extent;         }
-       VkSampleCountFlagBits           getSamples              (void) const { return m_samples;        }
+                                               ExternalDeviceMemoryAndroid             (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
+               : m_hwbuffer(findOrCreateHwBuffer(pAllocInfo))
+       {}
+       virtual                         ~ExternalDeviceMemoryAndroid    (void)
+       {
+               if (m_hwbuffer)
+                       AHardwareBuffer_release(m_hwbuffer);
+       }
+
+       virtual void*           map                                                             (void) /*override*/
+       {
+               void* p;
+               AHardwareBuffer_lock(m_hwbuffer, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, NULL, &p);
+               return p;
+       }
+
+       virtual void            unmap                                                   (void) /*override*/ { AHardwareBuffer_unlock(m_hwbuffer, NULL); }
+
+       AHardwareBuffer*        getHwBuffer                                             (void)                          { return m_hwbuffer;                                            }
 
 private:
-       const VkImageType                       m_imageType;
-       const VkFormat                          m_format;
-       const VkExtent3D                        m_extent;
-       const VkSampleCountFlagBits     m_samples;
+       AHardwareBuffer* const  m_hwbuffer;
 };
+#endif // (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
 
 class CommandBuffer
 {
@@ -559,7 +703,8 @@ VKAPI_ATTR VkResult VKAPI_CALL enumerateInstanceExtensionProperties (const char*
 {
        static const VkExtensionProperties      s_extensions[]  =
        {
-               { "VK_KHR_get_physical_device_properties2", 1u }
+               { "VK_KHR_get_physical_device_properties2", 1u },
+               { "VK_KHR_external_memory_capabilities",        1u },
        };
 
        if (!pLayerName)
@@ -574,9 +719,14 @@ VKAPI_ATTR VkResult VKAPI_CALL enumerateDeviceExtensionProperties (VkPhysicalDev
 
        static const VkExtensionProperties      s_extensions[]  =
        {
-               { "VK_KHR_get_memory_requirements2",    1u },
-               { "VK_KHR_bind_memory2",                                1u },
-               { "VK_KHR_sampler_ycbcr_conversion",    1u },
+               { "VK_KHR_bind_memory2",                                                                1u },
+               { "VK_KHR_external_memory",                                                         1u },
+               { "VK_KHR_get_memory_requirements2",                                    1u },
+               { "VK_KHR_maintenance1",                                                                1u },
+               { "VK_KHR_sampler_ycbcr_conversion",                                    1u },
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+               { "VK_ANDROID_external_memory_android_hardware_buffer", 1u },
+#endif
        };
 
        if (!pLayerName)
@@ -961,21 +1111,22 @@ VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements (VkDevice, VkImage imageHa
 
 VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements2KHR (VkDevice device, const VkImageMemoryRequirementsInfo2KHR* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements)
 {
-       const VkImagePlaneMemoryRequirementsInfoKHR*    planeReqs       = findStructure<VkImagePlaneMemoryRequirementsInfoKHR>(pInfo->pNext);
+       const VkImagePlaneMemoryRequirementsInfoKHR* const      planeReqs               = findStructure<VkImagePlaneMemoryRequirementsInfoKHR>(pInfo->pNext);
+       VkMemoryDedicatedRequirementsKHR* const                         dedicatedReqs   = findStructure<VkMemoryDedicatedRequirementsKHR>(pMemoryRequirements->pNext);
 
        if (planeReqs)
        {
-               const deUint32                                  planeNdx        = getAspectPlaneNdx(planeReqs->planeAspect);
-               const Image*                                    image           = reinterpret_cast<const Image*>(pInfo->image.getInternal());
-               const VkFormat                                  format          = image->getFormat();
-               const PlanarFormatDescription   formatDesc      = getPlanarFormatDescription(format);
+               const deUint32                                          planeNdx                        = getAspectPlaneNdx(planeReqs->planeAspect);
+               const Image* const                                      image                           = reinterpret_cast<const Image*>(pInfo->image.getInternal());
+               const VkFormat                                          format                          = image->getFormat();
+               const PlanarFormatDescription           formatDesc                      = getPlanarFormatDescription(format);
 
                DE_ASSERT(de::inBounds<deUint32>(planeNdx, 0u, formatDesc.numPlanes));
 
-               const VkExtent3D                                extent          = image->getExtent();
-               const deUint32                                  planeW          = extent.width / formatDesc.planes[planeNdx].widthDivisor;
-               const deUint32                                  planeH          = extent.height / formatDesc.planes[planeNdx].heightDivisor;
-               const deUint32                                  elementSize     = formatDesc.planes[planeNdx].elementSizeBytes;
+               const VkExtent3D                                        extent                          = image->getExtent();
+               const deUint32                                          planeW                          = extent.width / formatDesc.planes[planeNdx].widthDivisor;
+               const deUint32                                          planeH                          = extent.height / formatDesc.planes[planeNdx].heightDivisor;
+               const deUint32                                          elementSize                     = formatDesc.planes[planeNdx].elementSizeBytes;
 
                pMemoryRequirements->memoryRequirements.memoryTypeBits  = 1u;
                pMemoryRequirements->memoryRequirements.alignment               = 16u;
@@ -983,16 +1134,77 @@ VKAPI_ATTR void VKAPI_CALL getImageMemoryRequirements2KHR (VkDevice device, cons
        }
        else
                getImageMemoryRequirements(device, pInfo->image, &pMemoryRequirements->memoryRequirements);
+
+       if (dedicatedReqs)
+       {
+               const Image* const                                      image                           = reinterpret_cast<const Image*>(pInfo->image.getInternal());
+               VkExternalMemoryHandleTypeFlagsKHR      externalHandleTypes     = image->getExternalHandleTypes();
+
+               dedicatedReqs->prefersDedicatedAllocation               = VK_FALSE;
+
+               if ((externalHandleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0)
+                       dedicatedReqs->requiresDedicatedAllocation      = VK_TRUE;
+               else
+                       dedicatedReqs->requiresDedicatedAllocation      = VK_FALSE;
+       }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL allocateMemory (VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
+{
+       const VkExportMemoryAllocateInfoKHR* const                              exportInfo      = findStructure<VkExportMemoryAllocateInfoKHR>(pAllocateInfo->pNext);
+       const VkImportAndroidHardwareBufferInfoANDROID* const   importInfo      = findStructure<VkImportAndroidHardwareBufferInfoANDROID>(pAllocateInfo->pNext);
+
+       if ((exportInfo && (exportInfo->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0)
+               || (importInfo && importInfo->buffer.internal))
+       {
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+               VK_NULL_RETURN((*pMemory = allocateNonDispHandle<ExternalDeviceMemoryAndroid, DeviceMemory, VkDeviceMemory>(device, pAllocateInfo, pAllocator)));
+#else
+               return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
+#endif
+       }
+       else
+       {
+               VK_NULL_RETURN((*pMemory = allocateNonDispHandle<PrivateDeviceMemory, DeviceMemory, VkDeviceMemory>(device, pAllocateInfo, pAllocator)));
+       }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
 {
-       const DeviceMemory*     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
+       DeviceMemory* const     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
 
        DE_UNREF(size);
        DE_UNREF(flags);
 
-       *ppData = (deUint8*)memory->getPtr() + offset;
+       *ppData = (deUint8*)memory->map() + offset;
+
+       return VK_SUCCESS;
+}
+
+VKAPI_ATTR void VKAPI_CALL unmapMemory (VkDevice device, VkDeviceMemory memHandle)
+{
+       DeviceMemory* const     memory  = reinterpret_cast<DeviceMemory*>(memHandle.getInternal());
+
+       DE_UNREF(device);
+
+       memory->unmap();
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL getMemoryAndroidHardwareBufferANDROID (VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, pt::AndroidHardwareBufferPtr* pBuffer)
+{
+       DE_UNREF(device);
+
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+       DeviceMemory* const                                     memory                  = reinterpret_cast<ExternalDeviceMemoryAndroid*>(pInfo->memory.getInternal());
+       ExternalDeviceMemoryAndroid* const      androidMemory   = static_cast<ExternalDeviceMemoryAndroid*>(memory);
+
+       AHardwareBuffer* hwbuffer = androidMemory->getHwBuffer();
+       AHardwareBuffer_acquire(hwbuffer);
+       pBuffer->internal = hwbuffer;
+#else
+       DE_UNREF(pInfo);
+       DE_UNREF(pBuffer);
+#endif
 
        return VK_SUCCESS;
 }
@@ -1085,6 +1297,87 @@ VKAPI_ATTR VkResult VKAPI_CALL createSharedSwapchainsKHR (VkDevice device, deUin
        return VK_SUCCESS;
 }
 
+VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceExternalBufferPropertiesKHR (VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo, VkExternalBufferPropertiesKHR* pExternalBufferProperties)
+{
+       DE_UNREF(physicalDevice);
+       DE_UNREF(pExternalBufferInfo);
+
+       pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures = 0;
+       pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes = 0;
+       pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes = 0;
+
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+       if (pExternalBufferInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
+       {
+               pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
+               pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+               pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+       }
+#endif
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceImageFormatProperties2KHR (VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties)
+{
+       const VkPhysicalDeviceExternalImageFormatInfoKHR* const externalInfo            = findStructure<VkPhysicalDeviceExternalImageFormatInfoKHR>(pImageFormatInfo->pNext);
+       VkExternalImageFormatPropertiesKHR*     const                           externalProperties      = findStructure<VkExternalImageFormatPropertiesKHR>(pImageFormatProperties->pNext);
+       VkResult                                                                                                result;
+
+       result = getPhysicalDeviceImageFormatProperties(physicalDevice, pImageFormatInfo->format, pImageFormatInfo->type, pImageFormatInfo->tiling, pImageFormatInfo->usage, pImageFormatInfo->flags, &pImageFormatProperties->imageFormatProperties);
+       if (result != VK_SUCCESS)
+               return result;
+
+       if (externalInfo && externalInfo->handleType != 0)
+       {
+#if (DE_OS == DE_OS_ANDROID) && (__ANDROID_API__ >= __ANDROID_API_O__)
+               if (externalInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
+                       return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+               if (!(pImageFormatInfo->format == VK_FORMAT_R8G8B8A8_UNORM
+                         || pImageFormatInfo->format == VK_FORMAT_R8G8B8_UNORM
+                         || pImageFormatInfo->format == VK_FORMAT_R5G6B5_UNORM_PACK16
+                         || pImageFormatInfo->format == VK_FORMAT_R16G16B16A16_SFLOAT
+                         || pImageFormatInfo->format == VK_FORMAT_A2R10G10B10_UNORM_PACK32))
+               {
+                       return VK_ERROR_FORMAT_NOT_SUPPORTED;
+               }
+
+               if (pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
+                       return VK_ERROR_FORMAT_NOT_SUPPORTED;
+
+               if ((pImageFormatInfo->usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+                                                                               | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+                                                                               | VK_IMAGE_USAGE_SAMPLED_BIT
+                                                                               | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
+                       != 0)
+               {
+                       return VK_ERROR_FORMAT_NOT_SUPPORTED;
+               }
+
+               if ((pImageFormatInfo->flags & ~(VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
+                                                                               /*| VK_IMAGE_CREATE_PROTECTED_BIT_KHR*/
+                                                                               /*| VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR*/))
+                       != 0)
+               {
+                       return VK_ERROR_FORMAT_NOT_SUPPORTED;
+               }
+
+               if (externalProperties)
+               {
+                       externalProperties->externalMemoryProperties.externalMemoryFeatures                     = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR
+                                                                                                                                                                               | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR
+                                                                                                                                                                               | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
+                       externalProperties->externalMemoryProperties.exportFromImportedHandleTypes      = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+                       externalProperties->externalMemoryProperties.compatibleHandleTypes                      = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+               }
+#else
+               DE_UNREF(externalProperties);
+               return VK_ERROR_FORMAT_NOT_SUPPORTED;
+#endif
+       }
+
+       return VK_SUCCESS;
+}
+
 // \note getInstanceProcAddr is a little bit special:
 // vkNullDriverImpl.inl needs it to define s_platformFunctions but
 // getInstanceProcAddr() implementation needs other entry points from
index adafdf2..4428768 100644 (file)
@@ -13,12 +13,6 @@ VKAPI_ATTR VkResult VKAPI_CALL createDevice (VkPhysicalDevice physicalDevice, co
        VK_NULL_RETURN((*pDevice = allocateHandle<Device, VkDevice>(physicalDevice, pCreateInfo, pAllocator)));
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL allocateMemory (VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory)
-{
-       DE_UNREF(pAllocator);
-       VK_NULL_RETURN((*pMemory = allocateNonDispHandle<DeviceMemory, VkDeviceMemory>(device, pAllocateInfo, pAllocator)));
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL createFence (VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence)
 {
        DE_UNREF(pAllocator);
@@ -377,12 +371,6 @@ VKAPI_ATTR VkResult VKAPI_CALL deviceWaitIdle (VkDevice device)
        return VK_SUCCESS;
 }
 
-VKAPI_ATTR void VKAPI_CALL unmapMemory (VkDevice device, VkDeviceMemory memory)
-{
-       DE_UNREF(device);
-       DE_UNREF(memory);
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL flushMappedMemoryRanges (VkDevice device, deUint32 memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges)
 {
        DE_UNREF(device);
@@ -1118,14 +1106,6 @@ VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceFormatProperties2KHR (VkPhysicalDevi
        DE_UNREF(pFormatProperties);
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL getPhysicalDeviceImageFormatProperties2KHR (VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties)
-{
-       DE_UNREF(physicalDevice);
-       DE_UNREF(pImageFormatInfo);
-       DE_UNREF(pImageFormatProperties);
-       return VK_SUCCESS;
-}
-
 VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceQueueFamilyProperties2KHR (VkPhysicalDevice physicalDevice, deUint32* pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR* pQueueFamilyProperties)
 {
        DE_UNREF(physicalDevice);
@@ -1262,13 +1242,6 @@ VKAPI_ATTR void VKAPI_CALL debugReportMessageEXT (VkInstance instance, VkDebugRe
        DE_UNREF(pMessage);
 }
 
-VKAPI_ATTR void VKAPI_CALL getPhysicalDeviceExternalBufferPropertiesKHR (VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfoKHR* pExternalBufferInfo, VkExternalBufferPropertiesKHR* pExternalBufferProperties)
-{
-       DE_UNREF(physicalDevice);
-       DE_UNREF(pExternalBufferInfo);
-       DE_UNREF(pExternalBufferProperties);
-}
-
 VKAPI_ATTR VkResult VKAPI_CALL getMemoryWin32HandleKHR (VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, pt::Win32Handle* pHandle)
 {
        DE_UNREF(device);
@@ -1454,14 +1427,6 @@ VKAPI_ATTR VkResult VKAPI_CALL getMemoryAndroidHardwareBufferPropertiesANDROID (
        return VK_SUCCESS;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL getMemoryAndroidHardwareBufferANDROID (VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, pt::AndroidHardwareBufferPtr* pBuffer)
-{
-       DE_UNREF(device);
-       DE_UNREF(pInfo);
-       DE_UNREF(pBuffer);
-       return VK_SUCCESS;
-}
-
 static const tcu::StaticFunctionLibrary::Entry s_platformFunctions[] =
 {
        VK_NULL_FUNC_ENTRY(vkCreateInstance,                                            createInstance),
index 697477b..7dee952 100644 (file)
@@ -749,7 +749,9 @@ def writeNullDriverImpl (api, filename):
                                "vkGetBufferMemoryRequirements2KHR",
                                "vkGetImageMemoryRequirements",
                                "vkGetImageMemoryRequirements2KHR",
+                               "vkAllocateMemory",
                                "vkMapMemory",
+                               "vkUnmapMemory",
                                "vkAllocateDescriptorSets",
                                "vkFreeDescriptorSets",
                                "vkResetDescriptorPool",
@@ -757,6 +759,9 @@ def writeNullDriverImpl (api, filename):
                                "vkFreeCommandBuffers",
                                "vkCreateDisplayModeKHR",
                                "vkCreateSharedSwapchainsKHR",
+                               "vkGetPhysicalDeviceExternalBufferPropertiesKHR",
+                               "vkGetPhysicalDeviceImageFormatProperties2KHR",
+                               "vkGetMemoryAndroidHardwareBufferANDROID",
                        ]
                specialFuncs            = [f for f in api.functions if f.name in specialFuncNames]
                createFuncs                     = [f for f in api.functions if (f.name[:8] == "vkCreate" or f.name == "vkAllocateMemory") and not f in specialFuncs]