Add derived class for every type of external memory
This CL removes the "external" member in vk::DeviceMemory
and instead uses derived classes for each type of external
memory, in order to achieve the same result without the
extra level of indirection.
Bug: b/199306480
Change-Id: I1cab3c94e5bb35f027b8fd242a060a511776f100
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/56930
Presubmit-Ready: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Commit-Queue: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkDeviceMemory.cpp b/src/Vulkan/VkDeviceMemory.cpp
index e3c8229..20fc6cd 100644
--- a/src/Vulkan/VkDeviceMemory.cpp
+++ b/src/Vulkan/VkDeviceMemory.cpp
@@ -15,102 +15,13 @@
#include "VkDeviceMemory.hpp"
#include "VkBuffer.hpp"
#include "VkDevice.hpp"
-#include "VkDeviceMemoryExternalBase.hpp"
#include "VkImage.hpp"
#include "VkStringify.hpp"
#include "VkConfig.hpp"
-namespace vk {
-
-// Small class describing a given DeviceMemory::ExternalBase derived class.
-// |typeFlagBit| corresponds to the external memory handle type.
-// |instanceSize| is the size of each class instance in bytes.
-// |instanceInit| is a function pointer used to initialize an instance inplace
-// according to a |pAllocateInfo| parameter.
-class ExternalMemoryTraits
-{
-public:
- VkExternalMemoryHandleTypeFlagBits typeFlagBit;
- size_t instanceSize;
- void (*instanceInit)(void *external, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo);
-};
-
-// Template function that parses a |pAllocateInfo.pNext| chain to verify that
-// it asks for the creation or import of a memory type managed by implementation
-// class T. On success, return true and sets |pTraits| accordingly. Otherwise
-// return false.
-template<typename T>
-static bool parseCreateInfo(const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo,
- ExternalMemoryTraits *pTraits)
-{
- if(T::SupportsAllocateInfo(extendedAllocationInfo))
- {
- pTraits->typeFlagBit = T::typeFlagBit;
- pTraits->instanceSize = sizeof(T);
- pTraits->instanceInit = [](void *external,
- const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo) {
- new(external) T(extendedAllocationInfo);
- };
- return true;
- }
- return false;
-}
-
-// DeviceMemory::ExternalBase implementation that uses host memory.
-// Not really external, but makes everything simpler.
-class DeviceMemoryHostExternalBase : public DeviceMemory::ExternalBase
-{
-public:
- // Does not support any external memory type at all.
- static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = (VkExternalMemoryHandleTypeFlagBits)0;
-
- // Always return true as is used as a fallback in findTraits() below.
- static bool SupportsAllocateInfo(const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- {
- return true;
- }
-
- DeviceMemoryHostExternalBase(const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo) {}
-
- VkResult allocate(size_t size, void **pBuffer) override
- {
- buffer = vk::allocate(size, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY);
- if(!buffer)
- {
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
- }
-
- *pBuffer = buffer;
- return VK_SUCCESS;
- }
-
- void deallocate(void * /* buffer */, size_t size) override
- {
- vk::deallocate(buffer, DEVICE_MEMORY);
- buffer = nullptr;
- }
-
- VkExternalMemoryHandleTypeFlagBits getFlagBit() const override
- {
- return typeFlagBit;
- }
-
-#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
- uint64_t getMemoryObjectId() const override
- {
- return (uint64_t)buffer;
- }
-#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
-
-private:
- void *buffer = nullptr;
-};
-
-} // namespace vk
-
// Host-allocated memory and host-mapped foreign memory
-class ExternalMemoryHost : public vk::DeviceMemory::ExternalBase
+class ExternalMemoryHost : public vk::DeviceMemory, public vk::ObjectBase<ExternalMemoryHost, VkDeviceMemory>
{
public:
struct AllocateInfo
@@ -127,7 +38,8 @@
if((extendedAllocationInfo.importMemoryHostPointerInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT) &&
(extendedAllocationInfo.importMemoryHostPointerInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT))
{
- UNSUPPORTED("extendedAllocationInfo.importMemoryHostPointerInfo->handleType");
+ UNSUPPORTED("extendedAllocationInfo.importMemoryHostPointerInfo->handleType, %d",
+ int(extendedAllocationInfo.importMemoryHostPointerInfo->handleType));
}
hostPointer = extendedAllocationInfo.importMemoryHostPointerInfo->pHostPointer;
supported = true;
@@ -143,10 +55,10 @@
return info.supported;
}
- explicit ExternalMemoryHost(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- : allocateInfo(extendedAllocationInfo)
- {
- }
+ explicit ExternalMemoryHost(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
+ : vk::DeviceMemory(pCreateInfo, pDevice)
+ , allocateInfo(extendedAllocationInfo)
+ {}
VkResult allocate(size_t size, void **pBuffer) override
{
@@ -172,9 +84,9 @@
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
-// Helper struct to parse the VkMemoryAllocateInfo.pNext chain and
-// extract relevant information related to the handle type supported
-// by this DeviceMemory;:ExternalBase subclass.
+// Helper struct which reads the parsed allocation info and
+// extracts relevant information related to the handle type
+// supported by this DeviceMemory subclass.
struct OpaqueFdAllocateInfo
{
bool importFd = false;
@@ -183,7 +95,7 @@
OpaqueFdAllocateInfo() = default;
- // Parse the VkMemoryAllocateInfo.pNext chain to initialize an OpaqueFdAllocateInfo.
+ // Read the parsed allocation info to initialize an OpaqueFdAllocateInfo.
OpaqueFdAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
{
if(extendedAllocationInfo.importMemoryFdInfo)
@@ -230,69 +142,79 @@
namespace vk {
-static void findTraits(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo,
- ExternalMemoryTraits *pTraits)
+VkResult DeviceMemory::Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory, Device *device)
+{
+ *pMemory = VK_NULL_HANDLE;
+
+ vk::DeviceMemory::ExtendedAllocationInfo extendedAllocationInfo = {};
+ VkResult result = vk::DeviceMemory::ParseAllocationInfo(pAllocateInfo, &extendedAllocationInfo);
+ if(result != VK_SUCCESS)
+ {
+ return result;
+ }
+
+ result = Allocate(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
+ if(result != VK_SUCCESS)
+ {
+ return result;
+ }
+
+ // Make sure the memory allocation is done now so that OOM errors can be checked now
+ return vk::Cast(*pMemory)->allocate();
+}
+
+VkResult DeviceMemory::Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory,
+ const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *device)
{
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
- if(parseCreateInfo<AHardwareBufferExternalMemory>(extendedAllocationInfo, pTraits))
+ if(AHardwareBufferExternalMemory::SupportsAllocateInfo(extendedAllocationInfo))
{
- return;
+ return AHardwareBufferExternalMemory::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
}
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
- if(parseCreateInfo<OpaqueFdExternalMemory>(extendedAllocationInfo, pTraits))
+ if(OpaqueFdExternalMemory::SupportsAllocateInfo(extendedAllocationInfo))
{
- return;
+ return OpaqueFdExternalMemory::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
}
#endif
#if VK_USE_PLATFORM_FUCHSIA
- if(parseCreateInfo<zircon::VmoExternalMemory>(extendedAllocationInfo, pTraits))
+ if(zircon::VmoExternalMemory::SupportsAllocateInfo(extendedAllocationInfo))
{
- return;
+ return zircon::VmoExternalMemory::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
}
#endif
- if(parseCreateInfo<ExternalMemoryHost>(extendedAllocationInfo, pTraits))
+ if(ExternalMemoryHost::SupportsAllocateInfo(extendedAllocationInfo))
{
- return;
+ return ExternalMemoryHost::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
}
- parseCreateInfo<DeviceMemoryHostExternalBase>(extendedAllocationInfo, pTraits);
+
+ return vk::DeviceMemoryInternal::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
}
-DeviceMemory::DeviceMemory(const VkMemoryAllocateInfo *pAllocateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice)
+DeviceMemory::DeviceMemory(const VkMemoryAllocateInfo *pAllocateInfo, Device *pDevice)
: size(pAllocateInfo->allocationSize)
, memoryTypeIndex(pAllocateInfo->memoryTypeIndex)
, device(pDevice)
{
ASSERT(size);
-
- ExternalMemoryTraits traits;
- findTraits(extendedAllocationInfo, &traits);
- traits.instanceInit(mem, extendedAllocationInfo);
- external = reinterpret_cast<ExternalBase *>(mem);
- external->setDevicePtr(device);
}
void DeviceMemory::destroy(const VkAllocationCallbacks *pAllocator)
{
#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
- device->emitDeviceMemoryReport(external->isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT, external->getMemoryObjectId(), 0 /* size */, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
+ device->emitDeviceMemoryReport(isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT, getMemoryObjectId(), 0 /* size */, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
if(buffer)
{
- external->deallocate(buffer, size);
+ deallocate(buffer, size);
buffer = nullptr;
}
- external->~ExternalBase(); // Call virtual destructor in place.
- vk::deallocate(external, pAllocator);
}
size_t DeviceMemory::ComputeRequiredAllocationSize(const VkMemoryAllocateInfo *pAllocateInfo)
{
- ExtendedAllocationInfo extendedAllocationInfo;
- ParseAllocationInfo(pAllocateInfo, &extendedAllocationInfo);
- ExternalMemoryTraits traits;
- findTraits(extendedAllocationInfo, &traits);
- return traits.instanceSize;
+ return 0;
}
VkResult DeviceMemory::ParseAllocationInfo(const VkMemoryAllocateInfo *pAllocateInfo, DeviceMemory::ExtendedAllocationInfo *extendedAllocationInfo)
@@ -393,12 +315,12 @@
VkResult result = VK_SUCCESS;
if(!buffer)
{
- result = external->allocate(size, &buffer);
+ result = allocate(size, &buffer);
}
#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
if(result == VK_SUCCESS)
{
- device->emitDeviceMemoryReport(external->isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT, external->getMemoryObjectId(), size, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
+ device->emitDeviceMemoryReport(isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT, getMemoryObjectId(), size, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
}
else
{
@@ -435,7 +357,7 @@
// memory, so this check should always pass.
return true;
}
- VkExternalMemoryHandleTypeFlagBits handle_type_bit = external->getFlagBit();
+ VkExternalMemoryHandleTypeFlagBits handle_type_bit = getFlagBit();
if(!handle_type_bit)
{
// This device memory is not external and can accommodate
@@ -448,50 +370,47 @@
return (supportedHandleTypes & handle_type_bit) != 0;
}
-bool DeviceMemory::hasExternalImageProperties() const
+// Allocate the memory according to |size|. On success return VK_SUCCESS
+// and sets |*pBuffer|.
+VkResult DeviceMemory::allocate(size_t size, void **pBuffer)
{
- return external && external->hasExternalImageProperties();
-}
-
-int DeviceMemory::externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const
-{
- if(external)
+ buffer = vk::allocate(size, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY);
+ if(!buffer)
{
- return external->externalImageRowPitchBytes(aspect);
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
- // This function should never be called on non-external memory.
- ASSERT(false);
- return -1;
+ *pBuffer = buffer;
+ return VK_SUCCESS;
}
-VkDeviceSize DeviceMemory::externalImageMemoryOffset(VkImageAspectFlagBits aspect) const
+// Deallocate previously allocated memory at |buffer|.
+void DeviceMemory::deallocate(void *buffer, size_t size)
{
- if(external)
- {
- return external->externalImageMemoryOffset(aspect);
- }
+ vk::deallocate(buffer, DEVICE_MEMORY);
+ buffer = nullptr;
+}
- // This function should never be called on non-external memory.
- ASSERT(false);
- return -1;
+// Return the handle type flag bit supported by this implementation.
+// A value of 0 corresponds to non-external memory.
+VkExternalMemoryHandleTypeFlagBits DeviceMemory::getFlagBit() const
+{
+ // Does not support any external memory type at all.
+ static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = (VkExternalMemoryHandleTypeFlagBits)0;
+ return typeFlagBit;
}
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
VkResult DeviceMemory::exportFd(int *pFd) const
{
- return external->exportFd(pFd);
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
VkResult DeviceMemory::exportAndroidHardwareBuffer(struct AHardwareBuffer **pAhb) const
{
- if(external->getFlagBit() != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
- {
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
- return static_cast<AHardwareBufferExternalMemory *>(external)->exportAndroidHardwareBuffer(pAhb);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
}
VkResult DeviceMemory::GetAndroidHardwareBufferProperties(VkDevice &ahbDevice, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties)
@@ -503,7 +422,7 @@
#if VK_USE_PLATFORM_FUCHSIA
VkResult DeviceMemory::exportHandle(zx_handle_t *pHandle) const
{
- return external->exportHandle(pHandle);
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
#endif
diff --git a/src/Vulkan/VkDeviceMemory.hpp b/src/Vulkan/VkDeviceMemory.hpp
index 098494c..77bf23a 100644
--- a/src/Vulkan/VkDeviceMemory.hpp
+++ b/src/Vulkan/VkDeviceMemory.hpp
@@ -22,11 +22,13 @@
class Device;
-class DeviceMemory : public Object<DeviceMemory, VkDeviceMemory>
+class DeviceMemory
{
public:
struct ExtendedAllocationInfo
{
+ VkDeviceSize allocationSize = 0;
+ uint32_t memoryTypeIndex = 0;
const VkExportMemoryAllocateInfo *exportMemoryAllocateInfo = nullptr;
const VkImportMemoryHostPointerInfoEXT *importMemoryHostPointerInfo = nullptr;
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
@@ -41,22 +43,37 @@
#endif
};
- DeviceMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice);
+protected:
+ DeviceMemory(const VkMemoryAllocateInfo *pCreateInfo, Device *pDevice);
+
+public:
+ virtual ~DeviceMemory() {}
+
+ static VkResult Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory, Device *device);
+
+ operator VkDeviceMemory()
+ {
+ return vk::TtoVkT<DeviceMemory, VkDeviceMemory>(this);
+ }
+
+ static inline DeviceMemory *Cast(VkDeviceMemory object)
+ {
+ return vk::VkTtoT<DeviceMemory, VkDeviceMemory>(object);
+ }
static size_t ComputeRequiredAllocationSize(const VkMemoryAllocateInfo *pCreateInfo);
- static VkResult ParseAllocationInfo(const VkMemoryAllocateInfo *pAllocateInfo, DeviceMemory::ExtendedAllocationInfo *extendedAllocationInfo);
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
- VkResult exportFd(int *pFd) const;
+ virtual VkResult exportFd(int *pFd) const;
#endif
#if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
- VkResult exportAndroidHardwareBuffer(struct AHardwareBuffer **pAhb) const;
+ virtual VkResult exportAndroidHardwareBuffer(struct AHardwareBuffer **pAhb) const;
static VkResult GetAndroidHardwareBufferProperties(VkDevice &device, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties);
#endif
#if VK_USE_PLATFORM_FUCHSIA
- VkResult exportHandle(zx_handle_t *pHandle) const;
+ virtual VkResult exportHandle(zx_handle_t *pHandle) const;
#endif
void destroy(const VkAllocationCallbacks *pAllocator);
@@ -71,21 +88,58 @@
bool checkExternalMemoryHandleType(
VkExternalMemoryHandleTypeFlags supportedExternalMemoryHandleType) const;
- // Internal implementation class for external memory. Platform-specific.
- class ExternalBase;
+ // Some external device memories, such as Android hardware buffers, represent
+ // specific images with requirements.
+ virtual bool hasExternalImageProperties() const { return false; }
+ virtual int externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const { return 0; }
+ virtual VkDeviceSize externalImageMemoryOffset(VkImageAspectFlagBits aspect) const { return 0; }
- bool hasExternalImageProperties() const;
- int externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const;
- VkDeviceSize externalImageMemoryOffset(VkImageAspectFlagBits aspect) const;
+protected:
+ // Allocate the memory according to |size|. On success return VK_SUCCESS
+ // and sets |*pBuffer|.
+ virtual VkResult allocate(size_t size, void **pBuffer);
+
+ // Deallocate previously allocated memory at |buffer|.
+ virtual void deallocate(void *buffer, size_t size);
+
+ // Return the handle type flag bit supported by this implementation.
+ // A value of 0 corresponds to non-external memory.
+ virtual VkExternalMemoryHandleTypeFlagBits getFlagBit() const;
+
+ virtual void setDevicePtr(Device *pDevice) {}
+
+#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
+ virtual bool isImport() const
+ {
+ return false;
+ }
+
+ virtual uint64_t getMemoryObjectId() const
+ {
+ return (uint64_t)buffer;
+ }
+#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
private:
+ static VkResult ParseAllocationInfo(const VkMemoryAllocateInfo *pAllocateInfo, DeviceMemory::ExtendedAllocationInfo *extendedAllocationInfo);
+ static VkResult Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory,
+ const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *device);
+
void *buffer = nullptr;
VkDeviceSize size = 0;
uint32_t memoryTypeIndex = 0;
- ExternalBase *external = nullptr;
Device *device;
};
+// This class represents a DeviceMemory object with no external memory
+class DeviceMemoryInternal : public DeviceMemory, public ObjectBase<DeviceMemoryInternal, VkDeviceMemory>
+{
+public:
+ DeviceMemoryInternal(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice)
+ : DeviceMemory(pCreateInfo, pDevice)
+ {}
+};
+
static inline DeviceMemory *Cast(VkDeviceMemory object)
{
return DeviceMemory::Cast(object);
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
index 1eab778..9085814 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
@@ -191,8 +191,9 @@
}
}
-AHardwareBufferExternalMemory::AHardwareBufferExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- : allocateInfo(extendedAllocationInfo)
+AHardwareBufferExternalMemory::AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
+ : vk::DeviceMemory(pCreateInfo, pDevice)
+ , allocateInfo(extendedAllocationInfo)
{
}
@@ -332,6 +333,11 @@
VkResult AHardwareBufferExternalMemory::exportAndroidHardwareBuffer(AHardwareBuffer **pAhb) const
{
+ if(getFlagBit() != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
+ {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
// Each call to vkGetMemoryAndroidHardwareBufferANDROID *must* return an Android hardware buffer with a new reference
// acquired in addition to the reference held by the VkDeviceMemory. To avoid leaking resources, the application *must*
// release the reference by calling AHardwareBuffer_release when it is no longer needed.
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
index aa9f989..b8e5844 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.hpp
@@ -18,17 +18,16 @@
#include "VkBuffer.hpp"
#include "VkDevice.hpp"
#include "VkDeviceMemory.hpp"
-#include "VkDeviceMemoryExternalBase.hpp"
#include "VkImage.hpp"
#include <vndk/hardware_buffer.h>
-class AHardwareBufferExternalMemory : public vk::DeviceMemory::ExternalBase
+class AHardwareBufferExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<AHardwareBufferExternalMemory, VkDeviceMemory>
{
public:
- // Helper struct to used the parse allocation info and extract
- // relevant information related to the handle type supported
- // by this DeviceMemory::ExternalBase subclass.
+ // Helper struct which reads the parsed allocation info and
+ // extracts relevant information related to the handle type
+ // supported by this DeviceMemory subclass.
struct AllocateInfo
{
bool importAhb = false;
@@ -39,7 +38,7 @@
AllocateInfo() = default;
- // Used the parsed allocation info to initialize a AllocateInfo.
+ // Use the parsed allocation info to initialize a AllocateInfo.
AllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo);
};
@@ -51,7 +50,7 @@
return info.importAhb || info.exportAhb;
}
- explicit AHardwareBufferExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo);
+ explicit AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice);
~AHardwareBufferExternalMemory();
VkResult allocate(size_t size, void **pBuffer) override;
@@ -59,7 +58,7 @@
VkExternalMemoryHandleTypeFlagBits getFlagBit() const override { return typeFlagBit; }
- VkResult exportAndroidHardwareBuffer(AHardwareBuffer **pAhb) const;
+ virtual VkResult exportAndroidHardwareBuffer(AHardwareBuffer **pAhb) const override final;
void setDevicePtr(vk::Device *pDevice) override { device = pDevice; }
diff --git a/src/Vulkan/VkDeviceMemoryExternalBase.hpp b/src/Vulkan/VkDeviceMemoryExternalBase.hpp
deleted file mode 100644
index c8dc313..0000000
--- a/src/Vulkan/VkDeviceMemoryExternalBase.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
-//
-// 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.
-
-#ifndef VK_DEVICE_MEMORY_EXTERNAL_BASE_HPP_
-#define VK_DEVICE_MEMORY_EXTERNAL_BASE_HPP_
-
-#include "VkDeviceMemory.hpp"
-
-namespace vk {
-
-// Base abstract interface for a device memory implementation.
-class DeviceMemory::ExternalBase
-{
-public:
- virtual ~ExternalBase() = default;
-
- // Allocate the memory according to |size|. On success return VK_SUCCESS
- // and sets |*pBuffer|.
- virtual VkResult allocate(size_t size, void **pBuffer) = 0;
-
- // Deallocate previously allocated memory at |buffer|.
- virtual void deallocate(void *buffer, size_t size) = 0;
-
- // Return the handle type flag bit supported by this implementation.
- // A value of 0 corresponds to non-external memory.
- virtual VkExternalMemoryHandleTypeFlagBits getFlagBit() const = 0;
-
- virtual void setDevicePtr(Device *pDevice) {}
-
-#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
- virtual VkResult exportFd(int *pFd) const
- {
- return VK_ERROR_INVALID_EXTERNAL_HANDLE;
- }
-#endif
-
- // Some external device memories, such as Android hardware buffers, represent
- // specific images with requirements.
- virtual bool hasExternalImageProperties() const { return false; }
- virtual int externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const { return 0; }
- virtual VkDeviceSize externalImageMemoryOffset(VkImageAspectFlagBits aspect) const { return 0; }
-
-#ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
- virtual bool isImport() const
- {
- return false;
- }
-
- virtual uint64_t getMemoryObjectId() const
- {
- return 0;
- }
-#endif // SWIFTSHADER_DEVICE_MEMORY_REPORT
-
-protected:
- ExternalBase() = default;
-};
-
-} // namespace vk
-
-#endif // VK_DEVICE_MEMORY_EXTERNAL_BASE_HPP_
diff --git a/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp b/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
index 5c2c8f3..b7a4cef 100644
--- a/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "VkDeviceMemory.hpp"
#include "VkStringify.hpp"
#include "System/Debug.hpp"
@@ -21,12 +22,12 @@
namespace zircon {
-class VmoExternalMemory : public vk::DeviceMemory::ExternalBase
+class VmoExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<VmoExternalMemory, VkDeviceMemory>
{
public:
- // Helper struct to parse the VkMemoryAllocateInfo.pNext chain and
- // extract relevant information related to the handle type supported
- // by this DeviceMemory::ExternalBase subclass.
+ // Helper struct which reads the parsed allocation info and
+ // extracts relevant information related to the handle type
+ // supported by this DeviceMemory subclass.
struct AllocateInfo
{
bool importHandle = false;
@@ -35,7 +36,7 @@
AllocateInfo() = default;
- // Used the parsed allocation info to initialize a AllocateInfo.
+ // Use the parsed allocation info to initialize a AllocateInfo.
AllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
{
if(extendedAllocationInfo.importMemoryZirconHandleInfo)
@@ -67,8 +68,9 @@
return info.importHandle || info.exportHandle;
}
- explicit VmoExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- : allocateInfo(extendedAllocationInfo)
+ explicit VmoExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
+ : vk::DeviceMemory(pCreateInfo, pDevice)
+ , allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/VkDeviceMemoryExternalLinux.hpp b/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
index 462dd7c..f4d7f66 100644
--- a/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "VkDeviceMemory.hpp"
+
#include "System/Debug.hpp"
#include "System/Linux/MemFd.hpp"
@@ -19,7 +21,7 @@
#include <string.h>
#include <sys/mman.h>
-class OpaqueFdExternalMemory : public vk::DeviceMemory::ExternalBase
+class OpaqueFdExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<OpaqueFdExternalMemory, VkDeviceMemory>
{
public:
static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
@@ -30,8 +32,9 @@
return info.importFd || info.exportFd;
}
- explicit OpaqueFdExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- : allocateInfo(extendedAllocationInfo)
+ explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
+ : vk::DeviceMemory(pCreateInfo, pDevice)
+ , allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/VkDeviceMemoryExternalMac.hpp b/src/Vulkan/VkDeviceMemoryExternalMac.hpp
index 4d35810..b68f618 100644
--- a/src/Vulkan/VkDeviceMemoryExternalMac.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalMac.hpp
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "VkDeviceMemory.hpp"
+
#include "System/Debug.hpp"
#include <errno.h>
@@ -55,7 +57,7 @@
// An implementation of OpaqueFdExternalMemory that relies on shm_open().
// Useful on OS X which do not have Linux memfd regions.
-class OpaqueFdExternalMemory : public vk::DeviceMemory::ExternalBase
+class OpaqueFdExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<OpaqueFdExternalMemory, VkDeviceMemory>
{
public:
static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
@@ -66,8 +68,9 @@
return info.importFd || info.exportFd;
}
- explicit OpaqueFdExternalMemory(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
- : allocateInfo(extendedAllocationInfo)
+ explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
+ : vk::DeviceMemory(pCreateInfo, pDevice)
+ , allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index f2551d6..1dcb45e 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -1025,21 +1025,8 @@
TRACE("(VkDevice device = %p, const VkMemoryAllocateInfo* pAllocateInfo = %p, const VkAllocationCallbacks* pAllocator = %p, VkDeviceMemory* pMemory = %p)",
device, pAllocateInfo, pAllocator, pMemory);
- vk::DeviceMemory::ExtendedAllocationInfo extendedAllocationInfo = {};
- VkResult result = vk::DeviceMemory::ParseAllocationInfo(pAllocateInfo, &extendedAllocationInfo);
- if(result != VK_SUCCESS)
- {
- return result;
- }
+ VkResult result = vk::DeviceMemory::Allocate(pAllocator, pAllocateInfo, pMemory, vk::Cast(device));
- result = vk::DeviceMemory::Create(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, vk::Cast(device));
- if(result != VK_SUCCESS)
- {
- return result;
- }
-
- // Make sure the memory allocation is done now so that OOM errors can be checked now
- result = vk::Cast(*pMemory)->allocate();
if(result != VK_SUCCESS)
{
vk::destroy(*pMemory, pAllocator);