1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
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
16 #include <vulkan/vulkan.h>
17
18 #include <base/util/formats.h>
19
20 #include "vulkan/device_vk.h"
21 #include "vulkan/platform_hardware_buffer_util_vk.h"
22 #include "vulkan/validate_vk.h"
23
24 struct OH_NativeBuffer;
25
26 RENDER_BEGIN_NAMESPACE()
27 namespace PlatformHardwareBufferUtil {
QueryHwBufferFormatProperties(const DeviceVk & deviceVk,uintptr_t hwBuffer)28 HardwareBufferProperties QueryHwBufferFormatProperties(const DeviceVk& deviceVk, uintptr_t hwBuffer)
29 {
30 HardwareBufferProperties hardwareBufferProperties;
31
32 const DevicePlatformDataVk& devicePlat = ((const DevicePlatformDataVk&)deviceVk.GetPlatformData());
33 const VkDevice device = devicePlat.device;
34 const PlatformExtFunctions& extFunctions = deviceVk.GetPlatformExtFunctions();
35
36 OH_NativeBuffer* nativeBuffer = static_cast<OH_NativeBuffer*>(reinterpret_cast<void*>(hwBuffer));
37 if (nativeBuffer && extFunctions.vkGetNativeBufferPropertiesOHOS && extFunctions.vkGetMemoryNativeBufferOHOS) {
38 VkNativeBufferFormatPropertiesOHOS bufferFormatProperties;
39 bufferFormatProperties.sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_FORMAT_PROPERTIES_OHOS;
40 bufferFormatProperties.pNext = nullptr;
41
42 VkNativeBufferPropertiesOHOS bufferProperties {
43 VK_STRUCTURE_TYPE_NATIVE_BUFFER_PROPERTIES_OHOS, // sType
44 &bufferFormatProperties, // pNext
45 0, // allocationSize
46 0, // memoryTypeBits
47 };
48 VALIDATE_VK_RESULT(extFunctions.vkGetNativeBufferPropertiesOHOS(device, // device
49 nativeBuffer, // buffer
50 &bufferProperties)); // pProperties
51
52 PLUGIN_ASSERT_MSG(bufferProperties.allocationSize > 0, "ohos native buffer allocation size is zero");
53 PLUGIN_ASSERT_MSG(bufferFormatProperties.externalFormat != 0, "ohos native buffer externalFormat cannot be 0");
54
55 hardwareBufferProperties.allocationSize = bufferProperties.allocationSize;
56 hardwareBufferProperties.memoryTypeBits = bufferProperties.memoryTypeBits;
57
58 hardwareBufferProperties.format = bufferFormatProperties.format;
59 hardwareBufferProperties.externalFormat = bufferFormatProperties.externalFormat;
60 hardwareBufferProperties.formatFeatures = bufferFormatProperties.formatFeatures;
61 hardwareBufferProperties.samplerYcbcrConversionComponents =
62 bufferFormatProperties.samplerYcbcrConversionComponents;
63 hardwareBufferProperties.suggestedYcbcrModel = bufferFormatProperties.suggestedYcbcrModel;
64 hardwareBufferProperties.suggestedYcbcrRange = bufferFormatProperties.suggestedYcbcrRange;
65 hardwareBufferProperties.suggestedXChromaOffset = bufferFormatProperties.suggestedXChromaOffset;
66 hardwareBufferProperties.suggestedYChromaOffset = bufferFormatProperties.suggestedYChromaOffset;
67 }
68
69 return hardwareBufferProperties;
70 }
71
CreateHwPlatformImage(const DeviceVk & deviceVk,const HardwareBufferProperties & hwBufferProperties,const GpuImageDesc & desc,uintptr_t hwBuffer)72 HardwareBufferImage CreateHwPlatformImage(const DeviceVk& deviceVk, const HardwareBufferProperties& hwBufferProperties,
73 const GpuImageDesc& desc, uintptr_t hwBuffer)
74 {
75 HardwareBufferImage hwBufferImage;
76 GpuImageDesc validDesc = desc;
77 const bool useExternalFormat = (validDesc.format == BASE_NS::BASE_FORMAT_UNDEFINED);
78 if (useExternalFormat) {
79 validDesc.usageFlags = CORE_IMAGE_USAGE_SAMPLED_BIT;
80 }
81 VkImageCreateInfo imageCreateInfo = GetHwBufferImageCreateInfo(validDesc);
82
83 VkExternalFormatOHOS externalFormat {
84 VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS, // sType
85 nullptr, // pNext
86 hwBufferProperties.externalFormat, // externalFormat
87 };
88 VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo {
89 VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, // sType
90 nullptr, // pNext
91 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS, // handleTypes
92 };
93 imageCreateInfo.pNext = &externalMemoryImageCreateInfo;
94 if (useExternalFormat) { // chain external format
95 externalMemoryImageCreateInfo.pNext = &externalFormat;
96 }
97
98 const DevicePlatformDataVk& platData = (const DevicePlatformDataVk&)deviceVk.GetPlatformData();
99 VkDevice device = platData.device;
100 VALIDATE_VK_RESULT(vkCreateImage(device, // device
101 &imageCreateInfo, // pCreateInfo
102 nullptr, // pAllocator
103 &hwBufferImage.image)); // pImage
104 // get memory type index based on
105 const uint32_t memoryTypeIndex =
106 GetMemoryTypeIndex(platData.physicalDeviceProperties.physicalDeviceMemoryProperties,
107 hwBufferProperties.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
108 VkMemoryAllocateInfo memoryAllocateInfo {
109 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
110 nullptr, // pNext
111 hwBufferProperties.allocationSize, // allocationSize
112 memoryTypeIndex, // memoryTypeIndex
113 };
114
115 OH_NativeBuffer* nativeBuffer = static_cast<OH_NativeBuffer*>(reinterpret_cast<void*>(hwBuffer));
116 PLUGIN_ASSERT(nativeBuffer);
117 VkMemoryDedicatedAllocateInfo dedicatedMemoryAllocateInfo {
118 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // sType
119 nullptr, // pNext
120 hwBufferImage.image, // image
121 VK_NULL_HANDLE, // buffer
122 };
123 VkImportNativeBufferInfoOHOS importHardwareBufferInfo {
124 VK_STRUCTURE_TYPE_IMPORT_NATIVE_BUFFER_INFO_OHOS, // sType
125 &dedicatedMemoryAllocateInfo, // pNext
126 nativeBuffer, // buffer
127 };
128 memoryAllocateInfo.pNext = &importHardwareBufferInfo;
129
130 VALIDATE_VK_RESULT(vkAllocateMemory(device, // device
131 &memoryAllocateInfo, // pAllocateInfo
132 nullptr, // pAllocator
133 &hwBufferImage.deviceMemory)); // pMemory
134 VALIDATE_VK_RESULT(vkBindImageMemory(device, // device
135 hwBufferImage.image, // image
136 hwBufferImage.deviceMemory, // memory
137 0)); // memoryOffset
138
139 return hwBufferImage;
140 }
141 } // namespace PlatformHardwareBufferUtil
142 RENDER_END_NAMESPACE()
143