diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 5677dbf6569a182eddba494852d39320f8154711..7f23c38467b372cc553e1b26af75577bb3f518c8 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -249,16 +249,16 @@ namespace vkcv bool beginFrame(uint32_t& width, uint32_t& height); void recordDrawcallsToCmdStream( - const CommandStreamHandle cmdStreamHandle, - const PassHandle renderpassHandle, + const CommandStreamHandle& cmdStreamHandle, + const PassHandle& renderpassHandle, const PipelineHandle pipelineHandle, const PushConstants &pushConstants, const std::vector<DrawcallInfo> &drawcalls, const std::vector<ImageHandle> &renderTargets); void recordMeshShaderDrawcalls( - const CommandStreamHandle cmdStreamHandle, - const PassHandle renderpassHandle, + const CommandStreamHandle& cmdStreamHandle, + const PassHandle& renderpassHandle, const PipelineHandle pipelineHandle, const PushConstants& pushConstantData, const std::vector<MeshShaderDrawcall>& drawcalls, diff --git a/include/vkcv/FeatureManager.hpp b/include/vkcv/FeatureManager.hpp index 742fd25957d3521077d777f2137cbe5528322728..9e472a38bfca33ce507515148a919a8b867554cb 100644 --- a/include/vkcv/FeatureManager.hpp +++ b/include/vkcv/FeatureManager.hpp @@ -19,6 +19,9 @@ namespace vkcv { vk::PhysicalDeviceFeatures2 m_featuresBase; std::vector<vk::BaseOutStructure*> m_featuresExtensions; + [[nodiscard]] + bool checkSupport(const vk::PhysicalDeviceFeatures& features, bool required) const; + [[nodiscard]] bool checkSupport(const vk::PhysicalDevice16BitStorageFeatures& features, bool required) const; @@ -75,6 +78,8 @@ namespace vkcv { [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const; + + vk::BaseOutStructure* findFeatureStructure(vk::StructureType type) const; public: explicit FeatureManager(vk::PhysicalDevice& physicalDevice); @@ -102,24 +107,36 @@ namespace vkcv { template<typename T> bool useFeatures(const std::function<void(T&)>& featureFunction, bool required = true) { - T* features = new T(); - featureFunction(*features); + T features; + T* features_ptr = reinterpret_cast<T*>(findFeatureStructure(features.sType)); + + if (features_ptr) { + features = *features_ptr; + } - if (!checkSupport(*features, required)) { - delete features; + featureFunction(features); + + if (!checkSupport(features, required)) { return false; } + if (features_ptr) { + *features_ptr = features; + return true; + } + + features_ptr = new T(features); + if (m_featuresExtensions.empty()) { - m_featuresBase.setPNext(features); + m_featuresBase.setPNext(features_ptr); } else { m_featuresExtensions.back()->setPNext( - reinterpret_cast<vk::BaseOutStructure*>(features) + reinterpret_cast<vk::BaseOutStructure*>(features_ptr) ); } m_featuresExtensions.push_back( - reinterpret_cast<vk::BaseOutStructure*>(features) + reinterpret_cast<vk::BaseOutStructure*>(features_ptr) ); return true; diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index e8e172dd236ac5cb49d0e2caf03599c198a07092..69da1106df8c8a946e1fcdc9ce1afd7c2825362a 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -331,8 +331,8 @@ namespace vkcv } void Core::recordDrawcallsToCmdStream( - const CommandStreamHandle cmdStreamHandle, - const PassHandle renderpassHandle, + const CommandStreamHandle& cmdStreamHandle, + const PassHandle& renderpassHandle, const PipelineHandle pipelineHandle, const PushConstants &pushConstantData, const std::vector<DrawcallInfo> &drawcalls, @@ -368,7 +368,6 @@ namespace vkcv submitInfo.signalSemaphores = { m_SyncResources.renderFinished }; auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { - const std::vector<vk::ClearValue> clearValues = createAttachmentClearValues(passConfig.attachments); const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, clearValues.size(), clearValues.data()); @@ -377,16 +376,14 @@ namespace vkcv cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {}); const PipelineConfig &pipeConfig = m_PipelineManager->getPipelineConfig(pipelineHandle); - if(pipeConfig.m_UseDynamicViewport) - { + if (pipeConfig.m_UseDynamicViewport) { recordDynamicViewport(cmdBuffer, width, height); } - for (int i = 0; i < drawcalls.size(); i++) { + for (size_t i = 0; i < drawcalls.size(); i++) { recordDrawcall(drawcalls[i], cmdBuffer, pipelineLayout, pushConstantData, i); } - vk::Rect2D dynamicScissor({0, 0}, {width, height}); cmdBuffer.endRenderPass(); }; @@ -399,8 +396,8 @@ namespace vkcv } void Core::recordMeshShaderDrawcalls( - const CommandStreamHandle cmdStreamHandle, - const PassHandle renderpassHandle, + const CommandStreamHandle& cmdStreamHandle, + const PassHandle& renderpassHandle, const PipelineHandle pipelineHandle, const PushConstants& pushConstantData, const std::vector<MeshShaderDrawcall>& drawcalls, @@ -436,7 +433,6 @@ namespace vkcv submitInfo.signalSemaphores = { m_SyncResources.renderFinished }; auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { - const std::vector<vk::ClearValue> clearValues = createAttachmentClearValues(passConfig.attachments); const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, clearValues.size(), clearValues.data()); @@ -445,12 +441,11 @@ namespace vkcv cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline, {}); const PipelineConfig& pipeConfig = m_PipelineManager->getPipelineConfig(pipelineHandle); - if (pipeConfig.m_UseDynamicViewport) - { + if (pipeConfig.m_UseDynamicViewport) { recordDynamicViewport(cmdBuffer, width, height); } - for (int i = 0; i < drawcalls.size(); i++) { + for (size_t i = 0; i < drawcalls.size(); i++) { const uint32_t pushConstantOffset = i * pushConstantData.getSizePerDrawcall(); recordMeshShaderDrawcall( cmdBuffer, @@ -458,14 +453,14 @@ namespace vkcv pushConstantData, pushConstantOffset, drawcalls[i], - 0); + 0 + ); } cmdBuffer.endRenderPass(); }; - auto finishFunction = [framebuffer, this]() - { + auto finishFunction = [framebuffer, this]() { m_Context.m_Device.destroy(framebuffer); }; diff --git a/src/vkcv/FeatureManager.cpp b/src/vkcv/FeatureManager.cpp index 1ef33b1617f8d574ca72bec8f104d01c9fd280c9..416858c836f089f87f3d7efeb5b5d48dbb8cf7fb 100644 --- a/src/vkcv/FeatureManager.cpp +++ b/src/vkcv/FeatureManager.cpp @@ -29,6 +29,68 @@ m_physicalDevice.getFeatures2(&query) } \ } + bool FeatureManager::checkSupport(const vk::PhysicalDeviceFeatures &features, bool required) const { + const auto& supported = m_physicalDevice.getFeatures(); + + vkcv_check_feature(alphaToOne); + vkcv_check_feature(depthBiasClamp); + vkcv_check_feature(depthBounds); + vkcv_check_feature(depthClamp); + vkcv_check_feature(drawIndirectFirstInstance); + vkcv_check_feature(dualSrcBlend); + vkcv_check_feature(fillModeNonSolid); + vkcv_check_feature(fragmentStoresAndAtomics); + vkcv_check_feature(fullDrawIndexUint32); + vkcv_check_feature(geometryShader); + vkcv_check_feature(imageCubeArray); + vkcv_check_feature(independentBlend); + vkcv_check_feature(inheritedQueries); + vkcv_check_feature(largePoints); + vkcv_check_feature(logicOp); + vkcv_check_feature(multiDrawIndirect); + vkcv_check_feature(multiViewport); + vkcv_check_feature(occlusionQueryPrecise); + vkcv_check_feature(pipelineStatisticsQuery); + vkcv_check_feature(robustBufferAccess); + vkcv_check_feature(sampleRateShading); + vkcv_check_feature(samplerAnisotropy); + vkcv_check_feature(shaderClipDistance); + vkcv_check_feature(shaderCullDistance); + vkcv_check_feature(shaderFloat64); + vkcv_check_feature(shaderImageGatherExtended); + vkcv_check_feature(shaderInt16); + vkcv_check_feature(shaderInt64); + vkcv_check_feature(shaderResourceMinLod); + vkcv_check_feature(shaderResourceResidency); + vkcv_check_feature(shaderSampledImageArrayDynamicIndexing); + vkcv_check_feature(shaderStorageBufferArrayDynamicIndexing); + vkcv_check_feature(shaderStorageImageArrayDynamicIndexing); + vkcv_check_feature(shaderStorageImageExtendedFormats); + vkcv_check_feature(shaderStorageImageMultisample); + vkcv_check_feature(shaderStorageImageReadWithoutFormat); + vkcv_check_feature(shaderStorageImageWriteWithoutFormat); + vkcv_check_feature(shaderTessellationAndGeometryPointSize); + vkcv_check_feature(shaderUniformBufferArrayDynamicIndexing); + vkcv_check_feature(sparseBinding); + vkcv_check_feature(sparseResidency2Samples); + vkcv_check_feature(sparseResidency4Samples); + vkcv_check_feature(sparseResidency8Samples); + vkcv_check_feature(sparseResidency16Samples); + vkcv_check_feature(sparseResidencyAliased); + vkcv_check_feature(sparseResidencyBuffer); + vkcv_check_feature(sparseResidencyImage2D); + vkcv_check_feature(sparseResidencyImage3D); + vkcv_check_feature(tessellationShader); + vkcv_check_feature(textureCompressionASTC_LDR); + vkcv_check_feature(textureCompressionBC); + vkcv_check_feature(textureCompressionETC2); + vkcv_check_feature(variableMultisampleRate); + vkcv_check_feature(vertexPipelineStoresAndAtomics); + vkcv_check_feature(wideLines); + + return true; + } + bool FeatureManager::checkSupport(const vk::PhysicalDevice16BitStorageFeatures &features, bool required) const { vkcv_check_init_features2(vk::PhysicalDevice16BitStorageFeatures); @@ -230,6 +292,16 @@ m_physicalDevice.getFeatures2(&query) return true; } + vk::BaseOutStructure* FeatureManager::findFeatureStructure(vk::StructureType type) const { + for (auto& base : m_featuresExtensions) { + if (base->sType == type) { + return base; + } + } + + return nullptr; + } + const char* strclone(const char* str) { if (!str) { return nullptr; @@ -345,67 +417,15 @@ m_physicalDevice.getFeatures2(&query) bool FeatureManager::useFeatures(const std::function<void(vk::PhysicalDeviceFeatures &)> &featureFunction, bool required) { - featureFunction(m_featuresBase.features); + vk::PhysicalDeviceFeatures features = m_featuresBase.features; - const auto& features = m_featuresBase.features; - const auto& supported = m_physicalDevice.getFeatures(); + featureFunction(features); - vkcv_check_feature(alphaToOne); - vkcv_check_feature(depthBiasClamp); - vkcv_check_feature(depthBounds); - vkcv_check_feature(depthClamp); - vkcv_check_feature(drawIndirectFirstInstance); - vkcv_check_feature(dualSrcBlend); - vkcv_check_feature(fillModeNonSolid); - vkcv_check_feature(fragmentStoresAndAtomics); - vkcv_check_feature(fullDrawIndexUint32); - vkcv_check_feature(geometryShader); - vkcv_check_feature(imageCubeArray); - vkcv_check_feature(independentBlend); - vkcv_check_feature(inheritedQueries); - vkcv_check_feature(largePoints); - vkcv_check_feature(logicOp); - vkcv_check_feature(multiDrawIndirect); - vkcv_check_feature(multiViewport); - vkcv_check_feature(occlusionQueryPrecise); - vkcv_check_feature(pipelineStatisticsQuery); - vkcv_check_feature(robustBufferAccess); - vkcv_check_feature(sampleRateShading); - vkcv_check_feature(samplerAnisotropy); - vkcv_check_feature(shaderClipDistance); - vkcv_check_feature(shaderCullDistance); - vkcv_check_feature(shaderFloat64); - vkcv_check_feature(shaderImageGatherExtended); - vkcv_check_feature(shaderInt16); - vkcv_check_feature(shaderInt64); - vkcv_check_feature(shaderResourceMinLod); - vkcv_check_feature(shaderResourceResidency); - vkcv_check_feature(shaderSampledImageArrayDynamicIndexing); - vkcv_check_feature(shaderStorageBufferArrayDynamicIndexing); - vkcv_check_feature(shaderStorageImageArrayDynamicIndexing); - vkcv_check_feature(shaderStorageImageExtendedFormats); - vkcv_check_feature(shaderStorageImageMultisample); - vkcv_check_feature(shaderStorageImageReadWithoutFormat); - vkcv_check_feature(shaderStorageImageWriteWithoutFormat); - vkcv_check_feature(shaderTessellationAndGeometryPointSize); - vkcv_check_feature(shaderUniformBufferArrayDynamicIndexing); - vkcv_check_feature(sparseBinding); - vkcv_check_feature(sparseResidency2Samples); - vkcv_check_feature(sparseResidency4Samples); - vkcv_check_feature(sparseResidency8Samples); - vkcv_check_feature(sparseResidency16Samples); - vkcv_check_feature(sparseResidencyAliased); - vkcv_check_feature(sparseResidencyBuffer); - vkcv_check_feature(sparseResidencyImage2D); - vkcv_check_feature(sparseResidencyImage3D); - vkcv_check_feature(tessellationShader); - vkcv_check_feature(textureCompressionASTC_LDR); - vkcv_check_feature(textureCompressionBC); - vkcv_check_feature(textureCompressionETC2); - vkcv_check_feature(variableMultisampleRate); - vkcv_check_feature(vertexPipelineStoresAndAtomics); - vkcv_check_feature(wideLines); + if (!checkSupport(features, required)) { + return false; + } + m_featuresBase.features = features; return true; }