Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-swiftshader: Commit

external/swiftshader


Commit MetaInfo

Revisione52e2dbcdf9d46b63ec6cc4df8bdea6f916c97e9 (tree)
Time2020-04-14 21:38:49
AuthorDavid 'Digit' Turner <digit@goog...>
CommiterDavid Turner

Log Message

[vulkan] Implement VK_FUCHSIA_external_memory extension.

This implements external memory using a Zircon VMO handle
that can be transferred between Fuchsia processes easily.

Bug: b/140419396
Change-Id: I81cecec35b218eb22f3318ddec7b790b89e5ce09
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/36168
Tested-by: David Turner <digit@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>

Change Summary

Incremental Difference

--- a/src/Vulkan/VkDeviceMemory.cpp
+++ b/src/Vulkan/VkDeviceMemory.cpp
@@ -51,6 +51,13 @@ public:
5151 }
5252 #endif
5353
54+#if VK_USE_PLATFORM_FUCHSIA
55+ virtual VkResult exportHandle(zx_handle_t *pHandle) const
56+ {
57+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
58+ }
59+#endif
60+
5461 protected:
5562 ExternalBase() = default;
5663 };
@@ -219,6 +226,10 @@ private:
219226 # endif
220227 #endif
221228
229+#if VK_USE_PLATFORM_FUCHSIA
230+# include "VkDeviceMemoryExternalFuchsia.hpp"
231+#endif
232+
222233 namespace vk {
223234
224235 static void findTraits(const VkMemoryAllocateInfo *pAllocateInfo,
@@ -236,6 +247,12 @@ static void findTraits(const VkMemoryAllocateInfo *pAllocateInfo,
236247 return;
237248 }
238249 #endif
250+#if VK_USE_PLATFORM_FUCHSIA
251+ if(parseCreateInfo<zircon::VmoExternalMemory>(pAllocateInfo, pTraits))
252+ {
253+ return;
254+ }
255+#endif
239256 if(parseCreateInfo<ExternalMemoryHost>(pAllocateInfo, pTraits))
240257 {
241258 return;
@@ -348,4 +365,11 @@ VkResult DeviceMemory::getAhbProperties(const struct AHardwareBuffer *buffer, Vk
348365 }
349366 #endif
350367
368+#if VK_USE_PLATFORM_FUCHSIA
369+VkResult DeviceMemory::exportHandle(zx_handle_t *pHandle) const
370+{
371+ return external->exportHandle(pHandle);
372+}
373+#endif
374+
351375 } // namespace vk
--- a/src/Vulkan/VkDeviceMemory.hpp
+++ b/src/Vulkan/VkDeviceMemory.hpp
@@ -36,6 +36,10 @@ public:
3636 static VkResult getAhbProperties(const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties);
3737 #endif
3838
39+#if VK_USE_PLATFORM_FUCHSIA
40+ VkResult exportHandle(zx_handle_t *pHandle) const;
41+#endif
42+
3943 void destroy(const VkAllocationCallbacks *pAllocator);
4044 VkResult allocate();
4145 VkResult map(VkDeviceSize offset, VkDeviceSize size, void **ppData);
--- /dev/null
+++ b/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp
@@ -0,0 +1,178 @@
1+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2+//
3+// Licensed under the Apache License, Version 2.0 (the "License");
4+// you may not use this file except in compliance with the License.
5+// You may obtain a copy of the License at
6+//
7+// http://www.apache.org/licenses/LICENSE-2.0
8+//
9+// Unless required by applicable law or agreed to in writing, software
10+// distributed under the License is distributed on an "AS IS" BASIS,
11+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+// See the License for the specific language governing permissions and
13+// limitations under the License.
14+
15+#include "VkStringify.hpp"
16+
17+#include "System/Debug.hpp"
18+
19+#include <zircon/process.h>
20+#include <zircon/syscalls.h>
21+
22+namespace zircon {
23+
24+class VmoExternalMemory : public vk::DeviceMemory::ExternalBase
25+{
26+public:
27+ // Helper struct to parse the VkMemoryAllocateInfo.pNext chain and
28+ // extract relevant information related to the handle type supported
29+ // by this DeviceMemory::ExternalBase subclass.
30+ struct AllocateInfo
31+ {
32+ bool importHandle = false;
33+ bool exportHandle = false;
34+ zx_handle_t handle = ZX_HANDLE_INVALID;
35+
36+ AllocateInfo() = default;
37+
38+ // Parse the VkMemoryAllocateInfo->pNext chain to initialize a AllocateInfo.
39+ AllocateInfo(const VkMemoryAllocateInfo *pAllocateInfo)
40+ {
41+ const auto *extInfo = reinterpret_cast<const VkBaseInStructure *>(pAllocateInfo->pNext);
42+ while(extInfo)
43+ {
44+ switch(extInfo->sType)
45+ {
46+ case VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA:
47+ {
48+ const auto *importInfo = reinterpret_cast<const VkImportMemoryZirconHandleInfoFUCHSIA *>(extInfo);
49+
50+ if(importInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
51+ {
52+ UNSUPPORTED("importInfo->handleType");
53+ }
54+ importHandle = true;
55+ handle = importInfo->handle;
56+ break;
57+ }
58+ case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
59+ {
60+ const auto *exportInfo = reinterpret_cast<const VkExportMemoryAllocateInfo *>(extInfo);
61+
62+ if(exportInfo->handleTypes != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
63+ {
64+ UNSUPPORTED("exportInfo->handleTypes");
65+ }
66+ exportHandle = true;
67+ break;
68+ }
69+
70+ default:
71+ WARN("VkMemoryAllocateInfo->pNext sType = %s", vk::Stringify(extInfo->sType).c_str());
72+ }
73+ extInfo = extInfo->pNext;
74+ }
75+ }
76+ };
77+
78+ static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
79+
80+ static bool supportsAllocateInfo(const VkMemoryAllocateInfo *pAllocateInfo)
81+ {
82+ AllocateInfo info(pAllocateInfo);
83+ return info.importHandle || info.exportHandle;
84+ }
85+
86+ explicit VmoExternalMemory(const VkMemoryAllocateInfo *pAllocateInfo)
87+ : allocateInfo(pAllocateInfo)
88+ {
89+ }
90+
91+ ~VmoExternalMemory()
92+ {
93+ closeVmo();
94+ }
95+
96+ VkResult allocate(size_t size, void **pBuffer) override
97+ {
98+ if(allocateInfo.importHandle)
99+ {
100+ // NOTE: handle ownership is passed to the VkDeviceMemory.
101+ vmoHandle = allocateInfo.handle;
102+ }
103+ else
104+ {
105+ ASSERT(allocateInfo.exportHandle);
106+ zx_status_t status = zx_vmo_create(size, 0, &vmoHandle);
107+ if(status != ZX_OK)
108+ {
109+ TRACE("zx_vmo_create() returned %d", status);
110+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
111+ }
112+ }
113+
114+ // Now map it directly.
115+ zx_vaddr_t addr = 0;
116+ zx_status_t status = zx_vmar_map(zx_vmar_root_self(),
117+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
118+ 0, // vmar_offset
119+ vmoHandle,
120+ 0, // vmo_offset
121+ size,
122+ &addr);
123+ if(status != ZX_OK)
124+ {
125+ TRACE("zx_vmar_map() failed with %d", status);
126+ return VK_ERROR_MEMORY_MAP_FAILED;
127+ }
128+ *pBuffer = reinterpret_cast<void *>(addr);
129+ return VK_SUCCESS;
130+ }
131+
132+ void deallocate(void *buffer, size_t size) override
133+ {
134+ zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(),
135+ reinterpret_cast<zx_vaddr_t>(buffer),
136+ size);
137+ if(status != ZX_OK)
138+ {
139+ TRACE("zx_vmar_unmap() failed with %d", status);
140+ }
141+ closeVmo();
142+ }
143+
144+ VkExternalMemoryHandleTypeFlagBits getFlagBit() const override
145+ {
146+ return typeFlagBit;
147+ }
148+
149+ VkResult exportHandle(zx_handle_t *pHandle) const override
150+ {
151+ if(vmoHandle == ZX_HANDLE_INVALID)
152+ {
153+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
154+ }
155+ zx_status_t status = zx_handle_duplicate(vmoHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
156+ if(status != ZX_OK)
157+ {
158+ TRACE("zx_handle_duplicate() returned %d", status);
159+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
160+ }
161+ return VK_SUCCESS;
162+ }
163+
164+private:
165+ void closeVmo()
166+ {
167+ if(vmoHandle != ZX_HANDLE_INVALID)
168+ {
169+ zx_handle_close(vmoHandle);
170+ vmoHandle = ZX_HANDLE_INVALID;
171+ }
172+ }
173+
174+ zx_handle_t vmoHandle = ZX_HANDLE_INVALID;
175+ AllocateInfo allocateInfo;
176+};
177+
178+} // namespace zircon
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -397,6 +397,16 @@ static const std::vector<std::pair<const char *, std::unordered_map<std::string,
397397 MAKE_VULKAN_DEVICE_ENTRY(vkGetMemoryAndroidHardwareBufferANDROID),
398398 } },
399399 #endif
400+
401+#if VK_USE_PLATFORM_FUCHSIA
402+ // VK_FUCHSIA_external_memory
403+ {
404+ VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME,
405+ {
406+ MAKE_VULKAN_DEVICE_ENTRY(vkGetMemoryZirconHandleFUCHSIA),
407+ MAKE_VULKAN_DEVICE_ENTRY(vkGetMemoryZirconHandlePropertiesFUCHSIA),
408+ } },
409+#endif
400410 };
401411
402412 #undef MAKE_VULKAN_DEVICE_ENTRY
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -43,6 +43,15 @@ static void setExternalMemoryProperties(VkExternalMemoryHandleTypeFlagBits handl
4343 return;
4444 }
4545 #endif
46+#if VK_USE_PLATFORM_FUCHSIA
47+ if(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
48+ {
49+ properties->compatibleHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
50+ properties->exportFromImportedHandleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
51+ properties->externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT;
52+ return;
53+ }
54+#endif
4655 properties->compatibleHandleTypes = 0;
4756 properties->exportFromImportedHandleTypes = 0;
4857 properties->externalMemoryFeatures = 0;
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -348,6 +348,7 @@ static const VkExtensionProperties deviceExtensionProperties[] = {
348348
349349 #if VK_USE_PLATFORM_FUCHSIA
350350 { VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION },
351+ { VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION },
351352 #endif
352353 { VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION },
353354 };
@@ -946,6 +947,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryA
946947 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
947948 break;
948949 #endif
950+#if VK_USE_PLATFORM_FUCHSIA
951+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA:
952+ break;
953+#endif
949954 default:
950955 UNSUPPORTED("exportInfo->handleTypes %u", exportInfo->handleTypes);
951956 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
@@ -967,6 +972,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory(VkDevice device, const VkMemoryA
967972 }
968973 break;
969974 }
975+#if VK_USE_PLATFORM_FUCHSIA
976+ case VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA:
977+ {
978+ auto *importInfo = reinterpret_cast<const VkImportMemoryZirconHandleInfoFUCHSIA *>(allocationInfo);
979+ if(importInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
980+ {
981+ UNSUPPORTED("importInfo->handleType %u", importInfo->handleType);
982+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
983+ }
984+ break;
985+ }
986+#endif // VK_USE_PLATFORM_FUCHSIA
970987 default:
971988 LOG_TRAP("pAllocateInfo->pNext sType = %s", vk::Stringify(allocationInfo->sType).c_str());
972989 break;
@@ -1039,6 +1056,45 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR(VkDevice device, VkExt
10391056 return VK_SUCCESS;
10401057 }
10411058 #endif // SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
1059+#if VK_USE_PLATFORM_FUCHSIA
1060+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA *pGetHandleInfo, zx_handle_t *pHandle)
1061+{
1062+ TRACE("(VkDevice device = %p, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetHandleInfo = %p, zx_handle_t* pHandle = %p",
1063+ device, pGetHandleInfo, pHandle);
1064+
1065+ if(pGetHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
1066+ {
1067+ UNSUPPORTED("pGetHandleInfo->handleType %u", pGetHandleInfo->handleType);
1068+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1069+ }
1070+ return vk::Cast(pGetHandleInfo->memory)->exportHandle(pHandle);
1071+}
1072+
1073+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t handle, VkMemoryZirconHandlePropertiesFUCHSIA *pMemoryZirconHandleProperties)
1074+{
1075+ TRACE("(VkDevice device = %p, VkExternalMemoryHandleTypeFlagBits handleType = %x, zx_handle_t handle = %d, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties = %p)",
1076+ device, handleType, handle, pMemoryZirconHandleProperties);
1077+
1078+ if(handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA)
1079+ {
1080+ UNSUPPORTED("handleType %u", handleType);
1081+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1082+ }
1083+
1084+ if(handle == ZX_HANDLE_INVALID)
1085+ {
1086+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1087+ }
1088+
1089+ const VkPhysicalDeviceMemoryProperties &memoryProperties =
1090+ vk::Cast(device)->getPhysicalDevice()->getMemoryProperties();
1091+
1092+ // All SwiftShader memory types support this!
1093+ pMemoryZirconHandleProperties->memoryTypeBits = (1U << memoryProperties.memoryTypeCount) - 1U;
1094+
1095+ return VK_SUCCESS;
1096+}
1097+#endif // VK_USE_PLATFORM_FUCHSIA
10421098
10431099 VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void *pHostPointer, VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
10441100 {
Show on old repository browser