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 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 RENDER_END_NAMESPACE()
40
CORE3D_BEGIN_NAMESPACE()41 CORE3D_BEGIN_NAMESPACE()
42 /**
43 RenderDataStoreDefaultMaterial implementation.
44 */
45 class RenderDataStoreDefaultMaterial final : public IRenderDataStoreDefaultMaterial {
46 public:
47 static constexpr uint64_t SLOT_SORT_HASH_MASK { 0xFFFFffff };
48 static constexpr uint64_t SLOT_SORT_HASH_SHIFT { 32u };
49 static constexpr uint64_t SLOT_SORT_MAX_DEPTH { 0xFFFFffff };
50 static constexpr uint64_t SLOT_SORT_DEPTH_SHIFT { 32u };
51
52 RenderDataStoreDefaultMaterial(RENDER_NS::IRenderContext& renderContext, const BASE_NS::string_view name);
53 ~RenderDataStoreDefaultMaterial() override = default;
54
55 struct LinearAllocatorStruct {
56 uint32_t currentIndex { 0 };
57 BASE_NS::vector<BASE_NS::unique_ptr<LinearAllocator>> allocators;
58 };
59
60 // IRenderDataStore
61 void PreRender() override {}
62 // Reset and start indexing from the beginning. i.e. frame boundary reset.
63 void PostRender() override;
64 void PreRenderBackend() override {}
65 void PostRenderBackend() override {}
66 void Clear() override;
67
68 uint32_t GetFlags() const override
69 {
70 return 0;
71 }
72
73 BASE_NS::string_view GetTypeName() const override
74 {
75 return TYPE_NAME;
76 }
77
78 BASE_NS::string_view GetName() const override
79 {
80 return name_;
81 }
82
83 const BASE_NS::Uid& GetUid() const override
84 {
85 return UID;
86 }
87
88 void Ref() override;
89 void Unref() override;
90 int32_t GetRefCount() override;
91
92 // IRenderDataStoreDefaultMaterial
93 uint32_t AddMeshData(const RenderMeshData& meshData) override;
94 uint32_t UpdateMaterialData(const uint64_t id,
95 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
96 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
97 const RenderDataDefaultMaterial::MaterialData& materialData) override;
98 uint32_t UpdateMaterialData(const uint64_t id,
99 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
100 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
101 const RenderDataDefaultMaterial::MaterialData& materialData,
102 const BASE_NS::array_view<const uint8_t> customData) override;
103 uint32_t UpdateMaterialData(const uint64_t id,
104 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
105 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
106 const RenderDataDefaultMaterial::MaterialData& materialData,
107 const BASE_NS::array_view<const uint8_t> customPropertyData,
108 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
109
110 void DestroyMaterialData(const uint64_t id) override;
111 void DestroyMaterialData(const BASE_NS::array_view<uint64_t> ids) override;
112
113 RenderFrameMaterialIndices AddFrameMaterialData(uint64_t id) override;
114 RenderFrameMaterialIndices AddFrameMaterialData(uint64_t id, uint32_t instanceCount) override;
115 RenderFrameMaterialIndices AddFrameMaterialData(BASE_NS::array_view<const uint64_t> id) override;
116 RenderFrameMaterialIndices AddFrameMaterialData(
117 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
118 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
119 const RenderDataDefaultMaterial::MaterialData& materialData,
120 const BASE_NS::array_view<const uint8_t> customPropertyData,
121 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
122 RenderFrameMaterialIndices AddFrameMaterialInstanceData(
123 uint32_t materialIndex, uint32_t frameOffset, uint32_t instanceIndex) override;
124
125 BASE_NS::array_view<const uint32_t> GetMaterialFrameIndices() const override;
126
127 uint32_t GetMaterialIndex(const uint64_t id) const override;
128 uint32_t AddSkinJointMatrices(const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> skinJointMatrices,
129 const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> prevSkinJointMatrices) override;
130
131 void AddSubmesh(const RenderSubmeshWithHandleReference& submesh) override;
132 void AddSubmesh(const RenderSubmeshWithHandleReference& submesh,
133 const BASE_NS::array_view<const RENDER_NS::IShaderManager::RenderSlotData> renderSlotAndShaders) override;
134
135 void SetRenderSlots(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType,
136 const BASE_NS::array_view<const uint32_t> renderSlotIds) override;
137 uint64_t GetRenderSlotMask(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType) const override;
138
139 BASE_NS::array_view<const uint32_t> GetSlotSubmeshIndices(const uint32_t renderSlotId) const override;
140 BASE_NS::array_view<const RenderDataDefaultMaterial::SlotMaterialData> GetSlotSubmeshMaterialData(
141 const uint32_t renderSlotId) const override;
142 RenderDataDefaultMaterial::ObjectCounts GetSlotObjectCounts(const uint32_t renderSlotId) const override;
143
144 RenderDataDefaultMaterial::ObjectCounts GetObjectCounts() const override;
145 BASE_NS::array_view<const RenderMeshData> GetMeshData() const override;
146 BASE_NS::array_view<const RenderDataDefaultMaterial::JointMatrixData> GetMeshJointMatrices() const override;
147 BASE_NS::array_view<const RenderSubmesh> GetSubmeshes() const override;
148 BASE_NS::array_view<const BASE_NS::Math::Mat4X4> GetSubmeshJointMatrixData(
149 const uint32_t skinJointIndex) const override;
150
151 BASE_NS::array_view<const RenderDataDefaultMaterial::AllMaterialUniforms> GetMaterialUniforms() const override;
152 BASE_NS::array_view<const RenderDataDefaultMaterial::MaterialHandles> GetMaterialHandles() const override;
153 BASE_NS::array_view<const uint8_t> GetMaterialCustomPropertyData(const uint32_t materialIndex) const override;
154 BASE_NS::array_view<const RenderDataDefaultMaterial::SubmeshMaterialFlags> GetSubmeshMaterialFlags() const override;
155
156 BASE_NS::array_view<const RenderDataDefaultMaterial::CustomResourceData> GetCustomResourceHandles() const override;
157
158 uint32_t GenerateRenderHash(const RenderDataDefaultMaterial::SubmeshMaterialFlags& flags) const override;
159
160 RenderFrameMaterialIndices AddRenderSlotSubmeshesFrameMaterialData(const uint32_t toSlotId,
161 BASE_NS::array_view<const uint32_t> fromSlotIds,
162 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
163 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
164 const RenderDataDefaultMaterial::MaterialData& materialData,
165 const BASE_NS::array_view<const uint8_t> customPropertyData,
166 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customBindings) override;
167
168 // for plugin / factory interface
169 static constexpr const char* const TYPE_NAME = "RenderDataStoreDefaultMaterial";
170 static BASE_NS::refcnt_ptr<IRenderDataStore> Create(RENDER_NS::IRenderContext& renderContext, char const* name);
171
172 // container for MaterialData and frame info
173 struct MaterialDataContainer {
174 RenderDataDefaultMaterial::MaterialData md;
175 // provided information if the material in in use this frame
176 // this is then used to add references of resources
177 bool frameReferenced { false };
178 bool noId { false };
179 };
180 struct CustomPropertyData {
181 // vector inside a vector
182 BASE_NS::vector<uint8_t> data;
183 };
184 struct AllMaterialData {
185 // NOTE: Uses packing, needs to be modified if changed
186 BASE_NS::vector<RenderDataDefaultMaterial::AllMaterialUniforms> allUniforms;
187 BASE_NS::vector<RenderDataDefaultMaterial::MaterialHandles> handles;
188 BASE_NS::vector<MaterialDataContainer> data;
189 BASE_NS::vector<CustomPropertyData> customPropertyData;
190 BASE_NS::vector<RenderDataDefaultMaterial::CustomResourceData> customResourceData;
191 // material id is normally Entity.id, index to material vectors
192 BASE_NS::unordered_map<uint64_t, uint32_t> materialIdToIndex;
193
194 // The processing order of materials for a frame (takes into account instancing)
195 // The same material index can there multiple times
196 BASE_NS::vector<uint32_t> frameIndices;
197 BASE_NS::unordered_map<uint64_t, uint32_t> idHashToFrameIndex;
198
199 BASE_NS::vector<uint32_t> availableIndices;
200 };
201
202 private:
203 void FillSubmeshImpl(BASE_NS::array_view<const RENDER_NS::IShaderManager::RenderSlotData> renderSlotAndShaders,
204 uint32_t submeshIndex, RenderSubmesh& submesh);
205 uint32_t AddMaterialDataImpl(uint32_t matIndex,
206 const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
207 const RenderDataDefaultMaterial::MaterialHandlesWithHandleReference& materialHandles,
208 const RenderDataDefaultMaterial::MaterialData& materialData,
209 const BASE_NS::array_view<const uint8_t> customData,
210 const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> customResourceData);
211 void UpdateFrameMaterialResourceReferences(uint32_t materialIndex);
212
213 void GetDefaultRenderSlots();
214 uint32_t GetRenderSlotIdFromMasks(const uint32_t renderSlotId) const;
215
216 const BASE_NS::string name_;
217 RENDER_NS::IGpuResourceManager& gpuResourceMgr_;
218 RENDER_NS::IShaderManager& shaderMgr_;
219
220 BASE_NS::vector<RenderSubmesh> submeshes_;
221 BASE_NS::vector<RenderMeshData> meshData_;
222 BASE_NS::vector<RenderDataDefaultMaterial::JointMatrixData> submeshJointMatrixIndices_;
223
224 LinearAllocatorStruct submeshJointMatricesAllocator_;
225
226 AllMaterialData matData_;
227
228 // per submesh
229 BASE_NS::vector<RenderDataDefaultMaterial::SubmeshMaterialFlags> submeshMaterialFlags_;
230
231 // separate store for references
232 BASE_NS::vector<RENDER_NS::RenderHandleReference> handleReferences_;
233
234 struct SlotSubmeshData {
235 BASE_NS::vector<uint32_t> indices;
236 BASE_NS::vector<RenderDataDefaultMaterial::SlotMaterialData> materialData;
237
238 RenderDataDefaultMaterial::ObjectCounts objectCounts;
239 };
240 BASE_NS::unordered_map<uint32_t, SlotSubmeshData> slotToSubmeshIndices_;
241
242 struct MaterialRenderSlots {
243 uint32_t defaultOpaqueRenderSlot { ~0u };
244 uint64_t opaqueMask { 0 };
245
246 uint32_t defaultTranslucentRenderSlot { ~0u };
247 uint64_t translucentMask { 0 };
248
249 uint32_t defaultDepthRenderSlot { ~0u };
250 uint64_t depthMask { 0 };
251 };
252 MaterialRenderSlots materialRenderSlots_;
253
254 std::atomic_int32_t refcnt_ { 0 };
255 };
256 CORE3D_END_NAMESPACE()
257
258 #endif // CORE__RENDER__NODE_DATA__RENDER_DATA_STORE_DEFAULT_MATERIAL_H
259