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