bufferDeviceAddress: opaqueCaptureAddress support
This CL ads an implementation of these functions:
- vkGetBufferDeviceAddress. Relevant spec text:
"The 64-bit return value is an address of the start of pInfo->buffer.
...
If the buffer was created with a non-zero value of
VkBufferOpaqueCaptureAddressCreateInfo::opaqueCaptureAddress or
VkBufferDeviceAddressCreateInfoEXT::deviceAddress, the return value
will be the same address that was returned at capture time."
Note: SwiftShader does not expose VK_EXT_buffer_device_address, so
an assert was added, along with a comment explaining what to
do it we ever support this extension.
- vkGetBufferOpaqueCaptureAddress. Relevant spec text:
"The 64-bit return value is an opaque capture address of the start
of pInfo->buffer.
If the buffer was created with a non-zero value of
VkBufferOpaqueCaptureAddressCreateInfo::opaqueCaptureAddress the
return value must be the same address."
- vkGetDeviceMemoryOpaqueCaptureAddress. Relevant spec text:
"The 64-bit return value is an opaque address representing the
start of pInfo->memory.
If the memory object was allocated with a non-zero value of
VkMemoryOpaqueCaptureAddressAllocateInfo::opaqueCaptureAddress,
the return value must be the same address."
This implicitly means adding support for OpaqueCaptureAddress in
DeviceMemory and Buffer objects. This is required by the
bufferDeviceAddress feature, which is mandatory in Vulkan 1.3.
This CL does not add support for SPV_KHR_physical_storage_buffer,
which is the other half of the bufferDeviceAddress feature, so the
bufferDeviceAddress feature isn't be exposed in this CL.
Bug: b/184952772
Change-Id: I73ef36428ae0fd4474bc90a9e6cf8b17de0a36d9
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/64013
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Commit-Queue: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/VkBuffer.cpp b/src/Vulkan/VkBuffer.cpp
index e4559f4..daa37d9 100644
--- a/src/Vulkan/VkBuffer.cpp
+++ b/src/Vulkan/VkBuffer.cpp
@@ -43,6 +43,11 @@
const auto *externalInfo = reinterpret_cast<const VkExternalMemoryBufferCreateInfo *>(nextInfo);
supportedExternalMemoryHandleTypes = externalInfo->handleTypes;
}
+ else if(nextInfo->sType == VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO)
+ {
+ const auto *opaqueCaptureAddressInfo = reinterpret_cast<const VkBufferOpaqueCaptureAddressCreateInfo *>(nextInfo);
+ opaqueCaptureAddress = opaqueCaptureAddressInfo->opaqueCaptureAddress;
+ }
}
}
@@ -146,6 +151,11 @@
return reinterpret_cast<uint8_t *>(memory) + offset;
}
+uint64_t Buffer::getOpaqueCaptureAddress() const
+{
+ return (opaqueCaptureAddress != 0) ? opaqueCaptureAddress : static_cast<uint64_t>(reinterpret_cast<uintptr_t>(memory));
+}
+
uint8_t *Buffer::end() const
{
return reinterpret_cast<uint8_t *>(getOffsetPointer(size + 1));
diff --git a/src/Vulkan/VkBuffer.hpp b/src/Vulkan/VkBuffer.hpp
index f9428b8..f17480a 100644
--- a/src/Vulkan/VkBuffer.hpp
+++ b/src/Vulkan/VkBuffer.hpp
@@ -38,6 +38,7 @@
void fill(VkDeviceSize dstOffset, VkDeviceSize fillSize, uint32_t data);
void update(VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData);
void *getOffsetPointer(VkDeviceSize offset) const;
+ uint64_t getOpaqueCaptureAddress() const;
inline VkDeviceSize getSize() const { return size; }
uint8_t *end() const;
bool canBindToMemory(DeviceMemory *pDeviceMemory) const;
@@ -53,6 +54,7 @@
VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32_t queueFamilyIndexCount = 0;
uint32_t *queueFamilyIndices = nullptr;
+ uint64_t opaqueCaptureAddress = 0;
VkExternalMemoryHandleTypeFlags supportedExternalMemoryHandleTypes = (VkExternalMemoryHandleTypeFlags)0;
};
diff --git a/src/Vulkan/VkDeviceMemory.cpp b/src/Vulkan/VkDeviceMemory.cpp
index a366661..15c0e57 100644
--- a/src/Vulkan/VkDeviceMemory.cpp
+++ b/src/Vulkan/VkDeviceMemory.cpp
@@ -141,9 +141,10 @@
return vk::DeviceMemoryInternal::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
}
-DeviceMemory::DeviceMemory(const VkMemoryAllocateInfo *pAllocateInfo, Device *pDevice)
+DeviceMemory::DeviceMemory(const VkMemoryAllocateInfo *pAllocateInfo, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice)
: allocationSize(pAllocateInfo->allocationSize)
, memoryTypeIndex(pAllocateInfo->memoryTypeIndex)
+ , opaqueCaptureAddress(extendedAllocationInfo.opaqueCaptureAddress)
, device(pDevice)
{
ASSERT(allocationSize);
@@ -242,6 +243,10 @@
}
break;
#endif // VK_USE_PLATFORM_FUCHSIA
+ case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO:
+ extendedAllocationInfo->opaqueCaptureAddress =
+ reinterpret_cast<const VkMemoryOpaqueCaptureAddressAllocateInfo *>(allocationInfo)->opaqueCaptureAddress;
+ break;
default:
UNSUPPORTED("pAllocateInfo->pNext sType = %s", vk::Stringify(allocationInfo->sType).c_str());
break;
@@ -303,6 +308,11 @@
return reinterpret_cast<char *>(buffer) + pOffset;
}
+uint64_t DeviceMemory::getOpaqueCaptureAddress() const
+{
+ return (opaqueCaptureAddress != 0) ? opaqueCaptureAddress : static_cast<uint64_t>(reinterpret_cast<uintptr_t>(buffer));
+}
+
bool DeviceMemory::checkExternalMemoryHandleType(
VkExternalMemoryHandleTypeFlags supportedHandleTypes) const
{
diff --git a/src/Vulkan/VkDeviceMemory.hpp b/src/Vulkan/VkDeviceMemory.hpp
index cce7680..cf92549 100644
--- a/src/Vulkan/VkDeviceMemory.hpp
+++ b/src/Vulkan/VkDeviceMemory.hpp
@@ -29,6 +29,7 @@
{
VkDeviceSize allocationSize = 0;
uint32_t memoryTypeIndex = 0;
+ uint64_t opaqueCaptureAddress = 0;
const VkExportMemoryAllocateInfo *exportMemoryAllocateInfo = nullptr;
const VkImportMemoryHostPointerInfoEXT *importMemoryHostPointerInfo = nullptr;
#if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
@@ -44,7 +45,7 @@
};
protected:
- DeviceMemory(const VkMemoryAllocateInfo *pCreateInfo, Device *pDevice);
+ DeviceMemory(const VkMemoryAllocateInfo *pCreateInfo, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice);
public:
virtual ~DeviceMemory() {}
@@ -81,6 +82,7 @@
VkResult map(VkDeviceSize offset, VkDeviceSize size, void **ppData);
VkDeviceSize getCommittedMemoryInBytes() const;
void *getOffsetPointer(VkDeviceSize pOffset) const;
+ uint64_t getOpaqueCaptureAddress() const;
uint32_t getMemoryTypeIndex() const { return memoryTypeIndex; }
// If this is external memory, return true iff its handle type matches the bitmask
@@ -119,6 +121,7 @@
void *buffer = nullptr;
const VkDeviceSize allocationSize;
const uint32_t memoryTypeIndex;
+ uint64_t opaqueCaptureAddress = 0;
Device *const device;
private:
@@ -132,7 +135,7 @@
{
public:
DeviceMemoryInternal(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice)
- : DeviceMemory(pCreateInfo, pDevice)
+ : DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
{}
};
diff --git a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
index 3efbafd..07e2b92 100644
--- a/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
+++ b/src/Vulkan/VkDeviceMemoryExternalAndroid.cpp
@@ -194,7 +194,7 @@
}
AHardwareBufferExternalMemory::AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
- : vk::DeviceMemory(pCreateInfo, pDevice)
+ : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
, allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp b/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
index 9a7009b..492143b 100644
--- a/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
@@ -69,7 +69,7 @@
}
explicit VmoExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
- : vk::DeviceMemory(pCreateInfo, pDevice)
+ : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
, allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/VkDeviceMemoryExternalHost.cpp b/src/Vulkan/VkDeviceMemoryExternalHost.cpp
index 13022ac..9813f36 100644
--- a/src/Vulkan/VkDeviceMemoryExternalHost.cpp
+++ b/src/Vulkan/VkDeviceMemoryExternalHost.cpp
@@ -36,7 +36,7 @@
}
ExternalMemoryHost::ExternalMemoryHost(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
- : vk::DeviceMemory(pCreateInfo, pDevice)
+ : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
, allocateInfo(extendedAllocationInfo)
{}
diff --git a/src/Vulkan/VkDeviceMemoryExternalLinux.hpp b/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
index d68eb45..a62caa8 100644
--- a/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalLinux.hpp
@@ -33,7 +33,7 @@
}
explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
- : vk::DeviceMemory(pCreateInfo, pDevice)
+ : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
, allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/VkDeviceMemoryExternalMac.hpp b/src/Vulkan/VkDeviceMemoryExternalMac.hpp
index f23d416..005ae0f 100644
--- a/src/Vulkan/VkDeviceMemoryExternalMac.hpp
+++ b/src/Vulkan/VkDeviceMemoryExternalMac.hpp
@@ -69,7 +69,7 @@
}
explicit OpaqueFdExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
- : vk::DeviceMemory(pCreateInfo, pDevice)
+ : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
, allocateInfo(extendedAllocationInfo)
{
}
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index b6b5962..cfc15b8 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -1795,24 +1795,27 @@
{
TRACE("(VkDevice device = %p, const VkBufferDeviceAddressInfo* pInfo = %p)",
device, pInfo);
- UNSUPPORTED("VK_KHR_buffer_device_address");
- return 0;
+
+ // This function must return VkBufferDeviceAddressCreateInfoEXT::deviceAddress if provided
+ ASSERT(!vk::Cast(device)->hasExtension(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME));
+
+ return vk::Cast(pInfo->buffer)->getOpaqueCaptureAddress();
}
VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo)
{
TRACE("(VkDevice device = %p, const VkBufferDeviceAddressInfo* pInfo = %p)",
device, pInfo);
- UNSUPPORTED("VK_KHR_buffer_device_address");
- return 0;
+
+ return vk::Cast(pInfo->buffer)->getOpaqueCaptureAddress();
}
VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo *pInfo)
{
TRACE("(VkDevice device = %p, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo = %p)",
device, pInfo);
- UNSUPPORTED("VK_KHR_buffer_device_address");
- return 0;
+
+ return vk::Cast(pInfo->memory)->getOpaqueCaptureAddress();
}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkBufferView *pView)