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 <cstdint>
20 
21 #include <3d/render/intf_render_data_store_default_material.h>
22 #include <base/containers/array_view.h>
23 #include <base/containers/string.h>
24 #include <base/containers/string_view.h>
25 #include <base/containers/unique_ptr.h>
26 #include <base/containers/unordered_map.h>
27 #include <base/containers/vector.h>
28 #include <base/util/uid.h>
29 #include <render/device/intf_shader_manager.h>
30 
31 #include "util/linear_allocator.h"
32 
33 RENDER_BEGIN_NAMESPACE()
34 class IRenderContext;
35 class IShaderManager;
36 RENDER_END_NAMESPACE()
37 
CORE3D_BEGIN_NAMESPACE()38 CORE3D_BEGIN_NAMESPACE()
39 /**
40 RenderDataStoreDefaultMaterial implementation.
41 */
42 class RenderDataStoreDefaultMaterial final : public IRenderDataStoreDefaultMaterial {
43 public:
44     static constexpr uint64_t SLOT_SORT_HASH_MASK { 0xFFFFffff };
45     static constexpr uint64_t SLOT_SORT_HASH_SHIFT { 32u };
46     static constexpr uint64_t SLOT_SORT_MAX_DEPTH { 0xFFFFffff };
47     static constexpr uint64_t SLOT_SORT_DEPTH_SHIFT { 32u };
48 
49     RenderDataStoreDefaultMaterial(RENDER_NS::IRenderContext& renderContext, const BASE_NS::string_view name);
50     ~RenderDataStoreDefaultMaterial() override = default;
51 
52     struct LinearAllocatorStruct {
53         uint32_t currentIndex { 0 };
54         BASE_NS::vector<BASE_NS::unique_ptr<LinearAllocator>> allocators;
55     };
56 
57     void CommitFrameData() override {};
58     void PreRender() override {};
59     // Reset and start indexing from the beginning. i.e. frame boundary reset.
60     void PostRender() override;
61     void PreRenderBackend() override {};
62     void PostRenderBackend() override {};
63     void Clear() override;
64     uint32_t GetFlags() const override
65     {
66         return 0;
67     };
68 
69     uint32_t AddMeshData(const RenderMeshData& meshData) override;
70     uint32_t AddMaterialData(const uint64_t id,
71         const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
72         const RenderDataDefaultMaterial::MaterialHandles& materialHandles,
73         const RenderDataDefaultMaterial::MaterialData& materialData,
74         const BASE_NS::array_view<const uint8_t> customData) override;
75     uint32_t AddMaterialData(const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
76         const RenderDataDefaultMaterial::MaterialHandles& materialHandles,
77         const RenderDataDefaultMaterial::MaterialData& materialData,
78         const BASE_NS::array_view<const uint8_t> customData) override;
79 
80     uint32_t AllocateMaterials(uint64_t id, uint32_t instanceCount) override;
81     void AddInstanceMaterialData(uint32_t materialIndex, uint32_t materialInstanceIndex, uint32_t materialInstanceCount,
82         const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
83         const RenderDataDefaultMaterial::MaterialHandles& materialHandles,
84         const RenderDataDefaultMaterial::MaterialData& materialData,
85         const BASE_NS::array_view<const uint8_t> customPropertyData) override;
86     void AddInstanceMaterialData(uint32_t materialIndex, uint32_t materialInstanceIndex, uint32_t materialInstanceCount,
87         const RenderDataDefaultMaterial::InputMaterialUniforms& materialUniforms,
88         const BASE_NS::array_view<const uint8_t> customPropertyData) override;
89 
90     uint32_t GetMaterialIndex(const uint64_t id) const override;
91     uint32_t GetMaterialCustomResourceIndex(const uint64_t id) const override;
92     RenderDataDefaultMaterial::MaterialIndices GetMaterialIndices(const uint64_t id) const override;
93     RenderDataDefaultMaterial::MaterialIndices GetMaterialIndices(uint64_t id, uint32_t instanceCount) const override;
94     uint32_t AddSkinJointMatrices(const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> skinJointMatrices,
95         const BASE_NS::array_view<const BASE_NS::Math::Mat4X4> prevSkinJointMatrices) override;
96     uint32_t AddMaterialCustomResources(
97         uint64_t id, const BASE_NS::array_view<const RENDER_NS::RenderHandleReference> bindings) override;
98 
99     void AddSubmesh(const RenderSubmesh& submesh) override;
100     void AddSubmesh(const RenderSubmesh& submesh,
101         const BASE_NS::array_view<const RENDER_NS::IShaderManager::RenderSlotData> renderSlotAndShaders) override;
102 
103     void SetRenderSlots(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType,
104         const BASE_NS::array_view<const uint32_t> renderSlotIds) override;
105     uint64_t GetRenderSlotMask(const RenderDataDefaultMaterial::MaterialSlotType materialSlotType) const override;
106 
107     BASE_NS::array_view<const uint32_t> GetSlotSubmeshIndices(const uint32_t renderSlotId) const override;
108     BASE_NS::array_view<const RenderDataDefaultMaterial::SlotMaterialData> GetSlotSubmeshMaterialData(
109         const uint32_t renderSlotId) const override;
110     RenderDataDefaultMaterial::ObjectCounts GetSlotObjectCounts(const uint32_t renderSlotId) const override;
111 
112     RenderDataDefaultMaterial::ObjectCounts GetObjectCounts() const override;
113     BASE_NS::array_view<const RenderMeshData> GetMeshData() const override;
114     BASE_NS::array_view<const RenderDataDefaultMaterial::JointMatrixData> GetMeshJointMatrices() const override;
115     BASE_NS::array_view<const RenderSubmesh> GetSubmeshes() const override;
116     BASE_NS::array_view<const BASE_NS::Math::Mat4X4> GetSubmeshJointMatrixData(
117         const uint32_t skinJointIndex) const override;
118 
119     BASE_NS::array_view<const RenderDataDefaultMaterial::AllMaterialUniforms> GetMaterialUniforms() const override;
120     BASE_NS::array_view<const RenderDataDefaultMaterial::MaterialHandles> GetMaterialHandles() const override;
121     BASE_NS::array_view<const uint8_t> GetMaterialCustomPropertyData(const uint32_t materialIndex) const override;
122     BASE_NS::array_view<const RenderDataDefaultMaterial::SubmeshMaterialFlags> GetSubmeshMaterialFlags() const override;
123 
124     BASE_NS::array_view<const RenderDataDefaultMaterial::CustomResourceData> GetCustomResourceHandles() const override;
125 
126     uint32_t GenerateRenderHash(const RenderDataDefaultMaterial::SubmeshMaterialFlags& flags) const override;
127 
128     // for plugin / factory interface
129     static constexpr char const* const TYPE_NAME = "RenderDataStoreDefaultMaterial";
130     static IRenderDataStore* Create(RENDER_NS::IRenderContext& renderContext, char const* name);
131     static void Destroy(IRenderDataStore* instance);
132 
133     BASE_NS::string_view GetTypeName() const override
134     {
135         return TYPE_NAME;
136     }
137 
138     BASE_NS::string_view GetName() const override
139     {
140         return name_;
141     }
142 
143     const BASE_NS::Uid& GetUid() const override
144     {
145         return UID;
146     }
147 
148 private:
149     void GetDefaultRenderSlots();
150     uint32_t GetRenderSlotIdFromMasks(const uint32_t renderSlotId) const;
151 
152     const BASE_NS::string name_;
153     RENDER_NS::IShaderManager& shaderMgr_;
154 
155     BASE_NS::vector<RenderSubmesh> submeshes_;
156     BASE_NS::vector<RenderMeshData> meshData_;
157     BASE_NS::vector<RenderDataDefaultMaterial::JointMatrixData> submeshJointMatrixIndices_;
158 
159     LinearAllocatorStruct submeshJointMatricesAllocator_;
160 
161     // NOTE: Uses packing, needs to be modified if changed
162     BASE_NS::vector<RenderDataDefaultMaterial::AllMaterialUniforms> materialAllUniforms_;
163     BASE_NS::vector<RenderDataDefaultMaterial::MaterialHandles> materialHandles_;
164     BASE_NS::vector<RenderDataDefaultMaterial::MaterialData> materialData_;
165     // material id is normally Entity.id, index to material vectors
166     BASE_NS::unordered_map<uint64_t, RenderDataDefaultMaterial::MaterialIndices> materialIdToIndices_;
167     // material custom property data offset
168     struct MaterialCustomPropertyOffset {
169         uint32_t offset { 0u };
170         uint32_t byteSize { 0u };
171     };
172     BASE_NS::vector<MaterialCustomPropertyOffset> materialCustomPropertyOffsets_;
173     BASE_NS::vector<uint8_t> materialCustomPropertyData_;
174     // per submesh
175     BASE_NS::vector<RenderDataDefaultMaterial::SubmeshMaterialFlags> submeshMaterialFlags_;
176 
177     BASE_NS::vector<RenderDataDefaultMaterial::CustomResourceData> customResourceData_;
178 
179     struct SlotSubmeshData {
180         BASE_NS::vector<uint32_t> indices;
181         BASE_NS::vector<RenderDataDefaultMaterial::SlotMaterialData> materialData;
182 
183         RenderDataDefaultMaterial::ObjectCounts objectCounts;
184     };
185     BASE_NS::unordered_map<uint32_t, SlotSubmeshData> slotToSubmeshIndices_;
186 
187     struct MaterialRenderSlots {
188         uint32_t defaultOpaqueRenderSlot { ~0u };
189         uint64_t opaqueMask { 0 };
190 
191         uint32_t defaultTranslucentRenderSlot { ~0u };
192         uint64_t translucentMask { 0 };
193 
194         uint32_t defaultDepthRenderSlot { ~0u };
195         uint64_t depthMask { 0 };
196     };
197     MaterialRenderSlots materialRenderSlots_;
198 };
199 CORE3D_END_NAMESPACE()
200 
201 #endif // CORE__RENDER__NODE_DATA__RENDER_DATA_STORE_DEFAULT_MATERIAL_H
202