Line data Source code
1 : /**
2 : Copyright (c) 2021-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 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_BACKEND_VK_XLVKDEVICE_H_
25 : #define XENOLITH_BACKEND_VK_XLVKDEVICE_H_
26 :
27 : #include "XLVkInstance.h"
28 : #include "XLVkDeviceQueue.h"
29 : #include "XLVkLoop.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::xenolith::vk {
32 :
33 : class Fence;
34 : class Allocator;
35 : class TextureSetLayout;
36 : class Sampler;
37 : class Loop;
38 : class DeviceMemoryPool;
39 :
40 : class DeviceFrameHandle : public core::FrameHandle {
41 : public:
42 : virtual ~DeviceFrameHandle();
43 :
44 : bool init(Loop &loop, Device &, Rc<FrameRequest> &&, uint64_t gen);
45 :
46 4640 : const Rc<Allocator> &getAllocator() const { return _allocator; }
47 : const Rc<DeviceMemoryPool> &getMemPool(void *key);
48 :
49 : protected:
50 : Rc<Allocator> _allocator;
51 : Mutex _mutex;
52 : Map<void *, Rc<DeviceMemoryPool>> _memPools;
53 : };
54 :
55 : class Device : public core::Device {
56 : public:
57 : using Features = DeviceInfo::Features;
58 : using Properties = DeviceInfo::Properties;
59 : using FrameHandle = core::FrameHandle;
60 :
61 : Device();
62 : virtual ~Device();
63 :
64 : bool init(const vk::Instance *instance, DeviceInfo &&, const Features &, const Vector<StringView> &);
65 :
66 40 : const Instance *getInstance() const { return _vkInstance; }
67 55779927 : VkDevice getDevice() const { return _device; }
68 : VkPhysicalDevice getPhysicalDevice() const;
69 :
70 : void begin(Loop &loop, thread::TaskQueue &, Function<void(bool)> &&);
71 : virtual void end() override;
72 :
73 1882 : const DeviceInfo & getInfo() const { return _info; }
74 : const DeviceTable * getTable() const;
75 63704 : const Rc<Allocator> & getAllocator() const { return _allocator; }
76 :
77 : const DeviceQueueFamily *getQueueFamily(uint32_t) const;
78 : const DeviceQueueFamily *getQueueFamily(QueueOperations) const;
79 : const DeviceQueueFamily *getQueueFamily(core::PassType) const;
80 :
81 : const Vector<DeviceQueueFamily> &getQueueFamilies() const;
82 :
83 : // acquire VkQueue handle
84 : // - QueueOperations - one of QueueOperations flags, defining capabilities of required queue
85 : // - gl::FrameHandle - frame, in which queue will be used
86 : // - acquire - function, to call with result, can be called immediately
87 : // or when queue for specified operations become available (on GL thread)
88 : // - invalidate - function to call when queue query is invalidated (e.g. when frame is invalidated)
89 : // - ref - ref to preserve until query is completed
90 : // returns
91 : // - true is query was completed or scheduled,
92 : // - false if frame is not valid or no queue family with requested capabilities exists
93 : //
94 : // Acquired DeviceQueue must be released with releaseQueue
95 : bool acquireQueue(QueueOperations, FrameHandle &, Function<void(FrameHandle &, const Rc<DeviceQueue> &)> && acquire,
96 : Function<void(FrameHandle &)> && invalidate, Rc<Ref> && = nullptr);
97 : bool acquireQueue(QueueOperations, Loop &, Function<void(Loop &, const Rc<DeviceQueue> &)> && acquire,
98 : Function<void(Loop &)> && invalidate, Rc<Ref> && = nullptr);
99 : void releaseQueue(Rc<DeviceQueue> &&);
100 :
101 : // Запросить DeviceQueue синхронно, может блокировать текущий поток до завершения захвата
102 : // Преднахзначна для потоков, не относящихся к группе графических (например, для потока окна)
103 : // Вызов в графическом потоке может заблокировать возврат очереди, уже принадлежащей потоку
104 : Rc<DeviceQueue> tryAcquireQueueSync(QueueOperations, bool lock);
105 :
106 : Rc<CommandPool> acquireCommandPool(QueueOperations, uint32_t = 0);
107 : Rc<CommandPool> acquireCommandPool(uint32_t familyIndex);
108 : void releaseCommandPool(core::Loop &, Rc<CommandPool> &&);
109 : void releaseCommandPoolUnsafe(Rc<CommandPool> &&);
110 :
111 13286 : const Rc<TextureSetLayout> &getTextureSetLayout() const { return _textureSetLayout; }
112 :
113 : BytesView emplaceConstant(core::PredefinedConstant, Bytes &) const;
114 :
115 : virtual bool supportsUpdateAfterBind(DescriptorType) const override;
116 :
117 : virtual Rc<core::ImageObject> getEmptyImageObject() const override;
118 : virtual Rc<core::ImageObject> getSolidImageObject() const override;
119 :
120 : virtual Rc<core::Framebuffer> makeFramebuffer(const core::QueuePassData *, SpanView<Rc<core::ImageView>>) override;
121 : virtual Rc<ImageStorage> makeImage(const ImageInfoData &) override;
122 : virtual Rc<core::Semaphore> makeSemaphore() override;
123 : virtual Rc<core::ImageView> makeImageView(const Rc<core::ImageObject> &, const ImageViewInfo &) override;
124 :
125 : template <typename Callback>
126 107482941 : void makeApiCall(const Callback &cb) {
127 : //_apiMutex.lock();
128 107482941 : cb(*getTable(), getDevice());
129 : //_apiMutex.unlock();
130 107483019 : }
131 :
132 : bool hasNonSolidFillMode() const;
133 : bool hasDynamicIndexedBuffers() const;
134 :
135 : virtual void waitIdle() const override;
136 :
137 : void compileImage(const Loop &loop, const Rc<core::DynamicImage> &, Function<void(bool)> &&);
138 :
139 : private:
140 : using core::Device::init;
141 :
142 : friend class DeviceQueue;
143 :
144 : virtual void compileSamplers(thread::TaskQueue &q, bool force);
145 :
146 : bool setup(const Instance *instance, VkPhysicalDevice p, const Properties &prop,
147 : const Vector<DeviceQueueFamily> &queueFamilies, const Features &features, const Vector<StringView> &requiredExtension);
148 :
149 : const vk::Instance *_vkInstance = nullptr;
150 : const DeviceTable *_table = nullptr;
151 : #if VK_HOOK_DEBUG
152 : const DeviceTable *_original = nullptr;
153 : #endif
154 : VkDevice _device = VK_NULL_HANDLE;
155 :
156 : DeviceInfo _info;
157 : Features _enabledFeatures;
158 :
159 : Rc<Allocator> _allocator;
160 : Rc<TextureSetLayout> _textureSetLayout;
161 :
162 : Vector<DeviceQueueFamily> _families;
163 :
164 : bool _finished = false;
165 : bool _updateAfterBindEnabled = true;
166 :
167 : Vector<VkSampler> _immutableSamplers;
168 : Vector<Rc<Sampler>> _samplers;
169 : size_t _compiledSamplers = 0;
170 : std::atomic<bool> _samplersCompiled = false;
171 :
172 : std::unordered_map<VkFormat, VkFormatProperties> _formats;
173 :
174 : Mutex _resourceMutex;
175 : uint32_t _resourceQueueWaiters = 0;
176 : std::condition_variable _resourceQueueCond;
177 : Mutex _apiMutex;
178 : };
179 :
180 : }
181 :
182 : #endif /* XENOLITH_BACKEND_VK_XLVKDEVICE_H_ */
|