1 // Copyright 2020 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 "VkDeviceMemoryExternalAndroid.hpp"
16 
17 #include "VkDestroy.hpp"
18 #include "VkFormat.hpp"
19 #include "VkObject.hpp"
20 #include "VkPhysicalDevice.hpp"
21 #include "VkStringify.hpp"
22 #include "System/Debug.hpp"
23 
24 namespace {
25 
GetAHBFormatFromVkFormat(VkFormat format)26 uint32_t GetAHBFormatFromVkFormat(VkFormat format)
27 {
28 	switch(format)
29 	{
30 		case VK_FORMAT_D16_UNORM:
31 			return AHARDWAREBUFFER_FORMAT_D16_UNORM;
32 		case VK_FORMAT_X8_D24_UNORM_PACK32:
33 			UNSUPPORTED("AHardwareBufferExternalMemory::VkFormat VK_FORMAT_X8_D24_UNORM_PACK32");
34 			return AHARDWAREBUFFER_FORMAT_D24_UNORM;
35 		case VK_FORMAT_D24_UNORM_S8_UINT:
36 			UNSUPPORTED("AHardwareBufferExternalMemory::VkFormat VK_FORMAT_D24_UNORM_S8_UINT");
37 			return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
38 		case VK_FORMAT_D32_SFLOAT:
39 			return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
40 		case VK_FORMAT_D32_SFLOAT_S8_UINT:
41 			return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
42 		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
43 			return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
44 		case VK_FORMAT_R16G16B16A16_SFLOAT:
45 			return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
46 		case VK_FORMAT_R5G6B5_UNORM_PACK16:
47 			return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
48 		case VK_FORMAT_R8G8B8A8_UNORM:
49 			return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
50 		case VK_FORMAT_R8G8B8_UNORM:
51 			return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
52 		case VK_FORMAT_S8_UINT:
53 			return AHARDWAREBUFFER_FORMAT_S8_UINT;
54 		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
55 			return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
56 		default:
57 			UNSUPPORTED("AHardwareBufferExternalMemory::VkFormat %d", int(format));
58 			return 0;
59 	}
60 }
61 
GetAHBLockUsageFromVkImageUsageFlags(VkImageUsageFlags flags)62 uint64_t GetAHBLockUsageFromVkImageUsageFlags(VkImageUsageFlags flags)
63 {
64 	uint64_t usage = 0;
65 
66 	if(flags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT ||
67 	   flags & VK_IMAGE_USAGE_SAMPLED_BIT ||
68 	   flags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
69 	{
70 		usage |= AHARDWAREBUFFER_USAGE_CPU_READ_MASK;
71 	}
72 
73 	if(flags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT ||
74 	   flags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)
75 	{
76 		usage |= AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK;
77 	}
78 
79 	return usage;
80 }
81 
GetAHBLockUsageFromVkBufferUsageFlags(VkBufferUsageFlags flags)82 uint64_t GetAHBLockUsageFromVkBufferUsageFlags(VkBufferUsageFlags flags)
83 {
84 	uint64_t usage = 0;
85 
86 	if(flags & VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
87 	{
88 		usage |= AHARDWAREBUFFER_USAGE_CPU_READ_MASK;
89 	}
90 
91 	if(flags & VK_BUFFER_USAGE_TRANSFER_DST_BIT)
92 	{
93 		usage |= AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK;
94 	}
95 
96 	return usage;
97 }
98 
GetAHBUsageFromVkImageFlags(VkImageCreateFlags createFlags,VkImageUsageFlags usageFlags)99 uint64_t GetAHBUsageFromVkImageFlags(VkImageCreateFlags createFlags, VkImageUsageFlags usageFlags)
100 {
101 	uint64_t ahbUsage = 0;
102 
103 	if(usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT)
104 	{
105 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
106 	}
107 	if(usageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
108 	{
109 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
110 	}
111 	if(usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
112 	{
113 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
114 	}
115 
116 	if(createFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
117 	{
118 		ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
119 	}
120 	if(createFlags & VK_IMAGE_CREATE_PROTECTED_BIT)
121 	{
122 		ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
123 	}
124 
125 	// No usage bits set - set at least one GPU usage
126 	if(ahbUsage == 0)
127 	{
128 		ahbUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
129 		           AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
130 	}
131 
132 	return ahbUsage;
133 }
134 
GetAHBUsageFromVkBufferFlags(VkBufferCreateFlags,VkBufferUsageFlags)135 uint64_t GetAHBUsageFromVkBufferFlags(VkBufferCreateFlags /*createFlags*/, VkBufferUsageFlags /*usageFlags*/)
136 {
137 	uint64_t ahbUsage = 0;
138 
139 	// TODO(b/141698760): needs fleshing out.
140 	ahbUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
141 
142 	return ahbUsage;
143 }
144 
GetVkFormatFeaturesFromAHBFormat(uint32_t ahbFormat)145 VkFormatFeatureFlags GetVkFormatFeaturesFromAHBFormat(uint32_t ahbFormat)
146 {
147 	VkFormatFeatureFlags features = 0;
148 
149 	VkFormat format = AHardwareBufferExternalMemory::GetVkFormatFromAHBFormat(ahbFormat);
150 	VkFormatProperties formatProperties;
151 	vk::PhysicalDevice::GetFormatProperties(vk::Format(format), &formatProperties);
152 
153 	formatProperties.optimalTilingFeatures |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
154 
155 	// TODO: b/167896057
156 	//   The correct formatFeatureFlags depends on consumer and format
157 	//   So this solution is incomplete without more information
158 	features |= formatProperties.linearTilingFeatures |
159 	            formatProperties.optimalTilingFeatures |
160 	            formatProperties.bufferFeatures;
161 
162 	return features;
163 }
164 
165 }  // namespace
166 
AllocateInfo(const VkMemoryAllocateInfo * pAllocateInfo)167 AHardwareBufferExternalMemory::AllocateInfo::AllocateInfo(const VkMemoryAllocateInfo *pAllocateInfo)
168 {
169 	const auto *createInfo = reinterpret_cast<const VkBaseInStructure *>(pAllocateInfo->pNext);
170 	while(createInfo)
171 	{
172 		switch(createInfo->sType)
173 		{
174 			case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:
175 			{
176 				const auto *importInfo = reinterpret_cast<const VkImportAndroidHardwareBufferInfoANDROID *>(createInfo);
177 				importAhb = true;
178 				ahb = importInfo->buffer;
179 			}
180 			break;
181 			case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
182 			{
183 				const auto *exportInfo = reinterpret_cast<const VkExportMemoryAllocateInfo *>(createInfo);
184 
185 				if(exportInfo->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
186 				{
187 					exportAhb = true;
188 				}
189 				else
190 				{
191 					UNSUPPORTED("VkExportMemoryAllocateInfo::handleTypes %d", int(exportInfo->handleTypes));
192 				}
193 			}
194 			break;
195 			case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
196 			{
197 				const auto *dedicatedAllocateInfo = reinterpret_cast<const VkMemoryDedicatedAllocateInfo *>(createInfo);
198 				dedicatedImageHandle = vk::Cast(dedicatedAllocateInfo->image);
199 				dedicatedBufferHandle = vk::Cast(dedicatedAllocateInfo->buffer);
200 			}
201 			break;
202 			default:
203 			{
204 				LOG_TRAP("VkMemoryAllocateInfo->pNext sType = %s", vk::Stringify(createInfo->sType).c_str());
205 			}
206 			break;
207 		}
208 		createInfo = createInfo->pNext;
209 	}
210 }
211 
AHardwareBufferExternalMemory(const VkMemoryAllocateInfo * pAllocateInfo)212 AHardwareBufferExternalMemory::AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pAllocateInfo)
213     : allocateInfo(pAllocateInfo)
214 {
215 }
216 
~AHardwareBufferExternalMemory()217 AHardwareBufferExternalMemory::~AHardwareBufferExternalMemory()
218 {
219 	// correct deallocation of AHB does not require a pointer or size
220 	deallocate(nullptr, 0);
221 }
222 
223 // VkAllocateMemory
allocate(size_t size,void ** pBuffer)224 VkResult AHardwareBufferExternalMemory::allocate(size_t size, void **pBuffer)
225 {
226 	if(allocateInfo.importAhb)
227 	{
228 		return importAndroidHardwareBuffer(allocateInfo.ahb, pBuffer);
229 	}
230 	else
231 	{
232 		ASSERT(allocateInfo.exportAhb);
233 		return allocateAndroidHardwareBuffer(size, pBuffer);
234 	}
235 }
236 
deallocate(void * buffer,size_t size)237 void AHardwareBufferExternalMemory::deallocate(void *buffer, size_t size)
238 {
239 	if(ahb != nullptr)
240 	{
241 		unlockAndroidHardwareBuffer();
242 
243 		AHardwareBuffer_release(ahb);
244 		ahb = nullptr;
245 	}
246 }
247 
importAndroidHardwareBuffer(AHardwareBuffer * buffer,void ** pBuffer)248 VkResult AHardwareBufferExternalMemory::importAndroidHardwareBuffer(AHardwareBuffer *buffer, void **pBuffer)
249 {
250 	ahb = buffer;
251 
252 	AHardwareBuffer_acquire(ahb);
253 	AHardwareBuffer_describe(ahb, &ahbDesc);
254 
255 	return lockAndroidHardwareBuffer(pBuffer);
256 }
257 
allocateAndroidHardwareBuffer(size_t size,void ** pBuffer)258 VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(size_t size, void **pBuffer)
259 {
260 	if(allocateInfo.dedicatedImageHandle)
261 	{
262 		vk::Image *image = allocateInfo.dedicatedImageHandle;
263 		ASSERT(image->getArrayLayers() == 1);
264 
265 		VkExtent3D extent = image->getExtent();
266 
267 		ahbDesc.width = extent.width;
268 		ahbDesc.height = extent.height;
269 		ahbDesc.layers = image->getArrayLayers();
270 		ahbDesc.format = GetAHBFormatFromVkFormat(image->getFormat());
271 		ahbDesc.usage = GetAHBUsageFromVkImageFlags(image->getFlags(), image->getUsage());
272 	}
273 	else if(allocateInfo.dedicatedBufferHandle)
274 	{
275 		vk::Buffer *buffer = allocateInfo.dedicatedBufferHandle;
276 
277 		ahbDesc.width = static_cast<uint32_t>(buffer->getSize());
278 		ahbDesc.height = 1;
279 		ahbDesc.layers = 1;
280 		ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
281 		ahbDesc.usage = GetAHBUsageFromVkBufferFlags(buffer->getFlags(), buffer->getUsage());
282 	}
283 	else
284 	{
285 		// Android Hardware Buffer Buffer Resources: "Android hardware buffers with a format of
286 		// AHARDWAREBUFFER_FORMAT_BLOB and usage that includes AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER can
287 		// be used as the backing store for VkBuffer objects. Such Android hardware buffers have a size
288 		// in bytes specified by their width; height and layers are both 1."
289 		ahbDesc.width = static_cast<uint32_t>(size);
290 		ahbDesc.height = 1;
291 		ahbDesc.layers = 1;
292 		ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
293 		ahbDesc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
294 	}
295 
296 	int ret = AHardwareBuffer_allocate(&ahbDesc, &ahb);
297 	if(ret != 0)
298 	{
299 		return VK_ERROR_OUT_OF_HOST_MEMORY;
300 	}
301 
302 	AHardwareBuffer_describe(ahb, &ahbDesc);
303 
304 	return lockAndroidHardwareBuffer(pBuffer);
305 }
306 
lockAndroidHardwareBuffer(void ** pBuffer)307 VkResult AHardwareBufferExternalMemory::lockAndroidHardwareBuffer(void **pBuffer)
308 {
309 	uint64_t usage = 0;
310 	if(allocateInfo.dedicatedImageHandle)
311 	{
312 		usage = GetAHBLockUsageFromVkImageUsageFlags(allocateInfo.dedicatedImageHandle->getUsage());
313 	}
314 	else if(allocateInfo.dedicatedBufferHandle)
315 	{
316 		usage = GetAHBLockUsageFromVkBufferUsageFlags(allocateInfo.dedicatedBufferHandle->getUsage());
317 	}
318 	else
319 	{
320 		usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
321 	}
322 
323 	// Empty fence, lock immedietly.
324 	int32_t fence = -1;
325 
326 	// Empty rect, lock entire buffer.
327 	ARect *rect = nullptr;
328 
329 	int ret = AHardwareBuffer_lockPlanes(ahb, usage, fence, rect, &ahbPlanes);
330 	if(ret != 0)
331 	{
332 		return VK_ERROR_OUT_OF_HOST_MEMORY;
333 	}
334 
335 	*pBuffer = ahbPlanes.planes[0].data;
336 
337 	return VK_SUCCESS;
338 }
339 
unlockAndroidHardwareBuffer()340 VkResult AHardwareBufferExternalMemory::unlockAndroidHardwareBuffer()
341 {
342 	int ret = AHardwareBuffer_unlock(ahb, /*fence=*/nullptr);
343 	if(ret != 0)
344 	{
345 		return VK_ERROR_UNKNOWN;
346 	}
347 
348 	return VK_SUCCESS;
349 }
350 
exportAndroidHardwareBuffer(AHardwareBuffer ** pAhb) const351 VkResult AHardwareBufferExternalMemory::exportAndroidHardwareBuffer(AHardwareBuffer **pAhb) const
352 {
353 	// Each call to vkGetMemoryAndroidHardwareBufferANDROID *must* return an Android hardware buffer with a new reference
354 	// acquired in addition to the reference held by the VkDeviceMemory. To avoid leaking resources, the application *must*
355 	// release the reference by calling AHardwareBuffer_release when it is no longer needed.
356 	AHardwareBuffer_acquire(ahb);
357 	*pAhb = ahb;
358 	return VK_SUCCESS;
359 }
360 
GetVkFormatFromAHBFormat(uint32_t ahbFormat)361 VkFormat AHardwareBufferExternalMemory::GetVkFormatFromAHBFormat(uint32_t ahbFormat)
362 {
363 	switch(ahbFormat)
364 	{
365 		case AHARDWAREBUFFER_FORMAT_BLOB:
366 			return VK_FORMAT_UNDEFINED;
367 		case AHARDWAREBUFFER_FORMAT_D16_UNORM:
368 			return VK_FORMAT_D16_UNORM;
369 		case AHARDWAREBUFFER_FORMAT_D24_UNORM:
370 			UNSUPPORTED("AHardwareBufferExternalMemory::AndroidHardwareBuffer_Format AHARDWAREBUFFER_FORMAT_D24_UNORM");
371 			return VK_FORMAT_X8_D24_UNORM_PACK32;
372 		case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
373 			UNSUPPORTED("AHardwareBufferExternalMemory::AndroidHardwareBuffer_Format AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT");
374 			return VK_FORMAT_X8_D24_UNORM_PACK32;
375 		case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
376 			return VK_FORMAT_D32_SFLOAT;
377 		case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
378 			return VK_FORMAT_D32_SFLOAT_S8_UINT;
379 		case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
380 			return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
381 		case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
382 			return VK_FORMAT_R16G16B16A16_SFLOAT;
383 		case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
384 			return VK_FORMAT_R5G6B5_UNORM_PACK16;
385 		case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
386 			return VK_FORMAT_R8G8B8A8_UNORM;
387 		case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
388 			return VK_FORMAT_R8G8B8A8_UNORM;
389 		case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
390 			return VK_FORMAT_R8G8B8_UNORM;
391 		case AHARDWAREBUFFER_FORMAT_S8_UINT:
392 			return VK_FORMAT_S8_UINT;
393 		case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
394 		case AHARDWAREBUFFER_FORMAT_YV12:
395 			return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
396 		default:
397 			UNSUPPORTED("AHardwareBufferExternalMemory::AHardwareBuffer_Format %d", int(ahbFormat));
398 			return VK_FORMAT_UNDEFINED;
399 	}
400 }
401 
GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc & ahbDesc,VkAndroidHardwareBufferFormatPropertiesANDROID * pFormat)402 VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc &ahbDesc, VkAndroidHardwareBufferFormatPropertiesANDROID *pFormat)
403 {
404 	pFormat->sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
405 	pFormat->pNext = nullptr;
406 	pFormat->format = GetVkFormatFromAHBFormat(ahbDesc.format);
407 	pFormat->externalFormat = ahbDesc.format;
408 	pFormat->formatFeatures = GetVkFormatFeaturesFromAHBFormat(ahbDesc.format);
409 	pFormat->samplerYcbcrConversionComponents = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
410 	pFormat->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
411 	pFormat->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW;
412 	pFormat->suggestedXChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
413 	pFormat->suggestedYChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
414 
415 	// YUV formats are not listed in the AHardwareBuffer Format Equivalence table in the Vulkan spec.
416 	// Clients must use VkExternalFormatANDROID.
417 	if(pFormat->format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
418 	{
419 		pFormat->format = VK_FORMAT_UNDEFINED;
420 	}
421 
422 	return VK_SUCCESS;
423 }
424 
GetAndroidHardwareBufferProperties(VkDevice & device,const AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)425 VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(VkDevice &device, const AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties)
426 {
427 	VkResult result = VK_SUCCESS;
428 
429 	AHardwareBuffer_Desc ahbDesc;
430 	AHardwareBuffer_describe(buffer, &ahbDesc);
431 
432 	if(pProperties->pNext != nullptr)
433 	{
434 		result = GetAndroidHardwareBufferFormatProperties(ahbDesc, (VkAndroidHardwareBufferFormatPropertiesANDROID *)pProperties->pNext);
435 		if(result != VK_SUCCESS)
436 		{
437 			return result;
438 		}
439 	}
440 
441 	const VkPhysicalDeviceMemoryProperties phyDeviceMemProps = vk::PhysicalDevice::GetMemoryProperties();
442 	pProperties->memoryTypeBits = phyDeviceMemProps.memoryTypes[0].propertyFlags;
443 
444 	if(ahbDesc.format == AHARDWAREBUFFER_FORMAT_BLOB)
445 	{
446 		pProperties->allocationSize = ahbDesc.width;
447 	}
448 	else
449 	{
450 		VkImageCreateInfo info = {};
451 		info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
452 		info.pNext = nullptr;
453 		info.flags = 0;
454 		info.imageType = VK_IMAGE_TYPE_2D;
455 		info.format = GetVkFormatFromAHBFormat(ahbDesc.format);
456 		info.extent.width = ahbDesc.width;
457 		info.extent.height = ahbDesc.height;
458 		info.extent.depth = 1;
459 		info.mipLevels = 1;
460 		info.arrayLayers = 1;
461 		info.samples = VK_SAMPLE_COUNT_1_BIT;
462 		info.tiling = VK_IMAGE_TILING_OPTIMAL;
463 		info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
464 
465 		VkImage Image;
466 
467 		result = vk::Image::Create(vk::DEVICE_MEMORY, &info, &Image, vk::Cast(device));
468 		if(result != VK_SUCCESS)
469 		{
470 			return result;
471 		}
472 
473 		pProperties->allocationSize = vk::Cast(Image)->getMemoryRequirements().size;
474 		vk::destroy(Image, vk::DEVICE_MEMORY);
475 	}
476 
477 	return result;
478 }
479 
externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const480 int AHardwareBufferExternalMemory::externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const
481 {
482 	ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
483 
484 	switch(ahbDesc.format)
485 	{
486 		case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
487 		case AHARDWAREBUFFER_FORMAT_YV12:
488 			switch(aspect)
489 			{
490 				case VK_IMAGE_ASPECT_PLANE_0_BIT:
491 					return static_cast<int>(ahbPlanes.planes[0].rowStride);
492 				case VK_IMAGE_ASPECT_PLANE_1_BIT:
493 					return static_cast<int>(ahbPlanes.planes[1].rowStride);
494 				case VK_IMAGE_ASPECT_PLANE_2_BIT:
495 					return static_cast<int>(ahbPlanes.planes[2].rowStride);
496 				default:
497 					UNSUPPORTED("Unsupported aspect %d for AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420", int(aspect));
498 					return 0;
499 			}
500 			break;
501 		default:
502 			break;
503 	}
504 	return static_cast<int>(ahbPlanes.planes[0].rowStride);
505 }
506 
externalImageMemoryOffset(VkImageAspectFlagBits aspect) const507 VkDeviceSize AHardwareBufferExternalMemory::externalImageMemoryOffset(VkImageAspectFlagBits aspect) const
508 {
509 	ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
510 
511 	switch(ahbDesc.format)
512 	{
513 		case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
514 		case AHARDWAREBUFFER_FORMAT_YV12:
515 			switch(aspect)
516 			{
517 				case VK_IMAGE_ASPECT_PLANE_0_BIT:
518 					return 0;
519 				case VK_IMAGE_ASPECT_PLANE_1_BIT:
520 					return reinterpret_cast<const char *>(ahbPlanes.planes[1].data) -
521 					       reinterpret_cast<const char *>(ahbPlanes.planes[0].data);
522 				case VK_IMAGE_ASPECT_PLANE_2_BIT:
523 					return reinterpret_cast<const char *>(ahbPlanes.planes[2].data) -
524 					       reinterpret_cast<const char *>(ahbPlanes.planes[0].data);
525 				default:
526 					UNSUPPORTED("Unsupported aspect %d for AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420", int(aspect));
527 					return 0;
528 			}
529 			break;
530 		default:
531 			break;
532 	}
533 	return 0;
534 }
535 
536 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
getMemoryObjectId() const537 uint64_t AHardwareBufferExternalMemory::getMemoryObjectId() const
538 {
539 	uint64_t id = 0;
540 	int ret = AHardwareBuffer_getId(ahb, &id);
541 	ASSERT(ret == 0);
542 	return id;
543 }
544 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
545