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