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