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