diff --git a/bin/data/config.json b/bin/data/config.json index e434031d..7ffa230c 100644 --- a/bin/data/config.json +++ b/bin/data/config.json @@ -62,7 +62,9 @@ "MessageID = 0x609a13b", // UNASSIGNED-CoreValidation-Shader-OutputNotConsumed (from depth-only calls) "MessageID = 0x23e43bb7", // UNASSIGNED-CoreValidation-Shader-InputNotProduced (from depth-only calls) - "MessageID = 0x71500fba" // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup) + "MessageID = 0x71500fba", // VUID-vkDestroyDevice-device-00378 (don't care about a clean cleanup) + "MessageID = 0x7d560045" // VUID-vkCmdPipelineBarrier-dstStageMask-06462 (false positive, pipeline barrier for BLAS) + // "MessageID = 0x9cacd67a" // UNASSIGNED-CoreValidation-DrawState-QueryNotReset (false positive) // "MessageID = 0xe91b58a0" // VUID-vkCmdDrawIndexed-None-02686 (?) @@ -98,10 +100,10 @@ "pipelines": { "vsync": false, "hdr": false, - "vxgi": true, + "vxgi": false, "culling": true, "bloom": false, - "rt": true + "rt": false }, "formats": { "depth": "D32_SFLOAT", @@ -123,12 +125,24 @@ "fragmentStoresAndAtomics", "geometryShader", "multiViewport", - "shaderOutputLayer", "shaderInt64", "shaderFloat64", "shaderSubgroupClock", "shaderSampledImageArrayDynamicIndexing", - "shaderStorageImageArrayDynamicIndexing" + "shaderStorageImageArrayDynamicIndexing", + // 1.2 features + "descriptorIndexing", + + "shaderOutputViewportIndex", + "shaderOutputLayer", + + "shaderSampledImageArrayNonUniformIndexing", + "shaderStorageImageArrayNonUniformIndexing", + "runtimeDescriptorArray", + "descriptorBindingVariableDescriptorCount", + + "hostQueryReset", + "bufferDeviceAddress" ], "extensions": { "instance": [ diff --git a/bin/data/shaders/display/subpass.h b/bin/data/shaders/display/subpass.h index 8704ee5f..d876bbf2 100644 --- a/bin/data/shaders/display/subpass.h +++ b/bin/data/shaders/display/subpass.h @@ -9,6 +9,10 @@ #define MAX_TEXTURES TEXTURES //#define TEXTURE_WORKAROUND 0 +#define BUFFER_REFERENCE 1 +#define UINT64_ENABLED 1 + + #include "../common/macros.h" layout (constant_id = 0) const uint TEXTURES = 512; @@ -201,6 +205,12 @@ void populateSurface() { const Instance instance = instances[instanceID]; surface.instance = instance; + { + const InstanceAddresses instanceAddresses = instanceAddresses[instanceID]; + // uint64_t address = (instanceAddresses.vertex[0] << 32) & instanceAddresses.vertex[1]; + Vertices vertices = Vertices(nonuniformEXT(instanceAddresses.vertex)); + } + const Material material = materials[surface.instance.materialID]; surface.material.albedo = material.colorBase; surface.material.metallic = material.factorMetallic; diff --git a/client/client/ext.cpp b/client/client/ext.cpp index c865b3d7..3cecf74c 100644 --- a/client/client/ext.cpp +++ b/client/client/ext.cpp @@ -50,6 +50,9 @@ void client::initialize() { // Miscellaneous client::window.setVisible(client::config["window"]["visible"].as()); client::window.setCursorVisible(client::config["window"]["cursor"]["visible"].as()); + if ( client::config["engine"]["ext"]["imgui"]["enabled"].as() ) { + client::window.setCursorVisible(false); + } client::window.setKeyRepeatEnabled(client::config["window"]["keyboard"]["repeat"].as()); // client::window.centerWindow(); // client::window.setPosition({0, 0}); @@ -67,7 +70,11 @@ void client::initialize() { /* Initialize hooks */ { uf::hooks.addHook( "window:Mouse.CursorVisibility", [&]( pod::payloads::windowMouseCursorVisibility& payload ){ - client::window.setCursorVisible(payload.mouse.visible); + if ( !client::config["engine"]["ext"]["imgui"]["enabled"].as() ) { + client::window.setCursorVisible(payload.mouse.visible); + } else { + client::window.setCursorVisible(false); + } client::window.setMouseGrabbed(!payload.mouse.visible); client::config["mouse"]["visible"] = payload.mouse.visible; client::config["window"]["mouse"]["center"] = !payload.mouse.visible; @@ -131,6 +138,7 @@ void client::tick() { auto current = client::window.getMousePosition(); auto center = client::window.getSize() / 2.0f; client::window.setMousePosition(client::window.getSize() / 2.0f); + client::window.setCursorVisible(false); uf::hooks.call("window:Mouse.Moved", pod::payloads::windowMouseMoved{ { diff --git a/engine/inc/uf/ext/vulkan/graphic.h b/engine/inc/uf/ext/vulkan/graphic.h index 06108934..b9254cbd 100644 --- a/engine/inc/uf/ext/vulkan/graphic.h +++ b/engine/inc/uf/ext/vulkan/graphic.h @@ -86,8 +86,8 @@ namespace ext { } metadata; struct { - uf::renderer::AccelerationStructure top; uf::stl::vector bottoms; + uf::stl::vector tops; } accelerationStructures; ~Graphic(); diff --git a/engine/src/ext/imgui/imgui.cpp b/engine/src/ext/imgui/imgui.cpp index 0a8ba0fc..e1ec7e4d 100644 --- a/engine/src/ext/imgui/imgui.cpp +++ b/engine/src/ext/imgui/imgui.cpp @@ -17,6 +17,7 @@ #include #include +#include namespace { #if UF_USE_VULKAN @@ -33,6 +34,9 @@ namespace { bool AutoScroll; bool ScrollToBottom; + pod::Vector2ui size{640, 480}; + pod::Vector2ui position{32, 32}; + ConsoleWindow() { ClearLog(); memset(InputBuf, 0, sizeof(InputBuf)); @@ -104,7 +108,8 @@ namespace { } void Draw(const char *title, bool *p_open) { - ImGui::SetNextWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(size.x, size.y), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(position.x, position.y), ImGuiCond_FirstUseEver); if (!ImGui::Begin(title, p_open)) { ImGui::End(); return; @@ -396,15 +401,17 @@ void ext::imgui::initialize() { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; // +// io.ConfigFlags |= ImGuiConfigFlags_NoMouse; // io.DisplaySize = ImVec2(uf::renderer::settings::width,uf::renderer::settings::height); + io.MouseDrawCursor = false; io.IniFilename = NULL; -/* - uf::hooks.addHook("system:Console.Log", [&]( const pod::payloads::Log& payload){ - ext::imgui::log( payload.message ); + + uf::hooks.addHook( "window:Mouse.CursorVisibility", [&]( pod::payloads::windowMouseCursorVisibility& payload ){ + io.MouseDrawCursor = payload.mouse.visible; }); -*/ #if UF_ENV_WINDOWS ImGui_ImplWin32_Init(uf::renderer::device.window->getHandle()); diff --git a/engine/src/ext/vulkan/device.cpp b/engine/src/ext/vulkan/device.cpp index 4660e209..3feed137 100644 --- a/engine/src/ext/vulkan/device.cpp +++ b/engine/src/ext/vulkan/device.cpp @@ -375,6 +375,141 @@ namespace { return json; } + + void enableRequestedDeviceFeatures12( VkPhysicalDeviceVulkan12Features& features, VkPhysicalDeviceVulkan12Features& enabledFeatures ) { + ext::json::Value json; + + #define CHECK_FEATURE( NAME )\ + if ( feature == #NAME ) {\ + if ( features.NAME == VK_TRUE ) {\ + enabledFeatures.NAME = true;\ + UF_MSG_VALIDATION("Enabled feature: {}", feature);\ + } else UF_MSG_VALIDATION("Failed to enable feature: {}", feature);\ + } + + for ( auto& feature : ext::vulkan::settings::requestedDeviceFeatures ) { + CHECK_FEATURE(samplerMirrorClampToEdge); + CHECK_FEATURE(drawIndirectCount); + CHECK_FEATURE(storageBuffer8BitAccess); + CHECK_FEATURE(uniformAndStorageBuffer8BitAccess); + CHECK_FEATURE(storagePushConstant8); + CHECK_FEATURE(shaderBufferInt64Atomics); + CHECK_FEATURE(shaderSharedInt64Atomics); + CHECK_FEATURE(shaderFloat16); + CHECK_FEATURE(shaderInt8); + CHECK_FEATURE(descriptorIndexing); + CHECK_FEATURE(shaderInputAttachmentArrayDynamicIndexing); + CHECK_FEATURE(shaderUniformTexelBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderStorageTexelBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderUniformBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderSampledImageArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageImageArrayNonUniformIndexing); + CHECK_FEATURE(shaderInputAttachmentArrayNonUniformIndexing); + CHECK_FEATURE(shaderUniformTexelBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageTexelBufferArrayNonUniformIndexing); + CHECK_FEATURE(descriptorBindingUniformBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingSampledImageUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageImageUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingUniformTexelBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageTexelBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingUpdateUnusedWhilePending); + CHECK_FEATURE(descriptorBindingPartiallyBound); + CHECK_FEATURE(descriptorBindingVariableDescriptorCount); + CHECK_FEATURE(runtimeDescriptorArray); + CHECK_FEATURE(samplerFilterMinmax); + CHECK_FEATURE(scalarBlockLayout); + CHECK_FEATURE(imagelessFramebuffer); + CHECK_FEATURE(uniformBufferStandardLayout); + CHECK_FEATURE(shaderSubgroupExtendedTypes); + CHECK_FEATURE(separateDepthStencilLayouts); + CHECK_FEATURE(hostQueryReset); + CHECK_FEATURE(timelineSemaphore); + CHECK_FEATURE(bufferDeviceAddress); + CHECK_FEATURE(bufferDeviceAddressCaptureReplay); + CHECK_FEATURE(bufferDeviceAddressMultiDevice); + CHECK_FEATURE(vulkanMemoryModel); + CHECK_FEATURE(vulkanMemoryModelDeviceScope); + CHECK_FEATURE(vulkanMemoryModelAvailabilityVisibilityChains); + CHECK_FEATURE(shaderOutputViewportIndex); + CHECK_FEATURE(shaderOutputLayer); + CHECK_FEATURE(subgroupBroadcastDynamicId); + } + #undef CHECK_FEATURE + + #define CHECK_FEATURE2( NAME )\ + if ( feature == #NAME ) {\ + if ( device.features2.NAME == VK_TRUE ) {\ + device.enabledFeatures2.NAME = true;\ + UF_MSG_VALIDATION("Enabled feature: {}", feature);\ + } else UF_MSG_VALIDATION("Failed to enable feature: {}", feature);\ + } + #undef CHECK_FEATURE2 + } + ext::json::Value retrieveDeviceFeatures12( ext::vulkan::Device& device, VkPhysicalDeviceVulkan12Features& features, VkPhysicalDeviceVulkan12Features& enabledFeatures ) { + ext::json::Value json; + + #define CHECK_FEATURE( NAME )\ + json[#NAME]["supported"] = features.NAME;\ + json[#NAME]["enabled"] = enabledFeatures.NAME; + + CHECK_FEATURE(samplerMirrorClampToEdge); + CHECK_FEATURE(drawIndirectCount); + CHECK_FEATURE(storageBuffer8BitAccess); + CHECK_FEATURE(uniformAndStorageBuffer8BitAccess); + CHECK_FEATURE(storagePushConstant8); + CHECK_FEATURE(shaderBufferInt64Atomics); + CHECK_FEATURE(shaderSharedInt64Atomics); + CHECK_FEATURE(shaderFloat16); + CHECK_FEATURE(shaderInt8); + CHECK_FEATURE(descriptorIndexing); + CHECK_FEATURE(shaderInputAttachmentArrayDynamicIndexing); + CHECK_FEATURE(shaderUniformTexelBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderStorageTexelBufferArrayDynamicIndexing); + CHECK_FEATURE(shaderUniformBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderSampledImageArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageImageArrayNonUniformIndexing); + CHECK_FEATURE(shaderInputAttachmentArrayNonUniformIndexing); + CHECK_FEATURE(shaderUniformTexelBufferArrayNonUniformIndexing); + CHECK_FEATURE(shaderStorageTexelBufferArrayNonUniformIndexing); + CHECK_FEATURE(descriptorBindingUniformBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingSampledImageUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageImageUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingUniformTexelBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingStorageTexelBufferUpdateAfterBind); + CHECK_FEATURE(descriptorBindingUpdateUnusedWhilePending); + CHECK_FEATURE(descriptorBindingPartiallyBound); + CHECK_FEATURE(descriptorBindingVariableDescriptorCount); + CHECK_FEATURE(runtimeDescriptorArray); + CHECK_FEATURE(samplerFilterMinmax); + CHECK_FEATURE(scalarBlockLayout); + CHECK_FEATURE(imagelessFramebuffer); + CHECK_FEATURE(uniformBufferStandardLayout); + CHECK_FEATURE(shaderSubgroupExtendedTypes); + CHECK_FEATURE(separateDepthStencilLayouts); + CHECK_FEATURE(hostQueryReset); + CHECK_FEATURE(timelineSemaphore); + CHECK_FEATURE(bufferDeviceAddress); + CHECK_FEATURE(bufferDeviceAddressCaptureReplay); + CHECK_FEATURE(bufferDeviceAddressMultiDevice); + CHECK_FEATURE(vulkanMemoryModel); + CHECK_FEATURE(vulkanMemoryModelDeviceScope); + CHECK_FEATURE(vulkanMemoryModelAvailabilityVisibilityChains); + CHECK_FEATURE(shaderOutputViewportIndex); + CHECK_FEATURE(shaderOutputLayer); + CHECK_FEATURE(subgroupBroadcastDynamicId); + #undef CHECK_FEATURE + + #define CHECK_FEATURE2( NAME )\ + json[#NAME]["supported"] = device.features2.NAME;\ + json[#NAME]["enabled"] = device.enabledFeatures2.NAME; + #undef CHECK_FEATURE2 + + return json; + } } uint32_t ext::vulkan::Device::getQueueFamilyIndex( VkQueueFlagBits queueFlags ) { @@ -903,19 +1038,36 @@ void ext::vulkan::Device::initialize() { } VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{}; - VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{}; + VkPhysicalDeviceVulkan12Features physicalDeviceVulkan12Features{}; + // VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures{}; + // VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddresFeatures{}; VkPhysicalDeviceShaderDrawParametersFeatures shaderDrawParametersFeatures{}; VkPhysicalDeviceRobustness2FeaturesEXT robustnessFeatures{}; - VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddresFeatures{}; VkPhysicalDeviceRayTracingPipelineFeaturesKHR rayTracingPipelineFeatures{}; VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{}; VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures{}; VkPhysicalDeviceShaderClockFeaturesKHR shaderClockFeatures{}; + VkPhysicalDeviceVulkan12Features enabledPhysicalDeviceVulkan12Features{}; + VkPhysicalDeviceFeatures2 enabledDeviceFeatures2{}; { + enabledPhysicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + + enabledDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + enabledDeviceFeatures2.pNext = &enabledPhysicalDeviceVulkan12Features; + + vkGetPhysicalDeviceFeatures2(device.physicalDevice, &enabledDeviceFeatures2); + } + { physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; physicalDeviceFeatures2.features = enabledFeatures; } + { + + physicalDeviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + enableRequestedDeviceFeatures12( enabledPhysicalDeviceVulkan12Features, physicalDeviceVulkan12Features ); + } + /* { descriptorIndexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; descriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing = VK_TRUE; @@ -923,6 +1075,11 @@ void ext::vulkan::Device::initialize() { descriptorIndexingFeatures.runtimeDescriptorArray = VK_TRUE; descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount = VK_TRUE; } + { + bufferDeviceAddresFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; + bufferDeviceAddresFeatures.bufferDeviceAddress = VK_TRUE; + } + */ { shaderDrawParametersFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; shaderDrawParametersFeatures.shaderDrawParameters = VK_TRUE; @@ -931,10 +1088,6 @@ void ext::vulkan::Device::initialize() { robustnessFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; robustnessFeatures.nullDescriptor = VK_TRUE; } - { - bufferDeviceAddresFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; - bufferDeviceAddresFeatures.bufferDeviceAddress = VK_TRUE; - } { rayTracingPipelineFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR; rayTracingPipelineFeatures.rayTracingPipeline = VK_TRUE; @@ -955,11 +1108,12 @@ void ext::vulkan::Device::initialize() { } deviceCreateInfo.pNext = &physicalDeviceFeatures2; - physicalDeviceFeatures2.pNext = &descriptorIndexingFeatures; - descriptorIndexingFeatures.pNext = &shaderDrawParametersFeatures; + physicalDeviceFeatures2.pNext = &physicalDeviceVulkan12Features; + physicalDeviceVulkan12Features.pNext = &shaderDrawParametersFeatures; + // descriptorIndexingFeatures.pNext = &bufferDeviceAddresFeatures; + // bufferDeviceAddresFeatures.pNext = &shaderDrawParametersFeatures; shaderDrawParametersFeatures.pNext = &robustnessFeatures; - robustnessFeatures.pNext = &bufferDeviceAddresFeatures; - bufferDeviceAddresFeatures.pNext = &rayTracingPipelineFeatures; + robustnessFeatures.pNext = &rayTracingPipelineFeatures; rayTracingPipelineFeatures.pNext = &rayQueryFeatures; rayQueryFeatures.pNext = &accelerationStructureFeatures; accelerationStructureFeatures.pNext = &shaderClockFeatures; diff --git a/engine/src/ext/vulkan/graphic.cpp b/engine/src/ext/vulkan/graphic.cpp index 51382c59..74f0ade0 100644 --- a/engine/src/ext/vulkan/graphic.cpp +++ b/engine/src/ext/vulkan/graphic.cpp @@ -545,7 +545,7 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip auto& descriptorAccelerationStructureInfo = accelerationStructureInfos.emplace_back(); descriptorAccelerationStructureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; descriptorAccelerationStructureInfo.accelerationStructureCount = 1; - descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.top.handle; + descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.tops[0].handle; } */ @@ -592,12 +592,15 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip else infos.image.emplace_back(Texture2D::empty.descriptor); } - infos.accelerationStructure.emplace_back(graphic.accelerationStructures.top.buffer.descriptor); + if ( !graphic.accelerationStructures.tops.empty() ) { + infos.accelerationStructure.emplace_back(graphic.accelerationStructures.tops[0].buffer.descriptor); + } + for ( auto& info : infos.accelerationStructure ) { auto& descriptorAccelerationStructureInfo = infos.accelerationStructureInfos.emplace_back(); descriptorAccelerationStructureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; descriptorAccelerationStructureInfo.accelerationStructureCount = 1; - descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.top.handle; + descriptorAccelerationStructureInfo.pAccelerationStructures = &graphic.accelerationStructures.tops[infos.accelerationStructureInfos.size()-1].handle; } auto uniformBufferInfo = infos.uniform.begin(); @@ -958,6 +961,8 @@ void ext::vulkan::Graphic::initialize( const uf::stl::string& renderModeName ) { material.initialize( *device ); ext::vulkan::Buffers::initialize( *device ); + + if ( this->accelerationStructures.tops.empty() ) this->accelerationStructures.tops.resize(2); } void ext::vulkan::Graphic::initializePipeline() { initializePipeline( this->descriptor, false ); @@ -1420,6 +1425,7 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { this->buffers[blasBufferIndex].swap(oldBuffer); size_t blasBufferOffset{}; + VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE); for ( auto& blasData : blasDatas ) { blasData.as.buffer = this->buffers[blasBufferIndex].alias(); blasData.as.buffer.descriptor.offset = blasBufferOffset; @@ -1443,10 +1449,9 @@ void ext::vulkan::Graphic::generateBottomAccelerationStructures() { copyInfo.dst = blasData.as.handle; copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR; - VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE); uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, ©Info); - device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE); } + device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE); oldBuffer.destroy(); } @@ -1463,7 +1468,7 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect auto& device = *this->device; bool rebuild = false; - bool update = this->accelerationStructures.top.handle != VK_NULL_HANDLE; + bool update = this->accelerationStructures.tops[0].handle != VK_NULL_HANDLE; bool shouldCompact = false; VkPhysicalDeviceAccelerationStructurePropertiesKHR acclerationStructureProperties{}; @@ -1512,27 +1517,35 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect size_t instanceIndex{}; size_t tlasBufferIndex{}; + size_t tlasBackBufferIndex{}; + if ( !update ) { // do not stage, because apparently vkQueueWaitIdle doesn't actually wait for the transfer to complete instanceIndex = this->initializeBuffer( (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, false ); - this->metadata.buffers["tlasInstance"] = instanceIndex; } else { if ( this->metadata.buffers.count("tlasInstance") > 0 ) { instanceIndex = this->metadata.buffers["tlasInstance"]; - } else for ( int i = 0; i < buffers.size(); ++i ) { - if ( !(this->buffers[i].usage & (uf::renderer::enums::Buffer::ADDRESS | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR)) ) continue; - instanceIndex = i; - break; - } + } else UF_EXCEPTION("Buffers not found: {}", "tlasInstance"); rebuild = rebuild || this->updateBuffer( (const void*) instancesVK.data(), instancesVK.size() * sizeof(VkAccelerationStructureInstanceKHR), instanceIndex, false ); } size_t instanceBufferAddress = this->buffers[instanceIndex].getAddress(); - auto& tlas = this->accelerationStructures.top; + // have a front-and-back TLAS (buffer) + // provides zero benefit so far +#define TLAS_FRONT_AND_BACK 0 + +#if TLAS_FRONT_AND_BACK + rebuild = true; + auto& tlasBack = this->accelerationStructures.tops[0]; + auto& tlas = this->accelerationStructures.tops[1]; +#else + auto& tlas = this->accelerationStructures.tops[0]; +#endif + { VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR; if ( shouldCompact ) flags |= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR; @@ -1565,35 +1578,58 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect // create BLAS buffer and handle auto tlasBufferUsageFlags = uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS; if ( !update ) { - const size_t EXTRANEOUS_SIZE = 1024 * 1024; + const size_t EXTRANEOUS_SIZE = 1024 * 1024; // oversize, to avoid having to constantly resize size_t bufferSize = MAX( sizeInfo.accelerationStructureSize, EXTRANEOUS_SIZE ); tlasBufferIndex = this->initializeBuffer( NULL, bufferSize, tlasBufferUsageFlags); this->metadata.buffers["tlasBuffer"] = tlasBufferIndex; + #if TLAS_FRONT_AND_BACK + tlasBackBufferIndex = this->initializeBuffer( NULL, bufferSize, tlasBufferUsageFlags); + this->metadata.buffers["tlasBackBuffer"] = tlasBackBufferIndex; + #endif } else { if ( this->metadata.buffers.count("tlasBuffer") > 0 ) { tlasBufferIndex = this->metadata.buffers["tlasBuffer"]; - } else for ( int i = buffers.size() - 1; i >= 0; --i ) { - if ( !(this->buffers[i].usage & tlasBufferUsageFlags) ) continue; - tlasBufferIndex = i; - break; - } + } else UF_EXCEPTION("Buffers not found: {}", "tlasBuffer"); + #if TLAS_FRONT_AND_BACK + if ( this->metadata.buffers.count("tlasBackBuffer") > 0 ) { + tlasBackBufferIndex = this->metadata.buffers["tlasBackBuffer"]; + } else UF_EXCEPTION("Buffers not found: {}", "tlasBackBuffer"); + #endif rebuild = rebuild || this->updateBuffer( NULL, sizeInfo.accelerationStructureSize, tlasBufferIndex ); } - tlas.buffer = this->buffers[tlasBufferIndex].alias(); - + if ( !update ) { + tlas.buffer = this->buffers[tlasBufferIndex].alias(); + #if TLAS_FRONT_AND_BACK + tlasBack.buffer = this->buffers[tlasBackBufferIndex].alias(); + #endif + VkAccelerationStructureCreateInfoKHR createInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR}; createInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; createInfo.size = sizeInfo.accelerationStructureSize; createInfo.buffer = tlas.buffer.buffer; VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlas.handle)); + + #if TLAS_FRONT_AND_BACK + // create back TLAS + createInfo.buffer = tlasBack.buffer.buffer; + VK_CHECK_RESULT(uf::renderer::vkCreateAccelerationStructureKHR(device, &createInfo, nullptr, &tlasBack.handle)); + #endif + } + { VkAccelerationStructureDeviceAddressInfoKHR accelerationDeviceAddressInfo{}; accelerationDeviceAddressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR; accelerationDeviceAddressInfo.accelerationStructure = tlas.handle; tlas.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo); + + #if TLAS_FRONT_AND_BACK + // create back TLAS + accelerationDeviceAddressInfo.accelerationStructure = tlasBack.handle; + tlasBack.deviceAddress = uf::renderer::vkGetAccelerationStructureDeviceAddressKHR(device, &accelerationDeviceAddressInfo); + #endif } // write to TLAS @@ -1627,6 +1663,19 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE); } +#if TLAS_FRONT_AND_BACK + if ( !update ) { + VkCopyAccelerationStructureInfoKHR copyInfo{VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR}; + copyInfo.src = tlas.handle; + copyInfo.dst = tlasBack.handle; + copyInfo.mode = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR; + + VkCommandBuffer commandBuffer = device.createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, uf::renderer::Device::QueueEnum::COMPUTE); + uf::renderer::vkCmdCopyAccelerationStructureKHR(commandBuffer, ©Info); + device.flushCommandBuffer(commandBuffer, uf::renderer::Device::QueueEnum::COMPUTE); + } +#endif + // compact if ( queryPool ) { VkDeviceSize compactSize{}; @@ -1669,12 +1718,18 @@ void ext::vulkan::Graphic::generateTopAccelerationStructure( const uf::stl::vect oldBuffer.destroy(); } + // swap from back to front +#if TLAS_FRONT_AND_BACK + std::swap( tlas, tlasBack ); +// UF_MSG_DEBUG("{} {}", tlas.deviceAddress, tlasBack.deviceAddress); +#endif + if ( queryPool ) vkDestroyQueryPool(device, queryPool, nullptr); if ( rebuild ) { - // uf::renderer::states::rebuild = true; auto& renderMode = ext::vulkan::getRenderMode( descriptor.renderMode, true ); renderMode.rebuild = true; + // uf::renderer::states::rebuild = true; } @@ -1873,11 +1928,16 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicD } } void ext::vulkan::Graphic::destroy() { - for ( auto& as : accelerationStructures.bottoms ) { - uf::renderer::vkDestroyAccelerationStructureKHR(*device, as.handle, nullptr); - } - if ( accelerationStructures.top.handle ) { - uf::renderer::vkDestroyAccelerationStructureKHR(*device, accelerationStructures.top.handle, nullptr); + if ( device ) { + for ( auto& as : accelerationStructures.bottoms ) { + uf::renderer::vkDestroyAccelerationStructureKHR(*device, as.handle, nullptr); + } + accelerationStructures.bottoms.clear(); + + for ( auto& as : accelerationStructures.tops ) { + uf::renderer::vkDestroyAccelerationStructureKHR(*device, as.handle, nullptr); + } + accelerationStructures.tops.clear(); } for ( auto& pair : pipelines ) pair.second.destroy(); pipelines.clear(); diff --git a/engine/src/ext/vulkan/rendermodes/deferred.cpp b/engine/src/ext/vulkan/rendermodes/deferred.cpp index af551e15..03a09a27 100644 --- a/engine/src/ext/vulkan/rendermodes/deferred.cpp +++ b/engine/src/ext/vulkan/rendermodes/deferred.cpp @@ -251,6 +251,7 @@ void ext::vulkan::DeferredRenderMode::initialize( Device& device ) { }; FOR_ARRAY( settings ) if ( settings[i].first ) fragmentShaderFilename = uf::string::replace( fragmentShaderFilename, "frag", settings[i].second ); } + UF_MSG_DEBUG("Using fragment shader: {}", fragmentShaderFilename); blitter.material.initializeShaders({ {uf::io::resolveURI(vertexShaderFilename), VK_SHADER_STAGE_VERTEX_BIT}, diff --git a/engine/src/ext/vulkan/vulkan.cpp b/engine/src/ext/vulkan/vulkan.cpp index 2171b9fb..460afe49 100644 --- a/engine/src/ext/vulkan/vulkan.cpp +++ b/engine/src/ext/vulkan/vulkan.cpp @@ -257,7 +257,7 @@ void ext::vulkan::initialize() { swapchain.initialize( device ); ext::vulkan::scratchBuffer.alignment = ext::vulkan::settings::scratchBufferAlignment; - ext::vulkan::scratchBuffer.initialize( NULL, ext::vulkan::settings::scratchBufferInitialSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS ); + ext::vulkan::scratchBuffer.initialize( NULL, ext::vulkan::settings::scratchBufferInitialSize, uf::renderer::enums::Buffer::ACCELERATION_STRUCTURE | uf::renderer::enums::Buffer::ADDRESS | uf::renderer::enums::Buffer::STORAGE ); if ( uf::io::exists(uf::io::root + "/textures/missing.png") ) { uf::Image image;