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 : #include "XLCoreAttachment.h"
24 : #include "XLCoreFrameQueue.h"
25 : #include "XLCoreFrameHandle.h"
26 : #include "XLCoreDevice.h"
27 :
28 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
29 :
30 877 : uint32_t DependencyEvent::GetNextId() {
31 : static std::atomic<uint32_t> s_eventId = 1;
32 877 : return s_eventId.fetch_add(1);
33 : }
34 :
35 1754 : DependencyEvent::~DependencyEvent() { }
36 :
37 877 : DependencyEvent::DependencyEvent(QueueSet &&q) : _queues(move(q)) { }
38 :
39 0 : DependencyEvent::DependencyEvent(InitializerList<Rc<Queue>> &&il) : _queues(move(il)) { }
40 :
41 3346 : bool DependencyEvent::signal(Queue *q, bool success) {
42 3346 : if (!success) {
43 0 : _success = success;
44 : }
45 :
46 3346 : auto it = _queues.find(q);
47 3346 : if (it != _queues.end()) {
48 1673 : _queues.erase(it);
49 : }
50 6692 : return _queues.empty();
51 : }
52 :
53 3508 : bool DependencyEvent::isSignaled() const {
54 3508 : return _queues.empty();
55 : }
56 :
57 0 : bool DependencyEvent::isSuccessful() const {
58 0 : return _success;
59 : }
60 :
61 796 : void DependencyEvent::addQueue(Rc<Queue> &&q) {
62 796 : _queues.emplace(move(q));
63 796 : }
64 :
65 624 : bool Attachment::init(AttachmentBuilder &builder) {
66 624 : _data = builder.getAttachmentData();
67 624 : return true;
68 : }
69 :
70 32 : void Attachment::clear() {
71 :
72 32 : }
73 :
74 48 : StringView Attachment::getName() const {
75 48 : return _data->key;
76 : }
77 :
78 21998 : uint64_t Attachment::getId() const {
79 21998 : return _data->id;
80 : }
81 :
82 2782308 : AttachmentUsage Attachment::getUsage() const {
83 2782308 : return _data->usage;
84 : }
85 :
86 21998 : bool Attachment::isTransient() const {
87 21998 : return _data->transient;
88 : }
89 :
90 16 : void Attachment::setInputCallback(Function<void(FrameQueue &, const Rc<AttachmentHandle> &, Function<void(bool)> &&)> &&input) {
91 16 : _inputCallback = move(input);
92 16 : }
93 :
94 48 : void Attachment::setValidateInputCallback(ValidateInputCallback &&cb) {
95 48 : _validateInputCallback = move(cb);
96 48 : }
97 :
98 48 : void Attachment::setFrameHandleCallback(FrameHandleCallback &&cb) {
99 48 : _frameHandleCallback = move(cb);
100 48 : }
101 :
102 29352 : void Attachment::acquireInput(FrameQueue &frame, const Rc<AttachmentHandle> &a, Function<void(bool)> &&cb) {
103 29352 : if (_inputCallback) {
104 0 : _inputCallback(frame, a, move(cb));
105 : } else {
106 : // wait for input on handle
107 29352 : frame.getFrame()->waitForInput(frame, a, move(cb));
108 : }
109 29352 : }
110 :
111 54972 : bool Attachment::validateInput(const Rc<AttachmentInputData> &data) const {
112 54972 : if (_validateInputCallback) {
113 38416 : return _validateInputCallback(*this, data);
114 : }
115 16555 : return true;
116 : }
117 :
118 0 : Rc<AttachmentHandle> Attachment::makeFrameHandle(const FrameQueue &queue) {
119 0 : if (_frameHandleCallback) {
120 0 : return _frameHandleCallback(*this, queue);
121 : }
122 0 : return nullptr;
123 : }
124 :
125 395280 : Vector<const QueuePassData *> Attachment::getRenderPasses() const {
126 395280 : Vector<const PassData *> ret;
127 908574 : for (auto &it : _data->passes) {
128 513294 : ret.emplace_back(it->pass);
129 : }
130 395280 : return ret;
131 0 : }
132 :
133 512177 : const QueuePassData *Attachment::getFirstRenderPass() const {
134 512177 : if (_data->passes.empty()) {
135 0 : return nullptr;
136 : }
137 :
138 512177 : return _data->passes.front()->pass;
139 : }
140 :
141 540612 : const QueuePassData *Attachment::getLastRenderPass() const {
142 540612 : if (_data->passes.empty()) {
143 0 : return nullptr;
144 : }
145 :
146 540612 : return _data->passes.back()->pass;
147 : }
148 :
149 48 : const QueuePassData *Attachment::getNextRenderPass(const PassData *pass) const {
150 48 : size_t idx = 0;
151 96 : for (auto &it : _data->passes) {
152 96 : if (it->pass == pass) {
153 48 : break;
154 : }
155 48 : ++idx;
156 : }
157 48 : if (idx + 1 >= _data->passes.size()) {
158 0 : return nullptr;
159 : }
160 48 : return _data->passes.at(idx + 1)->pass;
161 : }
162 :
163 64 : const QueuePassData *Attachment::getPrevRenderPass(const PassData *pass) const {
164 64 : size_t idx = 0;
165 112 : for (auto &it : _data->passes) {
166 112 : if (it->pass == pass) {
167 64 : break;
168 : }
169 48 : ++ idx;
170 : }
171 64 : if (idx == 0) {
172 16 : return nullptr;
173 : }
174 48 : return _data->passes.at(idx - 1)->pass;
175 : }
176 :
177 544 : void Attachment::setCompiled(Device &dev) {
178 :
179 544 : }
180 :
181 256 : bool BufferAttachment::init(AttachmentBuilder &builder, const BufferInfo &info) {
182 256 : _info = info;
183 256 : builder.setType(AttachmentType::Buffer);
184 256 : if (Attachment::init(builder)) {
185 256 : _info.key = _data->key;
186 256 : return true;
187 : }
188 0 : return false;
189 : }
190 :
191 16 : bool BufferAttachment::init(AttachmentBuilder &builder, const BufferData *data) {
192 16 : _info = *data;
193 16 : builder.setType(AttachmentType::Buffer);
194 16 : if (Attachment::init(builder)) {
195 16 : _staticBuffers.emplace_back(data);
196 16 : _info.key = _data->key;
197 16 : return true;
198 : }
199 0 : return false;
200 : }
201 :
202 112 : bool BufferAttachment::init(AttachmentBuilder &builder, Vector<const BufferData *> &&buffers) {
203 112 : _info = *buffers.front();
204 112 : builder.setType(AttachmentType::Buffer);
205 112 : if (Attachment::init(builder)) {
206 112 : _staticBuffers = move(buffers);
207 112 : _info.key = _data->key;
208 112 : return true;
209 : }
210 0 : return false;
211 : }
212 :
213 16 : void BufferAttachment::clear() {
214 16 : Attachment::clear();
215 16 : }
216 :
217 134400 : Vector<BufferObject *> BufferAttachment::getStaticBuffers() const {
218 134400 : Vector<BufferObject *> ret; ret.reserve(_staticBuffers.size());
219 499200 : for (auto &it : _staticBuffers) {
220 364800 : if (it->buffer) {
221 364800 : ret.emplace_back(it->buffer);
222 : }
223 : }
224 134400 : return ret;
225 0 : }
226 :
227 80 : bool ImageAttachment::init(AttachmentBuilder &builder, const ImageInfo &info, AttachmentInfo &&a) {
228 80 : builder.setType(AttachmentType::Image);
229 80 : if (Attachment::init(builder)) {
230 80 : _imageInfo = info;
231 80 : _attachmentInfo = move(a);
232 80 : _imageInfo.key = _data->key;
233 80 : return true;
234 : }
235 0 : return false;
236 : }
237 :
238 32 : bool ImageAttachment::init(AttachmentBuilder &builder, const ImageData *data, AttachmentInfo &&a) {
239 32 : builder.setType(AttachmentType::Image);
240 32 : if (Attachment::init(builder)) {
241 32 : _imageInfo = *data; // copy info
242 32 : if ((_imageInfo.hints & ImageHints::Static) != ImageHints::Static) {
243 32 : log::error("ImageAttachment", "Image ", data->key, " is not defined as ImageHint::Static to be used as static image attachment");
244 : }
245 32 : _staticImage = data;
246 32 : _attachmentInfo = move(a);
247 32 : _imageInfo.key = _data->key;
248 32 : return true;
249 : }
250 0 : return false;
251 : }
252 :
253 112 : void ImageAttachment::addImageUsage(ImageUsage usage) {
254 112 : _imageInfo.usage |= usage;
255 112 : }
256 :
257 32 : bool ImageAttachment::isCompatible(const ImageInfo &image) const {
258 32 : return _imageInfo.isCompatible(image);
259 : }
260 :
261 57328 : ImageViewInfo ImageAttachment::getImageViewInfo(const ImageInfoData &info, const AttachmentPassData &passAttachment) const {
262 57328 : bool allowSwizzle = true;
263 57328 : AttachmentUsage usage = AttachmentUsage::None;
264 124999 : for (auto &subpassAttachment : passAttachment.subpasses) {
265 67671 : usage |= subpassAttachment->usage;
266 : }
267 :
268 57328 : if ((usage & AttachmentUsage::Input) != AttachmentUsage::None
269 39663 : || (usage & AttachmentUsage::Output) != AttachmentUsage::None
270 32325 : || (usage & AttachmentUsage::Resolve) != AttachmentUsage::None
271 96991 : || (usage & AttachmentUsage::DepthStencil) != AttachmentUsage::None) {
272 42668 : allowSwizzle = false;
273 : }
274 :
275 57328 : ImageViewInfo passInfo(info);
276 57328 : passInfo.setup(passAttachment.colorMode, allowSwizzle);
277 114656 : return passInfo;
278 : }
279 :
280 21998 : Vector<ImageViewInfo> ImageAttachment::getImageViews(const ImageInfoData &info) const {
281 21998 : Vector<ImageViewInfo> ret;
282 :
283 51302 : auto addView = [&] (const ImageViewInfo &info) {
284 51302 : auto it = std::find(ret.begin(), ret.end(), info);
285 51302 : if (it == ret.end()) {
286 29320 : ret.emplace_back(info);
287 : }
288 51302 : };
289 :
290 51318 : for (auto &passAttachment : _data->passes) {
291 29320 : addView(getImageViewInfo(info, *passAttachment));
292 :
293 51302 : for (auto &desc : passAttachment->descriptors) {
294 21982 : bool allowSwizzle = (desc->type == DescriptorType::SampledImage);
295 :
296 21982 : ImageViewInfo passInfo(info);
297 21982 : passInfo.setup(passAttachment->colorMode, allowSwizzle);
298 21982 : addView(passInfo);
299 : }
300 : }
301 :
302 43996 : return ret;
303 0 : }
304 :
305 80 : void ImageAttachment::setCompiled(Device &dev) {
306 80 : Attachment::setCompiled(dev);
307 :
308 80 : if (!isStatic()) {
309 80 : return;
310 : }
311 :
312 0 : auto views = getImageViews(getImageInfo());
313 :
314 0 : _staticImageStorage = Rc<ImageStorage>::create(getStaticImage());
315 :
316 0 : for (auto &info : views) {
317 0 : auto v = _staticImageStorage->getView(info);
318 0 : if (!v) {
319 0 : auto v = dev.makeImageView(_staticImageStorage->getImage(), info);
320 0 : _staticImageStorage->addView(info, move(v));
321 0 : }
322 0 : }
323 0 : }
324 :
325 128 : bool GenericAttachment::init(AttachmentBuilder &builder) {
326 128 : builder.setType(AttachmentType::Generic);
327 128 : return Attachment::init(builder);
328 : }
329 :
330 394355 : bool AttachmentHandle::init(const Rc<Attachment> &attachment, const FrameQueue &frame) {
331 394355 : _attachment = attachment;
332 394355 : return true;
333 : }
334 :
335 38416 : bool AttachmentHandle::init(Attachment &attachment, const FrameQueue &frame) {
336 38416 : return init(&attachment, frame);
337 : }
338 :
339 394355 : void AttachmentHandle::setQueueData(FrameAttachmentData &data) {
340 394355 : _queueData = &data;
341 394355 : }
342 :
343 38416 : void AttachmentHandle::setInputCallback(InputCallback &&cb) {
344 38416 : _inputCallback = move(cb);
345 38416 : }
346 :
347 : // returns true for immediate setup, false if seyup job was scheduled
348 385136 : bool AttachmentHandle::setup(FrameQueue &, Function<void(bool)> &&) {
349 385136 : return true;
350 : }
351 :
352 394355 : void AttachmentHandle::finalize(FrameQueue &, bool successful) {
353 :
354 394355 : }
355 :
356 38416 : void AttachmentHandle::submitInput(FrameQueue &q, Rc<AttachmentInputData> &&data, Function<void(bool)> &&cb) {
357 38416 : _input = move(data);
358 :
359 38416 : if (_input->waitDependencies.empty()) {
360 38416 : auto ret = true;
361 38416 : if (_inputCallback) {
362 38416 : _inputCallback(*this, q, _input, move(cb));
363 : } else {
364 0 : cb(ret);
365 : }
366 : } else {
367 0 : q.getFrame()->waitForDependencies(_input->waitDependencies, [this, cb = move(cb), q = Rc<FrameQueue>(&q)] (FrameHandle &, bool success) mutable {
368 0 : if (!success) {
369 0 : cb(success);
370 0 : } else if (_inputCallback) {
371 0 : _inputCallback(*this, *q, _input, move(cb));
372 : } else {
373 0 : cb(success);
374 : }
375 0 : });
376 : }
377 38416 : }
378 :
379 394355 : bool AttachmentHandle::isInput() const {
380 394355 : return (_attachment->getUsage() & AttachmentUsage::Input) != AttachmentUsage::None;
381 : }
382 :
383 2387953 : bool AttachmentHandle::isOutput() const {
384 2387953 : return (_attachment->getUsage() & AttachmentUsage::Output) != AttachmentUsage::None;
385 : }
386 :
387 245725 : uint32_t AttachmentHandle::getDescriptorArraySize(const PassHandle &, const PipelineDescriptor &d, bool isExternal) const {
388 245725 : return d.count;
389 : }
390 :
391 0 : bool AttachmentHandle::isDescriptorDirty(const PassHandle &, const PipelineDescriptor &d, uint32_t, bool isExternal) const {
392 0 : return false;
393 : }
394 :
395 : }
|