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