diff --git a/src/application.cpp b/src/application.cpp index a713d07..fd467b0 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -169,9 +169,6 @@ namespace engine { m_window->resetAvgFPS(); } - /* draw */ - gfx()->finishRender(renderData.drawBuffer); - /* poll events */ m_window->getInputAndEvents(); diff --git a/src/gfx_device_vulkan.cpp b/src/gfx_device_vulkan.cpp index 0cd1070..934b063 100644 --- a/src/gfx_device_vulkan.cpp +++ b/src/gfx_device_vulkan.cpp @@ -48,7 +48,7 @@ inline static void checkVulkanError(VkResult errorCode, int lineNo) namespace engine { - static constexpr uint32_t FRAMES_IN_FLIGHT = 1; // This improved FPS by 5x! (on Intel IGPU) + static constexpr uint32_t FRAMES_IN_FLIGHT = 2; // This improved FPS by 5x! (on Intel IGPU) static constexpr size_t PUSH_CONSTANT_MAX_SIZE = 128; // bytes static constexpr VkIndexType INDEX_TYPE = VK_INDEX_TYPE_UINT32; @@ -517,7 +517,7 @@ namespace engine { VKCHECK(res); res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence); VKCHECK(res); -#if 0 + /* perform any pending uniform buffer writes */ VKCHECK(vkResetCommandPool(pimpl->device.device, frameData.transferPool, 0)); @@ -531,11 +531,26 @@ namespace engine { // transfer cmds... - std::vector barriers(pimpl->descriptorBufferWriteQueues[currentFrameIndex].size()); + std::vector barriers{}; for (gfx::DescriptorBuffer* descriptorBuffer : pimpl->descriptorBufferWriteQueues[currentFrameIndex]) { - VkBufferMemoryBarrier& barrier = barriers.emplace_back(); - barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + + VkBufferCopy copyRegion{}; + copyRegion.srcOffset = 0; + copyRegion.dstOffset = 0; + copyRegion.size = descriptorBuffer->stagingBuffer.size; + vkCmdCopyBuffer( + frameData.transferBuf, + descriptorBuffer->stagingBuffer.buffer, + descriptorBuffer->gpuBuffers[currentFrameIndex].buffer, + 1, + ©Region + ); + + VkBufferMemoryBarrier2& barrier = barriers.emplace_back(); + barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2; + barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; + barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; barrier.dstAccessMask = 0; barrier.srcQueueFamilyIndex = pimpl->device.queues.transferQueueFamily; barrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily; @@ -543,14 +558,13 @@ namespace engine { barrier.offset = 0; barrier.size = descriptorBuffer->gpuBuffers[currentFrameIndex].size; } + pimpl->descriptorBufferWriteQueues[currentFrameIndex].clear(); - vkCmdPipelineBarrier(frameData.transferBuf, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, nullptr, - (uint32_t)barriers.size(), barriers.data(), - 0, nullptr - ); + VkDependencyInfo dependencyInfo{}; + dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + dependencyInfo.bufferMemoryBarrierCount = (uint32_t)barriers.size(); + dependencyInfo.pBufferMemoryBarriers = barriers.data(); + vkCmdPipelineBarrier2(frameData.transferBuf, &dependencyInfo); VKCHECK(vkEndCommandBuffer(frameData.transferBuf)); @@ -567,7 +581,7 @@ namespace engine { }; res = vkQueueSubmit(pimpl->device.queues.transferQueues[0], 1, &transferSubmitInfo, VK_NULL_HANDLE); assert(res == VK_SUCCESS); -#endif + uint32_t swapchainImageIndex; do { @@ -600,6 +614,15 @@ namespace engine { { // RECORDING + /* change barriers to perform a queue ownership acquire operation */ + for (VkBufferMemoryBarrier2& barrier : barriers) { + barrier.srcStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; + barrier.srcAccessMask = 0; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; + barrier.dstAccessMask = VK_ACCESS_2_UNIFORM_READ_BIT; + } + vkCmdPipelineBarrier2(frameData.drawBuf, &dependencyInfo); + std::array clearValues{}; // Using same value for all components enables compression according to NVIDIA Best Practices clearValues[0].color.float32[0] = 1.0f; clearValues[0].color.float32[1] = 1.0f; @@ -662,8 +685,8 @@ namespace engine { waitSemaphores.push_back(drawBuffer->frameData.presentSemaphore); waitDstStageMasks.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - //waitSemaphores.push_back(drawBuffer->frameData.transferSemaphore); - //waitDstStageMasks.push_back(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT); + waitSemaphores.push_back(drawBuffer->frameData.transferSemaphore); + waitDstStageMasks.push_back(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT); VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, diff --git a/src/systems/render.cpp b/src/systems/render.cpp index 8fb23d3..874f26b 100644 --- a/src/systems/render.cpp +++ b/src/systems/render.cpp @@ -110,6 +110,9 @@ namespace engine { } } + /* draw */ + m_gfx->finishRender(renderData.drawBuffer); + } void RenderSystem::setCameraEntity(uint32_t entity) diff --git a/src/vulkan/device.cpp b/src/vulkan/device.cpp index 701ef96..1f41b81 100644 --- a/src/vulkan/device.cpp +++ b/src/vulkan/device.cpp @@ -51,10 +51,6 @@ namespace engine { res = vkEnumerateDeviceExtensionProperties(physDev, nullptr, &extensionCount, availableExtensions.data()); assert(res == VK_SUCCESS); - for ([[maybe_unused]] const VkExtensionProperties& ext : availableExtensions) { - LOG_TRACE("extension: {}", ext.extensionName); - } - bool foundRequiredExtensions = true; for (const char* extToFind : requirements.requiredExtensions) { bool extFound = false; @@ -82,9 +78,12 @@ namespace engine { /* check features */ VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures{}; memoryPriorityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; + VkPhysicalDeviceSynchronization2Features synchronization2Features{}; + synchronization2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES; + synchronization2Features.pNext = &memoryPriorityFeatures; VkPhysicalDeviceFeatures2 devFeatures{}; devFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - devFeatures.pNext = &memoryPriorityFeatures; + devFeatures.pNext = &synchronization2Features; vkGetPhysicalDeviceFeatures2(physDev, &devFeatures); { if (requirements.requiredFeatures.robustBufferAccess) @@ -197,6 +196,9 @@ namespace engine { if (devFeatures.features.variableMultisampleRate == VK_FALSE) continue; if (requirements.requiredFeatures.inheritedQueries == VK_TRUE) if (devFeatures.features.inheritedQueries == VK_FALSE) continue; + + /* ensure synchronization 2 is found */ + if (synchronization2Features.synchronization2 == VK_FALSE) continue; /* check the memory priority extension was even requested */ bool memoryPriorityRequired = false; @@ -343,12 +345,16 @@ namespace engine { } /* set enabled features */ - VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeaturesToEnable{}; - memoryPriorityFeaturesToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; - memoryPriorityFeaturesToEnable.memoryPriority = d.memoryPriorityFeature ? VK_TRUE : VK_FALSE; + VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures{}; + memoryPriorityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; + memoryPriorityFeatures.memoryPriority = d.memoryPriorityFeature ? VK_TRUE : VK_FALSE; + VkPhysicalDeviceSynchronization2Features synchronization2Features{}; + synchronization2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES; + synchronization2Features.pNext = &memoryPriorityFeatures; + synchronization2Features.synchronization2 = VK_TRUE; VkPhysicalDeviceFeatures2 featuresToEnable{}; featuresToEnable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - featuresToEnable.pNext = &memoryPriorityFeaturesToEnable; + featuresToEnable.pNext = &synchronization2Features; featuresToEnable.features = requirements.requiredFeatures; /* get list of extensions to enable */ diff --git a/src/vulkan/swapchain.cpp b/src/vulkan/swapchain.cpp index 1b8b7a5..adbb386 100644 --- a/src/vulkan/swapchain.cpp +++ b/src/vulkan/swapchain.cpp @@ -183,9 +183,9 @@ namespace engine { // Depth buffer .srcSubpass = VK_SUBPASS_EXTERNAL, .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + .srcStageMask = VK_PIPELINE_STAGE_NONE, .dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .srcAccessMask = 0, .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dependencyFlags = 0, }, @@ -193,7 +193,7 @@ namespace engine { // Image Layout Transition .srcSubpass = VK_SUBPASS_EXTERNAL, .dstSubpass = 0, - .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + .srcStageMask = VK_PIPELINE_STAGE_NONE, .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .srcAccessMask = 0, .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, diff --git a/test/src/camera_controller.cpp b/test/src/camera_controller.cpp index 6348fe9..dde09c4 100644 --- a/test/src/camera_controller.cpp +++ b/test/src/camera_controller.cpp @@ -3,6 +3,7 @@ #include "application.hpp" #include "window.hpp" #include "input_manager.hpp" +#include "scene_manager.hpp" #include "scene.hpp" #include "components/transform.hpp" @@ -157,6 +158,11 @@ void CameraControllerSystem::onUpdate(float ts) LOG_INFO("position: " + pos_string); } + if (m_scene->app()->window()->getKeyPress(engine::inputs::Key::K_R)) { + t->position = { 0.0f, 5.0f, 0.0f }; + c->dy = 0.0f; + } + if (m_scene->app()->inputManager()->getButtonPress("fullscreen")) { m_scene->app()->window()->toggleFullscreen(); } diff --git a/test/src/game.cpp b/test/src/game.cpp index 43b311d..839e8b6 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -56,7 +56,7 @@ void playGame(GameSettings settings) app.setFrameLimiter(settings.enableFrameLimiter); // configure window - app.window()->setRelativeMouseMode(true); + //app.window()->setRelativeMouseMode(true); configureInputs(app.inputManager()); @@ -112,7 +112,7 @@ void playGame(GameSettings settings) /* cube */ { uint32_t cube = myScene->createEntity("cube"); - myScene->getComponent(cube)->position = glm::vec3{ -0.5f, -0.5f + 5.0f, -0.5f }; + myScene->getComponent(cube)->position = glm::vec3{ -0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f }; auto cubeRenderable = myScene->addComponent(cube); cubeRenderable->material = std::make_shared(app.getResource("builtin.standard")); cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);