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 #ifndef CORE__RENDER__NODE_DATA__RENDER_DATA_STORE_DEFAULT_MATERIAL_H
17 #define CORE__RENDER__NODE_DATA__RENDER_DATA_STORE_DEFAULT_MATERIAL_H
18
19 #include <atomic>
20 #include <cstdint>
21
22 #include <3d/render/intf_render_data_store_default_material.h>
23 #include <base/containers/array_view.h>
24 #include <base/containers/refcnt_ptr.h>
25 #include <base/containers/string.h>
26 #include <base/containers/string_view.h>
27 #include <base/containers/unique_ptr.h>
28 #include <base/containers/unordered_map.h>
29 #include <base/containers/vector.h>
30 #include <base/util/uid.h>
31 #include <render/device/intf_shader_manager.h>
32
33 #include "util/linear_allocator.h"
34
35 RENDER_BEGIN_NAMESPACE()
36 class IRenderContext;
37 class IGpuResourceManager;
38 class IShaderManager;
39 class IRenderDataStoreDefaultAccelerationStructureStaging;
40 RENDER_END_NAMESPACE()
41
CORE3D_BEGIN_NAMESPACE()42 CORE3D_BEGIN_NAMESPACE()
43 /**
44 RenderDataStoreDefaultMaterial implementation.
45 */
46 class RenderDataStoreDefaultMaterial final : public IRenderDataStoreDefaultMaterial {
47 public:
48 static constexpr uint64_t SLOT_SORT_HASH_MASK { 0xFFFFffff };
49 static constexpr uint64_t SLOT_SORT_HASH_SHIFT { 32U };
50 static constexpr uint64_t SLOT_SORT_MAX_DEPTH { 0xFFFFffff };
51 static constexpr uint64_t SLOT_SORT_DEPTH_SHIFT { 32U };
52
53 static constexpr uint32_t SHADER_DEFAULT_RENDER_SLOT_COUNT { 2U };
54
55 RenderDataStoreDefaultMaterial(RENDER_NS::IRenderContext& renderContext, const BASE_NS::string_view name);
56 ~RenderDataStoreDefaultMaterial() override = default;
57
58 struct LinearAllocatorStruct {
59 uint32_t currentIndex { 0 };
60 BASE_NS::vector<BASE_NS::unique_ptr<LinearAllocator>> allocators;
61 };
62
63 // IRenderDataStore
64 void PreRender() override {}
65 // Reset and start indexing from the beginning. i.e. frame boundary reset.
66 void PostRender() override;
67 void PreRenderBackend() override {}
68 void PostRenderBackend() override {}
69 void Clear() override;
70
71 uint32_t GetFlags() const override
72 {
73 return 0U;
74 }
75
76 BASE_NS::string_view GetTypeName() const override
77 {
78 return TYPE_NAME;
79 }
80
81 BASE_NS::string_view GetName() const override
82 {
83 return name_;
84 }
85
86 const BASE_NS::Uid& GetUid() const override
87 {
88 return UID;
89 }
90
91 void Ref() override;
92 void Unref() override;
93 int32_t GetRefCount() override;
94
95 // IRenderDataStoreDefaultMaterial
96 uint32_t AddMeshData(const RenderMeshData& meshData) override;
97 void AddFrameRenderMeshData(const RenderMeshData& meshData, const RenderMeshAabbData& meshAabbData,
98 const RenderMeshSkinData& meshSkinData) override;
99 void AddFrameRenderMeshData(BASE_NS::array_view<const RenderMeshData> meshData,
100 const RenderMeshAabbData& meshAabbData, const RenderMeshSkinData& meshSkinData,
101 const RenderMeshBatchData& batchData) override;
102
103 void UpdateMeshData(uint64_t id, const MeshDataWithHandleReference& meshData) override;
104 void DestroyMeshData(uint64_t id) override;
105
106 uint32_t UpdateMaterialData(const uint64_t id,
107 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
108 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
109 const RenderDataDefaultMaterial::MaterialData& materialData) override;
110 uint32_t UpdateMaterialData(const uint64_t id,
111 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
112 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
113 const RenderDataDefaultMaterial::MaterialData& materialData,
114 const BASE_NS::array_view<const uint8_t> customData) override;
115 uint32_t UpdateMaterialData(const uint64_t id,
116 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
117 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
118 const RenderDataDefaultMaterial::MaterialData& materialData,
119 const BASE_NS::array_view<const uint8_t> customPropertyData,
120 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
121
122 void DestroyMaterialData(const uint64_t id) override;
123 void DestroyMaterialData(const BASE_NS::array_view<uint64_t> ids) override;
124
125 RenderFrameMaterialIndices AddFrameMaterialData(uint64_t id) override;
126 RenderFrameMaterialIndices AddFrameMaterialData(uint64_t id, uint32_t instanceCount) override;
127 RenderFrameMaterialIndices AddFrameMaterialData(BASE_NS::array_view<const uint64_t> id) override;
128 RenderFrameMaterialIndices AddFrameMaterialData(
129 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
130 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
131 const RenderDataDefaultMaterial::MaterialData& materialData,
132 const BASE_NS::array_view<const uint8_t> customPropertyData,
133 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
134 RenderFrameMaterialIndices AddFrameMaterialInstanceData(
135 uint32_t materialIndex, uint32_t frameOffset, uint32_t instanceIndex) override;
136
137 BASE_NS::array_view<const uint32_t> GetMaterialFrameIndices() const override;
138
139 uint32_t GetMaterialIndex(const uint64_t id) const override;
140
141 void AddSubmesh(const RenderSubmeshWithHandleReference& submesh) override;
142 void AddSubmesh(const RenderSubmeshWithHandleReference& submesh,
143 const BASE_NS::array_view<const RENDER_NS::IShaderManager::RenderSlotData> renderSlotAndShaders) override;
144
145 void SetRenderSlots(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType,
146 const BASE_NS::array_view<const uint32_t> renderSlotIds) override;
147 uint64_t GetRenderSlotMask(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType) const override;
148
149 BASE_NS::array_view<const uint32_t> GetSlotSubmeshIndices(const uint32_t renderSlotId) const override;
150 BASE_NS::array_view<const RenderDataDefaultMaterial::SlotMaterialData> GetSlotSubmeshMaterialData(
151 const uint32_t renderSlotId) const override;
152 RenderDataDefaultMaterial::ObjectCounts GetSlotObjectCounts(const uint32_t renderSlotId) const override;
153
154 RenderDataDefaultMaterial::ObjectCounts GetObjectCounts() const override;
155 BASE_NS::array_view<const RenderMeshData> GetMeshData() const override;
156 BASE_NS::array_view<const RenderDataDefaultMaterial::JointMatrixData> GetMeshJointMatrices() const override;
157 BASE_NS::array_view<const RenderSubmesh> GetSubmeshes() const override;
158 BASE_NS::array_view<const BASE_NS::Math::Mat4X4> GetSubmeshJointMatrixData(
159 const uint32_t skinJointIndex) const override;
160
161 BASE_NS::array_view<const RenderDataDefaultMaterial::AllMaterialUniforms> GetMaterialUniforms() const override;
162 BASE_NS::array_view<const RenderDataDefaultMaterial::MaterialHandles> GetMaterialHandles() const override;
163 BASE_NS::array_view<const uint8_t> GetMaterialCustomPropertyData(const uint32_t materialIndex) const override;
164 BASE_NS::array_view<const RenderDataDefaultMaterial::SubmeshMaterialFlags> GetSubmeshMaterialFlags() const override;
165
166 BASE_NS::array_view<const RenderDataDefaultMaterial::CustomResourceData> GetCustomResourceHandles() const override;
167
168 RenderFrameObjectInfo GetRenderFrameObjectInfo() const override;
169
170 uint32_t GenerateRenderHash(const RenderDataDefaultMaterial::SubmeshMaterialFlags& flags) const override;
171
172 RenderFrameMaterialIndices AddRenderSlotSubmeshesFrameMaterialData(const uint32_t toSlotId,
173 BASE_NS::array_view<const uint32_t> fromSlotIds,
174 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
175 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
176 const RenderDataDefaultMaterial::MaterialData& materialData,
177 const BASE_NS::array_view<const uint8_t> customPropertyData,
178 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
179
180 // NOTE: hidden method at the moment
181 // returns frame mesh blas data
182 BASE_NS::array_view<const RENDER_NS::AsInstance> GetMeshBlasData() const;
183
184 // for plugin / factory interface
185 static constexpr const char* const TYPE_NAME = "RenderDataStoreDefaultMaterial";
186 static BASE_NS::refcnt_ptr<IRenderDataStore> Create(RENDER_NS::IRenderContext& renderContext, char const* name);
187
188 // container for MaterialData and frame info
189 struct MaterialDataContainer {
190 RenderDataDefaultMaterial::MaterialData md;
191 // provided information if the material in in use this frame
192 // this is then used to add references of resources
193 bool frameReferenced { false };
194 bool noId { false };
195 };
196 struct CustomPropertyData {
197 // vector inside a vector
198 BASE_NS::vector<uint8_t> data;
199 };
200 struct MaterialDefaultRenderSlotData {
201 RENDER_NS::IShaderManager::RenderSlotData data[SHADER_DEFAULT_RENDER_SLOT_COUNT] {};
202 uint32_t count { 0U };
203 };
204 struct AllMaterialData {
205 // NOTE: Uses packing, needs to be modified if changed
206 BASE_NS::vector<RenderDataDefaultMaterial::AllMaterialUniforms> allUniforms;
207 BASE_NS::vector<RenderDataDefaultMaterial::MaterialHandles> handles;
208 BASE_NS::vector<MaterialDataContainer> data;
209 BASE_NS::vector<MaterialDefaultRenderSlotData> renderSlotData;
210 BASE_NS::vector<CustomPropertyData> customPropertyData;
211 BASE_NS::vector<RenderDataDefaultMaterial::CustomResourceData> customResourceData;
212 // material id is normally Entity.id, index to material vectors
213 BASE_NS::unordered_map<uint64_t, uint32_t> materialIdToIndex;
214
215 // The processing order of materials for a frame (takes into account instancing)
216 // The same material index can be there multiple times
217 BASE_NS::vector<uint32_t> frameIndices;
218 BASE_NS::unordered_map<uint64_t, uint32_t> idHashToFrameIndex;
219
220 BASE_NS::vector<uint32_t> availableIndices;
221 };
222 struct MaterialRenderSlots {
223 uint32_t defaultOpaqueRenderSlot { ~0u };
224 uint64_t opaqueMask { 0 };
225
226 uint32_t defaultTranslucentRenderSlot { ~0u };
227 uint64_t translucentMask { 0 };
228
229 uint32_t defaultDepthRenderSlot { ~0u };
230 uint64_t depthMask { 0 };
231 };
232
233 struct SubmeshData {
234 RenderSubmeshFlags submeshFlags { 0U };
235
236 // Additional rendering flags for this submesh material. Typically zero.
237 // Use case could be adding some specific flags for e.g. pso creation / specialization.
238 RenderMaterialFlags renderSubmeshMaterialFlags { 0U };
239
240 RenderDrawCommand drawCommand;
241
242 RenderSubmeshBuffers buffers;
243
244 uint64_t material { RenderSceneDataConstants::INVALID_ID };
245
246 uint32_t additionalMaterialOffset { 0U };
247 uint32_t additionalMaterialCount { 0U };
248
249 // Mesh render sort layer id. Valid values are 0 - 63
250 uint8_t meshRenderSortLayer { RenderSceneDataConstants::DEFAULT_RENDER_SORT_LAYER_ID };
251 // Mesh render sort layer id. Valid values are 0 - 255
252 uint8_t meshRenderSortLayerOrder { 0 };
253
254 // NOTE: missing local aabb data
255 };
256 struct MeshData {
257 uint64_t meshId { RenderSceneDataConstants::INVALID_ID };
258
259 // NOTE: missing local aabb data
260 };
261 struct SubmeshDataContainer {
262 SubmeshData sd;
263 // provided information if the material in in use this frame
264 // this is then used to add references of resources
265 bool frameReferenced { false };
266 };
267 // container for Mesh blas data
268 struct MeshBlasContainerWithHandleReference {
269 RENDER_NS::RenderHandleReference blas;
270 RENDER_NS::AsInstanceWithHandleReference instance;
271 };
272 // container for MeshData and frame info
273 struct MeshDataContainer {
274 MeshData md;
275
276 // provided information if the material in in use this frame
277 // this is then used to add references of resources
278 bool frameReferenced { false };
279
280 BASE_NS::vector<SubmeshDataContainer> submeshes;
281 // submeshes have indices to additional materials (submeshAdditionalMaterials.size() != submeshes.size()
282 BASE_NS::vector<uint64_t> submeshAdditionalMaterials;
283
284 MeshBlasContainerWithHandleReference blas;
285 };
286 struct AllMeshData {
287 // mesh data, no render mesh instance based data
288 BASE_NS::vector<MeshDataContainer> data;
289 // mesh id is normally Entity.id, index to meshData vector
290 BASE_NS::unordered_map<uint64_t, uint32_t> meshIdToIndex;
291
292 BASE_NS::vector<uint32_t> availableIndices;
293
294 // frame data
295 BASE_NS::vector<RenderMeshData> frameMeshData;
296 BASE_NS::vector<RenderDataDefaultMaterial::JointMatrixData> frameJointMatrixIndices;
297 BASE_NS::vector<RenderSubmesh> frameSubmeshes;
298 BASE_NS::vector<RenderDataDefaultMaterial::SubmeshMaterialFlags> frameSubmeshMaterialFlags;
299 BASE_NS::vector<RENDER_NS::AsInstance> frameMeshBlasInstanceData;
300 };
301
302 private:
303 uint32_t AddMaterialDataImpl(uint32_t matIndex,
304 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
305 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
306 const RenderDataDefaultMaterial::MaterialData& materialData,
307 const BASE_NS::array_view<const uint8_t> customData,
308 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customResourceData);
309 void UpdateFrameMaterialResourceReferences(uint32_t materialIndex);
310
311 void FillSubmeshImpl(BASE_NS::array_view<const RENDER_NS::IShaderManager::RenderSlotData> renderSlotAndShaders,
312 uint32_t submeshIndex, RenderSubmesh& submesh);
313 void UpdateFrameMeshResourceReferences(SubmeshDataContainer& submeshData);
314 void AddFrameRenderMeshDataImpl(const RenderMeshData& meshData, const RenderMeshAabbData& meshAabbData,
315 const RenderMeshSkinData& meshSkinData, const RenderMeshBatchData& batchData, const uint32_t batchCount);
316 void AddFrameRenderMeshDataAdditionalMaterial(
317 uint64_t matId, const uint32_t submeshFrameIndex, RenderSubmesh& renderSubmesh);
318 uint32_t AddFrameSkinJointMatricesImpl(const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> skinJointMatrices,
319 const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> prevSkinJointMatrices);
320
321 void GetDefaultRenderSlots();
322 uint32_t GetRenderSlotIdFromMasks(const uint32_t renderSlotId) const;
323
324 void UpdateMeshBlasData(MeshDataContainer& meshData);
325 void UpdateFrameMeshBlasInstanceData(const MeshDataContainer& meshData, const BASE_NS::Math::Mat4X4& transform);
326
327 const BASE_NS::string name_;
328 RENDER_NS::IRenderContext& renderContext_;
329 RENDER_NS::IGpuResourceManager& gpuResourceMgr_;
330 RENDER_NS::IShaderManager& shaderMgr_;
331 BASE_NS::refcnt_ptr<RENDER_NS::IRenderDataStoreDefaultAccelerationStructureStaging> dsAcceleration_;
332
333 LinearAllocatorStruct meshJointMatricesAllocator_;
334
335 AllMaterialData matData_;
336 AllMeshData meshData_;
337 RenderFrameObjectInfo renderFrameObjectInfo_;
338
339 // separate store for references
340 BASE_NS::vector<RENDER_NS::RenderHandleReference> handleReferences_;
341
342 struct SlotSubmeshData {
343 BASE_NS::vector<uint32_t> indices;
344 BASE_NS::vector<RenderDataDefaultMaterial::SlotMaterialData> materialData;
345
346 RenderDataDefaultMaterial::ObjectCounts objectCounts;
347 };
348 BASE_NS::unordered_map<uint32_t, SlotSubmeshData> slotToSubmeshIndices_;
349
350 MaterialRenderSlots materialRenderSlots_;
351
352 // helper
353 BASE_NS::vector<uint32_t> materialFrameOffsets_;
354 bool rtEnabled_ { false };
355
356 std::atomic_int32_t refcnt_ { 0 };
357 };
358 CORE3D_END_NAMESPACE()
359
360 #endif // CORE__RENDER__NODE_DATA__RENDER_DATA_STORE_DEFAULT_MATERIAL_H
361