• 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 	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 vk::DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo)167 AHardwareBufferExternalMemory::AllocateInfo::AllocateInfo(const vk::DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo)
168 {
169 	if(extendedAllocationInfo.importAndroidHardwareBufferInfo)
170 	{
171 		importAhb = true;
172 		ahb = extendedAllocationInfo.importAndroidHardwareBufferInfo->buffer;
173 	}
174 
175 	if(extendedAllocationInfo.exportMemoryAllocateInfo)
176 	{
177 		if(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes == VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
178 		{
179 			exportAhb = true;
180 		}
181 		else
182 		{
183 			UNSUPPORTED("VkExportMemoryAllocateInfo::handleTypes %d", int(extendedAllocationInfo.exportMemoryAllocateInfo->handleTypes));
184 		}
185 	}
186 
187 	if(extendedAllocationInfo.dedicatedAllocateInfo)
188 	{
189 		dedicatedImageHandle = vk::Cast(extendedAllocationInfo.dedicatedAllocateInfo->image);
190 		dedicatedBufferHandle = vk::Cast(extendedAllocationInfo.dedicatedAllocateInfo->buffer);
191 	}
192 }
193 
AHardwareBufferExternalMemory(const VkMemoryAllocateInfo * pCreateInfo,void * mem,const DeviceMemory::ExtendedAllocationInfo & extendedAllocationInfo,vk::Device * pDevice)194 AHardwareBufferExternalMemory::AHardwareBufferExternalMemory(const VkMemoryAllocateInfo *pCreateInfo, void *mem, const DeviceMemory::ExtendedAllocationInfo &extendedAllocationInfo, vk::Device *pDevice)
195     : vk::DeviceMemory(pCreateInfo, pDevice)
196     , allocateInfo(extendedAllocationInfo)
197 {
198 }
199 
~AHardwareBufferExternalMemory()200 AHardwareBufferExternalMemory::~AHardwareBufferExternalMemory()
201 {
202 	freeBuffer();
203 }
204 
205 // vkAllocateMemory
allocateBuffer()206 VkResult AHardwareBufferExternalMemory::allocateBuffer()
207 {
208 	if(allocateInfo.importAhb)
209 	{
210 		return importAndroidHardwareBuffer(allocateInfo.ahb, &buffer);
211 	}
212 	else
213 	{
214 		ASSERT(allocateInfo.exportAhb);
215 		return allocateAndroidHardwareBuffer(allocationSize, &buffer);
216 	}
217 }
218 
freeBuffer()219 void AHardwareBufferExternalMemory::freeBuffer()
220 {
221 	if(ahb != nullptr)
222 	{
223 		unlockAndroidHardwareBuffer();
224 
225 		AHardwareBuffer_release(ahb);
226 		ahb = nullptr;
227 	}
228 }
229 
importAndroidHardwareBuffer(AHardwareBuffer * buffer,void ** pBuffer)230 VkResult AHardwareBufferExternalMemory::importAndroidHardwareBuffer(AHardwareBuffer *buffer, void **pBuffer)
231 {
232 	ahb = buffer;
233 
234 	AHardwareBuffer_acquire(ahb);
235 	AHardwareBuffer_describe(ahb, &ahbDesc);
236 
237 	return lockAndroidHardwareBuffer(pBuffer);
238 }
239 
allocateAndroidHardwareBuffer(size_t size,void ** pBuffer)240 VkResult AHardwareBufferExternalMemory::allocateAndroidHardwareBuffer(size_t size, void **pBuffer)
241 {
242 	if(allocateInfo.dedicatedImageHandle)
243 	{
244 		vk::Image *image = allocateInfo.dedicatedImageHandle;
245 		ASSERT(image->getArrayLayers() == 1);
246 
247 		VkExtent3D extent = image->getExtent();
248 
249 		ahbDesc.width = extent.width;
250 		ahbDesc.height = extent.height;
251 		ahbDesc.layers = image->getArrayLayers();
252 		ahbDesc.format = GetAHBFormatFromVkFormat(image->getFormat());
253 		ahbDesc.usage = GetAHBUsageFromVkImageFlags(image->getFlags(), image->getUsage());
254 	}
255 	else if(allocateInfo.dedicatedBufferHandle)
256 	{
257 		vk::Buffer *buffer = allocateInfo.dedicatedBufferHandle;
258 
259 		ahbDesc.width = static_cast<uint32_t>(buffer->getSize());
260 		ahbDesc.height = 1;
261 		ahbDesc.layers = 1;
262 		ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
263 		ahbDesc.usage = GetAHBUsageFromVkBufferFlags(buffer->getFlags(), buffer->getUsage());
264 	}
265 	else
266 	{
267 		// Android Hardware Buffer Buffer Resources: "Android hardware buffers with a format of
268 		// AHARDWAREBUFFER_FORMAT_BLOB and usage that includes AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER can
269 		// be used as the backing store for VkBuffer objects. Such Android hardware buffers have a size
270 		// in bytes specified by their width; height and layers are both 1."
271 		ahbDesc.width = static_cast<uint32_t>(size);
272 		ahbDesc.height = 1;
273 		ahbDesc.layers = 1;
274 		ahbDesc.format = AHARDWAREBUFFER_FORMAT_BLOB;
275 		ahbDesc.usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
276 	}
277 
278 	int ret = AHardwareBuffer_allocate(&ahbDesc, &ahb);
279 	if(ret != 0)
280 	{
281 		return VK_ERROR_OUT_OF_HOST_MEMORY;
282 	}
283 
284 	AHardwareBuffer_describe(ahb, &ahbDesc);
285 
286 	return lockAndroidHardwareBuffer(pBuffer);
287 }
288 
lockAndroidHardwareBuffer(void ** pBuffer)289 VkResult AHardwareBufferExternalMemory::lockAndroidHardwareBuffer(void **pBuffer)
290 {
291 	uint64_t usage = 0;
292 	if(allocateInfo.dedicatedImageHandle)
293 	{
294 		usage = GetAHBLockUsageFromVkImageUsageFlags(allocateInfo.dedicatedImageHandle->getUsage());
295 	}
296 	else if(allocateInfo.dedicatedBufferHandle)
297 	{
298 		usage = GetAHBLockUsageFromVkBufferUsageFlags(allocateInfo.dedicatedBufferHandle->getUsage());
299 	}
300 	else
301 	{
302 		usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
303 	}
304 
305 	// Empty fence, lock immedietly.
306 	int32_t fence = -1;
307 
308 	// Empty rect, lock entire buffer.
309 	ARect *rect = nullptr;
310 
311 	int ret = AHardwareBuffer_lockPlanes(ahb, usage, fence, rect, &ahbPlanes);
312 	if(ret != 0)
313 	{
314 		return VK_ERROR_OUT_OF_HOST_MEMORY;
315 	}
316 
317 	*pBuffer = ahbPlanes.planes[0].data;
318 
319 	return VK_SUCCESS;
320 }
321 
unlockAndroidHardwareBuffer()322 VkResult AHardwareBufferExternalMemory::unlockAndroidHardwareBuffer()
323 {
324 	int ret = AHardwareBuffer_unlock(ahb, /*fence=*/nullptr);
325 	if(ret != 0)
326 	{
327 		return VK_ERROR_UNKNOWN;
328 	}
329 
330 	return VK_SUCCESS;
331 }
332 
exportAndroidHardwareBuffer(AHardwareBuffer ** pAhb) const333 VkResult AHardwareBufferExternalMemory::exportAndroidHardwareBuffer(AHardwareBuffer **pAhb) const
334 {
335 	if(getFlagBit() != VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
336 	{
337 		return VK_ERROR_OUT_OF_HOST_MEMORY;
338 	}
339 
340 	// Each call to vkGetMemoryAndroidHardwareBufferANDROID *must* return an Android hardware buffer with a new reference
341 	// acquired in addition to the reference held by the VkDeviceMemory. To avoid leaking resources, the application *must*
342 	// release the reference by calling AHardwareBuffer_release when it is no longer needed.
343 	AHardwareBuffer_acquire(ahb);
344 	*pAhb = ahb;
345 	return VK_SUCCESS;
346 }
347 
GetVkFormatFromAHBFormat(uint32_t ahbFormat)348 VkFormat AHardwareBufferExternalMemory::GetVkFormatFromAHBFormat(uint32_t ahbFormat)
349 {
350 	switch(ahbFormat)
351 	{
352 	case AHARDWAREBUFFER_FORMAT_BLOB:
353 		return VK_FORMAT_UNDEFINED;
354 	case AHARDWAREBUFFER_FORMAT_D16_UNORM:
355 		return VK_FORMAT_D16_UNORM;
356 	case AHARDWAREBUFFER_FORMAT_D24_UNORM:
357 		UNSUPPORTED("AHardwareBufferExternalMemory::AndroidHardwareBuffer_Format AHARDWAREBUFFER_FORMAT_D24_UNORM");
358 		return VK_FORMAT_X8_D24_UNORM_PACK32;
359 	case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
360 		UNSUPPORTED("AHardwareBufferExternalMemory::AndroidHardwareBuffer_Format AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT");
361 		return VK_FORMAT_X8_D24_UNORM_PACK32;
362 	case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
363 		return VK_FORMAT_D32_SFLOAT;
364 	case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
365 		return VK_FORMAT_D32_SFLOAT_S8_UINT;
366 	case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
367 		return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
368 	case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
369 		return VK_FORMAT_R16G16B16A16_SFLOAT;
370 	case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
371 		return VK_FORMAT_R5G6B5_UNORM_PACK16;
372 	case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
373 		return VK_FORMAT_R8G8B8A8_UNORM;
374 	case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
375 		return VK_FORMAT_R8G8B8A8_UNORM;
376 	case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
377 		return VK_FORMAT_R8G8B8_UNORM;
378 	case AHARDWAREBUFFER_FORMAT_S8_UINT:
379 		return VK_FORMAT_S8_UINT;
380 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
381 	case AHARDWAREBUFFER_FORMAT_YV12:
382 		return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
383 	default:
384 		UNSUPPORTED("AHardwareBufferExternalMemory::AHardwareBuffer_Format %d", int(ahbFormat));
385 		return VK_FORMAT_UNDEFINED;
386 	}
387 }
388 
GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc & ahbDesc,VkAndroidHardwareBufferFormatPropertiesANDROID * pFormat)389 VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferFormatProperties(const AHardwareBuffer_Desc &ahbDesc, VkAndroidHardwareBufferFormatPropertiesANDROID *pFormat)
390 {
391 	pFormat->sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
392 	pFormat->pNext = nullptr;
393 	pFormat->format = GetVkFormatFromAHBFormat(ahbDesc.format);
394 	pFormat->externalFormat = ahbDesc.format;
395 	pFormat->formatFeatures = GetVkFormatFeaturesFromAHBFormat(ahbDesc.format);
396 	pFormat->samplerYcbcrConversionComponents = { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
397 	pFormat->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
398 	pFormat->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW;
399 	pFormat->suggestedXChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
400 	pFormat->suggestedYChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
401 
402 	// YUV formats are not listed in the AHardwareBuffer Format Equivalence table in the Vulkan spec.
403 	// Clients must use VkExternalFormatANDROID.
404 	if(pFormat->format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
405 	{
406 		pFormat->format = VK_FORMAT_UNDEFINED;
407 	}
408 
409 	return VK_SUCCESS;
410 }
411 
GetAndroidHardwareBufferProperties(VkDevice & device,const AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)412 VkResult AHardwareBufferExternalMemory::GetAndroidHardwareBufferProperties(VkDevice &device, const AHardwareBuffer *buffer, VkAndroidHardwareBufferPropertiesANDROID *pProperties)
413 {
414 	VkResult result = VK_SUCCESS;
415 
416 	AHardwareBuffer_Desc ahbDesc;
417 	AHardwareBuffer_describe(buffer, &ahbDesc);
418 
419 	if(pProperties->pNext != nullptr)
420 	{
421 		result = GetAndroidHardwareBufferFormatProperties(ahbDesc, (VkAndroidHardwareBufferFormatPropertiesANDROID *)pProperties->pNext);
422 		if(result != VK_SUCCESS)
423 		{
424 			return result;
425 		}
426 	}
427 
428 	const VkPhysicalDeviceMemoryProperties phyDeviceMemProps = vk::PhysicalDevice::GetMemoryProperties();
429 	pProperties->memoryTypeBits = phyDeviceMemProps.memoryTypes[0].propertyFlags;
430 
431 	if(ahbDesc.format == AHARDWAREBUFFER_FORMAT_BLOB)
432 	{
433 		pProperties->allocationSize = ahbDesc.width;
434 	}
435 	else
436 	{
437 		VkImageCreateInfo info = {};
438 		info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
439 		info.pNext = nullptr;
440 		info.flags = 0;
441 		info.imageType = VK_IMAGE_TYPE_2D;
442 		info.format = GetVkFormatFromAHBFormat(ahbDesc.format);
443 		info.extent.width = ahbDesc.width;
444 		info.extent.height = ahbDesc.height;
445 		info.extent.depth = 1;
446 		info.mipLevels = 1;
447 		info.arrayLayers = 1;
448 		info.samples = VK_SAMPLE_COUNT_1_BIT;
449 		info.tiling = VK_IMAGE_TILING_OPTIMAL;
450 		info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
451 
452 		VkImage Image;
453 
454 		result = vk::Image::Create(vk::NULL_ALLOCATION_CALLBACKS, &info, &Image, vk::Cast(device));
455 		if(result != VK_SUCCESS)
456 		{
457 			return result;
458 		}
459 
460 		pProperties->allocationSize = vk::Cast(Image)->getMemoryRequirements().size;
461 		vk::destroy(Image, vk::NULL_ALLOCATION_CALLBACKS);
462 	}
463 
464 	return result;
465 }
466 
externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const467 int AHardwareBufferExternalMemory::externalImageRowPitchBytes(VkImageAspectFlagBits aspect) const
468 {
469 	ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
470 
471 	switch(ahbDesc.format)
472 	{
473 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
474 	case AHARDWAREBUFFER_FORMAT_YV12:
475 		switch(aspect)
476 		{
477 		case VK_IMAGE_ASPECT_PLANE_0_BIT:
478 			return static_cast<int>(ahbPlanes.planes[0].rowStride);
479 		case VK_IMAGE_ASPECT_PLANE_1_BIT:
480 			return static_cast<int>(ahbPlanes.planes[1].rowStride);
481 		case VK_IMAGE_ASPECT_PLANE_2_BIT:
482 			return static_cast<int>(ahbPlanes.planes[2].rowStride);
483 		default:
484 			UNSUPPORTED("Unsupported aspect %d for AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420", int(aspect));
485 			return 0;
486 		}
487 		break;
488 	default:
489 		break;
490 	}
491 	return static_cast<int>(ahbPlanes.planes[0].rowStride);
492 }
493 
externalImageMemoryOffset(VkImageAspectFlagBits aspect) const494 VkDeviceSize AHardwareBufferExternalMemory::externalImageMemoryOffset(VkImageAspectFlagBits aspect) const
495 {
496 	ASSERT(allocateInfo.dedicatedImageHandle != nullptr);
497 
498 	switch(ahbDesc.format)
499 	{
500 	case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
501 	case AHARDWAREBUFFER_FORMAT_YV12:
502 		switch(aspect)
503 		{
504 		case VK_IMAGE_ASPECT_PLANE_0_BIT:
505 			return 0;
506 		case VK_IMAGE_ASPECT_PLANE_1_BIT:
507 			return reinterpret_cast<const char *>(ahbPlanes.planes[1].data) -
508 			       reinterpret_cast<const char *>(ahbPlanes.planes[0].data);
509 		case VK_IMAGE_ASPECT_PLANE_2_BIT:
510 			return reinterpret_cast<const char *>(ahbPlanes.planes[2].data) -
511 			       reinterpret_cast<const char *>(ahbPlanes.planes[0].data);
512 		default:
513 			UNSUPPORTED("Unsupported aspect %d for AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420", int(aspect));
514 			return 0;
515 		}
516 		break;
517 	default:
518 		break;
519 	}
520 	return 0;
521 }
522 
523 #ifdef SWIFTSHADER_DEVICE_MEMORY_REPORT
getMemoryObjectId() const524 uint64_t AHardwareBufferExternalMemory::getMemoryObjectId() const
525 {
526 	uint64_t id = 0;
527 	int ret = AHardwareBuffer_getId(ahb, &id);
528 	ASSERT(ret == 0);
529 	return id;
530 }
531 #endif  // SWIFTSHADER_DEVICE_MEMORY_REPORT
532