Line data Source code
1 : /**
2 : Copyright (c) 2021-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef XENOLITH_CORE_XLCOREMATERIAL_H_
25 : #define XENOLITH_CORE_XLCOREMATERIAL_H_
26 :
27 : #include "XLCoreResource.h"
28 : #include "XLCoreAttachment.h"
29 : #include "XLCoreDynamicImage.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
32 :
33 : class Material;
34 : class MaterialSet;
35 : class MaterialAttachment;
36 :
37 : using MaterialId = uint32_t;
38 :
39 : struct MaterialInputData : AttachmentInputData {
40 : const MaterialAttachment * attachment;
41 : Vector<Rc<Material>> materialsToAddOrUpdate;
42 : Vector<MaterialId> materialsToRemove;
43 : Vector<MaterialId> dynamicMaterialsToUpdate;
44 : Function<void()> callback;
45 : };
46 :
47 : struct MaterialImage {
48 : const ImageData *image;
49 : Rc<DynamicImageInstance> dynamic;
50 : ImageViewInfo info;
51 : Rc<ImageView> view;
52 : uint16_t sampler = 0;
53 : uint32_t set;
54 : uint32_t descriptor;
55 :
56 : bool canAlias(const MaterialImage &) const;
57 : };
58 :
59 : class MaterialSet final : public Ref {
60 : public:
61 : using ImageSlot = MaterialImageSlot;
62 : using EncodeCallback = Function<bool(uint8_t *, const Material *)>;
63 :
64 : virtual ~MaterialSet();
65 :
66 : bool init(const BufferInfo &, const EncodeCallback &callback,
67 : uint32_t objectSize, uint32_t imagesInSet, uint32_t buffersInSet, const MaterialAttachment * = nullptr);
68 : bool init(const Rc<MaterialSet> &);
69 :
70 : bool encode(uint8_t *, const Material *);
71 :
72 : void clear();
73 :
74 : Vector<Rc<Material>> updateMaterials(const Rc<MaterialInputData> &,
75 : const Callback<Rc<ImageView>(const MaterialImage &)> &);
76 : Vector<Rc<Material>> updateMaterials(const Vector<Rc<Material>> &materials, SpanView<MaterialId> dynamic, SpanView<MaterialId> remove,
77 : const Callback<Rc<ImageView>(const MaterialImage &)> &);
78 :
79 1214 : const BufferInfo &getInfo() const { return _info; }
80 9554 : uint32_t getObjectSize() const { return _objectSize; }
81 : uint32_t getImagesInSet() const { return _imagesInSet; }
82 5183 : uint64_t getGeneration() const { return _generation; }
83 11946 : const HashMap<MaterialId, Rc<Material>> &getMaterials() const { return _materials; }
84 :
85 : void setBuffer(Rc<BufferObject> &&, HashMap<MaterialId, uint32_t> &&);
86 10647 : Rc<BufferObject> getBuffer() const { return _buffer; }
87 : const HashMap<MaterialId, uint32_t> & getOrdering() const { return _ordering; }
88 :
89 10731 : Vector<MaterialLayout> &getLayouts() { return _layouts; }
90 : const MaterialLayout *getLayout(uint32_t) const;
91 : const Material * getMaterialById(MaterialId) const;
92 : uint32_t getMaterialOrder(MaterialId) const;
93 :
94 : protected:
95 : void removeMaterial(Material *oldMaterial);
96 : void emplaceMaterialImages(Material *oldMaterial, Material *newMaterial,
97 : const Callback<Rc<ImageView>(const MaterialImage &)> &);
98 :
99 : BufferInfo _info;
100 : EncodeCallback _encodeCallback;
101 : uint32_t _objectSize = 0;
102 : uint32_t _imagesInSet = 16;
103 : uint32_t _buffersInSet = 16;
104 :
105 : uint32_t _generation = 1;
106 : HashMap<MaterialId, Rc<Material>> _materials;
107 : HashMap<MaterialId, uint32_t> _ordering;
108 :
109 : // describes image location in descriptor sets
110 : // all images from same material must be in one set
111 : Vector<MaterialLayout> _layouts;
112 :
113 : Rc<BufferObject> _buffer;
114 : const MaterialAttachment *_owner = nullptr;
115 : };
116 :
117 : class Material final : public Ref {
118 : public:
119 : // Использовать только для определения встроенных в аттачмент материалов
120 : static constexpr auto MaterialIdInitial = maxOf<uint32_t>();
121 :
122 : using PipelineData = GraphicPipelineData;
123 :
124 : virtual ~Material();
125 :
126 : // view for image must be empty
127 : bool init(MaterialId, const PipelineData *, Vector<MaterialImage> &&, Rc<Ref> && = Rc<Ref>());
128 : bool init(MaterialId, const PipelineData *, const Rc<DynamicImageInstance> &, Rc<Ref> && = Rc<Ref>());
129 : bool init(MaterialId, const PipelineData *, const ImageData *, Rc<Ref> && = Rc<Ref>(), bool ownedData = false);
130 : bool init(MaterialId, const PipelineData *, const ImageData *, ColorMode, Rc<Ref> && = Rc<Ref>(), bool ownedData = false);
131 : bool init(const Material *, Rc<ImageObject> &&, Rc<DataAtlas> &&, Rc<Ref> && = Rc<Ref>());
132 : bool init(const Material *, Vector<MaterialImage> &&);
133 :
134 4083 : MaterialId getId() const { return _id; }
135 164263 : const PipelineData * getPipeline() const { return _pipeline; }
136 101999 : const Vector<MaterialImage> &getImages() const { return _images; }
137 :
138 46957 : uint32_t getLayoutIndex() const { return _layoutIndex; }
139 : void setLayoutIndex(uint32_t);
140 :
141 20995 : const Rc<DataAtlas> &getAtlas() const { return _atlas; }
142 0 : const ImageData *getOwnedData() const { return _ownedData; }
143 :
144 : protected:
145 : friend class MaterialSet;
146 : friend class MaterialAttachment; // for id replacement
147 :
148 : bool _dirty = true;
149 : MaterialId _id = 0;
150 : uint32_t _layoutIndex = 0; // set after compilation
151 : const PipelineData *_pipeline;
152 : Vector<MaterialImage> _images;
153 : Rc<DataAtlas> _atlas;
154 : Rc<Ref> _data;
155 : const ImageData *_ownedData = nullptr;
156 : };
157 :
158 : // this attachment should provide material data buffer for rendering
159 : class MaterialAttachment : public BufferAttachment {
160 : public:
161 : virtual ~MaterialAttachment();
162 :
163 : virtual bool init(AttachmentBuilder &builder, const BufferInfo &, MaterialSet::EncodeCallback &&,
164 : uint32_t materialObjectSize);
165 :
166 : void addPredefinedMaterials(Vector<Rc<Material>> &&);
167 :
168 : const Rc<MaterialSet> &getMaterials() const;
169 : void setMaterials(const Rc<MaterialSet> &) const;
170 :
171 63 : const Vector<Rc<Material>> &getPredefinedMaterials() const { return _predefinedMaterials; }
172 :
173 : virtual Rc<MaterialSet> allocateSet(const Device &) const;
174 : virtual Rc<MaterialSet> cloneSet(const Rc<MaterialSet> &) const;
175 :
176 : virtual void addDynamicTracker(MaterialId, const Rc<DynamicImage> &) const;
177 : virtual void removeDynamicTracker(MaterialId, const Rc<DynamicImage> &) const;
178 :
179 : virtual void updateDynamicImage(Loop &, const DynamicImage *,
180 : const Vector<Rc<DependencyEvent>> & = Vector<Rc<DependencyEvent>>()) const;
181 :
182 : MaterialId getNextMaterialId() const;
183 :
184 : void setCompiler(Queue *);
185 : Queue *getCompiler() const;
186 :
187 : protected:
188 : using BufferAttachment::init;
189 :
190 : struct DynamicImageTracker {
191 : uint32_t refCount;
192 : Map<MaterialId, uint32_t> materials;
193 : };
194 :
195 : Queue *_compiler = nullptr;
196 : mutable std::atomic<MaterialId> _attachmentMaterialId = 1;
197 : uint32_t _materialObjectSize = 0;
198 : MaterialSet::EncodeCallback _encodeCallback;
199 : mutable Rc<MaterialSet> _data;
200 : Vector<Rc<Material>> _predefinedMaterials;
201 :
202 : mutable Mutex _dynamicMutex;
203 : mutable Map<Rc<DynamicImage>, DynamicImageTracker> _dynamicTrackers;
204 : };
205 :
206 : }
207 :
208 : #endif /* XENOLITH_CORE_XLCOREMATERIAL_H_ */
209 :
|