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 "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 if (!plat_.platformHwBuffer || !deviceVk.GetPlatformDeviceExtensions().externalMemoryHardwareBuffer) {
54 return;
55 }
56 const PlatformHardwareBufferUtil::HardwareBufferProperties hwBufferProperties =
57 PlatformHardwareBufferUtil::QueryHwBufferFormatProperties(deviceVk, plat_.platformHwBuffer);
58 plat_.format = hwBufferProperties.format;
59 desc_.format = static_cast<BASE_NS::Format>(hwBufferProperties.format);
60 if (hwBufferProperties.allocationSize > 0) {
61 PlatformHardwareBufferUtil::HardwareBufferImage hwBufferImage =
62 PlatformHardwareBufferUtil::CreateHwPlatformImage(
63 deviceVk, hwBufferProperties, desc_, plat_.platformHwBuffer);
64 PLUGIN_ASSERT((hwBufferImage.image != VK_NULL_HANDLE) && ((hwBufferImage.deviceMemory != VK_NULL_HANDLE)));
65 plat_.image = hwBufferImage.image;
66 mem_.allocationInfo.deviceMemory = hwBufferImage.deviceMemory;
67
68 if (plat_.format == VK_FORMAT_UNDEFINED) {
69 // with external format, chained conversion info is needed
70 VkSamplerYcbcrConversionCreateInfo ycbcrConversionCreateInfo;
71 PlatformHardwareBufferUtil::FillYcbcrConversionInfo(hwBufferProperties, ycbcrConversionCreateInfo);
72
73 VkExternalFormatOHOS externalFormat {
74 VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS, // sType
75 nullptr, // pNext
76 hwBufferProperties.externalFormat, // externalFormat
77 };
78 ycbcrConversionCreateInfo.pNext = &externalFormat;
79
80 const DevicePlatformDataVk& devicePlat = (const DevicePlatformDataVk&)device_.GetPlatformData();
81 const VkDevice vkDevice = devicePlat.device;
82
83 VALIDATE_VK_RESULT(deviceVk.GetExtFunctions().vkCreateSamplerYcbcrConversion(
84 vkDevice, &ycbcrConversionCreateInfo, nullptr, &platConversion_.samplerConversion));
85
86 const VkSamplerYcbcrConversionInfo yCbcrConversionInfo {
87 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, // sType
88 nullptr, // pNext
89 platConversion_.samplerConversion, // conversion
90 };
91
92 VkSamplerCreateInfo samplerCreateInfo = CreateYcbcrSamplerCreateInfo();
93 samplerCreateInfo.pNext = &yCbcrConversionInfo;
94 VALIDATE_VK_RESULT(vkCreateSampler(vkDevice, // device
95 &samplerCreateInfo, // pCreateInfo
96 nullptr, // pAllocator
97 &platConversion_.sampler)); // pSampler
98
99 CreateVkImageViews(VK_IMAGE_ASPECT_COLOR_BIT, &yCbcrConversionInfo);
100 } else {
101 CreateVkImageViews(VK_IMAGE_ASPECT_COLOR_BIT, nullptr);
102 }
103 } else {
104 plat_.platformHwBuffer = 0;
105 }
106 }
107
DestroyPlatformHwBuffer()108 void GpuImageVk::DestroyPlatformHwBuffer()
109 {
110 const DeviceVk& deviceVk = (const DeviceVk&)device_;
111 PlatformHardwareBufferUtil::DestroyHwPlatformImage(deviceVk, plat_.image, mem_.allocationInfo.deviceMemory);
112 const DevicePlatformDataVk& devicePlat = (const DevicePlatformDataVk&)device_.GetPlatformData();
113 const VkDevice device = devicePlat.device;
114 if (platConversion_.samplerConversion != VK_NULL_HANDLE) {
115 deviceVk.GetExtFunctions().vkDestroySamplerYcbcrConversion(device, // device
116 platConversion_.samplerConversion, // ycbcrConversion
117 nullptr); // pAllocator
118 }
119 if (platConversion_.sampler != VK_NULL_HANDLE) {
120 vkDestroySampler(device, // device
121 platConversion_.sampler, // sampler
122 nullptr); // pAllocator
123 }
124 }
125 RENDER_END_NAMESPACE()
126