xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkDeviceMemoryExternalFuchsia.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "VkDeviceMemory.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include "VkStringify.hpp"
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "System/Debug.hpp"
19*03ce13f7SAndroid Build Coastguard Worker 
20*03ce13f7SAndroid Build Coastguard Worker #include <zircon/process.h>
21*03ce13f7SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker namespace zircon {
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker class VmoExternalMemory : public vk::DeviceMemory, public vk::ObjectBase<VmoExternalMemory, VkDeviceMemory>
26*03ce13f7SAndroid Build Coastguard Worker {
27*03ce13f7SAndroid Build Coastguard Worker public:
28*03ce13f7SAndroid Build Coastguard Worker 	// Helper struct which reads the parsed allocation info and
29*03ce13f7SAndroid Build Coastguard Worker 	// extracts relevant information related to the handle type
30*03ce13f7SAndroid Build Coastguard Worker 	// supported by this DeviceMemory subclass.
31*03ce13f7SAndroid Build Coastguard Worker 	struct AllocateInfo
32*03ce13f7SAndroid Build Coastguard Worker 	{
33*03ce13f7SAndroid Build Coastguard Worker 		bool importHandle = false;
34*03ce13f7SAndroid Build Coastguard Worker 		bool exportHandle = false;
35*03ce13f7SAndroid Build Coastguard Worker 		zx_handle_t handle = ZX_HANDLE_INVALID;
36*03ce13f7SAndroid Build Coastguard Worker 
37*03ce13f7SAndroid Build Coastguard Worker 		AllocateInfo() = default;
38*03ce13f7SAndroid Build Coastguard Worker 
39*03ce13f7SAndroid Build Coastguard Worker 		// Use the parsed allocation info to initialize a AllocateInfo.
AllocateInfozircon::VmoExternalMemory::AllocateInfo40*03ce13f7SAndroid Build Coastguard Worker 		AllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
41*03ce13f7SAndroid Build Coastguard Worker 		{
42*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo.importMemoryZirconHandleInfo)
43*03ce13f7SAndroid Build Coastguard Worker 			{
44*03ce13f7SAndroid Build Coastguard Worker 				if(extendedAllocationInfo.importMemoryZirconHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
45*03ce13f7SAndroid Build Coastguard Worker 				{
46*03ce13f7SAndroid Build Coastguard Worker 					UNSUPPORTED("extendedAllocationInfo.importMemoryZirconHandleInfo->handleType");
47*03ce13f7SAndroid Build Coastguard Worker 				}
48*03ce13f7SAndroid Build Coastguard Worker 				importHandle = true;
49*03ce13f7SAndroid Build Coastguard Worker 				handle = extendedAllocationInfo.importMemoryZirconHandleInfo->handle;
50*03ce13f7SAndroid Build Coastguard Worker 			}
51*03ce13f7SAndroid Build Coastguard Worker 
52*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo.exportMemoryAllocateInfo)
53*03ce13f7SAndroid Build Coastguard Worker 			{
54*03ce13f7SAndroid Build Coastguard Worker 				if(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
55*03ce13f7SAndroid Build Coastguard Worker 				{
56*03ce13f7SAndroid Build Coastguard Worker 					UNSUPPORTED("extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes");
57*03ce13f7SAndroid Build Coastguard Worker 				}
58*03ce13f7SAndroid Build Coastguard Worker 				exportHandle = true;
59*03ce13f7SAndroid Build Coastguard Worker 			}
60*03ce13f7SAndroid Build Coastguard Worker 		}
61*03ce13f7SAndroid Build Coastguard Worker 	};
62*03ce13f7SAndroid Build Coastguard Worker 
63*03ce13f7SAndroid Build Coastguard Worker 	static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA;
64*03ce13f7SAndroid Build Coastguard Worker 
supportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo)65*03ce13f7SAndroid Build Coastguard Worker 	static bool supportsAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
66*03ce13f7SAndroid Build Coastguard Worker 	{
67*03ce13f7SAndroid Build Coastguard Worker 		AllocateInfo info(extendedAllocationInfo);
68*03ce13f7SAndroid Build Coastguard Worker 		return info.importHandle || info.exportHandle;
69*03ce13f7SAndroid Build Coastguard Worker 	}
70*03ce13f7SAndroid Build Coastguard Worker 
VmoExternalMemory(const VkMemoryAllocateInfo * pCreateInfo,void * mem,const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,vk::Device * pDevice)71*03ce13f7SAndroid Build Coastguard Worker 	explicit VmoExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
72*03ce13f7SAndroid Build Coastguard Worker 	    : vk::DeviceMemory(pCreateInfo, extendedAllocationInfo, pDevice)
73*03ce13f7SAndroid Build Coastguard Worker 	    , allocateInfo(extendedAllocationInfo)
74*03ce13f7SAndroid Build Coastguard Worker 	{
75*03ce13f7SAndroid Build Coastguard Worker 	}
76*03ce13f7SAndroid Build Coastguard Worker 
~VmoExternalMemory()77*03ce13f7SAndroid Build Coastguard Worker 	~VmoExternalMemory()
78*03ce13f7SAndroid Build Coastguard Worker 	{
79*03ce13f7SAndroid Build Coastguard Worker 		closeVmo();
80*03ce13f7SAndroid Build Coastguard Worker 	}
81*03ce13f7SAndroid Build Coastguard Worker 
allocateBuffer()82*03ce13f7SAndroid Build Coastguard Worker 	VkResult allocateBuffer() override
83*03ce13f7SAndroid Build Coastguard Worker 	{
84*03ce13f7SAndroid Build Coastguard Worker 		if(allocateInfo.importHandle)
85*03ce13f7SAndroid Build Coastguard Worker 		{
86*03ce13f7SAndroid Build Coastguard Worker 			// NOTE: handle ownership is passed to the VkDeviceMemory.
87*03ce13f7SAndroid Build Coastguard Worker 			vmoHandle = allocateInfo.handle;
88*03ce13f7SAndroid Build Coastguard Worker 		}
89*03ce13f7SAndroid Build Coastguard Worker 		else
90*03ce13f7SAndroid Build Coastguard Worker 		{
91*03ce13f7SAndroid Build Coastguard Worker 			ASSERT(allocateInfo.exportHandle);
92*03ce13f7SAndroid Build Coastguard Worker 			zx_status_t status = zx_vmo_create(allocationSize, 0, &vmoHandle);
93*03ce13f7SAndroid Build Coastguard Worker 			if(status != ZX_OK)
94*03ce13f7SAndroid Build Coastguard Worker 			{
95*03ce13f7SAndroid Build Coastguard Worker 				TRACE("zx_vmo_create() returned %d", status);
96*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_OUT_OF_DEVICE_MEMORY;
97*03ce13f7SAndroid Build Coastguard Worker 			}
98*03ce13f7SAndroid Build Coastguard Worker 		}
99*03ce13f7SAndroid Build Coastguard Worker 
100*03ce13f7SAndroid Build Coastguard Worker 		// Now map it directly.
101*03ce13f7SAndroid Build Coastguard Worker 		zx_vaddr_t addr = 0;
102*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_vmar_map(zx_vmar_root_self(),
103*03ce13f7SAndroid Build Coastguard Worker 		                                 ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
104*03ce13f7SAndroid Build Coastguard Worker 		                                 0,  // vmar_offset
105*03ce13f7SAndroid Build Coastguard Worker 		                                 vmoHandle,
106*03ce13f7SAndroid Build Coastguard Worker 		                                 0,  // vmo_offset
107*03ce13f7SAndroid Build Coastguard Worker 		                                 allocationSize,
108*03ce13f7SAndroid Build Coastguard Worker 		                                 &addr);
109*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
110*03ce13f7SAndroid Build Coastguard Worker 		{
111*03ce13f7SAndroid Build Coastguard Worker 			TRACE("zx_vmar_map() failed with %d", status);
112*03ce13f7SAndroid Build Coastguard Worker 			return VK_ERROR_MEMORY_MAP_FAILED;
113*03ce13f7SAndroid Build Coastguard Worker 		}
114*03ce13f7SAndroid Build Coastguard Worker 		buffer = reinterpret_cast<void *>(addr);
115*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
116*03ce13f7SAndroid Build Coastguard Worker 	}
117*03ce13f7SAndroid Build Coastguard Worker 
freeBuffer()118*03ce13f7SAndroid Build Coastguard Worker 	void freeBuffer() override
119*03ce13f7SAndroid Build Coastguard Worker 	{
120*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_vmar_unmap(zx_vmar_root_self(),
121*03ce13f7SAndroid Build Coastguard Worker 		                                   reinterpret_cast<zx_vaddr_t>(buffer),
122*03ce13f7SAndroid Build Coastguard Worker 		                                   allocationSize);
123*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
124*03ce13f7SAndroid Build Coastguard Worker 		{
125*03ce13f7SAndroid Build Coastguard Worker 			TRACE("zx_vmar_unmap() failed with %d", status);
126*03ce13f7SAndroid Build Coastguard Worker 		}
127*03ce13f7SAndroid Build Coastguard Worker 		closeVmo();
128*03ce13f7SAndroid Build Coastguard Worker 	}
129*03ce13f7SAndroid Build Coastguard Worker 
getFlagBit() const130*03ce13f7SAndroid Build Coastguard Worker 	VkExternalMemoryHandleTypeFlagBits getFlagBit() const override
131*03ce13f7SAndroid Build Coastguard Worker 	{
132*03ce13f7SAndroid Build Coastguard Worker 		return typeFlagBit;
133*03ce13f7SAndroid Build Coastguard Worker 	}
134*03ce13f7SAndroid Build Coastguard Worker 
exportHandle(zx_handle_t * pHandle) const135*03ce13f7SAndroid Build Coastguard Worker 	VkResult exportHandle(zx_handle_t *pHandle) const override
136*03ce13f7SAndroid Build Coastguard Worker 	{
137*03ce13f7SAndroid Build Coastguard Worker 		if(vmoHandle == ZX_HANDLE_INVALID)
138*03ce13f7SAndroid Build Coastguard Worker 		{
139*03ce13f7SAndroid Build Coastguard Worker 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
140*03ce13f7SAndroid Build Coastguard Worker 		}
141*03ce13f7SAndroid Build Coastguard Worker 		zx_status_t status = zx_handle_duplicate(vmoHandle, ZX_RIGHT_SAME_RIGHTS, pHandle);
142*03ce13f7SAndroid Build Coastguard Worker 		if(status != ZX_OK)
143*03ce13f7SAndroid Build Coastguard Worker 		{
144*03ce13f7SAndroid Build Coastguard Worker 			TRACE("zx_handle_duplicate() returned %d", status);
145*03ce13f7SAndroid Build Coastguard Worker 			return VK_ERROR_INVALID_EXTERNAL_HANDLE;
146*03ce13f7SAndroid Build Coastguard Worker 		}
147*03ce13f7SAndroid Build Coastguard Worker 		return VK_SUCCESS;
148*03ce13f7SAndroid Build Coastguard Worker 	}
149*03ce13f7SAndroid Build Coastguard Worker 
150*03ce13f7SAndroid Build Coastguard Worker private:
closeVmo()151*03ce13f7SAndroid Build Coastguard Worker 	void closeVmo()
152*03ce13f7SAndroid Build Coastguard Worker 	{
153*03ce13f7SAndroid Build Coastguard Worker 		if(vmoHandle != ZX_HANDLE_INVALID)
154*03ce13f7SAndroid Build Coastguard Worker 		{
155*03ce13f7SAndroid Build Coastguard Worker 			zx_handle_close(vmoHandle);
156*03ce13f7SAndroid Build Coastguard Worker 			vmoHandle = ZX_HANDLE_INVALID;
157*03ce13f7SAndroid Build Coastguard Worker 		}
158*03ce13f7SAndroid Build Coastguard Worker 	}
159*03ce13f7SAndroid Build Coastguard Worker 
160*03ce13f7SAndroid Build Coastguard Worker 	zx_handle_t vmoHandle = ZX_HANDLE_INVALID;
161*03ce13f7SAndroid Build Coastguard Worker 	AllocateInfo allocateInfo;
162*03ce13f7SAndroid Build Coastguard Worker };
163*03ce13f7SAndroid Build Coastguard Worker 
164*03ce13f7SAndroid Build Coastguard Worker }  // namespace zircon
165