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