From a0b8b66f2b1fab8ee86d0a486a2b0f23ba84986c Mon Sep 17 00:00:00 2001 From: ink-soul Date: Tue, 26 Mar 2024 14:59:23 +0800 Subject: [PATCH] revert --- base/VulkanDevice.hpp | 1 + base/vulkanexamplebase.cpp | 475 ++++++++++++++++--------------------- base/vulkanexamplebase.h | 41 ++-- src/render/render.cpp | 318 +++++++++++++++++++++---- src/render/render.h | 29 +-- 5 files changed, 510 insertions(+), 354 deletions(-) diff --git a/base/VulkanDevice.hpp b/base/VulkanDevice.hpp index e9b45c5..a4bd31c 100644 --- a/base/VulkanDevice.hpp +++ b/base/VulkanDevice.hpp @@ -120,6 +120,7 @@ namespace vks } } + /** * Get the index of a queue family that supports the requested queue flags * diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 8cf50b7..b52fb7b 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -132,7 +132,7 @@ void VulkanExampleBase::prepare() attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachments[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; // This is the frame buffer attachment to where the multisampled image // will be resolved to and which will be presented to the swapchain @@ -143,8 +143,15 @@ void VulkanExampleBase::prepare() attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - + if (settings.headless) + { + attachments[1].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + } + else + { + attachments[1].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } + // Multisampled depth attachment we render to attachments[2].format = depthFormat; attachments[2].samples = settings.sampleCount; @@ -214,30 +221,39 @@ void VulkanExampleBase::prepare() renderPassCI.pDependencies = dependencies.data(); VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass)); } - else { - std::array attachments = {}; + else + { + std::array attachmentDescriptions = {}; // Color attachment - attachments[0].format = swapChain.colorFormat; - attachments[0].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + attachmentDescriptions[0].format = swapChain.colorFormat; + attachmentDescriptions[0].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachmentDescriptions[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentDescriptions[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentDescriptions[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (settings.headless) + { + attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + } + else + { + attachmentDescriptions[0].finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } // Depth attachment - attachments[1].format = depthFormat; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + attachmentDescriptions[1].format = depthFormat; + attachmentDescriptions[1].samples = VK_SAMPLE_COUNT_1_BIT; + attachmentDescriptions[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachmentDescriptions[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentDescriptions[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + attachmentDescriptions[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachmentDescriptions[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + attachmentDescriptions[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; VkAttachmentReference colorReference = {}; colorReference.attachment = 0; colorReference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + VkAttachmentReference depthReference = {}; depthReference.attachment = 1; @@ -275,13 +291,16 @@ void VulkanExampleBase::prepare() VkRenderPassCreateInfo renderPassCI{}; renderPassCI.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassCI.attachmentCount = static_cast(attachments.size()); - renderPassCI.pAttachments = attachments.data(); + renderPassCI.attachmentCount = static_cast(attachmentDescriptions.size()); + renderPassCI.pAttachments = attachmentDescriptions.data(); renderPassCI.subpassCount = 1; renderPassCI.pSubpasses = &subpassDescription; renderPassCI.dependencyCount = static_cast(dependencies.size()); renderPassCI.pDependencies = dependencies.data(); VK_CHECK_RESULT(vkCreateRenderPass(device, &renderPassCI, nullptr, &renderPass)); + + + } /* @@ -299,189 +318,6 @@ void VulkanExampleBase::prepare() void VulkanExampleBase::fileDropped(std::string filename) { } -void VulkanExampleBase::renderFrame() -{ - auto tStart = std::chrono::high_resolution_clock::now(); - - render(); - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = (float)tDiff / 1000.0f; - camera.update(frameTimer); - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) { - lastFPS = static_cast((float)frameCounter * (1000.0f / fpsTimer)); - fpsTimer = 0.0f; - frameCounter = 0; - } -} - -void VulkanExampleBase::renderLoop() -{ - destWidth = width; - destHeight = height; -#if defined(_WIN32) - MSG msg; - bool quitMessageReceived = false; - while (!quitMessageReceived) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - if (msg.message == WM_QUIT) { - quitMessageReceived = true; - break; - } - } - if (!IsIconic(window)) { - renderFrame(); - } - } -#elif defined(VK_USE_PLATFORM_ANDROID_KHR) - while (1) - { - int ident; - int events; - struct android_poll_source* source; - bool destroy = false; - - focused = true; - - while ((ident = ALooper_pollAll(focused ? 0 : -1, NULL, &events, (void**)&source)) >= 0) - { - if (source != NULL) - { - source->process(androidApp, source); - } - if (androidApp->destroyRequested != 0) - { - LOGD("Android app destroy requested"); - destroy = true; - break; - } - } - - // App destruction requested - // Exit loop, example will be destroyed in application main - if (destroy) - { - break; - } - - // Render frame - if (prepared) - { - auto tStart = std::chrono::high_resolution_clock::now(); - render(); - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = tDiff / 1000.0f; - camera.update(frameTimer); - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) - { - lastFPS = (float)frameCounter * (1000.0f / fpsTimer); - fpsTimer = 0.0f; - frameCounter = 0; - } - - // Check gamepad state - const float deadZone = 0.0015f; - // todo : check if gamepad is present - // todo : time based and relative axis positions - if (camera.type != Camera::CameraType::firstperson) - { - // Rotate - if (std::abs(gamePadState.axisLeft.x) > deadZone) { - camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f)); - } - if (std::abs(gamePadState.axisLeft.y) > deadZone) { - camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f)); - } - } else { - camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer); - } - } - } -#elif defined(_DIRECT2DISPLAY) - while (!quit) - { - auto tStart = std::chrono::high_resolution_clock::now(); - render(); - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = tDiff / 1000.0f; - camera.update(frameTimer); - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) - { - lastFPS = (float)frameCounter * (1000.0f / fpsTimer); - fpsTimer = 0.0f; - frameCounter = 0; - } - } -#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) - while (!quit) - { - auto tStart = std::chrono::high_resolution_clock::now(); - - while (wl_display_prepare_read(display) != 0) - wl_display_dispatch_pending(display); - wl_display_flush(display); - wl_display_read_events(display); - wl_display_dispatch_pending(display); - - render(); - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = tDiff / 1000.0f; - camera.update(frameTimer); - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) - { - wl_shell_surface_set_title(shell_surface, title.c_str()); - lastFPS = (float)frameCounter * (1000.0f / fpsTimer); - fpsTimer = 0.0f; - frameCounter = 0; - } - } -#elif defined(VK_USE_PLATFORM_XCB_KHR) - xcb_flush(connection); - while (!quit) - { - auto tStart = std::chrono::high_resolution_clock::now(); - xcb_generic_event_t *event; - while ((event = xcb_poll_for_event(connection))) - { - handleEvent(event); - free(event); - } - render(); - frameCounter++; - auto tEnd = std::chrono::high_resolution_clock::now(); - auto tDiff = std::chrono::duration(tEnd - tStart).count(); - frameTimer = tDiff / 1000.0f; - camera.update(frameTimer); - fpsTimer += (float)tDiff; - if (fpsTimer > 1000.0f) - { - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, - window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, - title.size(), title.c_str()); - lastFPS = (float)frameCounter * (1000.0f / fpsTimer); - fpsTimer = 0.0f; - frameCounter = 0; - } - } -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - [NSApp run]; -#endif - // Flush device to make sure all resources can be freed - vkDeviceWaitIdle(device); -} VulkanExampleBase::VulkanExampleBase() { @@ -539,9 +375,9 @@ VulkanExampleBase::~VulkanExampleBase() for (uint32_t i = 0; i < frameBuffers.size(); i++) { vkDestroyFramebuffer(device, frameBuffers[i], nullptr); } - vkDestroyImageView(device, depthStencil.view, nullptr); - vkDestroyImage(device, depthStencil.image, nullptr); - vkFreeMemory(device, depthStencil.mem, nullptr); + vkDestroyImageView(device, depthAttachment.view, nullptr); + vkDestroyImage(device, depthAttachment.image, nullptr); + vkFreeMemory(device, depthAttachment.memory, nullptr); vkDestroyPipelineCache(device, pipelineCache, nullptr); vkDestroyCommandPool(device, cmdPool, nullptr); if (settings.multiSampling) { @@ -1822,8 +1658,9 @@ void VulkanExampleBase::setupFrameBuffer() imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; imageCI.samples = settings.sampleCount; - imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image)); VkMemoryRequirements memReqs; @@ -1891,65 +1728,140 @@ void VulkanExampleBase::setupFrameBuffer() imageViewCI.subresourceRange.levelCount = 1; imageViewCI.subresourceRange.layerCount = 1; VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &multisampleTarget.depth.view)); + + VkImageCreateInfo image = {}; + image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image.pNext = NULL; + image.imageType = VK_IMAGE_TYPE_2D; + image.format = depthFormat; + image.extent = { width, height, 1 }; + image.mipLevels = 1; + image.arrayLayers = 1; + image.samples = VK_SAMPLE_COUNT_1_BIT; + image.tiling = VK_IMAGE_TILING_OPTIMAL; + image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + image.flags = 0; + + VkMemoryAllocateInfo mem_alloc = {}; + mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + mem_alloc.pNext = NULL; + mem_alloc.allocationSize = 0; + mem_alloc.memoryTypeIndex = 0; + + VkImageViewCreateInfo depthStencilView = {}; + depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + depthStencilView.pNext = NULL; + depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; + depthStencilView.format = depthFormat; + depthStencilView.flags = 0; + depthStencilView.subresourceRange = {}; + depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + depthStencilView.subresourceRange.baseMipLevel = 0; + depthStencilView.subresourceRange.levelCount = 1; + depthStencilView.subresourceRange.baseArrayLayer = 0; + depthStencilView.subresourceRange.layerCount = 1; + + + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image)); + vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs); + mem_alloc.allocationSize = memReqs.size; + mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthAttachment.memory)); + VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 0)); + + depthStencilView.image = depthAttachment.image; + VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthAttachment.view)); + } + else // color attachment when MSAA is no enabled + { + VkFormat colorFormat = VK_FORMAT_B8G8R8A8_SRGB; + VkFormat depthFormat; + vks::tools::getSupportedDepthFormat(physicalDevice, &depthFormat); + + // Color attachment + VkImageCreateInfo image = vks::initializers::imageCreateInfo(); + image.imageType = VK_IMAGE_TYPE_2D; + image.format = colorFormat; + image.extent.width = width; + image.extent.height = height; + image.extent.depth = 1; + image.mipLevels = 1; + image.arrayLayers = 1; + image.samples = VK_SAMPLE_COUNT_1_BIT; + image.tiling = VK_IMAGE_TILING_OPTIMAL; + image.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + + VkMemoryAllocateInfo memAlloc = vks::initializers::memoryAllocateInfo(); + VkMemoryRequirements memReqs; + + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &colorAttachment.image)); + vkGetImageMemoryRequirements(device, colorAttachment.image, &memReqs); + memAlloc.allocationSize = memReqs.size; + memAlloc.memoryTypeIndex = vulkanDevice -> getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &colorAttachment.memory)); + VK_CHECK_RESULT(vkBindImageMemory(device, colorAttachment.image, colorAttachment.memory, 0)); + + VkImageViewCreateInfo colorImageView = vks::initializers::imageViewCreateInfo(); + colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D; + colorImageView.format = colorFormat; + colorImageView.subresourceRange = {}; + colorImageView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + colorImageView.subresourceRange.baseMipLevel = 0; + colorImageView.subresourceRange.levelCount = 1; + colorImageView.subresourceRange.baseArrayLayer = 0; + colorImageView.subresourceRange.layerCount = 1; + colorImageView.image = colorAttachment.image; + VK_CHECK_RESULT(vkCreateImageView(device, &colorImageView, nullptr, &colorAttachment.view)); + + // Depth stencil attachment + image.format = depthFormat; + image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthAttachment.image)); + vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs); + memAlloc.allocationSize = memReqs.size; + memAlloc.memoryTypeIndex = vulkanDevice -> getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &depthAttachment.memory)); + VK_CHECK_RESULT(vkBindImageMemory(device, depthAttachment.image, depthAttachment.memory, 0)); + + VkImageViewCreateInfo depthStencilView = vks::initializers::imageViewCreateInfo(); + depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; + depthStencilView.format = depthFormat; + depthStencilView.flags = 0; + depthStencilView.subresourceRange = {}; + depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT) + depthStencilView.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + depthStencilView.subresourceRange.baseMipLevel = 0; + depthStencilView.subresourceRange.levelCount = 1; + depthStencilView.subresourceRange.baseArrayLayer = 0; + depthStencilView.subresourceRange.layerCount = 1; + depthStencilView.image = depthAttachment.image; + VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthAttachment.view)); } + int i = 0; + if (settings.multiSampling) + { + i = 4; + } + else + { + i = 2; + } - // Depth/Stencil attachment is the same for all frame buffers - - VkImageCreateInfo image = {}; - image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image.pNext = NULL; - image.imageType = VK_IMAGE_TYPE_2D; - image.format = depthFormat; - image.extent = { width, height, 1 }; - image.mipLevels = 1; - image.arrayLayers = 1; - image.samples = VK_SAMPLE_COUNT_1_BIT; - image.tiling = VK_IMAGE_TILING_OPTIMAL; - image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - image.flags = 0; - - VkMemoryAllocateInfo mem_alloc = {}; - mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - mem_alloc.pNext = NULL; - mem_alloc.allocationSize = 0; - mem_alloc.memoryTypeIndex = 0; - - VkImageViewCreateInfo depthStencilView = {}; - depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - depthStencilView.pNext = NULL; - depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; - depthStencilView.format = depthFormat; - depthStencilView.flags = 0; - depthStencilView.subresourceRange = {}; - depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - depthStencilView.subresourceRange.baseMipLevel = 0; - depthStencilView.subresourceRange.levelCount = 1; - depthStencilView.subresourceRange.baseArrayLayer = 0; - depthStencilView.subresourceRange.layerCount = 1; - - VkMemoryRequirements memReqs; - VK_CHECK_RESULT(vkCreateImage(device, &image, nullptr, &depthStencil.image)); - vkGetImageMemoryRequirements(device, depthStencil.image, &memReqs); - mem_alloc.allocationSize = memReqs.size; - mem_alloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device, &mem_alloc, nullptr, &depthStencil.mem)); - VK_CHECK_RESULT(vkBindImageMemory(device, depthStencil.image, depthStencil.mem, 0)); - - depthStencilView.image = depthStencil.image; - VK_CHECK_RESULT(vkCreateImageView(device, &depthStencilView, nullptr, &depthStencil.view)); - - // - - VkImageView attachments[4]; + VkImageView attachments[i]; if (settings.multiSampling) { + attachments[0] = multisampleTarget.color.view; attachments[2] = multisampleTarget.depth.view; - attachments[3] = depthStencil.view; + attachments[3] = depthAttachment.view; } else { - attachments[1] = depthStencil.view; + + attachments[1] = depthAttachment.view; + attachments[0] = colorAttachment.view; } VkFramebufferCreateInfo frameBufferCI{}; @@ -1962,16 +1874,35 @@ void VulkanExampleBase::setupFrameBuffer() frameBufferCI.height = height; frameBufferCI.layers = 1; - // Create frame buffers for every swap chain image - frameBuffers.resize(swapChain.imageCount); - for (uint32_t i = 0; i < frameBuffers.size(); i++) { - if (settings.multiSampling) { - attachments[1] = swapChain.buffers[i].view; + if (settings.headless && ! settings.multiSampling) + { + VkImageView attachments[2]; + attachments[0] = colorAttachment.view; + attachments[1] = depthAttachment.view; + + VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo(); + framebufferCreateInfo.renderPass = renderPass; + framebufferCreateInfo.attachmentCount = 2; + framebufferCreateInfo.pAttachments = attachments; + framebufferCreateInfo.width = width; + framebufferCreateInfo.height = height; + framebufferCreateInfo.layers = 1; + VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffer)); + } + else + { + // Create frame buffers for every swap chain image + frameBuffers.resize(swapChain.imageCount); + for (uint32_t i = 0; i < frameBuffers.size(); i++) { + if (settings.multiSampling) { + attachments[1] = swapChain.buffers[i].view; + } + else { + attachments[0] = swapChain.buffers[i].view; + } + VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i])); } - else { - attachments[0] = swapChain.buffers[i].view; - } - VK_CHECK_RESULT(vkCreateFramebuffer(device, &frameBufferCI, nullptr, &frameBuffers[i])); + } } @@ -1994,9 +1925,9 @@ void VulkanExampleBase::windowResize() vkDestroyImage(device, multisampleTarget.depth.image, nullptr); vkFreeMemory(device, multisampleTarget.depth.memory, nullptr); } - vkDestroyImageView(device, depthStencil.view, nullptr); - vkDestroyImage(device, depthStencil.image, nullptr); - vkFreeMemory(device, depthStencil.mem, nullptr); + vkDestroyImageView(device, depthAttachment.view, nullptr); + vkDestroyImage(device, depthAttachment.image, nullptr); + vkFreeMemory(device, depthAttachment.memory, nullptr); for (uint32_t i = 0; i < frameBuffers.size(); i++) { vkDestroyFramebuffer(device, frameBuffers[i], nullptr); } diff --git a/base/vulkanexamplebase.h b/base/vulkanexamplebase.h index 7e743a6..5725e9a 100644 --- a/base/vulkanexamplebase.h +++ b/base/vulkanexamplebase.h @@ -58,16 +58,7 @@ class VulkanExampleBase { -private: - float fpsTimer = 0.0f; - uint32_t frameCounter = 0; - uint32_t destWidth; - uint32_t destHeight; - bool resizing = false; - void handleMouseMove(int32_t x, int32_t y); - PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback; - PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback; - VkDebugReportCallbackEXT debugReportCallback; +public: struct MultisampleTarget { struct { VkImage image; @@ -80,6 +71,17 @@ private: VkDeviceMemory memory; } depth; } multisampleTarget; + +private: + + uint32_t destWidth; + uint32_t destHeight; + bool resizing = false; + void handleMouseMove(int32_t x, int32_t y); + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback; + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback; + VkDebugReportCallbackEXT debugReportCallback; + protected: VkInstance instance; VkPhysicalDevice physicalDevice; @@ -90,6 +92,7 @@ protected: vks::VulkanDevice *vulkanDevice; VkQueue queue; VkFormat depthFormat; + VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; VkCommandPool cmdPool; VkRenderPass renderPass; std::vectorframeBuffers; @@ -106,25 +109,31 @@ public: bool prepared = false; uint32_t width = 1280; uint32_t height = 720; - float frameTimer = 1.0f; Camera camera; glm::vec2 mousePos; bool paused = false; - uint32_t lastFPS = 0; struct Settings { bool validation = true; bool fullscreen = false; bool vsync = false; bool multiSampling = true; + bool rotateModel = false; + bool enableSaveToImageSequeue = false; + uint32_t outputFrameCount = 50; + bool takeScreenShot = false; + bool headless = true; VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; } settings; - - struct DepthStencil { + + struct FrameBufferAttachment { VkImage image; - VkDeviceMemory mem; + VkDeviceMemory memory; VkImageView view; - } depthStencil; + }; + + FrameBufferAttachment colorAttachment, depthAttachment; + VkFramebuffer framebuffer; struct GamePadState { glm::vec2 axisLeft = glm::vec2(0.0f); diff --git a/src/render/render.cpp b/src/render/render.cpp index 00cddba..da2aa34 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -189,6 +189,9 @@ PlumageRender::PlumageRender() VK_CHECK_RESULT(vkEndCommandBuffer(currentCB)); } + + + } @@ -529,6 +532,7 @@ PlumageRender::PlumageRender() rasterizationStateCI.cullMode = VK_CULL_MODE_BACK_BIT; rasterizationStateCI.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterizationStateCI.lineWidth = 1.0f; + VkPipelineColorBlendAttachmentState blendAttachmentState{}; blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -558,6 +562,10 @@ PlumageRender::PlumageRender() if (settings.multiSampling) { multisampleStateCI.rasterizationSamples = settings.sampleCount; } + else + { + multisampleStateCI.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + } std::vector dynamicStateEnables = { VK_DYNAMIC_STATE_VIEWPORT, @@ -619,9 +627,7 @@ PlumageRender::PlumageRender() pipelineCI.stageCount = static_cast(shaderStages.size()); pipelineCI.pStages = shaderStages.data(); - if (settings.multiSampling) { - multisampleStateCI.rasterizationSamples = settings.sampleCount; - } + // Skybox pipeline (background cube) shaderStages = { @@ -1578,29 +1584,23 @@ PlumageRender::PlumageRender() prepared = true; } - void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue) + void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence) { VkSubmitInfo submitInfo = vks::initializers::submitInfo(); submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &cmdBuffer; - VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo(); - VkFence fence; - VK_CHECK_RESULT(vkCreateFence(device, &fenceInfo, nullptr, &fence)); + VK_CHECK_RESULT(vkResetFences(device, 1, &fence)); VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, fence)); VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); - vkDestroyFence(device, fence, nullptr); + //vkDestroyFence(device, fence, nullptr); } // todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName void PlumageRender::writeImageToFile(std::string filePath) { - - bool surpportBlit = true; - - - char* imageData; // create dst image to copy + VkImageCreateInfo imageCreateInfo(vks::initializers::imageCreateInfo()); imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; @@ -1610,7 +1610,14 @@ PlumageRender::PlumageRender() imageCreateInfo.arrayLayers = 1; imageCreateInfo.mipLevels = 1; imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + if (settings.multiSampling) + { + imageCreateInfo.samples = settings.sampleCount; + } + else + { + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + } imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR; imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; @@ -1623,20 +1630,28 @@ PlumageRender::PlumageRender() VkDeviceMemory dstImageMemory; vkGetImageMemoryRequirements(device, dstImage, &memRequirements); memAllocInfo.allocationSize = memRequirements.size; - memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + memAllocInfo.memoryTypeIndex = vulkanDevice -> getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); // allocate and bind memory VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &dstImageMemory)); VK_CHECK_RESULT(vkBindImageMemory(device, dstImage, dstImageMemory, 0)); // blit image and copy to host visualable memory - VkCommandBufferAllocateInfo cmdBufferAllocInfo; + VkCommandBufferAllocateInfo cmdBufferAllocInfo = vks::initializers::commandBufferAllocateInfo(cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY,1); VkCommandBuffer copyCmd; VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufferAllocInfo, ©Cmd)); VkCommandBufferBeginInfo cmdBufferBeginInfo = vks::initializers::commandBufferBeginInfo(); VK_CHECK_RESULT(vkBeginCommandBuffer(copyCmd, &cmdBufferBeginInfo)); - - vks::tools::insertImageMemoryBarrier(copyCmd, dstImage, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 }); + + vks::tools::insertImageMemoryBarrier(copyCmd, + dstImage, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 }); VkImageCopy imageCopyRegion{}; imageCopyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; @@ -1647,14 +1662,50 @@ PlumageRender::PlumageRender() imageCopyRegion.extent.height = height; imageCopyRegion.extent.depth = 1; - vkCmdCopyImage(copyCmd, offscreen.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageCopyRegion); + VkImage srcImage; + + if (settings.multiSampling) + { + srcImage = multisampleTarget.color.image; + } + else + { + srcImage = colorAttachment.image; + } + + vks::tools::insertImageMemoryBarrier(copyCmd, + srcImage, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VkImageSubresourceRange{ VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1 }); + + vkCmdCopyImage(copyCmd, + srcImage, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dstImage, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, &imageCopyRegion); // transition dst image to general layout for map memory - vks::tools::insertImageMemoryBarrier(copyCmd, dstImage, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}); + vks::tools::insertImageMemoryBarrier(copyCmd, + dstImage, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_MEMORY_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT,0,1,0,1}); VK_CHECK_RESULT(vkEndCommandBuffer(copyCmd)); - submitWork(copyCmd, queue); + submitWork(copyCmd, queue,waitFences[frameIndex]); + + vkDeviceWaitIdle(device); // Get layout of the image VkImageSubresource subResource{}; @@ -1705,7 +1756,7 @@ PlumageRender::PlumageRender() } - void PlumageRender::outputImageSequence() + void PlumageRender::outputImageSequence(uint32_t currentFrame) { std::string deviceFilePath = filePath.outputPath + "/device" + std::to_string(selectedPhysicalDeviceIndex); @@ -1713,33 +1764,34 @@ PlumageRender::PlumageRender() { _mkdir(deviceFilePath.c_str()); } - - for (uint32_t i = 0; i < settings.outputFrameCount; i++) - { - std::string fileName = "/" + std::to_string(i) + "result.pmm"; - std::string outputPath = deviceFilePath + fileName; + std::string fileName = "/" + std::to_string(currentFrame) + "result.pmm"; + std::string outputPath = deviceFilePath + fileName; //std::cout << outputPath << std::endl; - writeImageToFile(outputPath); - } + writeImageToFile(outputPath); + } - uint32_t PlumageRender::getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) + void PlumageRender::renderFrame() { - VkPhysicalDeviceMemoryProperties deviceMemoryProperties; - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); - for (uint32_t i = 0; i < deviceMemoryProperties.memoryTypeCount; i++) - { - if ((typeBits & 1) == 1) - { - if ((deviceMemoryProperties.memoryTypes[i].propertyFlags & properties) == properties) - { - return i; - } - } - typeBits >>= 1; + auto tStart = std::chrono::high_resolution_clock::now(); + + render(); + frameCounter++; + //VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX)); + outputImageSequence(frameCounter); + //VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex])); + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = (float)tDiff / 1000.0f; + camera.update(frameTimer); + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) { + lastFPS = static_cast((float)frameCounter * (1000.0f / fpsTimer)); + fpsTimer = 0.0f; + frameCounter = 0; } - return 0; } + void PlumageRender::render() { @@ -1750,12 +1802,9 @@ PlumageRender::PlumageRender() updateUIOverlay(); //加入写到文件的函数 //swapChainImage = swapChain.images[frameIndex]; - //outputImageSequeue(swapChainImage,filePath.imageSequenceFilePath); - - - VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX)); - VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex])); + //VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX)); + //VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex])); VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphores[frameIndex], ¤tBuffer); if ((acquire == VK_ERROR_OUT_OF_DATE_KHR) || (acquire == VK_SUBOPTIMAL_KHR)) { @@ -1764,7 +1813,6 @@ PlumageRender::PlumageRender() else { VK_CHECK_RESULT(acquire); - } // Update UBOs @@ -1784,8 +1832,10 @@ PlumageRender::PlumageRender() submitInfo.signalSemaphoreCount = 1; submitInfo.pCommandBuffers = &commandBuffers[currentBuffer]; submitInfo.commandBufferCount = 1; + VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex])); VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[frameIndex])); - + VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, MAXINT64)); + //显示队列 VkResult present = swapChain.queuePresent(queue, currentBuffer, renderCompleteSemaphores[frameIndex]); if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) { @@ -1826,6 +1876,174 @@ PlumageRender::PlumageRender() } + void PlumageRender::renderLoop() + { + destWidth = width; + destHeight = height; + + #if defined(_WIN32) + MSG msg; + bool quitMessageReceived = false; + while (!quitMessageReceived) { + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + if (msg.message == WM_QUIT) { + quitMessageReceived = true; + break; + } + } + if (!IsIconic(window)) { + renderFrame(); + } + } + #elif defined(VK_USE_PLATFORM_ANDROID_KHR) + while (1) + { + int ident; + int events; + struct android_poll_source* source; + bool destroy = false; + + focused = true; + + while ((ident = ALooper_pollAll(focused ? 0 : -1, NULL, &events, (void**)&source)) >= 0) + { + if (source != NULL) + { + source->process(androidApp, source); + } + if (androidApp->destroyRequested != 0) + { + LOGD("Android app destroy requested"); + destroy = true; + break; + } + } + + // App destruction requested + // Exit loop, example will be destroyed in application main + if (destroy) + { + break; + } + + // Render frame + if (prepared) + { + auto tStart = std::chrono::high_resolution_clock::now(); + render(); + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera.update(frameTimer); + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + lastFPS = (float)frameCounter * (1000.0f / fpsTimer); + fpsTimer = 0.0f; + frameCounter = 0; + } + + // Check gamepad state + const float deadZone = 0.0015f; + // todo : check if gamepad is present + // todo : time based and relative axis positions + if (camera.type != Camera::CameraType::firstperson) + { + // Rotate + if (std::abs(gamePadState.axisLeft.x) > deadZone) { + camera.rotate(glm::vec3(0.0f, gamePadState.axisLeft.x * 0.5f, 0.0f)); + } + if (std::abs(gamePadState.axisLeft.y) > deadZone) { + camera.rotate(glm::vec3(gamePadState.axisLeft.y * 0.5f, 0.0f, 0.0f)); + } + } + else { + camera.updatePad(gamePadState.axisLeft, gamePadState.axisRight, frameTimer); + } + } + } +#elif defined(_DIRECT2DISPLAY) + while (!quit) + { + auto tStart = std::chrono::high_resolution_clock::now(); + render(); + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera.update(frameTimer); + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + lastFPS = (float)frameCounter * (1000.0f / fpsTimer); + fpsTimer = 0.0f; + frameCounter = 0; + } + } +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + while (!quit) + { + auto tStart = std::chrono::high_resolution_clock::now(); + + while (wl_display_prepare_read(display) != 0) + wl_display_dispatch_pending(display); + wl_display_flush(display); + wl_display_read_events(display); + wl_display_dispatch_pending(display); + + render(); + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera.update(frameTimer); + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + wl_shell_surface_set_title(shell_surface, title.c_str()); + lastFPS = (float)frameCounter * (1000.0f / fpsTimer); + fpsTimer = 0.0f; + frameCounter = 0; + } + } +#elif defined(VK_USE_PLATFORM_XCB_KHR) + xcb_flush(connection); + while (!quit) + { + auto tStart = std::chrono::high_resolution_clock::now(); + xcb_generic_event_t* event; + while ((event = xcb_poll_for_event(connection))) + { + handleEvent(event); + free(event); + } + render(); + frameCounter++; + auto tEnd = std::chrono::high_resolution_clock::now(); + auto tDiff = std::chrono::duration(tEnd - tStart).count(); + frameTimer = tDiff / 1000.0f; + camera.update(frameTimer); + fpsTimer += (float)tDiff; + if (fpsTimer > 1000.0f) + { + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, + window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, + title.size(), title.c_str()); + lastFPS = (float)frameCounter * (1000.0f / fpsTimer); + fpsTimer = 0.0f; + frameCounter = 0; + } + } +#elif defined(VK_USE_PLATFORM_MACOS_MVK) + [NSApp run]; + #endif + // Flush device to make sure all resources can be freed + vkDeviceWaitIdle(device); + } + void PlumageRender::fileDropped(std::string filename) { vkDeviceWaitIdle(device); diff --git a/src/render/render.h b/src/render/render.h index c107dde..07ea87f 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -216,19 +216,6 @@ public: VkDescriptorSet tonemappingDescriptorSet = VK_NULL_HANDLE; }; - struct Settings { - bool validation = true; - bool fullscreen = false; - bool vsync = false; - bool multiSampling = true; - bool rotateModel = true; - bool enableSaveToImageSequeue = false; - uint32_t outputFrameCount = 50; - bool takeScreenShot = false; - - VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT; - } settings; - struct DescriptorSetLayouts { VkDescriptorSetLayout scene; VkDescriptorSetLayout material; @@ -260,6 +247,7 @@ public: glm::vec3 rotation = glm::vec3(75.0f, 40.0f, 0.0f); } lightSource; + //cube map generation @@ -286,7 +274,14 @@ public: } prefilterPushBlock; UI* gui; - + + float frameTimer = 1.0f; + uint32_t lastFPS = 0; + float fpsTimer = 0.0f; + uint32_t frameCounter = 0; + + uint32_t destWidth; + uint32_t destHeight; PlumageRender(); ~PlumageRender() @@ -345,12 +340,14 @@ public: void updateShaderData(); void windowResized(); void prepare(); - void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue); + void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue, VkFence fence); void writeImageToFile(std::string filePath); - void outputImageSequence(); + void outputImageSequence(uint32_t currentFrame); + void renderFrame(); void outputScreenShot(); uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties); virtual void render(); + void renderLoop(); virtual void updateUIOverlay(); virtual void fileDropped(std::string filename); }; \ No newline at end of file