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