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 "vulkan/device_vk.h"
19 #include "vulkan/gpu_image_vk.h"
20 #include "vulkan/platform_hardware_buffer_util_vk.h"
21 #include "vulkan/validate_vk.h"
22
23 RENDER_BEGIN_NAMESPACE()
24 namespace {
CreateYcbcrSamplerCreateInfo()25 VkSamplerCreateInfo CreateYcbcrSamplerCreateInfo()
26 {
27 return VkSamplerCreateInfo {
28 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // sType
29 nullptr, // pNext
30 0, // flags
31 VK_FILTER_NEAREST, // magFilter
32 VK_FILTER_NEAREST, // minFilter
33 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
34 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
35 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
36 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
37 0.0f, // mipLodBias
38 false, // anisotropyEnable
39 1.0f, // maxAnisotropy
40 false, // compareEnabled
41 VK_COMPARE_OP_NEVER, // compareOp
42 0.0f, // minLod
43 0.0f, // maxLod
44 VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, // borderColor
45 false, // unnormalizedCoordinates
46 };
47 }
48 } // namespace
49
CreatePlatformHwBuffer()50 void GpuImageVk::CreatePlatformHwBuffer()
51 {
52 const DeviceVk& deviceVk = (const DeviceVk&)device_;
53 const PlatformDeviceExtensions& deviceExtensions = deviceVk.GetPlatformDeviceExtensions();
54 if ((hwBuffer_ != 0) && deviceExtensions.externalMemoryHardwareBuffer) {
55 const PlatformHardwareBufferUtil::HardwareBufferProperties hwBufferProperties =
56 PlatformHardwareBufferUtil::QueryHwBufferFormatProperties(deviceVk, hwBuffer_);
57 if (hwBufferProperties.allocationSize > 0) {
58 PlatformHardwareBufferUtil::HardwareBufferImage hwBufferImage =
59 PlatformHardwareBufferUtil::CreateHwPlatformImage(deviceVk, hwBufferProperties, desc_, hwBuffer_);
60 PLUGIN_ASSERT((hwBufferImage.image != VK_NULL_HANDLE) && ((hwBufferImage.deviceMemory != VK_NULL_HANDLE)));
61 plat_.image = hwBufferImage.image;
62 mem_.allocationInfo.deviceMemory = hwBufferImage.deviceMemory;
63
64 if (plat_.format == VK_FORMAT_UNDEFINED) {
65 // with external format, chained conversion info is needed
66 VkSamplerYcbcrConversionCreateInfo ycbcrConversionCreateInfo;
67 PlatformHardwareBufferUtil::FillYcbcrConversionInfo(
68 deviceVk, hwBufferProperties, ycbcrConversionCreateInfo);
69
70 VkExternalFormatOHOS externalFormat {
71 VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS, // sType
72 nullptr, // pNext
73 hwBufferProperties.externalFormat, // externalFormat
74 };
75 ycbcrConversionCreateInfo.pNext = &externalFormat;
76
77 const DevicePlatformDataVk& devicePlat = (const DevicePlatformDataVk&)device_.GetPlatformData();
78 const VkDevice vkDevice = devicePlat.device;
79
80 VALIDATE_VK_RESULT(deviceVk.GetExtFunctions().vkCreateSamplerYcbcrConversion(
81 vkDevice, &ycbcrConversionCreateInfo, nullptr, &platConversion_.samplerConversion));
82
83 const VkSamplerYcbcrConversionInfo yCbcrConversionInfo {
84 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, // sType
85 nullptr, // pNext
86 platConversion_.samplerConversion, // conversion
87 };
88
89 VkSamplerCreateInfo samplerCreateInfo = CreateYcbcrSamplerCreateInfo();
90 samplerCreateInfo.pNext = &yCbcrConversionInfo;
91 VALIDATE_VK_RESULT(vkCreateSampler(vkDevice, // device
92 &samplerCreateInfo, // pCreateInfo
93 nullptr, // pAllocator
94 &platConversion_.sampler)); // pSampler
95
96 CreateVkImageViews(VK_IMAGE_ASPECT_COLOR_BIT, &yCbcrConversionInfo);
97 } else {
98 CreateVkImageViews(VK_IMAGE_ASPECT_COLOR_BIT, nullptr);
99 }
100 } else {
101 hwBuffer_ = 0;
102 }
103 }
104 }
105
DestroyPlatformHwBuffer()106 void GpuImageVk::DestroyPlatformHwBuffer()
107 {
108 const DeviceVk& deviceVk = (const DeviceVk&)device_;
109 PlatformHardwareBufferUtil::DestroyHwPlatformImage(deviceVk, plat_.image, mem_.allocationInfo.deviceMemory);
110 const DevicePlatformDataVk& devicePlat = (const DevicePlatformDataVk&)device_.GetPlatformData();
111 const VkDevice device = devicePlat.device;
112 if (platConversion_.samplerConversion != VK_NULL_HANDLE) {
113 deviceVk.GetExtFunctions().vkDestroySamplerYcbcrConversion(device, // device
114 platConversion_.samplerConversion, // ycbcrConversion
115 nullptr); // pAllocator
116 }
117 if (platConversion_.sampler != VK_NULL_HANDLE) {
118 vkDestroySampler(device, // device
119 platConversion_.sampler, // sampler
120 nullptr); // pAllocator
121 }
122 }
123 RENDER_END_NAMESPACE()
124