• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
41         VkNativeBufferPropertiesOHOS bufferProperties {};
42         bufferProperties.sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_PROPERTIES_OHOS;
43         bufferProperties.pNext = &bufferFormatProperties;
44 
45         VALIDATE_VK_RESULT(extFunctions.vkGetNativeBufferPropertiesOHOS(device, // device
46             nativeBuffer,                                                       // buffer
47             &bufferProperties));                                                // pProperties
48 
49         PLUGIN_ASSERT_MSG(bufferProperties.allocationSize > 0, "ohos native buffer allocation size is zero");
50         PLUGIN_ASSERT_MSG(bufferFormatProperties.externalFormat != 0, "ohos native buffer externalFormat cannot be 0");
51 
52         hardwareBufferProperties.allocationSize = bufferProperties.allocationSize;
53         hardwareBufferProperties.memoryTypeBits = bufferProperties.memoryTypeBits;
54 
55         hardwareBufferProperties.format = bufferFormatProperties.format;
56         hardwareBufferProperties.externalFormat = bufferFormatProperties.externalFormat;
57         hardwareBufferProperties.formatFeatures = bufferFormatProperties.formatFeatures;
58         hardwareBufferProperties.samplerYcbcrConversionComponents =
59             bufferFormatProperties.samplerYcbcrConversionComponents;
60         hardwareBufferProperties.suggestedYcbcrModel = bufferFormatProperties.suggestedYcbcrModel;
61         hardwareBufferProperties.suggestedYcbcrRange = bufferFormatProperties.suggestedYcbcrRange;
62         hardwareBufferProperties.suggestedXChromaOffset = bufferFormatProperties.suggestedXChromaOffset;
63         hardwareBufferProperties.suggestedYChromaOffset = bufferFormatProperties.suggestedYChromaOffset;
64     }
65 
66     return hardwareBufferProperties;
67 }
68 
CreateHwPlatformImage(const DeviceVk & deviceVk,const HardwareBufferProperties & hwBufferProperties,const GpuImageDesc & desc,uintptr_t hwBuffer)69 HardwareBufferImage CreateHwPlatformImage(const DeviceVk& deviceVk, const HardwareBufferProperties& hwBufferProperties,
70     const GpuImageDesc& desc, uintptr_t hwBuffer)
71 {
72     HardwareBufferImage hwBufferImage;
73     GpuImageDesc validDesc = desc;
74     const bool useExternalFormat = hwBufferProperties.externalFormat != 0U;
75     if (useExternalFormat) {
76         validDesc.usageFlags = CORE_IMAGE_USAGE_SAMPLED_BIT;
77     }
78     VkImageCreateInfo imageCreateInfo = GetHwBufferImageCreateInfo(validDesc);
79 
80     VkExternalFormatOHOS externalFormat {
81         VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS, // sType
82         nullptr,                                // pNext
83         hwBufferProperties.externalFormat,      // externalFormat
84     };
85     VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo {
86         VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,        // sType
87         nullptr,                                                    // pNext
88         VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OHOS, // handleTypes
89     };
90     imageCreateInfo.pNext = &externalMemoryImageCreateInfo;
91     if (useExternalFormat) { // chain external format
92         externalMemoryImageCreateInfo.pNext = &externalFormat;
93     }
94 
95     const DevicePlatformDataVk& platData = (const DevicePlatformDataVk&)deviceVk.GetPlatformData();
96     VkDevice device = platData.device;
97     VALIDATE_VK_RESULT(vkCreateImage(device, // device
98         &imageCreateInfo,                    // pCreateInfo
99         nullptr,                             // pAllocator
100         &hwBufferImage.image));              // pImage
101 
102     // some older version of validation layers required calling vkGetImageMemoryRequirements before
103     // vkAllocateMemory. with at least 1.3.224.1 it's an error to call vkGetImageMemoryRequirements:
104     // "If image was created with the VK_EXTERNAL_MEMORY_HANDLE_TYPE_OHOS_NATIVE_BUFFER_BIT_OPENHARMONY external memory
105     // handle type, then image must be bound to memory."
106 
107     // get memory type index based on
108     const uint32_t memoryTypeIndex =
109         GetMemoryTypeIndex(platData.physicalDeviceProperties.physicalDeviceMemoryProperties,
110             hwBufferProperties.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
111     VkMemoryAllocateInfo memoryAllocateInfo {
112         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
113         nullptr,                                // pNext
114         hwBufferProperties.allocationSize,      // allocationSize
115         memoryTypeIndex,                        // memoryTypeIndex
116     };
117 
118     OH_NativeBuffer* nativeBuffer = static_cast<OH_NativeBuffer*>(reinterpret_cast<void*>(hwBuffer));
119     PLUGIN_ASSERT(nativeBuffer);
120     VkMemoryDedicatedAllocateInfo dedicatedMemoryAllocateInfo {
121         VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // sType;
122         nullptr,                                          // pNext
123         hwBufferImage.image,                              // image
124         VK_NULL_HANDLE,                                   // buffer
125     };
126     VkImportNativeBufferInfoOHOS importHardwareBufferInfo {
127         VK_STRUCTURE_TYPE_IMPORT_NATIVE_BUFFER_INFO_OHOS, // sType
128         &dedicatedMemoryAllocateInfo,                     // pNext
129         nativeBuffer,                                     // buffer
130     };
131     memoryAllocateInfo.pNext = &importHardwareBufferInfo;
132 
133     VALIDATE_VK_RESULT(vkAllocateMemory(device,  // device
134         &memoryAllocateInfo,                     // pAllocateInfo
135         nullptr,                                 // pAllocator
136         &hwBufferImage.deviceMemory));           // pMemory
137     VALIDATE_VK_RESULT(vkBindImageMemory(device, // device
138         hwBufferImage.image,                     // image
139         hwBufferImage.deviceMemory,              // memory
140         0));                                     // memoryOffset
141 
142     return hwBufferImage;
143 }
144 
CreateHwPlatformBuffer(const DeviceVk & deviceVk,const HardwareBufferProperties & hwBufferProperties,const GpuBufferDesc & desc,uintptr_t hwBuffer)145 HardwareBufferBuffer CreateHwPlatformBuffer(const DeviceVk& deviceVk,
146     const HardwareBufferProperties& hwBufferProperties, const GpuBufferDesc& desc, uintptr_t hwBuffer)
147 {
148     constexpr VkBufferCreateFlags bufferCreateFlags { 0 };
149 
150     VkBufferCreateInfo bufferCreateInfo {
151         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,     // sType
152         nullptr,                                  // pNext
153         bufferCreateFlags,                        // flags
154         hwBufferProperties.allocationSize,        // size
155         desc.usageFlags,                          // usage
156         VkSharingMode::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
157         0,                                        // queueFamilyIndexCount
158         nullptr,                                  // pQueueFamilyIndices
159     };
160     VkExternalMemoryBufferCreateInfo externalMemoryBufferCreateInfo {
161         VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,               // sType
162         nullptr,                                                            // pNext
163         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, // handleTypes
164     };
165     bufferCreateInfo.pNext = &externalMemoryBufferCreateInfo;
166 
167     const auto& platData = (const DevicePlatformDataVk&)deviceVk.GetPlatformData();
168     VkDevice device = platData.device;
169     HardwareBufferBuffer hwBufferBuffer { VK_NULL_HANDLE, VK_NULL_HANDLE };
170     VALIDATE_VK_RESULT(vkCreateBuffer(device, // device
171         &bufferCreateInfo,                    // pCreateInfo
172         nullptr,                              // pAllocator
173         &hwBufferBuffer.buffer));             // pImage
174     // get memory type index based on
175     const uint32_t memoryTypeIndex =
176         GetMemoryTypeIndex(platData.physicalDeviceProperties.physicalDeviceMemoryProperties,
177             hwBufferProperties.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
178     VkMemoryAllocateInfo memoryAllocateInfo {
179         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // sType
180         nullptr,                                // pNext
181         hwBufferProperties.allocationSize,      // allocationSize
182         memoryTypeIndex,                        // memoryTypeIndex
183     };
184 
185     OH_NativeBuffer* nativeBuffer = static_cast<OH_NativeBuffer*>(reinterpret_cast<void*>(hwBuffer));
186     PLUGIN_ASSERT(nativeBuffer);
187 
188     VkImportNativeBufferInfoOHOS importHardwareBufferInfo {
189         VK_STRUCTURE_TYPE_IMPORT_NATIVE_BUFFER_INFO_OHOS, // sType
190         nullptr,                                          // pNext
191         nativeBuffer,                                     // buffer
192     };
193     memoryAllocateInfo.pNext = &importHardwareBufferInfo;
194 
195     VALIDATE_VK_RESULT(vkAllocateMemory(device,   // device
196         &memoryAllocateInfo,                      // pAllocateInfo
197         nullptr,                                  // pAllocator
198         &hwBufferBuffer.deviceMemory));           // pMemory
199     VALIDATE_VK_RESULT(vkBindBufferMemory(device, // device
200         hwBufferBuffer.buffer,                    // image
201         hwBufferBuffer.deviceMemory,              // memory
202         0));                                      // memoryOffset
203     return hwBufferBuffer;
204 }
205 } // namespace PlatformHardwareBufferUtil
206 RENDER_END_NAMESPACE()
207