1 /*
2 * Copyright (C) 2023 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 return VkImageCreateInfo {
58 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
59 nullptr, // pNext
60 0, // flags
61 (VkImageType)desc.imageType, // imageType
62 (VkFormat)desc.format, // format
63 { desc.width, desc.height, desc.depth }, // extent
64 desc.mipCount, // mipLevels
65 desc.layerCount, // arrayLayers
66 (VkSampleCountFlagBits)(desc.sampleCountFlags), // samples
67 (VkImageTiling)desc.imageTiling, // tiling
68 (VkImageUsageFlags)desc.usageFlags, // usage
69 VkSharingMode::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
70 0, // queueFamilyIndexCount
71 nullptr, // pQueueFamilyIndices
72 VkImageLayout::VK_IMAGE_LAYOUT_PREINITIALIZED, // initialLayout
73 };
74 }
75
GetImageMemoryRequirements(const DeviceVk & deviceVk,const VkImage image,const VkImageAspectFlags imageAspectFlags,const bool useMemoryRequirements2)76 VkMemoryRequirements GetImageMemoryRequirements(const DeviceVk& deviceVk, const VkImage image,
77 const VkImageAspectFlags imageAspectFlags, const bool useMemoryRequirements2)
78 {
79 VkMemoryRequirements memoryRequirements {
80 0, // size
81 0, // alignment
82 0, // memoryTypeBits
83 };
84 const DevicePlatformDataVk& devicePlat = ((const DevicePlatformDataVk&)deviceVk.GetPlatformData());
85 VkDevice device = devicePlat.device;
86
87 const DeviceVk::CommonDeviceExtensions& deviceExtensions = deviceVk.GetCommonDeviceExtensions();
88 const DeviceVk::ExtFunctions& extFunctions = deviceVk.GetExtFunctions();
89 if (deviceExtensions.getMemoryRequirements2 && useMemoryRequirements2) {
90 if (extFunctions.vkGetImageMemoryRequirements2) {
91 VkImagePlaneMemoryRequirementsInfo planeMemoryRequirementsInfo {
92 VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, // sType
93 nullptr, // pNext
94 (VkImageAspectFlagBits)(imageAspectFlags), // planeAspect
95 };
96 VkImageMemoryRequirementsInfo2 imageMemoryRequirementsInfo {
97 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, // sType
98 &planeMemoryRequirementsInfo, // pNext
99 image, // image
100 };
101 VkMemoryRequirements2 memoryRequirements2 {
102 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // sType
103 nullptr, // pNext
104 {}, // memoryRequirements
105 };
106
107 extFunctions.vkGetImageMemoryRequirements2(device, // device
108 &imageMemoryRequirementsInfo, // pInfo
109 &memoryRequirements2); // pMemoryRequirements
110 memoryRequirements = memoryRequirements2.memoryRequirements;
111 }
112 } else {
113 vkGetImageMemoryRequirements(device, // device
114 image, // image
115 &memoryRequirements); // pMemoryRequirements
116 }
117
118 return memoryRequirements;
119 }
120
DestroyHwPlatformImage(const DeviceVk & deviceVk,VkImage image,VkDeviceMemory deviceMemory)121 void DestroyHwPlatformImage(const DeviceVk& deviceVk, VkImage image, VkDeviceMemory deviceMemory)
122 {
123 VkDevice device = ((const DevicePlatformDataVk&)deviceVk.GetPlatformData()).device;
124 vkDestroyImage(device, // device
125 image, // image
126 nullptr); // pAllocator
127 vkFreeMemory(device, // device
128 deviceMemory, // memory
129 nullptr); // pAllocator
130 }
131
FillYcbcrConversionInfo(const DeviceVk & deviceVk,const HardwareBufferProperties & hwBufferProperties,VkSamplerYcbcrConversionCreateInfo & ycbcrConversionCreateInfo)132 void FillYcbcrConversionInfo(const DeviceVk& deviceVk, const HardwareBufferProperties& hwBufferProperties,
133 VkSamplerYcbcrConversionCreateInfo& ycbcrConversionCreateInfo)
134 {
135 constexpr VkComponentMapping componentMapping {
136 VK_COMPONENT_SWIZZLE_IDENTITY, // r
137 VK_COMPONENT_SWIZZLE_IDENTITY, // g
138 VK_COMPONENT_SWIZZLE_IDENTITY, // b
139 VK_COMPONENT_SWIZZLE_IDENTITY, // a
140 };
141 // NOTE: might not support linear (needs to be checked)
142 constexpr VkFilter hardcodedFilter = VK_FILTER_NEAREST;
143 ycbcrConversionCreateInfo = {
144 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, // sType
145 nullptr, // pNext
146 hwBufferProperties.format, // format
147 hwBufferProperties.suggestedYcbcrModel, // ycbcrModel
148 hwBufferProperties.suggestedYcbcrRange, // ycbcrRange
149 componentMapping, // components
150 hwBufferProperties.suggestedXChromaOffset, // xChromaOffset
151 hwBufferProperties.suggestedYChromaOffset, // yChromaOffset
152 hardcodedFilter, // chromaFilter
153 false, // forceExplicitReconstruction
154 };
155 }
156 } // namespace PlatformHardwareBufferUtil
157 RENDER_END_NAMESPACE()
158