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