xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkDeviceMemory.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 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 "VkDeviceMemoryExternalHost.hpp"
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include "VkBuffer.hpp"
19*03ce13f7SAndroid Build Coastguard Worker #include "VkConfig.hpp"
20*03ce13f7SAndroid Build Coastguard Worker #include "VkDevice.hpp"
21*03ce13f7SAndroid Build Coastguard Worker #include "VkImage.hpp"
22*03ce13f7SAndroid Build Coastguard Worker #include "VkMemory.hpp"
23*03ce13f7SAndroid Build Coastguard Worker #include "VkStringify.hpp"
24*03ce13f7SAndroid Build Coastguard Worker 
25*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
26*03ce13f7SAndroid Build Coastguard Worker 
27*03ce13f7SAndroid Build Coastguard Worker // Helper struct which reads the parsed allocation info and
28*03ce13f7SAndroid Build Coastguard Worker // extracts relevant information related to the handle type
29*03ce13f7SAndroid Build Coastguard Worker // supported by this DeviceMemory subclass.
30*03ce13f7SAndroid Build Coastguard Worker struct OpaqueFdAllocateInfo
31*03ce13f7SAndroid Build Coastguard Worker {
32*03ce13f7SAndroid Build Coastguard Worker 	bool importFd = false;
33*03ce13f7SAndroid Build Coastguard Worker 	bool exportFd = false;
34*03ce13f7SAndroid Build Coastguard Worker 	int fd = -1;
35*03ce13f7SAndroid Build Coastguard Worker 
36*03ce13f7SAndroid Build Coastguard Worker 	OpaqueFdAllocateInfo() = default;
37*03ce13f7SAndroid Build Coastguard Worker 
38*03ce13f7SAndroid Build Coastguard Worker 	// Read the parsed allocation info to initialize an OpaqueFdAllocateInfo.
OpaqueFdAllocateInfoOpaqueFdAllocateInfo39*03ce13f7SAndroid Build Coastguard Worker 	OpaqueFdAllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
40*03ce13f7SAndroid Build Coastguard Worker 	{
41*03ce13f7SAndroid Build Coastguard Worker 		if(extendedAllocationInfo.importMemoryFdInfo)
42*03ce13f7SAndroid Build Coastguard Worker 		{
43*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo.importMemoryFdInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
44*03ce13f7SAndroid Build Coastguard Worker 			{
45*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("VkImportMemoryFdInfoKHR::handleType %d", int(extendedAllocationInfo.importMemoryFdInfo->handleType));
46*03ce13f7SAndroid Build Coastguard Worker 			}
47*03ce13f7SAndroid Build Coastguard Worker 			importFd = true;
48*03ce13f7SAndroid Build Coastguard Worker 			fd = extendedAllocationInfo.importMemoryFdInfo->fd;
49*03ce13f7SAndroid Build Coastguard Worker 		}
50*03ce13f7SAndroid Build Coastguard Worker 
51*03ce13f7SAndroid Build Coastguard Worker 		if(extendedAllocationInfo.exportMemoryAllocateInfo)
52*03ce13f7SAndroid Build Coastguard Worker 		{
53*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
54*03ce13f7SAndroid Build Coastguard Worker 			{
55*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("VkExportMemoryAllocateInfo::handleTypes %d", int(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes));
56*03ce13f7SAndroid Build Coastguard Worker 			}
57*03ce13f7SAndroid Build Coastguard Worker 			exportFd = true;
58*03ce13f7SAndroid Build Coastguard Worker 		}
59*03ce13f7SAndroid Build Coastguard Worker 	}
60*03ce13f7SAndroid Build Coastguard Worker };
61*03ce13f7SAndroid Build Coastguard Worker 
62*03ce13f7SAndroid Build Coastguard Worker #	if defined(__APPLE__)
63*03ce13f7SAndroid Build Coastguard Worker #		include "VkDeviceMemoryExternalMac.hpp"
64*03ce13f7SAndroid Build Coastguard Worker #	elif defined(__linux__) && !defined(__ANDROID__)
65*03ce13f7SAndroid Build Coastguard Worker #		include "VkDeviceMemoryExternalLinux.hpp"
66*03ce13f7SAndroid Build Coastguard Worker #	else
67*03ce13f7SAndroid Build Coastguard Worker #		error "Missing VK_KHR_external_memory_fd implementation for this platform!"
68*03ce13f7SAndroid Build Coastguard Worker #	endif
69*03ce13f7SAndroid Build Coastguard Worker #endif
70*03ce13f7SAndroid Build Coastguard Worker 
71*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
72*03ce13f7SAndroid Build Coastguard Worker #	if defined(__ANDROID__)
73*03ce13f7SAndroid Build Coastguard Worker #		include "VkDeviceMemoryExternalAndroid.hpp"
74*03ce13f7SAndroid Build Coastguard Worker #	else
75*03ce13f7SAndroid Build Coastguard Worker #		error "Missing VK_ANDROID_external_memory_android_hardware_buffer implementation for this platform!"
76*03ce13f7SAndroid Build Coastguard Worker #	endif
77*03ce13f7SAndroid Build Coastguard Worker #endif
78*03ce13f7SAndroid Build Coastguard Worker 
79*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
80*03ce13f7SAndroid Build Coastguard Worker #	include "VkDeviceMemoryExternalFuchsia.hpp"
81*03ce13f7SAndroid Build Coastguard Worker #endif
82*03ce13f7SAndroid Build Coastguard Worker 
83*03ce13f7SAndroid Build Coastguard Worker namespace vk {
84*03ce13f7SAndroid Build Coastguard Worker 
Allocate(const VkAllocationCallbacks * pAllocator,const VkMemoryAllocateInfo * pAllocateInfo,VkDeviceMemory * pMemory,Device * device)85*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory, Device *device)
86*03ce13f7SAndroid Build Coastguard Worker {
87*03ce13f7SAndroid Build Coastguard Worker 	*pMemory = VK_NULL_HANDLE;
88*03ce13f7SAndroid Build Coastguard Worker 
89*03ce13f7SAndroid Build Coastguard Worker 	vk::DeviceMemory::ExtendedAllocationInfo extendedAllocationInfo = {};
90*03ce13f7SAndroid Build Coastguard Worker 	VkResult result = vk::DeviceMemory::ParseAllocationInfo(pAllocateInfo, &extendedAllocationInfo);
91*03ce13f7SAndroid Build Coastguard Worker 	if(result != VK_SUCCESS)
92*03ce13f7SAndroid Build Coastguard Worker 	{
93*03ce13f7SAndroid Build Coastguard Worker 		return result;
94*03ce13f7SAndroid Build Coastguard Worker 	}
95*03ce13f7SAndroid Build Coastguard Worker 
96*03ce13f7SAndroid Build Coastguard Worker 	result = Allocate(pAllocator, pAllocateInfo, pMemory, extendedAllocationInfo, device);
97*03ce13f7SAndroid Build Coastguard Worker 	if(result != VK_SUCCESS)
98*03ce13f7SAndroid Build Coastguard Worker 	{
99*03ce13f7SAndroid Build Coastguard Worker 		return result;
100*03ce13f7SAndroid Build Coastguard Worker 	}
101*03ce13f7SAndroid Build Coastguard Worker 
102*03ce13f7SAndroid Build Coastguard Worker 	// Make sure the memory allocation is done now so that OOM errors can be checked now
103*03ce13f7SAndroid Build Coastguard Worker 	return vk::Cast(*pMemory)->allocate();
104*03ce13f7SAndroid Build Coastguard Worker }
105*03ce13f7SAndroid Build Coastguard Worker 
Allocate(const VkAllocationCallbacks * pAllocator,const VkMemoryAllocateInfo * pAllocateInfo,VkDeviceMemory * pMemory,const vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,Device * device)106*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::Allocate(const VkAllocationCallbacks *pAllocator, const VkMemoryAllocateInfo *pAllocateInfo, VkDeviceMemory *pMemory,
107*03ce13f7SAndroid Build Coastguard Worker                                 const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *device)
108*03ce13f7SAndroid Build Coastguard Worker {
109*03ce13f7SAndroid Build Coastguard Worker 	VkMemoryAllocateInfo allocateInfo = *pAllocateInfo;
110*03ce13f7SAndroid Build Coastguard Worker 	// Add 15 bytes of padding to ensure that any type of attribute within
111*03ce13f7SAndroid Build Coastguard Worker 	// buffers and images can be read using 16-byte accesses.
112*03ce13f7SAndroid Build Coastguard Worker 	if(allocateInfo.allocationSize > UINT64_MAX - 15)
113*03ce13f7SAndroid Build Coastguard Worker 	{
114*03ce13f7SAndroid Build Coastguard Worker 		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
115*03ce13f7SAndroid Build Coastguard Worker 	}
116*03ce13f7SAndroid Build Coastguard Worker 	allocateInfo.allocationSize += 15;
117*03ce13f7SAndroid Build Coastguard Worker 
118*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
119*03ce13f7SAndroid Build Coastguard Worker 	if(AHardwareBufferExternalMemory::SupportsAllocateInfo(extendedAllocationInfo))
120*03ce13f7SAndroid Build Coastguard Worker 	{
121*03ce13f7SAndroid Build Coastguard Worker 		return AHardwareBufferExternalMemory::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
122*03ce13f7SAndroid Build Coastguard Worker 	}
123*03ce13f7SAndroid Build Coastguard Worker #endif
124*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
125*03ce13f7SAndroid Build Coastguard Worker 	if(OpaqueFdExternalMemory::SupportsAllocateInfo(extendedAllocationInfo))
126*03ce13f7SAndroid Build Coastguard Worker 	{
127*03ce13f7SAndroid Build Coastguard Worker 		return OpaqueFdExternalMemory::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
128*03ce13f7SAndroid Build Coastguard Worker 	}
129*03ce13f7SAndroid Build Coastguard Worker #endif
130*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
131*03ce13f7SAndroid Build Coastguard Worker 	if(zircon::VmoExternalMemory::supportsAllocateInfo(extendedAllocationInfo))
132*03ce13f7SAndroid Build Coastguard Worker 	{
133*03ce13f7SAndroid Build Coastguard Worker 		return zircon::VmoExternalMemory::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
134*03ce13f7SAndroid Build Coastguard Worker 	}
135*03ce13f7SAndroid Build Coastguard Worker #endif
136*03ce13f7SAndroid Build Coastguard Worker 	if(ExternalMemoryHost::SupportsAllocateInfo(extendedAllocationInfo))
137*03ce13f7SAndroid Build Coastguard Worker 	{
138*03ce13f7SAndroid Build Coastguard Worker 		return ExternalMemoryHost::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
139*03ce13f7SAndroid Build Coastguard Worker 	}
140*03ce13f7SAndroid Build Coastguard Worker 
141*03ce13f7SAndroid Build Coastguard Worker 	return vk::DeviceMemoryInternal::Create(pAllocator, &allocateInfo, pMemory, extendedAllocationInfo, device);
142*03ce13f7SAndroid Build Coastguard Worker }
143*03ce13f7SAndroid Build Coastguard Worker 
DeviceMemory(const VkMemoryAllocateInfo * pAllocateInfo,const DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,Device * pDevice)144*03ce13f7SAndroid Build Coastguard Worker DeviceMemory::DeviceMemory(const VkMemoryAllocateInfo *pAllocateInfo, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, Device *pDevice)
145*03ce13f7SAndroid Build Coastguard Worker     : allocationSize(pAllocateInfo->allocationSize)
146*03ce13f7SAndroid Build Coastguard Worker     , memoryTypeIndex(pAllocateInfo->memoryTypeIndex)
147*03ce13f7SAndroid Build Coastguard Worker     , opaqueCaptureAddress(extendedAllocationInfo.opaqueCaptureAddress)
148*03ce13f7SAndroid Build Coastguard Worker     , device(pDevice)
149*03ce13f7SAndroid Build Coastguard Worker {
150*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(allocationSize);
151*03ce13f7SAndroid Build Coastguard Worker }
152*03ce13f7SAndroid Build Coastguard Worker 
destroy(const VkAllocationCallbacks * pAllocator)153*03ce13f7SAndroid Build Coastguard Worker void DeviceMemory::destroy(const VkAllocationCallbacks *pAllocator)
154*03ce13f7SAndroid Build Coastguard Worker {
155*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
156*03ce13f7SAndroid Build Coastguard Worker 	VkDeviceMemoryReportEventTypeEXT eventType = isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT;
157*03ce13f7SAndroid Build Coastguard Worker 	device->emitDeviceMemoryReport(eventType, getMemoryObjectId(), 0 /* size */, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
158*03ce13f7SAndroid Build Coastguard Worker #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
159*03ce13f7SAndroid Build Coastguard Worker 
160*03ce13f7SAndroid Build Coastguard Worker 	if(buffer)
161*03ce13f7SAndroid Build Coastguard Worker 	{
162*03ce13f7SAndroid Build Coastguard Worker 		freeBuffer();
163*03ce13f7SAndroid Build Coastguard Worker 		buffer = nullptr;
164*03ce13f7SAndroid Build Coastguard Worker 	}
165*03ce13f7SAndroid Build Coastguard Worker }
166*03ce13f7SAndroid Build Coastguard Worker 
ComputeRequiredAllocationSize(const VkMemoryAllocateInfo * pAllocateInfo)167*03ce13f7SAndroid Build Coastguard Worker size_t DeviceMemory::ComputeRequiredAllocationSize(const VkMemoryAllocateInfo *pAllocateInfo)
168*03ce13f7SAndroid Build Coastguard Worker {
169*03ce13f7SAndroid Build Coastguard Worker 	return 0;
170*03ce13f7SAndroid Build Coastguard Worker }
171*03ce13f7SAndroid Build Coastguard Worker 
ParseAllocationInfo(const VkMemoryAllocateInfo * pAllocateInfo,DeviceMemory::ExtendedAllocationInfo * extendedAllocationInfo)172*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::ParseAllocationInfo(const VkMemoryAllocateInfo *pAllocateInfo, DeviceMemory::ExtendedAllocationInfo *extendedAllocationInfo)
173*03ce13f7SAndroid Build Coastguard Worker {
174*03ce13f7SAndroid Build Coastguard Worker 	const VkBaseInStructure *allocationInfo = reinterpret_cast<const VkBaseInStructure *>(pAllocateInfo->pNext);
175*03ce13f7SAndroid Build Coastguard Worker 	while(allocationInfo)
176*03ce13f7SAndroid Build Coastguard Worker 	{
177*03ce13f7SAndroid Build Coastguard Worker 		switch(allocationInfo->sType)
178*03ce13f7SAndroid Build Coastguard Worker 		{
179*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
180*03ce13f7SAndroid Build Coastguard Worker 			// This can safely be ignored on most platforms, as the Vulkan spec mentions:
181*03ce13f7SAndroid Build Coastguard Worker 			// "If the pNext chain includes a VkMemoryDedicatedAllocateInfo structure, then that structure
182*03ce13f7SAndroid Build Coastguard Worker 			//  includes a handle of the sole buffer or image resource that the memory *can* be bound to."
183*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
184*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->dedicatedAllocateInfo = reinterpret_cast<const VkMemoryDedicatedAllocateInfo *>(allocationInfo);
185*03ce13f7SAndroid Build Coastguard Worker #endif
186*03ce13f7SAndroid Build Coastguard Worker 			break;
187*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO:
188*03ce13f7SAndroid Build Coastguard Worker 			// This extension controls on which physical devices the memory gets allocated.
189*03ce13f7SAndroid Build Coastguard Worker 			// SwiftShader only has a single physical device, so this extension does nothing in this case.
190*03ce13f7SAndroid Build Coastguard Worker 			break;
191*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
192*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
193*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->importMemoryFdInfo = reinterpret_cast<const VkImportMemoryFdInfoKHR *>(allocationInfo);
194*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo->importMemoryFdInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
195*03ce13f7SAndroid Build Coastguard Worker 			{
196*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("extendedAllocationInfo->importMemoryFdInfo->handleType %u", extendedAllocationInfo->importMemoryFdInfo->handleType);
197*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
198*03ce13f7SAndroid Build Coastguard Worker 			}
199*03ce13f7SAndroid Build Coastguard Worker 			break;
200*03ce13f7SAndroid Build Coastguard Worker #endif  // SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
201*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
202*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->exportMemoryAllocateInfo = reinterpret_cast<const VkExportMemoryAllocateInfo *>(allocationInfo);
203*03ce13f7SAndroid Build Coastguard Worker 			switch(extendedAllocationInfo->exportMemoryAllocateInfo->handleTypes)
204*03ce13f7SAndroid Build Coastguard Worker 			{
205*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
206*03ce13f7SAndroid Build Coastguard Worker 			case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
207*03ce13f7SAndroid Build Coastguard Worker 				break;
208*03ce13f7SAndroid Build Coastguard Worker #endif
209*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
210*03ce13f7SAndroid Build Coastguard Worker 			case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
211*03ce13f7SAndroid Build Coastguard Worker 				break;
212*03ce13f7SAndroid Build Coastguard Worker #endif
213*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
214*03ce13f7SAndroid Build Coastguard Worker 			case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
215*03ce13f7SAndroid Build Coastguard Worker 				break;
216*03ce13f7SAndroid Build Coastguard Worker #endif
217*03ce13f7SAndroid Build Coastguard Worker 			default:
218*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("extendedAllocationInfo->exportMemoryAllocateInfo->handleTypes %u", extendedAllocationInfo->exportMemoryAllocateInfo->handleTypes);
219*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
220*03ce13f7SAndroid Build Coastguard Worker 			}
221*03ce13f7SAndroid Build Coastguard Worker 			break;
222*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
223*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:
224*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->importAndroidHardwareBufferInfo = reinterpret_cast<const VkImportAndroidHardwareBufferInfoANDROID *>(allocationInfo);
225*03ce13f7SAndroid Build Coastguard Worker 			break;
226*03ce13f7SAndroid Build Coastguard Worker #endif  // SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
227*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:
228*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->importMemoryHostPointerInfo = reinterpret_cast<const VkImportMemoryHostPointerInfoEXT *>(allocationInfo);
229*03ce13f7SAndroid Build Coastguard Worker 			if((extendedAllocationInfo->importMemoryHostPointerInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT) &&
230*03ce13f7SAndroid Build Coastguard Worker 			   (extendedAllocationInfo->importMemoryHostPointerInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT))
231*03ce13f7SAndroid Build Coastguard Worker 			{
232*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("extendedAllocationInfo->importMemoryHostPointerInfo->handleType %u", extendedAllocationInfo->importMemoryHostPointerInfo->handleType);
233*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
234*03ce13f7SAndroid Build Coastguard Worker 			}
235*03ce13f7SAndroid Build Coastguard Worker 			break;
236*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
237*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA:
238*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->importMemoryZirconHandleInfo = reinterpret_cast<const VkImportMemoryZirconHandleInfoFUCHSIA *>(allocationInfo);
239*03ce13f7SAndroid Build Coastguard Worker 			if(extendedAllocationInfo->importMemoryZirconHandleInfo->handleType != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA)
240*03ce13f7SAndroid Build Coastguard Worker 			{
241*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("extendedAllocationInfo->importMemoryZirconHandleInfo->handleType %u", extendedAllocationInfo->importMemoryZirconHandleInfo->handleType);
242*03ce13f7SAndroid Build Coastguard Worker 				return VK_ERROR_INVALID_EXTERNAL_HANDLE;
243*03ce13f7SAndroid Build Coastguard Worker 			}
244*03ce13f7SAndroid Build Coastguard Worker 			break;
245*03ce13f7SAndroid Build Coastguard Worker #endif  // VK_USE_PLATFORM_FUCHSIA
246*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO:
247*03ce13f7SAndroid Build Coastguard Worker 			extendedAllocationInfo->opaqueCaptureAddress =
248*03ce13f7SAndroid Build Coastguard Worker 			    reinterpret_cast<const VkMemoryOpaqueCaptureAddressAllocateInfo *>(allocationInfo)->opaqueCaptureAddress;
249*03ce13f7SAndroid Build Coastguard Worker 			break;
250*03ce13f7SAndroid Build Coastguard Worker 		default:
251*03ce13f7SAndroid Build Coastguard Worker 			UNSUPPORTED("pAllocateInfo->pNext sType = %s", vk::Stringify(allocationInfo->sType).c_str());
252*03ce13f7SAndroid Build Coastguard Worker 			break;
253*03ce13f7SAndroid Build Coastguard Worker 		}
254*03ce13f7SAndroid Build Coastguard Worker 
255*03ce13f7SAndroid Build Coastguard Worker 		allocationInfo = allocationInfo->pNext;
256*03ce13f7SAndroid Build Coastguard Worker 	}
257*03ce13f7SAndroid Build Coastguard Worker 
258*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
259*03ce13f7SAndroid Build Coastguard Worker }
260*03ce13f7SAndroid Build Coastguard Worker 
allocate()261*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::allocate()
262*03ce13f7SAndroid Build Coastguard Worker {
263*03ce13f7SAndroid Build Coastguard Worker 	if(allocationSize > MAX_MEMORY_ALLOCATION_SIZE)
264*03ce13f7SAndroid Build Coastguard Worker 	{
265*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
266*03ce13f7SAndroid Build Coastguard Worker 		device->emitDeviceMemoryReport(VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT, 0 /* memoryObjectId */, allocationSize, VK_OBJECT_TYPE_DEVICE_MEMORY, 0 /* objectHandle */);
267*03ce13f7SAndroid Build Coastguard Worker #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
268*03ce13f7SAndroid Build Coastguard Worker 
269*03ce13f7SAndroid Build Coastguard Worker 		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
270*03ce13f7SAndroid Build Coastguard Worker 	}
271*03ce13f7SAndroid Build Coastguard Worker 
272*03ce13f7SAndroid Build Coastguard Worker 	VkResult result = VK_SUCCESS;
273*03ce13f7SAndroid Build Coastguard Worker 	if(!buffer)
274*03ce13f7SAndroid Build Coastguard Worker 	{
275*03ce13f7SAndroid Build Coastguard Worker 		result = allocateBuffer();
276*03ce13f7SAndroid Build Coastguard Worker 	}
277*03ce13f7SAndroid Build Coastguard Worker 
278*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
279*03ce13f7SAndroid Build Coastguard Worker 	if(result == VK_SUCCESS)
280*03ce13f7SAndroid Build Coastguard Worker 	{
281*03ce13f7SAndroid Build Coastguard Worker 		VkDeviceMemoryReportEventTypeEXT eventType = isImport() ? VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT : VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT;
282*03ce13f7SAndroid Build Coastguard Worker 		device->emitDeviceMemoryReport(eventType, getMemoryObjectId(), allocationSize, VK_OBJECT_TYPE_DEVICE_MEMORY, (uint64_t)(void *)VkDeviceMemory(*this));
283*03ce13f7SAndroid Build Coastguard Worker 	}
284*03ce13f7SAndroid Build Coastguard Worker 	else
285*03ce13f7SAndroid Build Coastguard Worker 	{
286*03ce13f7SAndroid Build Coastguard Worker 		device->emitDeviceMemoryReport(VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT, 0 /* memoryObjectId */, allocationSize, VK_OBJECT_TYPE_DEVICE_MEMORY, 0 /* objectHandle */);
287*03ce13f7SAndroid Build Coastguard Worker 	}
288*03ce13f7SAndroid Build Coastguard Worker #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
289*03ce13f7SAndroid Build Coastguard Worker 
290*03ce13f7SAndroid Build Coastguard Worker 	return result;
291*03ce13f7SAndroid Build Coastguard Worker }
292*03ce13f7SAndroid Build Coastguard Worker 
map(VkDeviceSize pOffset,VkDeviceSize pSize,void ** ppData)293*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::map(VkDeviceSize pOffset, VkDeviceSize pSize, void **ppData)
294*03ce13f7SAndroid Build Coastguard Worker {
295*03ce13f7SAndroid Build Coastguard Worker 	*ppData = getOffsetPointer(pOffset);
296*03ce13f7SAndroid Build Coastguard Worker 
297*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
298*03ce13f7SAndroid Build Coastguard Worker }
299*03ce13f7SAndroid Build Coastguard Worker 
getCommittedMemoryInBytes() const300*03ce13f7SAndroid Build Coastguard Worker VkDeviceSize DeviceMemory::getCommittedMemoryInBytes() const
301*03ce13f7SAndroid Build Coastguard Worker {
302*03ce13f7SAndroid Build Coastguard Worker 	return allocationSize;
303*03ce13f7SAndroid Build Coastguard Worker }
304*03ce13f7SAndroid Build Coastguard Worker 
getOffsetPointer(VkDeviceSize pOffset) const305*03ce13f7SAndroid Build Coastguard Worker void *DeviceMemory::getOffsetPointer(VkDeviceSize pOffset) const
306*03ce13f7SAndroid Build Coastguard Worker {
307*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(buffer);
308*03ce13f7SAndroid Build Coastguard Worker 	return reinterpret_cast<char *>(buffer) + pOffset;
309*03ce13f7SAndroid Build Coastguard Worker }
310*03ce13f7SAndroid Build Coastguard Worker 
getOpaqueCaptureAddress() const311*03ce13f7SAndroid Build Coastguard Worker uint64_t DeviceMemory::getOpaqueCaptureAddress() const
312*03ce13f7SAndroid Build Coastguard Worker {
313*03ce13f7SAndroid Build Coastguard Worker 	return (opaqueCaptureAddress != 0) ? opaqueCaptureAddress : static_cast<uint64_t>(reinterpret_cast<uintptr_t>(buffer));
314*03ce13f7SAndroid Build Coastguard Worker }
315*03ce13f7SAndroid Build Coastguard Worker 
checkExternalMemoryHandleType(VkExternalMemoryHandleTypeFlags supportedHandleTypes) const316*03ce13f7SAndroid Build Coastguard Worker bool DeviceMemory::checkExternalMemoryHandleType(
317*03ce13f7SAndroid Build Coastguard Worker     VkExternalMemoryHandleTypeFlags supportedHandleTypes) const
318*03ce13f7SAndroid Build Coastguard Worker {
319*03ce13f7SAndroid Build Coastguard Worker 	if(!supportedHandleTypes)
320*03ce13f7SAndroid Build Coastguard Worker 	{
321*03ce13f7SAndroid Build Coastguard Worker 		// This image or buffer does not need to be stored on external
322*03ce13f7SAndroid Build Coastguard Worker 		// memory, so this check should always pass.
323*03ce13f7SAndroid Build Coastguard Worker 		return true;
324*03ce13f7SAndroid Build Coastguard Worker 	}
325*03ce13f7SAndroid Build Coastguard Worker 	VkExternalMemoryHandleTypeFlagBits handle_type_bit = getFlagBit();
326*03ce13f7SAndroid Build Coastguard Worker 	if(!handle_type_bit)
327*03ce13f7SAndroid Build Coastguard Worker 	{
328*03ce13f7SAndroid Build Coastguard Worker 		// This device memory is not external and can accommodate
329*03ce13f7SAndroid Build Coastguard Worker 		// any image or buffer as well.
330*03ce13f7SAndroid Build Coastguard Worker 		return true;
331*03ce13f7SAndroid Build Coastguard Worker 	}
332*03ce13f7SAndroid Build Coastguard Worker 	// Return true only if the external memory type is compatible with the
333*03ce13f7SAndroid Build Coastguard Worker 	// one specified during VkCreate{Image,Buffer}(), through a
334*03ce13f7SAndroid Build Coastguard Worker 	// VkExternalMemory{Image,Buffer}AllocateInfo struct.
335*03ce13f7SAndroid Build Coastguard Worker 	return (supportedHandleTypes & handle_type_bit) != 0;
336*03ce13f7SAndroid Build Coastguard Worker }
337*03ce13f7SAndroid Build Coastguard Worker 
338*03ce13f7SAndroid Build Coastguard Worker // Allocate the memory according to `allocationSize`. On success return VK_SUCCESS
339*03ce13f7SAndroid Build Coastguard Worker // and sets `buffer`.
allocateBuffer()340*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::allocateBuffer()
341*03ce13f7SAndroid Build Coastguard Worker {
342*03ce13f7SAndroid Build Coastguard Worker 	buffer = vk::allocateDeviceMemory(allocationSize, vk::DEVICE_MEMORY_ALLOCATION_ALIGNMENT);
343*03ce13f7SAndroid Build Coastguard Worker 	if(!buffer)
344*03ce13f7SAndroid Build Coastguard Worker 	{
345*03ce13f7SAndroid Build Coastguard Worker 		return VK_ERROR_OUT_OF_DEVICE_MEMORY;
346*03ce13f7SAndroid Build Coastguard Worker 	}
347*03ce13f7SAndroid Build Coastguard Worker 
348*03ce13f7SAndroid Build Coastguard Worker 	return VK_SUCCESS;
349*03ce13f7SAndroid Build Coastguard Worker }
350*03ce13f7SAndroid Build Coastguard Worker 
351*03ce13f7SAndroid Build Coastguard Worker // Free previously allocated memory at `buffer`.
freeBuffer()352*03ce13f7SAndroid Build Coastguard Worker void DeviceMemory::freeBuffer()
353*03ce13f7SAndroid Build Coastguard Worker {
354*03ce13f7SAndroid Build Coastguard Worker 	vk::freeDeviceMemory(buffer);
355*03ce13f7SAndroid Build Coastguard Worker 	buffer = nullptr;
356*03ce13f7SAndroid Build Coastguard Worker }
357*03ce13f7SAndroid Build Coastguard Worker 
358*03ce13f7SAndroid Build Coastguard Worker // Return the handle type flag bit supported by this implementation.
359*03ce13f7SAndroid Build Coastguard Worker // A value of 0 corresponds to non-external memory.
getFlagBit() const360*03ce13f7SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlagBits DeviceMemory::getFlagBit() const
361*03ce13f7SAndroid Build Coastguard Worker {
362*03ce13f7SAndroid Build Coastguard Worker 	// Does not support any external memory type at all.
363*03ce13f7SAndroid Build Coastguard Worker 	static const VkExternalMemoryHandleTypeFlagBits typeFlagBit = (VkExternalMemoryHandleTypeFlagBits)0;
364*03ce13f7SAndroid Build Coastguard Worker 	return typeFlagBit;
365*03ce13f7SAndroid Build Coastguard Worker }
366*03ce13f7SAndroid Build Coastguard Worker 
367*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_OPAQUE_FD
exportFd(int * pFd) const368*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::exportFd(int *pFd) const
369*03ce13f7SAndroid Build Coastguard Worker {
370*03ce13f7SAndroid Build Coastguard Worker 	return VK_ERROR_INVALID_EXTERNAL_HANDLE;
371*03ce13f7SAndroid Build Coastguard Worker }
372*03ce13f7SAndroid Build Coastguard Worker #endif
373*03ce13f7SAndroid Build Coastguard Worker 
374*03ce13f7SAndroid Build Coastguard Worker #if SWIFTSHADER_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER
exportAndroidHardwareBuffer(struct AHardwareBuffer ** pAhb) const375*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::exportAndroidHardwareBuffer(struct AHardwareBuffer **pAhb) const
376*03ce13f7SAndroid Build Coastguard Worker {
377*03ce13f7SAndroid Build Coastguard Worker 	return VK_ERROR_OUT_OF_HOST_MEMORY;
378*03ce13f7SAndroid Build Coastguard Worker }
379*03ce13f7SAndroid Build Coastguard Worker 
GetAndroidHardwareBufferProperties(VkDevice & ahbDevice,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)380*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::GetAndroidHardwareBufferProperties(VkDevice &ahbDevice, const struct AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties)
381*03ce13f7SAndroid Build Coastguard Worker {
382*03ce13f7SAndroid Build Coastguard Worker 	return AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(ahbDevice, buffer, pProperties);
383*03ce13f7SAndroid Build Coastguard Worker }
384*03ce13f7SAndroid Build Coastguard Worker #endif
385*03ce13f7SAndroid Build Coastguard Worker 
386*03ce13f7SAndroid Build Coastguard Worker #if VK_USE_PLATFORM_FUCHSIA
exportHandle(zx_handle_t * pHandle) const387*03ce13f7SAndroid Build Coastguard Worker VkResult DeviceMemory::exportHandle(zx_handle_t *pHandle) const
388*03ce13f7SAndroid Build Coastguard Worker {
389*03ce13f7SAndroid Build Coastguard Worker 	return VK_ERROR_INVALID_EXTERNAL_HANDLE;
390*03ce13f7SAndroid Build Coastguard Worker }
391*03ce13f7SAndroid Build Coastguard Worker #endif
392*03ce13f7SAndroid Build Coastguard Worker 
393*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
394