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 "XLCoreQueueData.h" 24 : #include "XLCoreQueuePass.h" 25 : #include "SPIRV-Reflect/spirv_reflect.h" 26 : 27 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core { 28 : 29 192 : void QueueData::clear() { 30 1520 : for (auto &it : programs) { 31 1328 : it->program = nullptr; 32 : } 33 : 34 512 : for (auto &it : passes) { 35 544 : for (auto &subpass : it->subpasses) { 36 304 : for (auto &pipeline : subpass->graphicPipelines) { 37 80 : pipeline->pipeline = nullptr; 38 : } 39 1376 : for (auto &pipeline : subpass->computePipelines) { 40 1152 : pipeline->pipeline = nullptr; 41 : } 42 : } 43 : 44 320 : it->pass->invalidate(); 45 320 : it->pass = nullptr; 46 320 : it->impl = nullptr; 47 : } 48 : 49 816 : for (auto &it : attachments) { 50 624 : it->attachment = nullptr; 51 : } 52 : 53 192 : if (resource) { 54 48 : resource->clear(); 55 48 : resource = nullptr; 56 : } 57 192 : linked.clear(); 58 192 : compiled = false; 59 : 60 192 : if (releaseCallback) { 61 144 : releaseCallback(); 62 144 : releaseCallback = nullptr; 63 : } 64 192 : } 65 : 66 : 67 64 : StringView getDescriptorTypeName(DescriptorType type) { 68 64 : switch (type) { 69 0 : case DescriptorType::Sampler: return StringView("Sampler"); break; 70 0 : case DescriptorType::CombinedImageSampler: return StringView("CombinedImageSampler"); break; 71 0 : case DescriptorType::SampledImage: return StringView("SampledImage"); break; 72 32 : case DescriptorType::StorageImage: return StringView("StorageImage"); break; 73 0 : case DescriptorType::UniformTexelBuffer: return StringView("UniformTexelBuffer"); break; 74 0 : case DescriptorType::StorageTexelBuffer: return StringView("StorageTexelBuffer"); break; 75 32 : case DescriptorType::UniformBuffer: return StringView("UniformBuffer"); break; 76 0 : case DescriptorType::StorageBuffer: return StringView("StorageBuffer"); break; 77 0 : case DescriptorType::UniformBufferDynamic: return StringView("UniformBufferDynamic"); break; 78 0 : case DescriptorType::StorageBufferDynamic: return StringView("StorageBufferDynamic"); break; 79 0 : case DescriptorType::InputAttachment: return StringView("InputAttachment"); break; 80 0 : default: break; 81 : } 82 0 : return StringView("Unknown"); 83 : } 84 : 85 16 : String getProgramStageDescription(ProgramStage fmt) { 86 16 : StringStream stream; 87 16 : if ((fmt & ProgramStage::Vertex) != ProgramStage::None) { stream << " Vertex"; } 88 16 : if ((fmt & ProgramStage::TesselationControl) != ProgramStage::None) { stream << " TesselationControl"; } 89 16 : if ((fmt & ProgramStage::TesselationEvaluation) != ProgramStage::None) { stream << " TesselationEvaluation"; } 90 16 : if ((fmt & ProgramStage::Geometry) != ProgramStage::None) { stream << " Geometry"; } 91 16 : if ((fmt & ProgramStage::Fragment) != ProgramStage::None) { stream << " Fragment"; } 92 16 : if ((fmt & ProgramStage::Compute) != ProgramStage::None) { stream << " Compute"; } 93 16 : if ((fmt & ProgramStage::RayGen) != ProgramStage::None) { stream << " RayGen"; } 94 16 : if ((fmt & ProgramStage::AnyHit) != ProgramStage::None) { stream << " AnyHit"; } 95 16 : if ((fmt & ProgramStage::ClosestHit) != ProgramStage::None) { stream << " ClosestHit"; } 96 16 : if ((fmt & ProgramStage::MissHit) != ProgramStage::None) { stream << " MissHit"; } 97 16 : if ((fmt & ProgramStage::AnyHit) != ProgramStage::None) { stream << " AnyHit"; } 98 16 : if ((fmt & ProgramStage::Intersection) != ProgramStage::None) { stream << " Intersection"; } 99 16 : if ((fmt & ProgramStage::Callable) != ProgramStage::None) { stream << " Callable"; } 100 16 : if ((fmt & ProgramStage::Task) != ProgramStage::None) { stream << " Task"; } 101 16 : if ((fmt & ProgramStage::Mesh) != ProgramStage::None) { stream << " Mesh"; } 102 32 : return stream.str(); 103 16 : } 104 : 105 1232 : void ProgramData::inspect(SpanView<uint32_t> data) { 106 : SpvReflectShaderModule shader; 107 : 108 1232 : spvReflectCreateShaderModule(data.size() * sizeof(uint32_t), data.data(), &shader); 109 : 110 1232 : switch (shader.spirv_execution_model) { 111 48 : case SpvExecutionModelVertex: stage = ProgramStage::Vertex; break; 112 0 : case SpvExecutionModelTessellationControl: stage = ProgramStage::TesselationControl; break; 113 0 : case SpvExecutionModelTessellationEvaluation: stage = ProgramStage::TesselationEvaluation; break; 114 0 : case SpvExecutionModelGeometry: stage = ProgramStage::Geometry; break; 115 32 : case SpvExecutionModelFragment: stage = ProgramStage::Fragment; break; 116 1152 : case SpvExecutionModelGLCompute: stage = ProgramStage::Compute; break; 117 0 : case SpvExecutionModelKernel: stage = ProgramStage::Compute; break; 118 0 : case SpvExecutionModelTaskNV: stage = ProgramStage::Task; break; 119 0 : case SpvExecutionModelMeshNV: stage = ProgramStage::Mesh; break; 120 0 : case SpvExecutionModelRayGenerationKHR: stage = ProgramStage::RayGen; break; 121 0 : case SpvExecutionModelIntersectionKHR: stage = ProgramStage::Intersection; break; 122 0 : case SpvExecutionModelAnyHitKHR: stage = ProgramStage::AnyHit; break; 123 0 : case SpvExecutionModelClosestHitKHR: stage = ProgramStage::ClosestHit; break; 124 0 : case SpvExecutionModelMissKHR: stage = ProgramStage::MissHit; break; 125 0 : case SpvExecutionModelCallableKHR: stage = ProgramStage::Callable; break; 126 0 : default: break; 127 : } 128 : 129 1232 : bindings.reserve(shader.descriptor_binding_count); 130 3792 : for (auto &it : makeSpanView(shader.descriptor_bindings, shader.descriptor_binding_count)) { 131 2560 : bindings.emplace_back(ProgramDescriptorBinding({it.set, it.binding, DescriptorType(it.descriptor_type), it.count})); 132 : } 133 : 134 1232 : constants.reserve(shader.push_constant_block_count); 135 2128 : for (auto &it : makeSpanView(shader.push_constant_blocks, shader.push_constant_block_count)) { 136 896 : constants.emplace_back(ProgramPushConstantBlock({it.absolute_offset, it.padded_size})); 137 : } 138 : 139 1232 : entryPoints.reserve(shader.entry_point_count); 140 2496 : for (auto &it : makeSpanView(shader.entry_points, shader.entry_point_count)) { 141 1264 : entryPoints.emplace_back(ProgramEntryPointBlock({it.id, memory::string(it.name), it.local_size.x, it.local_size.y, it.local_size.z})); 142 : } 143 : 144 1232 : spvReflectDestroyShaderModule(&shader); 145 1232 : } 146 : 147 128 : SpecializationInfo::SpecializationInfo(const ProgramData *d) : data(d) { } 148 : 149 1152 : SpecializationInfo::SpecializationInfo(const ProgramData *d, SpanView<SpecializationConstant> c) 150 1152 : : data(d), constants(c.vec<memory::PoolInterface>()) { } 151 : 152 80531 : bool GraphicPipelineInfo::isSolid() const { 153 80531 : if (material.getDepthInfo().writeEnabled || !material.getBlendInfo().enabled) { 154 71575 : return true; 155 : } 156 8956 : return false; 157 : } 158 : 159 : }