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