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_XLCOREQUEUEDATA_H_ 24 : #define XENOLITH_CORE_XLCOREQUEUEDATA_H_ 25 : 26 : #include "XLCorePipelineInfo.h" 27 : #include "XLCoreResource.h" 28 : 29 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core { 30 : 31 : class Instance; 32 : class Queue; 33 : class QueuePass; 34 : class QueuePassHandle; 35 : class QueuePassBuilder; 36 : class Device; 37 : class Attachment; 38 : class AttachmentHandle; 39 : class AttachmentBuilder; 40 : class RenderPass; 41 : class Shader; 42 : class Resource; 43 : class ComputePipeline; 44 : class GraphicPipeline; 45 : class FrameRequest; 46 : class FrameQueue; 47 : class FrameCache; 48 : class FrameHandle; 49 : class FrameEmitter; 50 : class ImageStorage; 51 : class ImageView; 52 : class Framebuffer; 53 : class Semaphore; 54 : class Loop; 55 : 56 : struct SubpassData; 57 : struct PipelineLayoutData; 58 : struct DescriptorSetData; 59 : struct AttachmentPassData; 60 : struct AttachmentData; 61 : struct QueuePassData; 62 : struct QueueData; 63 : 64 : struct FramePassData; 65 : struct FrameAttachmentData; 66 : struct FrameSync; 67 : struct FrameOutputBinding; 68 : 69 : struct ProgramDescriptorBinding { 70 : uint32_t set = 0; 71 : uint32_t descriptor = 0; 72 : DescriptorType type = DescriptorType::Unknown; 73 : uint32_t count = 0; 74 : }; 75 : 76 : struct ProgramPushConstantBlock { 77 : uint32_t offset = 0; 78 : uint32_t size = 0; 79 : }; 80 : 81 : struct ProgramEntryPointBlock { 82 : uint32_t id; 83 : memory::string name; 84 : uint32_t localX; 85 : uint32_t localY; 86 : uint32_t localZ; 87 : }; 88 : 89 : struct ProgramInfo : NamedMem { 90 : ProgramStage stage; 91 : memory::vector<ProgramDescriptorBinding> bindings; 92 : memory::vector<ProgramPushConstantBlock> constants; 93 : memory::vector<ProgramEntryPointBlock> entryPoints; 94 : }; 95 : 96 : struct ProgramData : ProgramInfo { 97 : using DataCallback = memory::callback<void(SpanView<uint32_t>)>; 98 : 99 : SpanView<uint32_t> data; 100 : memory::function<void(const DataCallback &)> callback = nullptr; 101 : Rc<Shader> program; // GL implementation-dependent object 102 : 103 : void inspect(SpanView<uint32_t>); 104 : }; 105 : 106 : struct SpecializationInfo { 107 : const ProgramData *data = nullptr; 108 : memory::vector<SpecializationConstant> constants; 109 : 110 1512 : SpecializationInfo() = default; 111 : SpecializationInfo(const ProgramData *); 112 : SpecializationInfo(const ProgramData *, SpanView<SpecializationConstant>); 113 : }; 114 : 115 : struct GraphicPipelineInfo : NamedMem { 116 : memory::vector<SpecializationInfo> shaders; 117 : DynamicState dynamicState = DynamicState::Default; 118 : PipelineMaterialInfo material; 119 : 120 : bool isSolid() const; 121 : }; 122 : 123 : struct GraphicPipelineData : GraphicPipelineInfo { 124 : const SubpassData *subpass = nullptr; 125 : const PipelineLayoutData *layout = nullptr; 126 : Rc<GraphicPipeline> pipeline; // GL implementation-dependent object 127 : }; 128 : 129 : struct ComputePipelineInfo : NamedMem { 130 : SpecializationInfo shader; 131 : }; 132 : 133 : struct ComputePipelineData : ComputePipelineInfo { 134 : const SubpassData *subpass = nullptr; 135 : const PipelineLayoutData *layout = nullptr; 136 : Rc<ComputePipeline> pipeline; // GL implementation-dependent object 137 : }; 138 : 139 : struct PipelineDescriptor : NamedMem { 140 : const DescriptorSetData *set = nullptr; 141 : const AttachmentPassData *attachment = nullptr; 142 : DescriptorType type = DescriptorType::Unknown; 143 : ProgramStage stages = ProgramStage::None; 144 : AttachmentLayout layout = AttachmentLayout::Ignored; 145 : uint32_t count = 1; 146 : uint32_t index = maxOf<uint32_t>(); 147 : bool updateAfterBind = false; 148 : bool countIsPredefined = false; 149 : mutable uint64_t boundGeneration = 0; 150 : }; 151 : 152 : struct SubpassDependency { 153 : static constexpr uint32_t External = maxOf<uint32_t>(); 154 : 155 : uint32_t srcSubpass; 156 : PipelineStage srcStage; 157 : AccessType srcAccess; 158 : uint32_t dstSubpass; 159 : PipelineStage dstStage; 160 : AccessType dstAccess; 161 : bool byRegion; 162 : 163 : uint64_t value() const { 164 : return uint64_t(srcSubpass) << 32 | uint64_t(dstSubpass); 165 : } 166 : }; 167 : 168 : inline bool operator < (const SubpassDependency &l, const SubpassDependency &r) { return l.value() < r.value(); } 169 : inline bool operator == (const SubpassDependency &l, const SubpassDependency &r) { return l.value() == r.value(); } 170 : inline bool operator != (const SubpassDependency &l, const SubpassDependency &r) { return l.value() != r.value(); } 171 : 172 : struct AttachmentDependencyInfo { 173 : // when and how within renderpass/subpass attachment will be used for a first time 174 : PipelineStage initialUsageStage = PipelineStage::None; 175 : AccessType initialAccessMask = AccessType::None; 176 : 177 : // when and how within renderpass/subpass attachment will be used for a last time 178 : PipelineStage finalUsageStage = PipelineStage::None; 179 : AccessType finalAccessMask = AccessType::None; 180 : 181 : // FrameRenderPassState, after which attachment can be used on next renderpass 182 : // Or Initial if no dependencies 183 : FrameRenderPassState requiredRenderPassState = FrameRenderPassState::Initial; 184 : 185 : // FrameRenderPassState that can be processed before attachment is acquired 186 : FrameRenderPassState lockedRenderPassState = FrameRenderPassState::Initial; 187 : 188 105 : static AttachmentDependencyInfo make(PipelineStage stage, AccessType type) { 189 105 : return AttachmentDependencyInfo{stage, type, stage, type}; 190 : } 191 : }; 192 : 193 : struct AttachmentSubpassData : NamedMem { 194 : const AttachmentPassData *pass = nullptr; 195 : const SubpassData *subpass = nullptr; 196 : AttachmentLayout layout = AttachmentLayout::Ignored; 197 : AttachmentUsage usage = AttachmentUsage::None; 198 : AttachmentOps ops = AttachmentOps::Undefined; 199 : AttachmentDependencyInfo dependency; 200 : BlendInfo blendInfo; 201 : }; 202 : 203 : struct AttachmentPassData : NamedMem { 204 : const AttachmentData *attachment = nullptr; 205 : const QueuePassData *pass = nullptr; 206 : 207 : mutable uint32_t index = maxOf<uint32_t>(); 208 : 209 : AttachmentOps ops = AttachmentOps::Undefined; 210 : 211 : // calculated initial layout 212 : // for first descriptor in execution chain - initial layout of queue's attachment or first usage layout 213 : // for others - final layout of previous descriptor in chain of execution 214 : AttachmentLayout initialLayout = AttachmentLayout::Ignored; 215 : 216 : // calculated final layout 217 : // for last descriptor in execution chain - final layout of queue's attachment or last usage layout 218 : // for others - last usage layout 219 : AttachmentLayout finalLayout = AttachmentLayout::Ignored; 220 : 221 : AttachmentLoadOp loadOp = AttachmentLoadOp::DontCare; 222 : AttachmentStoreOp storeOp = AttachmentStoreOp::DontCare; 223 : AttachmentLoadOp stencilLoadOp = AttachmentLoadOp::DontCare; 224 : AttachmentStoreOp stencilStoreOp = AttachmentStoreOp::DontCare; 225 : 226 : ColorMode colorMode; 227 : AttachmentDependencyInfo dependency; 228 : 229 : memory::vector<PipelineDescriptor *> descriptors; 230 : memory::vector<AttachmentSubpassData *> subpasses; 231 : }; 232 : 233 : struct AttachmentData : NamedMem { 234 : const QueueData *queue = nullptr; 235 : uint64_t id = 0; 236 : AttachmentOps ops = AttachmentOps::Undefined; 237 : AttachmentType type = AttachmentType::Image; 238 : AttachmentUsage usage = AttachmentUsage::None; 239 : FrameRenderPassState outputState = FrameRenderPassState::Submitted; 240 : memory::vector<AttachmentPassData *> passes; 241 : Rc<Attachment> attachment; 242 : bool transient = false; 243 : }; 244 : 245 : struct DescriptorSetData : NamedMem { 246 : const PipelineLayoutData *layout = nullptr; 247 : uint32_t index = 0; 248 : memory::vector<PipelineDescriptor *> descriptors; 249 : }; 250 : 251 : struct PipelineLayoutData : NamedMem { 252 : const QueuePassData *pass = nullptr; 253 : uint32_t index = 0; 254 : bool usesTextureSet = false; 255 : memory::vector<DescriptorSetData *> sets; 256 : memory::vector<const GraphicPipelineData *> graphicPipelines; 257 : memory::vector<const ComputePipelineData *> computePipelines; 258 : }; 259 : 260 : struct SubpassData : NamedMem { 261 224 : SubpassData() = default; 262 : SubpassData(const SubpassData &) = default; 263 : SubpassData(SubpassData &&) = default; 264 : 265 : SubpassData &operator=(const SubpassData &) = delete; 266 : SubpassData &operator=(SubpassData &&) = delete; 267 : 268 : const QueuePassData *pass = nullptr; 269 : uint32_t index = 0; 270 : 271 : HashTable<GraphicPipelineData *> graphicPipelines; 272 : HashTable<ComputePipelineData *> computePipelines; 273 : 274 : memory::vector<const AttachmentSubpassData *> inputImages; 275 : memory::vector<const AttachmentSubpassData *> outputImages; 276 : memory::vector<const AttachmentSubpassData *> resolveImages; 277 : const AttachmentSubpassData *depthStencil = nullptr; 278 : mutable memory::vector<uint32_t> preserve; 279 : 280 : memory::function<void(const SubpassData &, FrameQueue &)> prepareCallback = nullptr; 281 : memory::function<void(const SubpassData &, FrameQueue &, CommandBuffer &)> commandsCallback = nullptr; 282 : }; 283 : 284 : /** RenderOrdering defines order of execution for render passes between interdependent passes 285 : * if render passes is not interdependent, RenderOrdering can be used as an advice, or not used at all 286 : */ 287 : using RenderOrdering = ValueWrapper<uint32_t, class RenderOrderingFlag>; 288 : 289 : static constexpr RenderOrdering RenderOrderingLowest = RenderOrdering::min(); 290 : static constexpr RenderOrdering RenderOrderingHighest = RenderOrdering::max(); 291 : 292 : struct QueuePassRequirements { 293 : const QueuePassData *data = nullptr; 294 : FrameRenderPassState requiredState = FrameRenderPassState::Initial; 295 : FrameRenderPassState lockedState = FrameRenderPassState::Initial; 296 : 297 : QueuePassRequirements() = default; 298 96 : QueuePassRequirements(const QueuePassData &d, FrameRenderPassState required, FrameRenderPassState locked) 299 96 : : data(&d), requiredState(required), lockedState(locked) { } 300 : }; 301 : 302 : struct QueuePassDependency { 303 : const QueuePassData *source = nullptr; 304 : const QueuePassData *target = nullptr; 305 : memory::vector<const AttachmentData *> attachments; 306 : PipelineStage stageFlags = PipelineStage::None; 307 : }; 308 : 309 : struct QueuePassData : NamedMem { 310 320 : QueuePassData() = default; 311 : QueuePassData(const QueuePassData &) = default; 312 : QueuePassData(QueuePassData &&) = default; 313 : 314 : QueuePassData &operator=(const QueuePassData &) = delete; 315 : QueuePassData &operator=(QueuePassData &&) = delete; 316 : 317 : const QueueData *queue = nullptr; 318 : memory::vector<const AttachmentPassData *> attachments; 319 : memory::vector<const SubpassData *> subpasses; 320 : memory::vector<const PipelineLayoutData *> pipelineLayouts; 321 : memory::vector<SubpassDependency> dependencies; 322 : 323 : memory::vector<QueuePassDependency *> sourceQueueDependencies; 324 : memory::vector<QueuePassDependency *> targetQueueDependencies; 325 : 326 : memory::vector<QueuePassRequirements> required; 327 : 328 : PassType type = PassType::Graphics; 329 : RenderOrdering ordering = RenderOrderingLowest; 330 : bool hasUpdateAfterBind = false; 331 : 332 : Rc<QueuePass> pass; 333 : Rc<RenderPass> impl; 334 : 335 : memory::vector<memory::function<void(const QueuePassData &, FrameQueue &, bool)>> submittedCallbacks; 336 : memory::vector<memory::function<void(const QueuePassData &, FrameQueue &, bool)>> completeCallbacks; 337 : }; 338 : 339 : struct QueueData : NamedMem { 340 : memory::pool_t *pool = nullptr; 341 : memory::vector<AttachmentData *> input; 342 : memory::vector<AttachmentData *> output; 343 : HashTable<AttachmentData *> attachments; 344 : HashTable<QueuePassData *> passes; 345 : HashTable<ProgramData *> programs; 346 : HashTable<GraphicPipelineData *> graphicPipelines; 347 : HashTable<ComputePipelineData *> computePipelines; 348 : HashTable<Rc<Resource>> linked; 349 : Function<void(FrameRequest &)> beginCallback; 350 : Function<void(FrameRequest &)> endCallback; 351 : Function<void(const FrameHandle *)> attachCallback; 352 : Function<void(const FrameHandle *)> detachCallback; 353 : Function<void()> releaseCallback; 354 : Rc<Resource> resource; 355 : bool compiled = false; 356 : uint64_t order = 0; 357 : Queue *queue = nullptr; 358 : FrameRenderPassState defaultSyncPassState = FrameRenderPassState::Submitted; 359 : 360 : memory::map<std::type_index, Attachment *> typedInput; 361 : memory::map<std::type_index, Attachment *> typedOutput; 362 : 363 : memory::vector<QueuePassDependency> passDependencies; 364 : 365 : void clear(); 366 : }; 367 : 368 : StringView getDescriptorTypeName(DescriptorType); 369 : String getProgramStageDescription(ProgramStage fmt); 370 : 371 : } 372 : 373 : #endif /* XENOLITH_CORE_XLCOREQUEUEDATA_H_ */