diff --git a/include/vkcv/Context.hpp b/include/vkcv/Context.hpp index 2ecd9203701510837f49d10c1879efd4890145e9..12e02e96a9e81b461495ce5c2a76e35e6d226eb6 100644 --- a/include/vkcv/Context.hpp +++ b/include/vkcv/Context.hpp @@ -39,9 +39,9 @@ namespace vkcv static Context create(const char *applicationName, uint32_t applicationVersion, - std::vector<vk::QueueFlagBits> queueFlags, - std::vector<const char *> instanceExtensions, - std::vector<const char *> deviceExtensions); + const std::vector<vk::QueueFlagBits>& queueFlags, + const std::vector<const char *>& instanceExtensions, + const std::vector<const char *>& deviceExtensions); private: /** diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index cf36fa7a3072559cfaa83edd07e058431c50059b..076e1a3e7d28cf40d4d2e8fd439084a0de46db61 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -138,9 +138,9 @@ namespace vkcv static Core create(Window &window, const char *applicationName, uint32_t applicationVersion, - std::vector<vk::QueueFlagBits> queueFlags = {}, - std::vector<const char*> instanceExtensions = {}, - std::vector<const char*> deviceExtensions = {}); + const std::vector<vk::QueueFlagBits>& queueFlags = {}, + const std::vector<const char*>& instanceExtensions = {}, + const std::vector<const char*>& deviceExtensions = {}); /** * Creates a basic vulkan graphics pipeline using @p config from the pipeline config class and returns it using the @p handle. diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp index 776322e6270431f9fa52fd7c3cb4551e5b4bf752..767492eb2b27bd8dff56ef2aeb4769c08eed7200 100644 --- a/include/vkcv/DescriptorConfig.hpp +++ b/include/vkcv/DescriptorConfig.hpp @@ -23,7 +23,9 @@ namespace vkcv STORAGE_BUFFER, SAMPLER, IMAGE_SAMPLED, - IMAGE_STORAGE + IMAGE_STORAGE, + UNIFORM_BUFFER_DYNAMIC, + STORAGE_BUFFER_DYNAMIC }; /* diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index f28a6c91e189b13413ffefec0f05e5a0a358ee26..00e2d9a0494aec08767ced3a12086c812f6f1451 100644 --- a/include/vkcv/DescriptorWrites.hpp +++ b/include/vkcv/DescriptorWrites.hpp @@ -21,15 +21,19 @@ namespace vkcv { }; struct UniformBufferDescriptorWrite { - inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {}; + inline UniformBufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false) : + binding(binding), buffer(buffer), dynamic(dynamic) {}; uint32_t binding; BufferHandle buffer; + bool dynamic; }; struct StorageBufferDescriptorWrite { - inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer) : binding(binding), buffer(buffer) {}; + inline StorageBufferDescriptorWrite(uint32_t binding, BufferHandle buffer, bool dynamic = false) : + binding(binding), buffer(buffer), dynamic(dynamic) {}; uint32_t binding; BufferHandle buffer; + bool dynamic; }; struct SamplerDescriptorWrite { diff --git a/include/vkcv/DrawcallRecording.hpp b/include/vkcv/DrawcallRecording.hpp index 572fc2b6b51735bdcd7eb77c1dd9d4a3482a1640..2dfefab328a7cae395118c620ec6e5825b1cf63e 100644 --- a/include/vkcv/DrawcallRecording.hpp +++ b/include/vkcv/DrawcallRecording.hpp @@ -14,11 +14,13 @@ namespace vkcv { }; struct DescriptorSetUsage { - inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle) noexcept - : setLocation(setLocation), vulkanHandle(vulkanHandle) {} + inline DescriptorSetUsage(uint32_t setLocation, vk::DescriptorSet vulkanHandle, + const std::vector<uint32_t>& dynamicOffsets = {}) noexcept + : setLocation(setLocation), vulkanHandle(vulkanHandle), dynamicOffsets(dynamicOffsets) {} - const uint32_t setLocation; - const vk::DescriptorSet vulkanHandle; + const uint32_t setLocation; + const vk::DescriptorSet vulkanHandle; + const std::vector<uint32_t> dynamicOffsets; }; struct Mesh { diff --git a/include/vkcv/QueueManager.hpp b/include/vkcv/QueueManager.hpp index ac043b2d351014ea79fcae0d0fc439bb64a87b72..0919d20d8e07fee67ceb2f393c29b4a53c51b857 100644 --- a/include/vkcv/QueueManager.hpp +++ b/include/vkcv/QueueManager.hpp @@ -32,8 +32,8 @@ namespace vkcv { const std::vector<Queue> &getTransferQueues() const; static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, - std::vector<float> &queuePriorities, - std::vector<vk::QueueFlagBits> &queueFlags, + const std::vector<float> &queuePriorities, + const std::vector<vk::QueueFlagBits> &queueFlags, std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, std::vector<std::pair<int, int>> &queuePairsGraphics, std::vector<std::pair<int, int>> &queuePairsCompute, diff --git a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp index 0d9a39ccacb8451440150b7752a04d36eaddab39..274e1b9901b585554a56e2e6f503e904f6489ba4 100644 --- a/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp +++ b/modules/upscaling/include/vkcv/upscaling/FSRUpscaling.hpp @@ -29,6 +29,18 @@ namespace vkcv::upscaling { SamplerHandle m_sampler; bool m_hdr; + + /** + * Sharpness will calculate the rcasAttenuation value + * which should be between 0.0f and 2.0f (default: 0.25f). + * + * rcasAttenuation = (1.0f - sharpness) * 2.0f + * + * So the default value for sharpness should be 0.875f. + * + * Beware that 0.0f or any negative value of sharpness will + * disable the rcas pass completely. + */ float m_sharpness; public: diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index 0f499500f12e2778d1841f324717f2b66c2a721e..d028beceabd08ac8b1ae2aea13919477016b5cd1 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -18,6 +18,47 @@ namespace vkcv::upscaling { + static std::vector<DescriptorBinding> getDescriptorBindings() { + return std::vector<DescriptorBinding>({ + DescriptorBinding( + 0, DescriptorType::UNIFORM_BUFFER_DYNAMIC, + 1, ShaderStage::COMPUTE + ), + DescriptorBinding( + 1, DescriptorType::IMAGE_SAMPLED, + 1, ShaderStage::COMPUTE + ), + DescriptorBinding( + 2, DescriptorType::IMAGE_STORAGE, + 1, ShaderStage::COMPUTE + ), + DescriptorBinding( + 3, DescriptorType::SAMPLER, + 1, ShaderStage::COMPUTE + ) + }); + } + + template<typename T> + bool checkFeatures(const vk::BaseInStructure* base, vk::StructureType type, bool (*check)(const T& features)) { + if (base->sType == type) { + return check(*reinterpret_cast<const T*>(base)); + } else + if (base->pNext) { + return checkFeatures<T>(base->pNext, type, check); + } else { + return false; + } + } + + static bool checkFloat16(const vk::PhysicalDeviceFloat16Int8FeaturesKHR& features) { + return features.shaderFloat16; + } + + static bool check16Storage(const vk::PhysicalDevice16BitStorageFeaturesKHR& features) { + return features.storageBuffer16BitAccess; + } + static bool writeShaderCode(const std::filesystem::path &shaderPath, const std::string& code) { std::ofstream file (shaderPath.string(), std::ios::out); @@ -67,8 +108,8 @@ namespace vkcv::upscaling { m_core(core), m_easuPipeline(), m_rcasPipeline(), - m_easuDescriptorSet(), - m_rcasDescriptorSet(), + m_easuDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), + m_rcasDescriptorSet(m_core.createDescriptorSet(getDescriptorBindings())), m_constants(m_core.createBuffer<FSRConstants>( BufferType::UNIFORM,1, BufferMemoryType::HOST_VISIBLE @@ -81,13 +122,29 @@ namespace vkcv::upscaling { SamplerAddressMode::CLAMP_TO_EDGE )), m_hdr(false), - m_sharpness(0.0f) { + m_sharpness(0/*.875f*/) { vkcv::shader::GLSLCompiler easuCompiler, rcasCompiler; - easuCompiler.setDefine("SAMPLE_SLOW_FALLBACK", "1"); - easuCompiler.setDefine("SAMPLE_EASU", "1"); + const auto& features = m_core.getContext().getPhysicalDevice().getFeatures2(); + const bool float16Support = ( + checkFeatures<vk::PhysicalDeviceFloat16Int8FeaturesKHR>( + reinterpret_cast<const vk::BaseInStructure*>(&features), + vk::StructureType::ePhysicalDeviceShaderFloat16Int8FeaturesKHR, + checkFloat16 + ) && + checkFeatures<vk::PhysicalDevice16BitStorageFeaturesKHR>( + reinterpret_cast<const vk::BaseInStructure*>(&features), + vk::StructureType::ePhysicalDevice16BitStorageFeaturesKHR, + check16Storage + ) + ) || (true); // check doesn't work because chain is empty - rcasCompiler.setDefine("SAMPLE_SLOW_FALLBACK", "1"); + if (!float16Support) { + easuCompiler.setDefine("SAMPLE_SLOW_FALLBACK", "1"); + rcasCompiler.setDefine("SAMPLE_SLOW_FALLBACK", "1"); + } + + easuCompiler.setDefine("SAMPLE_EASU", "1"); rcasCompiler.setDefine("SAMPLE_RCAS", "1"); { @@ -97,13 +154,12 @@ namespace vkcv::upscaling { program.addShader(shaderStage, path); }); - m_easuDescriptorSet = m_core.createDescriptorSet(program.getReflectedDescriptors()[0]); m_easuPipeline = m_core.createComputePipeline(program, { m_core.getDescriptorSet(m_easuDescriptorSet).layout }); DescriptorWrites writes; - writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle()); + writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle(), true); writes.samplerWrites.emplace_back(3, m_sampler); m_core.writeDescriptorSet(m_easuDescriptorSet, writes); @@ -116,13 +172,12 @@ namespace vkcv::upscaling { program.addShader(shaderStage, path); }); - m_rcasDescriptorSet = m_core.createDescriptorSet(program.getReflectedDescriptors()[0]); m_rcasPipeline = m_core.createComputePipeline(program, { m_core.getDescriptorSet(m_rcasDescriptorSet).layout }); DescriptorWrites writes; - writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle()); + writes.uniformBufferWrites.emplace_back(0, m_constants.getHandle(), true); writes.samplerWrites.emplace_back(3, m_sampler); m_core.writeDescriptorSet(m_rcasDescriptorSet, writes); @@ -162,6 +217,7 @@ namespace vkcv::upscaling { ); consts.Sample[0] = (((m_hdr) && (m_sharpness <= +0.0f)) ? 1 : 0); + m_constants.fill(&consts); } @@ -172,7 +228,7 @@ namespace vkcv::upscaling { dispatch[1] = (outputHeight + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; dispatch[2] = 1; - m_core.recordMemoryBarrier(cmdStream); + m_core.recordBufferMemoryBarrier(cmdStream, m_constants.getHandle()); if (m_sharpness > +0.0f) { { @@ -182,6 +238,13 @@ namespace vkcv::upscaling { m_core.writeDescriptorSet(m_easuDescriptorSet, writes); } + { + DescriptorWrites writes; + writes.sampledImageWrites.emplace_back(1, m_intermediateImage); + writes.storageImageWrites.emplace_back(2, output); + + m_core.writeDescriptorSet(m_rcasDescriptorSet, writes); + } m_core.recordComputeDispatchToCmdStream( cmdStream, @@ -189,36 +252,29 @@ namespace vkcv::upscaling { dispatch, {DescriptorSetUsage(0, m_core.getDescriptorSet( m_easuDescriptorSet - ).vulkanHandle)}, + ).vulkanHandle, { 0 })}, PushConstants(0) ); { FSRConstants consts = {}; - FsrRcasCon(consts.Const0, 1.0f / m_sharpness); + FsrRcasCon(consts.Const0, (1.0f - m_sharpness) * 2.0f); consts.Sample[0] = (m_hdr ? 1 : 0); m_constants.fill(&consts); } + m_core.recordBufferMemoryBarrier(cmdStream, m_constants.getHandle()); m_core.prepareImageForSampling(cmdStream, m_intermediateImage); - { - DescriptorWrites writes; - writes.sampledImageWrites.emplace_back(1, m_intermediateImage); - writes.storageImageWrites.emplace_back(2, output); - - m_core.writeDescriptorSet(m_rcasDescriptorSet, writes); - } - m_core.recordComputeDispatchToCmdStream( cmdStream, m_rcasPipeline, dispatch, {DescriptorSetUsage(0, m_core.getDescriptorSet( m_rcasDescriptorSet - ).vulkanHandle)}, + ).vulkanHandle, { 0 })}, PushConstants(0) ); @@ -238,12 +294,10 @@ namespace vkcv::upscaling { dispatch, {DescriptorSetUsage(0, m_core.getDescriptorSet( m_easuDescriptorSet - ).vulkanHandle)}, + ).vulkanHandle, { 0 })}, PushConstants(0) ); } - - m_core.recordMemoryBarrier(cmdStream); } bool FSRUpscaling::isHdrEnabled() const { @@ -259,7 +313,7 @@ namespace vkcv::upscaling { } void FSRUpscaling::setSharpness(float sharpness) { - m_sharpness = sharpness; + m_sharpness = (sharpness < 0.0f ? 0.0f : (sharpness > 1.0f ? 1.0f : sharpness)); } } diff --git a/projects/particle_simulation/src/BloomAndFlares.cpp b/projects/particle_simulation/src/BloomAndFlares.cpp index 98d53c2a1a2c08d40473858b47aacf34da30f7ed..5961aae664a39dfb9bd597ffa7648c9b67999af4 100644 --- a/projects/particle_simulation/src/BloomAndFlares.cpp +++ b/projects/particle_simulation/src/BloomAndFlares.cpp @@ -263,6 +263,10 @@ void BloomAndFlares::execWholePipeline(const vkcv::CommandStreamHandle &cmdStrea void BloomAndFlares::updateImageDimensions(uint32_t width, uint32_t height) { + if ((width == m_Width) && (height == m_Height)) { + return; + } + m_Width = width; m_Height = height; diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 8d85dd99965797e34182e0f0da6a7e3b52773ea1..f707bb44625ad89c8831507901b03262779a8965 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -28,11 +28,11 @@ int main(int argc, const char** argv) { true ); - bool isFullscreen = false; - int windowedWidthBackup = windowWidth; - int windowedHeightBackup = windowHeight; - int windowedPosXBackup; - int windowedPosYBackup; + bool isFullscreen = false; + uint32_t windowedWidthBackup = windowWidth; + uint32_t windowedHeightBackup = windowHeight; + int windowedPosXBackup; + int windowedPosYBackup; glfwGetWindowPos(window.getWindow(), &windowedPosXBackup, &windowedPosYBackup); window.e_key.add([&](int key, int scancode, int action, int mods) { @@ -86,7 +86,7 @@ int main(int argc, const char** argv) { VK_MAKE_VERSION(0, 0, 1), { vk::QueueFlagBits::eTransfer,vk::QueueFlagBits::eGraphics, vk::QueueFlagBits::eCompute }, {}, - { "VK_KHR_swapchain" } + { "VK_KHR_swapchain", "VK_KHR_shader_float16_int8", "VK_KHR_16bit_storage" } ); vkcv::asset::Scene mesh; @@ -528,6 +528,9 @@ int main(int argc, const char** argv) { vkcv::upscaling::FSRUpscaling upscaling (core); + float fsrFactor = 1.5f; + float rcasSharpness = upscaling.getSharpness(); + vkcv::gui::GUI gui(core, window); glm::vec2 lightAnglesDegree = glm::vec2(90.f, 0.f); @@ -555,24 +558,33 @@ int main(int argc, const char** argv) { if (!core.beginFrame(swapchainWidth, swapchainHeight)) { continue; } + + if (fsrFactor < 1.0f) { + fsrFactor = 1.0f; + } else + if (fsrFactor > 2.0f) { + fsrFactor = 2.0f; + } + + const auto fsrWidth = static_cast<uint32_t>(std::round(static_cast<float>(swapchainWidth) / fsrFactor)); + const auto fsrHeight = static_cast<uint32_t>(std::round(static_cast<float>(swapchainHeight) / fsrFactor)); - if ((swapchainWidth != windowWidth) || ((swapchainHeight != windowHeight))) { - depthBuffer = core.createImage(depthBufferFormat, swapchainWidth, swapchainHeight, 1, false, false, false, msaa).getHandle(); - colorBuffer = core.createImage(colorBufferFormat, swapchainWidth, swapchainHeight, 1, false, colorBufferRequiresStorage, true, msaa).getHandle(); + if ((fsrWidth != windowWidth) || ((fsrHeight != windowHeight))) { + depthBuffer = core.createImage(depthBufferFormat, fsrWidth, fsrHeight, 1, false, false, false, msaa).getHandle(); + colorBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, colorBufferRequiresStorage, true, msaa).getHandle(); if (usingMsaa) { - resolvedColorBuffer = core.createImage(colorBufferFormat, swapchainWidth, swapchainHeight, 1, false, true, true).getHandle(); - } - else { + resolvedColorBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, true, true).getHandle(); + } else { resolvedColorBuffer = colorBuffer; } - swapBuffer = core.createImage(colorBufferFormat, swapchainWidth, swapchainHeight, 1, false, true).getHandle(); - + swapBuffer = core.createImage(colorBufferFormat, fsrWidth, fsrHeight, 1, false, true).getHandle(); + windowWidth = swapchainWidth; windowHeight = swapchainHeight; - - bloomFlares.updateImageDimensions(windowWidth, windowHeight); + + bloomFlares.updateImageDimensions(swapchainWidth, swapchainHeight); } auto end = std::chrono::system_clock::now(); @@ -687,8 +699,8 @@ int main(int argc, const char** argv) { const uint32_t fullscreenLocalGroupSize = 8; const uint32_t fulsscreenDispatchCount[3] = { - static_cast<uint32_t>(glm::ceil(windowWidth / static_cast<float>(fullscreenLocalGroupSize))), - static_cast<uint32_t>(glm::ceil(windowHeight / static_cast<float>(fullscreenLocalGroupSize))), + static_cast<uint32_t>(glm::ceil(fsrWidth / static_cast<float>(fullscreenLocalGroupSize))), + static_cast<uint32_t>(glm::ceil(fsrHeight / static_cast<float>(fullscreenLocalGroupSize))), 1 }; @@ -713,7 +725,7 @@ int main(int argc, const char** argv) { } } - bloomFlares.execWholePipeline(cmdStream, resolvedColorBuffer, windowWidth, windowHeight, + bloomFlares.execWholePipeline(cmdStream, resolvedColorBuffer, fsrWidth, fsrHeight, glm::normalize(cameraManager.getActiveCamera().getFront()) ); @@ -738,7 +750,16 @@ int main(int argc, const char** argv) { core.prepareImageForStorage(cmdStream, swapchainInput); core.prepareImageForSampling(cmdStream, swapBuffer); + + if (fsrFactor <= 1.0f) { + upscaling.setSharpness(0.0f); + } + upscaling.recordUpscaling(cmdStream, swapBuffer, swapchainInput); + + if (fsrFactor <= 1.0f) { + upscaling.setSharpness(rcasSharpness); + } // present and end core.prepareSwapchainImageForPresent(cmdStream); @@ -766,12 +787,16 @@ int main(int argc, const char** argv) { ImGui::DragFloat("Voxelization extent", &voxelizationExtent, 1.f, 0.f); voxelizationExtent = std::max(voxelizationExtent, 1.f); voxelVisualisationMip = std::max(voxelVisualisationMip, 0); - + ImGui::ColorEdit3("Scattering color", &scatteringColor.x); ImGui::DragFloat("Scattering density", &scatteringDensity, 0.0001); ImGui::ColorEdit3("Absorption color", &absorptionColor.x); ImGui::DragFloat("Absorption density", &absorptionDensity, 0.0001); ImGui::DragFloat("Volumetric ambient", &volumetricAmbient, 0.002); + ImGui::DragFloat("FidelityFX FSR Factor", &fsrFactor, 0.01f, 1.0f, 2.0f); + ImGui::DragFloat("RCAS Sharpness", &rcasSharpness, 0.01f, 0.0f, 1.0f); + + upscaling.setSharpness(rcasSharpness); if (ImGui::Button("Reload forward pass")) { diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index 5db50869498600fa8e926c0feff2cb5fda1eb22e..fb863f9d223fc091da924e27ebee4981a2afa110 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -151,7 +151,7 @@ namespace vkcv * @param check The elements to be checked * @return True, if all elements in "check" are supported */ - bool checkSupport(std::vector<const char*>& supported, std::vector<const char*>& check) + bool checkSupport(const std::vector<const char*>& supported, const std::vector<const char*>& check) { for (auto checkElem : check) { bool found = false; @@ -182,9 +182,9 @@ namespace vkcv Context Context::create(const char *applicationName, uint32_t applicationVersion, - std::vector<vk::QueueFlagBits> queueFlags, - std::vector<const char *> instanceExtensions, - std::vector<const char *> deviceExtensions) { + const std::vector<vk::QueueFlagBits>& queueFlags, + const std::vector<const char *>& instanceExtensions, + const std::vector<const char *>& deviceExtensions) { // check for layer support const std::vector<vk::LayerProperties>& layerProperties = vk::enumerateInstanceLayerProperties(); @@ -223,7 +223,7 @@ namespace vkcv // for GLFW: get all required extensions std::vector<const char*> requiredExtensions = getRequiredExtensions(); - instanceExtensions.insert(instanceExtensions.end(), requiredExtensions.begin(), requiredExtensions.end()); + requiredExtensions.insert(requiredExtensions.end(), instanceExtensions.begin(), instanceExtensions.end()); const vk::ApplicationInfo applicationInfo( applicationName, @@ -238,8 +238,8 @@ namespace vkcv &applicationInfo, 0, nullptr, - static_cast<uint32_t>(instanceExtensions.size()), - instanceExtensions.data() + static_cast<uint32_t>(requiredExtensions.size()), + requiredExtensions.data() ); #ifndef NDEBUG @@ -286,13 +286,31 @@ namespace vkcv deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); #endif - + const bool shaderFloat16 = checkSupport(deviceExtensions, { "VK_KHR_shader_float16_int8" }); + const bool storage16bit = checkSupport(deviceExtensions, { "VK_KHR_16bit_storage" }); + // FIXME: check if device feature is supported - vk::PhysicalDeviceFeatures deviceFeatures; - deviceFeatures.fragmentStoresAndAtomics = true; - deviceFeatures.geometryShader = true; - deviceFeatures.depthClamp = true; - deviceCreateInfo.pEnabledFeatures = &deviceFeatures; + vk::PhysicalDeviceShaderFloat16Int8Features deviceShaderFloat16Int8Features; + deviceShaderFloat16Int8Features.shaderFloat16 = shaderFloat16; + + vk::PhysicalDevice16BitStorageFeatures device16BitStorageFeatures; + device16BitStorageFeatures.storageBuffer16BitAccess = storage16bit; + + vk::PhysicalDeviceFeatures2 deviceFeatures2; + deviceFeatures2.features.fragmentStoresAndAtomics = true; + deviceFeatures2.features.geometryShader = true; + deviceFeatures2.features.depthClamp = true; + deviceFeatures2.features.shaderInt16 = true; + + if (shaderFloat16) { + deviceFeatures2.setPNext(&deviceShaderFloat16Int8Features); + } + + if (storage16bit) { + deviceShaderFloat16Int8Features.setPNext(&device16BitStorageFeatures); + } + + deviceCreateInfo.setPNext(&deviceFeatures2); // Ablauf // qCreateInfos erstellen --> braucht das Device diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index c9da14fbd6ba54b5682e68c4508776da00b1ae6d..a50303bbe64f559ca62dd3d5672d4b6ecadf97e5 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -53,9 +53,9 @@ namespace vkcv Core Core::create(Window &window, const char *applicationName, uint32_t applicationVersion, - std::vector<vk::QueueFlagBits> queueFlags, - std::vector<const char *> instanceExtensions, - std::vector<const char *> deviceExtensions) + const std::vector<vk::QueueFlagBits>& queueFlags, + const std::vector<const char *>& instanceExtensions, + const std::vector<const char *>& deviceExtensions) { Context context = Context::create( applicationName, applicationVersion, @@ -90,8 +90,8 @@ namespace vkcv Core::Core(Context &&context, Window &window, const Swapchain& swapChain, std::vector<vk::ImageView> swapchainImageViews, const CommandResources& commandResources, const SyncResources& syncResources) noexcept : m_Context(std::move(context)), + m_swapchain(swapChain), m_window(window), - m_swapchain(swapChain), m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_DescriptorManager(std::make_unique<DescriptorManager>(m_Context.m_Device)), @@ -118,7 +118,8 @@ namespace vkcv swapchainImageViews, swapChain.getExtent().width, swapChain.getExtent().height, - swapChain.getFormat()); + swapChain.getFormat() + ); } Core::~Core() noexcept { @@ -373,7 +374,8 @@ namespace vkcv pipelineLayout, usage.setLocation, { usage.vulkanHandle }, - {}); + usage.dynamicOffsets + ); } if (pushConstants.getSizePerDrawcall() > 0) { cmdBuffer.pushConstants( diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 07ca97b5ade9b69eed724000d9c7b388818d6725..226cf50817fc347a5c8db5f250b1e0af9a2e4fde 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -105,7 +105,6 @@ namespace vkcv const ImageManager &imageManager, const BufferManager &bufferManager, const SamplerManager &samplerManager) { - vk::DescriptorSet set = m_DescriptorSets[handle.getId()].vulkanHandle; std::vector<vk::DescriptorImageInfo> imageInfos; @@ -165,6 +164,8 @@ namespace vkcv 0, bufferInfos.size(), write.binding, + write.dynamic? + vk::DescriptorType::eUniformBufferDynamic : vk::DescriptorType::eUniformBuffer }; @@ -184,6 +185,8 @@ namespace vkcv 0, bufferInfos.size(), write.binding, + write.dynamic? + vk::DescriptorType::eStorageBufferDynamic : vk::DescriptorType::eStorageBuffer }; @@ -239,8 +242,12 @@ namespace vkcv { case DescriptorType::UNIFORM_BUFFER: return vk::DescriptorType::eUniformBuffer; + case DescriptorType::UNIFORM_BUFFER_DYNAMIC: + return vk::DescriptorType::eUniformBufferDynamic; case DescriptorType::STORAGE_BUFFER: return vk::DescriptorType::eStorageBuffer; + case DescriptorType::STORAGE_BUFFER_DYNAMIC: + return vk::DescriptorType::eStorageBufferDynamic; case DescriptorType::SAMPLER: return vk::DescriptorType::eSampler; case DescriptorType::IMAGE_SAMPLED: diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp index b4891c6be387b817b87f059f4155f5708d4f4710..15e958b0de929e53170324ade27a9b3663a15d6a 100644 --- a/src/vkcv/QueueManager.cpp +++ b/src/vkcv/QueueManager.cpp @@ -27,8 +27,8 @@ namespace vkcv { * @throws std::runtime_error If the requested queues from @p queueFlags are not creatable due to insufficient availability. */ void QueueManager::queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, - std::vector<float> &queuePriorities, - std::vector<vk::QueueFlagBits> &queueFlags, + const std::vector<float> &queuePriorities, + const std::vector<vk::QueueFlagBits> &queueFlags, std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, std::vector<std::pair<int, int>> &queuePairsGraphics, std::vector<std::pair<int, int>> &queuePairsCompute,