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 #ifndef DEVICE_GPU_RESOURCE_HANDLE_UTIL_H
17 #define DEVICE_GPU_RESOURCE_HANDLE_UTIL_H
18 
19 #include <cstdint>
20 
21 #include <base/namespace.h>
22 #include <base/util/hash.h>
23 #include <render/namespace.h>
24 #include <render/resource_handle.h>
25 
RENDER_BEGIN_NAMESPACE()26 RENDER_BEGIN_NAMESPACE()
27 constexpr const uint64_t GPU_RESOURCE_HANDLE_ID_MASK { INVALID_RESOURCE_HANDLE };
28 
29 struct EngineResourceHandle {
30     uint64_t id { GPU_RESOURCE_HANDLE_ID_MASK };
31 };
32 
33 inline bool operator==(EngineResourceHandle const& lhs, EngineResourceHandle const& rhs)
34 {
35     return (lhs.id & GPU_RESOURCE_HANDLE_ID_MASK) == (rhs.id & GPU_RESOURCE_HANDLE_ID_MASK);
36 }
37 
38 // NOTE: RenderHandleType valid max is currently 15
39 
40 enum RenderHandleInfoFlagBits {
41     CORE_RESOURCE_HANDLE_DYNAMIC_TRACK = 0x00000001,
42     CORE_RESOURCE_HANDLE_RESET_ON_FRAME_BORDERS = 0x00000002,
43     CORE_RESOURCE_HANDLE_DEPTH_IMAGE = 0x00000004,
44     CORE_RESOURCE_HANDLE_IMMEDIATELY_CREATED = 0x00000008,
45     CORE_RESOURCE_HANDLE_DEFERRED_DESTROY = 0x00000010,
46     CORE_RESOURCE_HANDLE_MAP_OUTSIDE_RENDERER = 0x00000020,
47     CORE_RESOURCE_HANDLE_PLATFORM_CONVERSION = 0x00000040, // e.g. hwBuffer ycbcr conversion / oes
48     CORE_RESOURCE_HANDLE_ACCELERATION_STRUCTURE = 0x00000080,
49     CORE_RESOURCE_HANDLE_SHALLOW_RESOURCE = 0x00000100,
50     CORE_RESOURCE_HANDLE_SWAPCHAIN_RESOURCE =
51         0x00000200, // created to be used as swapchain (fast check for additional processing)
52     CORE_RESOURCE_HANDLE_DYNAMIC_ADDITIONAL_STATE = 0x00000400, // additional image state tracking
53 };
54 using RenderHandleInfoFlags = uint32_t;
55 
56 namespace RenderHandleUtil {
57 static constexpr uint64_t RES_ID_MASK { GPU_RESOURCE_HANDLE_ID_MASK };
58 static constexpr uint64_t RES_HANDLE_ID_MASK { 0x00FFfff0 };
59 static constexpr uint64_t RES_HANDLE_GENERATION_MASK { 0xFF000000 };
60 static constexpr uint64_t RES_HANDLE_HAS_NAME_MASK { 0x1000000000000 };
61 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INFO_MASK { 0xffff00000000 };
62 
63 static constexpr uint64_t RES_HANDLE_ID_SHIFT { 4 };
64 static constexpr uint64_t RES_HANDLE_TYPE_SHIFT { 0 };
65 static constexpr uint64_t RES_HANDLE_GENERATION_SHIFT { 24 };
66 static constexpr uint64_t RES_HANDLE_HAS_NAME_SHIFT { 48 };
67 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INFO_SHIFT { 32 };
68 
69 RenderHandle CreateGpuResourceHandle(const RenderHandleType type, const RenderHandleInfoFlags infoFlags,
70     const uint32_t index, const uint32_t generationIndex);
71 RenderHandle CreateGpuResourceHandle(const RenderHandleType type, const RenderHandleInfoFlags infoFlags,
72     const uint32_t index, const uint32_t generationIndex, const uint32_t hasNameId);
73 
74 // only related to GPU resources
IsDynamicResource(const RenderHandle handle)75 inline constexpr bool IsDynamicResource(const RenderHandle handle)
76 {
77     return (handle.id != INVALID_RESOURCE_HANDLE) &&
78            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
79                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DYNAMIC_TRACK);
80 }
IsDynamicAdditionalStateResource(const RenderHandle handle)81 inline constexpr bool IsDynamicAdditionalStateResource(const RenderHandle handle)
82 {
83     return ((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
84            RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DYNAMIC_ADDITIONAL_STATE;
85 }
IsResetOnFrameBorders(const RenderHandle handle)86 inline constexpr bool IsResetOnFrameBorders(const RenderHandle handle)
87 {
88     return (handle.id != INVALID_RESOURCE_HANDLE) &&
89            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
90                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_RESET_ON_FRAME_BORDERS);
91 }
IsDepthImage(const RenderHandle handle)92 inline constexpr bool IsDepthImage(const RenderHandle handle)
93 {
94     return (handle.id != INVALID_RESOURCE_HANDLE) &&
95            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
96                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DEPTH_IMAGE);
97 }
IsDeferredDestroy(const RenderHandle handle)98 inline constexpr bool IsDeferredDestroy(const RenderHandle handle)
99 {
100     return (handle.id != INVALID_RESOURCE_HANDLE) &&
101            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
102                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DEFERRED_DESTROY);
103 }
IsMappableOutsideRenderer(const RenderHandle handle)104 inline constexpr bool IsMappableOutsideRenderer(const RenderHandle handle)
105 {
106     return (handle.id != INVALID_RESOURCE_HANDLE) &&
107            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
108                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_MAP_OUTSIDE_RENDERER);
109 }
IsImmediatelyCreated(const RenderHandle handle)110 inline constexpr bool IsImmediatelyCreated(const RenderHandle handle)
111 {
112     return (handle.id != INVALID_RESOURCE_HANDLE) &&
113            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
114                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_IMMEDIATELY_CREATED);
115 }
IsPlatformConversionResource(const RenderHandle handle)116 inline constexpr bool IsPlatformConversionResource(const RenderHandle handle)
117 {
118     return (handle.id != INVALID_RESOURCE_HANDLE) &&
119            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
120                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_PLATFORM_CONVERSION);
121 }
IsShallowResource(const RenderHandle handle)122 inline constexpr bool IsShallowResource(const RenderHandle handle)
123 {
124     return (handle.id != INVALID_RESOURCE_HANDLE) &&
125            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
126                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SHALLOW_RESOURCE);
127 }
IsSwapchain(const RenderHandle & handle)128 inline constexpr bool IsSwapchain(const RenderHandle& handle)
129 {
130     return ((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
131            RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SWAPCHAIN_RESOURCE;
132 }
GetHasNamePart(const RenderHandle handle)133 inline constexpr uint32_t GetHasNamePart(const RenderHandle handle)
134 {
135     return (handle.id != INVALID_RESOURCE_HANDLE) &&
136            ((handle.id & RES_HANDLE_HAS_NAME_MASK) >> RES_HANDLE_HAS_NAME_SHIFT);
137 }
IsGpuBuffer(const RenderHandle & handle)138 inline constexpr bool IsGpuBuffer(const RenderHandle& handle)
139 {
140     return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_BUFFER;
141 }
IsGpuImage(const RenderHandle & handle)142 inline constexpr bool IsGpuImage(const RenderHandle& handle)
143 {
144     return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_IMAGE;
145 }
IsGpuSampler(const RenderHandle & handle)146 inline constexpr bool IsGpuSampler(const RenderHandle& handle)
147 {
148     return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_SAMPLER;
149 }
IsGpuAccelerationStructure(const RenderHandle & handle)150 inline constexpr bool IsGpuAccelerationStructure(const RenderHandle& handle)
151 {
152     return (handle.id != INVALID_RESOURCE_HANDLE) &&
153            (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
154                RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_ACCELERATION_STRUCTURE);
155 }
156 
157 RenderHandle CreateHandle(const RenderHandleType type, const uint32_t index);
158 RenderHandle CreateHandle(const RenderHandleType type, const uint32_t index, const uint32_t generationIndex);
159 RenderHandle CreateHandle(
160     const RenderHandleType type, const uint32_t index, const uint32_t generationIndex, const uint32_t additionalData);
161 
GetIndexPart(const RenderHandle handle)162 inline constexpr uint32_t GetIndexPart(const RenderHandle handle)
163 {
164     return (handle.id & RES_HANDLE_ID_MASK) >> RES_HANDLE_ID_SHIFT;
165 }
GetIndexPart(const uint64_t handleId)166 inline constexpr uint32_t GetIndexPart(const uint64_t handleId)
167 {
168     return (handleId & RES_HANDLE_ID_MASK) >> RES_HANDLE_ID_SHIFT;
169 }
GetGenerationIndexPart(const RenderHandle handle)170 inline constexpr uint32_t GetGenerationIndexPart(const RenderHandle handle)
171 {
172     return (handle.id & RES_HANDLE_GENERATION_MASK) >> RES_HANDLE_GENERATION_SHIFT;
173 }
GetGenerationIndexPart(const uint64_t handleId)174 inline constexpr uint32_t GetGenerationIndexPart(const uint64_t handleId)
175 {
176     return (handleId & RES_HANDLE_GENERATION_MASK) >> RES_HANDLE_GENERATION_SHIFT;
177 }
178 
GetAdditionalData(const RenderHandle handle)179 inline constexpr uint32_t GetAdditionalData(const RenderHandle handle)
180 {
181     return (handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT;
182 }
183 // 0xF (1 << descriptorSetIndex)
GetPipelineLayoutDescriptorSetMask(const RenderHandle handle)184 inline constexpr uint32_t GetPipelineLayoutDescriptorSetMask(const RenderHandle handle)
185 {
186     return (handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT;
187 }
188 
IsValid(const EngineResourceHandle & handle)189 inline constexpr bool IsValid(const EngineResourceHandle& handle)
190 {
191     return handle.id != INVALID_RESOURCE_HANDLE;
192 }
GetHandleType(const EngineResourceHandle & handle)193 inline constexpr RenderHandleType GetHandleType(const EngineResourceHandle& handle)
194 {
195     return GetHandleType(RenderHandle { handle.id });
196 }
GetIndexPart(const EngineResourceHandle & handle)197 inline constexpr uint32_t GetIndexPart(const EngineResourceHandle& handle)
198 {
199     return GetIndexPart(RenderHandle { handle.id });
200 }
GetGenerationIndexPart(const EngineResourceHandle & handle)201 inline constexpr uint32_t GetGenerationIndexPart(const EngineResourceHandle& handle)
202 {
203     return GetGenerationIndexPart(RenderHandle { handle.id });
204 }
205 EngineResourceHandle CreateEngineResourceHandle(
206     const RenderHandleType type, const uint32_t index, const uint32_t generationIndex);
207 } // namespace RenderHandleUtil
208 RENDER_END_NAMESPACE()
209 
BASE_BEGIN_NAMESPACE()210 BASE_BEGIN_NAMESPACE()
211 template<>
212 inline uint64_t hash(const RENDER_NS::RenderHandle& value)
213 {
214     return value.id;
215 }
216 BASE_END_NAMESPACE()
217 
218 #endif // DEVICE_GPU_RESOURCE_HANDLE_UTIL_H
219