• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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