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, // e.g. remappable resource or dynamic ring buffer buffer
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 CORE_RESOURCE_HANDLE_RENDER_TIME_MAPPED_GPU_BUFFER = 0x00000800, // special render time mappable GPU buffer
54 };
55 using RenderHandleInfoFlags = uint32_t;
56
57 namespace RenderHandleUtil {
58 static constexpr uint64_t RES_ID_MASK { GPU_RESOURCE_HANDLE_ID_MASK };
59 static constexpr uint64_t RES_HANDLE_ID_MASK { 0x00FFfff0 };
60 static constexpr uint64_t RES_HANDLE_GENERATION_MASK { 0xFF000000 };
61 static constexpr uint64_t RES_HANDLE_HAS_NAME_MASK { 0x100000000000 };
62 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INFO_MASK { 0xfff00000000 };
63 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INDEX_MASK { 0xFFFF000000000000 };
64
65 static constexpr uint64_t RES_HANDLE_ID_SHIFT { 4 }; // 4 : param
66 static constexpr uint64_t RES_HANDLE_TYPE_SHIFT { 0 };
67 static constexpr uint64_t RES_HANDLE_GENERATION_SHIFT { 24 }; // 24 : param
68 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INFO_SHIFT { 32 }; // 32 : param
69 static constexpr uint64_t RES_HANDLE_HAS_NAME_SHIFT { 44 }; // 44 : param
70 static constexpr uint64_t RES_HANDLE_ADDITIONAL_INDEX_SHIFT { 48 }; // 48 : param
71
72 RenderHandle CreateGpuResourceHandle(
73 RenderHandleType type, RenderHandleInfoFlags infoFlags, uint32_t index, uint32_t generationIndex);
74 RenderHandle CreateGpuResourceHandle(RenderHandleType type, RenderHandleInfoFlags infoFlags, uint32_t index,
75 uint32_t generationIndex, uint32_t hasNameId);
76
77 // only related to GPU resources
IsDynamicResource(const RenderHandle handle)78 inline constexpr bool IsDynamicResource(const RenderHandle handle)
79 {
80 return (handle.id != INVALID_RESOURCE_HANDLE) &&
81 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
82 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DYNAMIC_TRACK);
83 }
IsDynamicAdditionalStateResource(const RenderHandle handle)84 inline constexpr bool IsDynamicAdditionalStateResource(const RenderHandle handle)
85 {
86 return ((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
87 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DYNAMIC_ADDITIONAL_STATE;
88 }
IsResetOnFrameBorders(const RenderHandle handle)89 inline constexpr bool IsResetOnFrameBorders(const RenderHandle handle)
90 {
91 return (handle.id != INVALID_RESOURCE_HANDLE) &&
92 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
93 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_RESET_ON_FRAME_BORDERS);
94 }
IsDepthImage(const RenderHandle handle)95 inline constexpr bool IsDepthImage(const RenderHandle handle)
96 {
97 return (handle.id != INVALID_RESOURCE_HANDLE) &&
98 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
99 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DEPTH_IMAGE);
100 }
IsDeferredDestroy(const RenderHandle handle)101 inline constexpr bool IsDeferredDestroy(const RenderHandle handle)
102 {
103 return (handle.id != INVALID_RESOURCE_HANDLE) &&
104 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
105 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_DEFERRED_DESTROY);
106 }
IsMappableOutsideRenderer(const RenderHandle handle)107 inline constexpr bool IsMappableOutsideRenderer(const RenderHandle handle)
108 {
109 return (handle.id != INVALID_RESOURCE_HANDLE) &&
110 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
111 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_MAP_OUTSIDE_RENDERER);
112 }
IsImmediatelyCreated(const RenderHandle handle)113 inline constexpr bool IsImmediatelyCreated(const RenderHandle handle)
114 {
115 return (handle.id != INVALID_RESOURCE_HANDLE) &&
116 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
117 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_IMMEDIATELY_CREATED);
118 }
IsPlatformConversionResource(const RenderHandle handle)119 inline constexpr bool IsPlatformConversionResource(const RenderHandle handle)
120 {
121 return (handle.id != INVALID_RESOURCE_HANDLE) &&
122 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
123 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_PLATFORM_CONVERSION);
124 }
IsShallowResource(const RenderHandle handle)125 inline constexpr bool IsShallowResource(const RenderHandle handle)
126 {
127 return (handle.id != INVALID_RESOURCE_HANDLE) &&
128 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
129 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SHALLOW_RESOURCE);
130 }
IsSwapchain(const RenderHandle & handle)131 inline constexpr bool IsSwapchain(const RenderHandle& handle)
132 {
133 return ((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
134 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_SWAPCHAIN_RESOURCE;
135 }
GetHasNamePart(const RenderHandle handle)136 inline constexpr uint32_t GetHasNamePart(const RenderHandle handle)
137 {
138 return (handle.id != INVALID_RESOURCE_HANDLE) &&
139 ((handle.id & RES_HANDLE_HAS_NAME_MASK) >> RES_HANDLE_HAS_NAME_SHIFT);
140 }
IsGpuBuffer(const RenderHandle & handle)141 inline constexpr bool IsGpuBuffer(const RenderHandle& handle)
142 {
143 return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_BUFFER;
144 }
IsGpuImage(const RenderHandle & handle)145 inline constexpr bool IsGpuImage(const RenderHandle& handle)
146 {
147 return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_IMAGE;
148 }
IsGpuSampler(const RenderHandle & handle)149 inline constexpr bool IsGpuSampler(const RenderHandle& handle)
150 {
151 return RenderHandleUtil::GetHandleType(handle) == RenderHandleType::GPU_SAMPLER;
152 }
IsGpuAccelerationStructure(const RenderHandle & handle)153 inline constexpr bool IsGpuAccelerationStructure(const RenderHandle& handle)
154 {
155 return (handle.id != INVALID_RESOURCE_HANDLE) &&
156 (((handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT) &
157 RenderHandleInfoFlagBits::CORE_RESOURCE_HANDLE_ACCELERATION_STRUCTURE);
158 }
159
160 RenderHandle CreateHandle(RenderHandleType type, uint32_t index);
161 RenderHandle CreateHandle(RenderHandleType type, uint32_t index, uint32_t generationIndex);
162 RenderHandle CreateHandle(RenderHandleType type, uint32_t index, uint32_t generationIndex, uint32_t additionalData);
163 RenderHandle CreateHandle(
164 RenderHandleType type, uint32_t index, uint32_t generationIndex, uint32_t additionalData, uint32_t additionalIndex);
165
GetIndexPart(const RenderHandle handle)166 inline constexpr uint32_t GetIndexPart(const RenderHandle handle)
167 {
168 return (handle.id & RES_HANDLE_ID_MASK) >> RES_HANDLE_ID_SHIFT;
169 }
GetIndexPart(const uint64_t handleId)170 inline constexpr uint32_t GetIndexPart(const uint64_t handleId)
171 {
172 return (handleId & RES_HANDLE_ID_MASK) >> RES_HANDLE_ID_SHIFT;
173 }
GetGenerationIndexPart(const RenderHandle handle)174 inline constexpr uint32_t GetGenerationIndexPart(const RenderHandle handle)
175 {
176 return (handle.id & RES_HANDLE_GENERATION_MASK) >> RES_HANDLE_GENERATION_SHIFT;
177 }
GetGenerationIndexPart(const uint64_t handleId)178 inline constexpr uint32_t GetGenerationIndexPart(const uint64_t handleId)
179 {
180 return (handleId & RES_HANDLE_GENERATION_MASK) >> RES_HANDLE_GENERATION_SHIFT;
181 }
182
GetAdditionalData(const RenderHandle handle)183 inline constexpr uint32_t GetAdditionalData(const RenderHandle handle)
184 {
185 return (handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT;
186 }
GetAdditionalIndexPart(const RenderHandle handle)187 inline constexpr uint32_t GetAdditionalIndexPart(const RenderHandle handle)
188 {
189 return (handle.id & RES_HANDLE_ADDITIONAL_INDEX_MASK) >> RES_HANDLE_ADDITIONAL_INDEX_SHIFT;
190 }
191 // 0xF (1 << descriptorSetIndex)
GetPipelineLayoutDescriptorSetMask(const RenderHandle handle)192 inline constexpr uint32_t GetPipelineLayoutDescriptorSetMask(const RenderHandle handle)
193 {
194 return (handle.id & RES_HANDLE_ADDITIONAL_INFO_MASK) >> RES_HANDLE_ADDITIONAL_INFO_SHIFT;
195 }
196
IsValid(const EngineResourceHandle & handle)197 inline constexpr bool IsValid(const EngineResourceHandle& handle)
198 {
199 // ignore generation mask, invalid handle might have generation index for update purposes
200 return ((handle.id | RenderHandleUtil::RES_HANDLE_GENERATION_MASK) != INVALID_RESOURCE_HANDLE);
201 }
GetHandleType(const EngineResourceHandle & handle)202 inline constexpr RenderHandleType GetHandleType(const EngineResourceHandle& handle)
203 {
204 return GetHandleType(RenderHandle { handle.id });
205 }
GetIndexPart(const EngineResourceHandle & handle)206 inline constexpr uint32_t GetIndexPart(const EngineResourceHandle& handle)
207 {
208 return GetIndexPart(RenderHandle { handle.id });
209 }
GetGenerationIndexPart(const EngineResourceHandle & handle)210 inline constexpr uint32_t GetGenerationIndexPart(const EngineResourceHandle& handle)
211 {
212 return GetGenerationIndexPart(RenderHandle { handle.id });
213 }
214 EngineResourceHandle CreateEngineResourceHandle(RenderHandleType type, uint32_t index, uint32_t generationIndex);
215 } // namespace RenderHandleUtil
216 RENDER_END_NAMESPACE()
217
BASE_BEGIN_NAMESPACE()218 BASE_BEGIN_NAMESPACE()
219 template<>
220 inline uint64_t hash(const RENDER_NS::RenderHandle& value)
221 {
222 return value.id;
223 }
224 BASE_END_NAMESPACE()
225
226 #endif // DEVICE_GPU_RESOURCE_HANDLE_UTIL_H
227