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