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 "platform_hardware_buffer_util_vk.h"
17
18 #include <algorithm>
19 #include <vulkan/vulkan_core.h>
20
21 #include <base/math/mathf.h>
22 #include <render/namespace.h>
23
24 #include "device/device.h"
25 #include "util/log.h"
26 #include "vulkan/device_vk.h"
27 #include "vulkan/validate_vk.h"
28
29 RENDER_BEGIN_NAMESPACE()
30 namespace PlatformHardwareBufferUtil {
GetMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties & physicalDeviceMemoryProperties,const uint32_t memoryTypeBits,const VkMemoryPropertyFlags memoryPropertyFlags)31 uint32_t GetMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& physicalDeviceMemoryProperties,
32 const uint32_t memoryTypeBits, const VkMemoryPropertyFlags memoryPropertyFlags)
33 {
34 uint32_t memTypeIndex = ~0u;
35 // first explicit check
36 for (uint32_t idx = 0; idx < physicalDeviceMemoryProperties.memoryTypeCount; ++idx) {
37 if ((memoryTypeBits & (1 << idx)) &&
38 (physicalDeviceMemoryProperties.memoryTypes[idx].propertyFlags == memoryPropertyFlags)) {
39 memTypeIndex = idx;
40 }
41 }
42 // then non explicit check
43 if (memTypeIndex == ~0u) {
44 for (uint32_t idx = 0; idx < physicalDeviceMemoryProperties.memoryTypeCount; ++idx) {
45 if ((memoryTypeBits & (1 << idx)) && ((physicalDeviceMemoryProperties.memoryTypes[idx].propertyFlags &
46 memoryPropertyFlags) == memoryPropertyFlags)) {
47 memTypeIndex = idx;
48 }
49 }
50 }
51 PLUGIN_ASSERT_MSG(memTypeIndex != ~0u, "requested memory not found for hwbuffer");
52 return memTypeIndex;
53 }
54
GetHwBufferImageCreateInfo(const GpuImageDesc & desc)55 VkImageCreateInfo GetHwBufferImageCreateInfo(const GpuImageDesc& desc)
56 {
57 // NOTE: undefined layout
58 return VkImageCreateInfo {
59 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
60 nullptr, // pNext
61 0, // flags
62 (VkImageType)desc.imageType, // imageType
63 (VkFormat)desc.format, // format
64 { desc.width, desc.height, desc.depth }, // extent
65 desc.mipCount, // mipLevels
66 desc.layerCount, // arrayLayers
67 (VkSampleCountFlagBits)(desc.sampleCountFlags), // samples
68 (VkImageTiling)desc.imageTiling, // tiling
69 (VkImageUsageFlags)desc.usageFlags, // usage
70 VkSharingMode::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
71 0, // queueFamilyIndexCount
72 nullptr, // pQueueFamilyIndices
73 VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
74 };
75 }
76
GetImageMemoryRequirements(const DeviceVk & deviceVk,const VkImage image,const VkImageAspectFlags imageAspectFlags,const bool useMemoryRequirements2)77 VkMemoryRequirements GetImageMemoryRequirements(const DeviceVk& deviceVk, const VkImage image,
78 const VkImageAspectFlags imageAspectFlags, const bool useMemoryRequirements2)
79 {
80 VkMemoryRequirements memoryRequirements {
81 0, // size
82 0, // alignment
83 0, // memoryTypeBits
84 };
85 const DevicePlatformDataVk& devicePlat = ((const DevicePlatformDataVk&)deviceVk.GetPlatformData());
86 VkDevice device = devicePlat.device;
87
88 const DeviceVk::CommonDeviceExtensions& deviceExtensions = deviceVk.GetCommonDeviceExtensions();
89 const DeviceVk::ExtFunctions& extFunctions = deviceVk.GetExtFunctions();
90 if (deviceExtensions.getMemoryRequirements2 && useMemoryRequirements2) {
91 if (extFunctions.vkGetImageMemoryRequirements2) {
92 VkImagePlaneMemoryRequirementsInfo planeMemoryRequirementsInfo {
93 VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, // sType
94 nullptr, // pNext
95 (VkImageAspectFlagBits)(imageAspectFlags), // planeAspect
96 };
97 VkImageMemoryRequirementsInfo2 imageMemoryRequirementsInfo {
98 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, // sType
99 &planeMemoryRequirementsInfo, // pNext
100 image, // image
101 };
102 VkMemoryRequirements2 memoryRequirements2 {
103 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // sType
104 nullptr, // pNext
105 {}, // memoryRequirements
106 };
107
108 extFunctions.vkGetImageMemoryRequirements2(device, // device
109 &imageMemoryRequirementsInfo, // pInfo
110 &memoryRequirements2); // pMemoryRequirements
111 memoryRequirements = memoryRequirements2.memoryRequirements;
112 }
113 } else {
114 vkGetImageMemoryRequirements(device, // device
115 image, // image
116 &memoryRequirements); // pMemoryRequirements
117 }
118
119 return memoryRequirements;
120 }
121
DestroyHwPlatformImage(const DeviceVk & deviceVk,VkImage image,VkDeviceMemory deviceMemory)122 void DestroyHwPlatformImage(const DeviceVk& deviceVk, VkImage image, VkDeviceMemory deviceMemory)
123 {
124 VkDevice device = ((const DevicePlatformDataVk&)deviceVk.GetPlatformData()).device;
125 vkDestroyImage(device, // device
126 image, // image
127 nullptr); // pAllocator
128 vkFreeMemory(device, // device
129 deviceMemory, // memory
130 nullptr); // pAllocator
131 }
132
FillYcbcrConversionInfo(const DeviceVk & deviceVk,const HardwareBufferProperties & hwBufferProperties,VkSamplerYcbcrConversionCreateInfo & ycbcrConversionCreateInfo)133 void FillYcbcrConversionInfo(const DeviceVk& deviceVk, const HardwareBufferProperties& hwBufferProperties,
134 VkSamplerYcbcrConversionCreateInfo& ycbcrConversionCreateInfo)
135 {
136 constexpr VkComponentMapping componentMapping {
137 VK_COMPONENT_SWIZZLE_IDENTITY, // r
138 VK_COMPONENT_SWIZZLE_IDENTITY, // g
139 VK_COMPONENT_SWIZZLE_IDENTITY, // b
140 VK_COMPONENT_SWIZZLE_IDENTITY, // a
141 };
142 // NOTE: might not support linear (needs to be checked)
143 constexpr VkFilter hardcodedFilter = VK_FILTER_NEAREST;
144 ycbcrConversionCreateInfo = {
145 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, // sType
146 nullptr, // pNext
147 hwBufferProperties.format, // format
148 hwBufferProperties.suggestedYcbcrModel, // ycbcrModel
149 hwBufferProperties.suggestedYcbcrRange, // ycbcrRange
150 componentMapping, // components
151 hwBufferProperties.suggestedXChromaOffset, // xChromaOffset
152 hwBufferProperties.suggestedYChromaOffset, // yChromaOffset
153 hardcodedFilter, // chromaFilter
154 false, // forceExplicitReconstruction
155 };
156 }
157 } // namespace PlatformHardwareBufferUtil
158 RENDER_END_NAMESPACE()
159