Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_CORE_XLCOREATTACHMENT_H_
24 : #define XENOLITH_CORE_XLCOREATTACHMENT_H_
25 :
26 : #include "XLCoreQueueData.h"
27 : #include "XLCoreInfo.h"
28 : #include "XLCorePlatform.h"
29 : #include "XLCoreImageStorage.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
32 :
33 : class DependencyEvent final : public Ref {
34 : public:
35 : using QueueSet = std::multiset<Rc<Queue>, std::less<Rc<Queue>>, std::allocator<Rc<Queue>>>;
36 :
37 : static uint32_t GetNextId();
38 :
39 : virtual ~DependencyEvent();
40 :
41 : DependencyEvent(QueueSet &&);
42 : DependencyEvent(InitializerList<Rc<Queue>> &&);
43 :
44 : uint32_t getId() const { return _id; }
45 :
46 : bool signal(Queue *, bool);
47 :
48 : bool isSignaled() const;
49 : bool isSuccessful() const;
50 :
51 : void addQueue(Rc<Queue> &&);
52 :
53 : protected:
54 : uint32_t _id = GetNextId();
55 : StringView _tag;
56 : uint64_t _clock = platform::clock(core::ClockType::Monotonic);
57 : QueueSet _queues;
58 : bool _success = true;
59 : };
60 :
61 : // dummy class for attachment input
62 : struct AttachmentInputData : public Ref {
63 47667 : virtual ~AttachmentInputData() { }
64 :
65 : Vector<Rc<DependencyEvent>> waitDependencies;
66 : };
67 :
68 : class Attachment : public NamedRef {
69 : public:
70 : using FrameQueue = core::FrameQueue;
71 : using RenderQueue = core::Queue;
72 : using PassData = core::QueuePassData;
73 : using AttachmentData = core::AttachmentData;
74 : using AttachmentHandle = core::AttachmentHandle;
75 : using AttachmentBuilder = core::AttachmentBuilder;
76 :
77 : using InputCallback = Function<void(FrameQueue &, const Rc<AttachmentHandle> &, Function<void(bool)> &&)>;
78 : using FrameHandleCallback = Function<Rc<AttachmentHandle>(Attachment &, const FrameQueue &)>;
79 : using ValidateInputCallback = Function<bool(const Attachment &, const Rc<AttachmentInputData> &)>;
80 :
81 624 : virtual ~Attachment() { }
82 :
83 : virtual bool init(AttachmentBuilder &builder);
84 : virtual void clear();
85 :
86 : virtual StringView getName() const override;
87 :
88 : uint64_t getId() const;
89 : AttachmentUsage getUsage() const;
90 : bool isTransient() const;
91 :
92 : // Set callback for frame to acquire input for this
93 : void setInputCallback(InputCallback &&);
94 :
95 : void setValidateInputCallback(ValidateInputCallback &&);
96 :
97 : void setFrameHandleCallback(FrameHandleCallback &&);
98 :
99 : // Run input callback for frame and handle
100 : void acquireInput(FrameQueue &, const Rc<AttachmentHandle> &, Function<void(bool)> &&);
101 :
102 : virtual bool validateInput(const Rc<AttachmentInputData> &) const;
103 :
104 21 : virtual bool isCompatible(const ImageInfo &) const { return false; }
105 :
106 : virtual Rc<AttachmentHandle> makeFrameHandle(const FrameQueue &);
107 :
108 : virtual Vector<const PassData *> getRenderPasses() const;
109 : virtual const PassData *getFirstRenderPass() const;
110 : virtual const PassData *getLastRenderPass() const;
111 : virtual const PassData *getNextRenderPass(const PassData *) const;
112 : virtual const PassData *getPrevRenderPass(const PassData *) const;
113 :
114 1209269 : const AttachmentData *getData() const { return _data; }
115 :
116 : virtual void setCompiled(Device &);
117 :
118 : protected:
119 : const AttachmentData *_data = nullptr;
120 :
121 : InputCallback _inputCallback;
122 : FrameHandleCallback _frameHandleCallback;
123 : ValidateInputCallback _validateInputCallback;
124 : };
125 :
126 : class BufferAttachment : public Attachment {
127 : public:
128 525 : virtual ~BufferAttachment() { }
129 :
130 : virtual bool init(AttachmentBuilder &builder, const BufferInfo &);
131 :
132 : // init as static buffer
133 : // static buffer should be pre-initialized and valid until attachment's queue exists
134 : // or be a part of queue's internal resource (`builder.addBuffer()`)
135 : virtual bool init(AttachmentBuilder &builder, const BufferData *);
136 : virtual bool init(AttachmentBuilder &builder, Vector<const BufferData *> &&);
137 :
138 : virtual void clear() override;
139 :
140 9111 : const BufferInfo &getInfo() const { return _info; }
141 :
142 428421 : virtual bool isStatic() const { return !_staticBuffers.empty(); }
143 :
144 : virtual Vector<BufferObject *> getStaticBuffers() const;
145 :
146 : protected:
147 : using Attachment::init;
148 :
149 : BufferInfo _info;
150 : Vector<const BufferData *> _staticBuffers;
151 : };
152 :
153 : class ImageAttachment : public Attachment {
154 : public:
155 189 : virtual ~ImageAttachment() { }
156 :
157 : struct AttachmentInfo {
158 : AttachmentLayout initialLayout = AttachmentLayout::Ignored;
159 : AttachmentLayout finalLayout = AttachmentLayout::Ignored;
160 : bool clearOnLoad = false;
161 : Color4F clearColor = Color4F::BLACK;
162 : ColorMode colorMode;
163 : };
164 :
165 : virtual bool init(AttachmentBuilder &builder, const ImageInfo &, AttachmentInfo &&);
166 :
167 : // init as static image
168 : // static image should be pre-initialized and valid until attachment's queue exists
169 : // or be a part of queue's internal resource (`builder.addImage()`)
170 : virtual bool init(AttachmentBuilder &builder, const ImageData *, AttachmentInfo &&);
171 :
172 48195 : virtual const ImageInfo &getImageInfo() const { return _imageInfo; }
173 168 : virtual bool shouldClearOnLoad() const { return _attachmentInfo.clearOnLoad; }
174 63 : virtual Color4F getClearColor() const { return _attachmentInfo.clearColor; }
175 0 : virtual ColorMode getColorMode() const { return _attachmentInfo.colorMode; }
176 :
177 105 : virtual AttachmentLayout getInitialLayout() const { return _attachmentInfo.initialLayout; }
178 9769 : virtual AttachmentLayout getFinalLayout() const { return _attachmentInfo.finalLayout; }
179 :
180 38194 : virtual bool isStatic() const { return _staticImage != nullptr; }
181 :
182 0 : virtual ImageObject *getStaticImage() const { return _staticImage->image; }
183 0 : virtual ImageStorage *getStaticImageStorage() const { return _staticImageStorage; }
184 :
185 : virtual void addImageUsage(ImageUsage);
186 :
187 : virtual bool isCompatible(const ImageInfo &) const override;
188 :
189 : virtual ImageViewInfo getImageViewInfo(const ImageInfoData &info, const AttachmentPassData &) const;
190 : virtual Vector<ImageViewInfo> getImageViews(const ImageInfoData &info) const;
191 :
192 : virtual void setCompiled(Device &) override;
193 :
194 : protected:
195 : using Attachment::init;
196 :
197 : ImageInfo _imageInfo;
198 : AttachmentInfo _attachmentInfo;
199 : const ImageData *_staticImage = nullptr;
200 : Rc<ImageStorage> _staticImageStorage;
201 : };
202 :
203 : class GenericAttachment : public Attachment {
204 : public:
205 168 : virtual ~GenericAttachment() { }
206 :
207 : virtual bool init(AttachmentBuilder &builder) override;
208 :
209 : protected:
210 : using Attachment::init;
211 : };
212 :
213 : class AttachmentHandle : public Ref {
214 : public:
215 : using PassHandle = core::QueuePassHandle;
216 : using FrameQueue = core::FrameQueue;
217 : using FrameHandle = core::FrameHandle;
218 : using Attachment = core::Attachment;
219 :
220 : using InputCallback = Function<void(AttachmentHandle &, FrameQueue &, AttachmentInputData *, Function<void(bool)> &&)>;
221 :
222 516753 : virtual ~AttachmentHandle() { }
223 :
224 : virtual bool init(const Rc<Attachment> &, const FrameQueue &);
225 : virtual bool init(Attachment &, const FrameQueue &);
226 : virtual void setQueueData(FrameAttachmentData &);
227 19034 : virtual FrameAttachmentData *getQueueData() const { return _queueData; }
228 :
229 : // Set callback for frame to acquire input for this
230 : virtual void setInputCallback(InputCallback &&);
231 :
232 545346 : virtual bool isAvailable(const FrameQueue &) const { return true; }
233 :
234 : // returns true for immediate setup, false if setup job was scheduled
235 : virtual bool setup(FrameQueue &, Function<void(bool)> &&);
236 :
237 : virtual void finalize(FrameQueue &, bool successful);
238 :
239 : virtual bool isInput() const;
240 : virtual bool isOutput() const;
241 2473146 : virtual const Rc<Attachment> &getAttachment() const { return _attachment; }
242 : StringView getName() const { return _attachment->getName(); }
243 :
244 : virtual void submitInput(FrameQueue &, Rc<AttachmentInputData> &&, Function<void(bool)> &&cb);
245 :
246 : virtual uint32_t getDescriptorArraySize(const PassHandle &, const PipelineDescriptor &, bool isExternal) const;
247 : virtual bool isDescriptorDirty(const PassHandle &, const PipelineDescriptor &, uint32_t, bool isExternal) const;
248 :
249 50400 : AttachmentInputData *getInput() const { return _input; }
250 :
251 : protected:
252 : InputCallback _inputCallback;
253 : Rc<AttachmentInputData> _input;
254 : Rc<Attachment> _attachment;
255 : FrameAttachmentData *_queueData = nullptr;
256 : };
257 :
258 : }
259 :
260 : #endif /* XENOLITH_CORE_XLCOREATTACHMENT_H_ */
|