From b9294307a61b577325eee7afea73f95f60636b4a Mon Sep 17 00:00:00 2001 From: ink-soul Date: Mon, 15 Apr 2024 11:32:00 +0800 Subject: [PATCH 1/4] fix instance creation error --- src/CMakeLists.txt | 2 +- src/render/render.cpp | 128 +++++++++++++++++++----------------------- src/render/render.h | 19 +++---- 3 files changed, 67 insertions(+), 82 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f8e21bd..9531ffb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,7 @@ function(buildHomework HOMEWORK_NAME) "render/glTFModel.cpp" "render/renderFoundation.h" "render/renderFoundation.cpp") - target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} glfw ) + target_link_libraries(${HOMEWORK_NAME} base ${Vulkan_LIBRARY} ) else(WIN32) add_executable(${HOMEWORK_NAME} ${MAIN_CPP} ${SOURCE} ${MAIN_HEADER} ${SHADERS_GLSL} ${SHADERS_HLSL} ${README_FILES}) target_link_libraries(${HOMEWORK_NAME} base ) diff --git a/src/render/render.cpp b/src/render/render.cpp index 7915081..d584e6f 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -30,7 +30,7 @@ void PlumageRender::initVulkan() { createInstance(); - createSurface(); + //createSurface(); pickupPhysicalDevice(); } @@ -43,48 +43,42 @@ VkResult PlumageRender::createInstance() throw std::runtime_error("validation layers requsted,but not available"); } - //setup appliaction info - VkApplicationInfo appInfo{}; - + VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = "Hello Triangle"; - appInfo.applicationVersion = VK_API_VERSION_1_0; - appInfo.pEngineName = "No_Engine"; - appInfo.engineVersion = VK_MAKE_API_VERSION(1, 0, 0,0); + appInfo.pApplicationName = name.c_str(); + appInfo.pEngineName = name.c_str(); appInfo.apiVersion = VK_API_VERSION_1_0; - + // setup createInfo VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - auto requiredExtensions = getRequiredExtensions(); - createInfo.enabledExtensionCount = static_cast(requiredExtensions.size()); - createInfo.ppEnabledExtensionNames = requiredExtensions.data(); + + std::vector instanceExtensions = { }; - // enable validation layer if available in createInfo - VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{}; - if (settings.validation) + VkInstanceCreateInfo instanceCreateInfo = {}; + instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instanceCreateInfo.pNext = NULL; + instanceCreateInfo.pApplicationInfo = &appInfo; + + if (instanceExtensions.size() > 0) { - createInfo.enabledLayerCount = static_cast(validationLayers.size()); - createInfo.ppEnabledLayerNames = validationLayers.data(); - - populateDebugMessengerCreateInfo(debugCreateInfo); - createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*)&debugCreateInfo; + if (settings.validation) { + instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + } + instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size(); + instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data(); } - else - { - createInfo.enabledLayerCount = 0; - createInfo.pNext = nullptr; - } - - // throw error in creating instance - if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) - { - throw std::runtime_error("failed to create instance"); - + std::vector validationLayerNames; + if (settings.validation) { + validationLayerNames.push_back("VK_LAYER_KHRONOS_validation"); + instanceCreateInfo.enabledLayerCount = (uint32_t)validationLayerNames.size(); + instanceCreateInfo.ppEnabledLayerNames = validationLayerNames.data(); } + return vkCreateInstance(&instanceCreateInfo, nullptr, &instance); + } bool PlumageRender::checkValidationLayerSupport() @@ -117,7 +111,7 @@ bool PlumageRender::checkValidationLayerSupport() std::vector PlumageRender::getRequiredExtensions() { - + /* uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); @@ -125,8 +119,8 @@ std::vector PlumageRender::getRequiredExtensions() if (settings.headless) { extensions.clear(); - } - + }*/ + std::vector extensions; if (settings.validation) { extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); @@ -140,18 +134,14 @@ std::vector PlumageRender::getRequiredExtensions() void PlumageRender::setupDebugMessager() { - if (!settings.validation) - { - return; - } - - VkDebugUtilsMessengerCreateInfoEXT createInfo{}; - populateDebugMessengerCreateInfo(createInfo); - - - if (CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger) != VK_SUCCESS) - { - throw std::runtime_error("failed to set up debug messenger in setupDebugMessenger"); + if (settings.validation) { + vkCreateDebugReportCallback = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); + vkDestroyDebugReportCallback = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); + VkDebugReportCallbackCreateInfoEXT debugCreateInfo{}; + debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + debugCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugMessageCallback; + debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + VK_CHECK_RESULT(vkCreateDebugReportCallback(instance, &debugCreateInfo, nullptr, &debugReportCallback)); } } @@ -172,7 +162,7 @@ void PlumageRender::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreate VKAPI_ATTR VkBool32 VKAPI_CALL PlumageRender::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) { { - std::cerr << "validation layer: " << pCallbackData->pMessage << "/n" << std::endl; + std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; return VK_FALSE; } @@ -208,11 +198,11 @@ void PlumageRender::createSurface() { return; } - + /* if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) { throw std::runtime_error("failed to create window surface in createSurface()"); - } + }*/ } void PlumageRender::pickupPhysicalDevice() @@ -432,7 +422,7 @@ void PlumageRender::createLogicalDevice() } vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue); - if (settings.headless) + if (!settings.headless) { vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); } @@ -559,7 +549,7 @@ VkExtent2D PlumageRender::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capab else { int width, height; - glfwGetFramebufferSize(window, &width, &height); + //glfwGetFramebufferSize(window, &width, &height); VkExtent2D actualExtent = { static_cast(width), @@ -596,6 +586,7 @@ void PlumageRender::createCommandPool() poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(); + if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) { @@ -1157,11 +1148,13 @@ void PlumageRender::renderLoop() } else { + /* while (!glfwWindowShouldClose(window)) { glfwPollEvents(); drawFrame(); } + */ } vkDeviceWaitIdle(device); } @@ -1205,6 +1198,7 @@ bool PlumageRender::swapChainAcquireNextImage(bool framebuffeerResized, uint32_t void PlumageRender::recreateSwapChain() { + /* int width = 0, height = 0; glfwGetFramebufferSize(window, &width, &height); while (width == 0 || height == 0) @@ -1223,7 +1217,7 @@ void PlumageRender::recreateSwapChain() createSwapChain(); createImageView(); - createFramebuffer(); + createFramebuffer();*/ } void PlumageRender::submitToGraphicQueue(uint32_t frameIndex, uint32_t currentBuffer) @@ -1427,7 +1421,7 @@ void PlumageRender::buildCommandBuffers() } // User interface - gui->draw(currentCB); + //gui->draw(currentCB); vkCmdEndRenderPass(currentCB); VK_CHECK_RESULT(vkEndCommandBuffer(currentCB)); @@ -2773,32 +2767,27 @@ void PlumageRender::updateShaderData() void PlumageRender::initWindow(int Width, int Height) { + /* glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); window = glfwCreateWindow(Width, Height, "vulkan", nullptr, nullptr); glfwSetWindowUserPointer(window, this); glfwSetFramebufferSizeCallback(window, framebufferResizeCallback); + */ } - +/* void PlumageRender::framebufferResizeCallback(GLFWwindow* window, int width, int height) { auto app = reinterpret_cast(glfwGetWindowUserPointer(window)); app->framebufferResized = true; } +*/ -void PlumageRender::windowResized() - { - buildCommandBuffers(); - vkDeviceWaitIdle(device); - updateUniformBuffers(); - //update UI - updateUIOverlay(); - } void PlumageRender::prepare() { - createSwapChain(); + //createSwapChain(); createCommandPool(); @@ -2814,9 +2803,9 @@ void PlumageRender::prepare() waitFences.resize(renderAhead); presentCompleteSemaphores.resize(renderAhead); renderCompleteSemaphores.resize(renderAhead); - commandBuffers.resize(swapChainImages.size()); - uniformBuffers.resize(swapChainImages.size()); - descriptorSets.resize(swapChainImages.size()); + commandBuffers.resize(renderAhead); + uniformBuffers.resize(renderAhead); + descriptorSets.resize(renderAhead); // Command buffer execution fences for (auto& waitFence : waitFences) { VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT }; @@ -2848,8 +2837,8 @@ void PlumageRender::prepare() setupDescriptors(); preparePipelines(); - gui = new UI(vulkanDevice, renderPass, graphicQueue, pipelineCache, settings.sampleCount); - updateUIOverlay(); + //gui = new UI(vulkanDevice, renderPass, graphicQueue, pipelineCache, settings.sampleCount); + //updateUIOverlay(); buildCommandBuffers(); @@ -3236,10 +3225,11 @@ void PlumageRender::render() uint32_t imageIndex; + /* if (settings.headless) { updateUIOverlay(); - } + }*/ //加入写到文件的函数 //swapChainImage = swapChain.images[frameIndex]; diff --git a/src/render/render.h b/src/render/render.h index 5f9b65a..920b6cf 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -12,7 +12,7 @@ #define GLFW_INCLUDE_VULKAN #include - +#include #include #include #include @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include + // #include @@ -46,12 +46,6 @@ - - -#define ENABLE_VALIDATION false - - - class PlumageRender { public: @@ -74,8 +68,9 @@ public: //"VK_EXT_headless_surface" }; - std::string title; + std::string title = "render"; std::string name = "plumage"; + VkInstance instance; Camera camera; VkPhysicalDevice physicalDevice; @@ -159,7 +154,7 @@ public: }chineseUI; - VkInstance instance; + struct UniformBufferSet { Buffer scene; @@ -253,7 +248,7 @@ public: bool vsync = false; // 垂直同步开关 bool multiSampling = true; // 多重采样 bool rotateModel = true; // 模型自旋转(暂时失效) - bool headless = false; // 无头开关 + bool headless = true; // 无头开关 bool outputPNGimage = false; uint32_t endFrameIndex = 75; bool enableSaveToImageSequeue = true; // 图片序列开关(暂时弃用) From 5c80c2b6036b82406bcb4c28c8fd008f8795af66 Mon Sep 17 00:00:00 2001 From: ink-soul Date: Mon, 15 Apr 2024 15:16:57 +0800 Subject: [PATCH 2/4] fix commandPool error --- base/VulkanDevice.hpp | 20 +- src/render/render.cpp | 420 +++++++++--------------------------------- src/render/render.h | 41 ++--- 3 files changed, 104 insertions(+), 377 deletions(-) diff --git a/base/VulkanDevice.hpp b/base/VulkanDevice.hpp index e9b45c5..cd2a9ad 100644 --- a/base/VulkanDevice.hpp +++ b/base/VulkanDevice.hpp @@ -100,24 +100,18 @@ namespace vks */ uint32_t getMemoryType(uint32_t typeBits, VkMemoryPropertyFlags properties, VkBool32 *memTypeFound = nullptr) { - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) { + VkPhysicalDeviceMemoryProperties deviceMemoryProperties; + vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemoryProperties); + for (uint32_t j = 0; j < deviceMemoryProperties.memoryTypeCount; j++) { if ((typeBits & 1) == 1) { - if ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties) { - if (memTypeFound) { - *memTypeFound = true; - } - return i; + if ((deviceMemoryProperties.memoryTypes[j].propertyFlags & properties) == properties) { + return j; } } typeBits >>= 1; } - - if (memTypeFound) { - *memTypeFound = false; - return 0; - } else { - throw std::runtime_error("Could not find a matching memory type"); - } + return 0; + } /** diff --git a/src/render/render.cpp b/src/render/render.cpp index d584e6f..359d1e8 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -30,9 +30,15 @@ void PlumageRender::initVulkan() { createInstance(); + setupDebugMessager(); + //createSurface(); + + pickupPhysicalDevice(); + + createLogicalDevice(); } VkResult PlumageRender::createInstance() @@ -63,14 +69,13 @@ VkResult PlumageRender::createInstance() instanceCreateInfo.pNext = NULL; instanceCreateInfo.pApplicationInfo = &appInfo; - if (instanceExtensions.size() > 0) - { - if (settings.validation) { - instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); - } - instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size(); - instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data(); + if (settings.validation) { + instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); + instanceExtensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } + instanceCreateInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size(); + instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.data(); + std::vector validationLayerNames; if (settings.validation) { validationLayerNames.push_back("VK_LAYER_KHRONOS_validation"); @@ -141,55 +146,28 @@ void PlumageRender::setupDebugMessager() debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; debugCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)debugMessageCallback; debugCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT; + debugCreateInfo.pUserData = NULL; VK_CHECK_RESULT(vkCreateDebugReportCallback(instance, &debugCreateInfo, nullptr, &debugReportCallback)); } } -void PlumageRender::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo) + +VKAPI_ATTR VkBool32 VKAPI_CALL PlumageRender::debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData) { - debugCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - - debugCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - debugCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - debugCreateInfo.pfnUserCallback = &debugCallback; - debugCreateInfo.pUserData = nullptr; -} - -VKAPI_ATTR VkBool32 VKAPI_CALL PlumageRender::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) -{ - { - std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl; - - return VK_FALSE; - } -} - -VkResult PlumageRender::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) -{ - auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); - - if (func != nullptr) - { - return func(instance, pCreateInfo, pAllocator, pDebugMessenger); - } - else - { - return VK_ERROR_EXTENSION_NOT_PRESENT; - } -} - -void PlumageRender::DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) -{ - auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); - - if (func != nullptr) - { - func(instance, debugMessenger, pAllocator); + std::string prefix(""); + if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { + prefix += "ERROR:"; + }; + if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) { + prefix += "WARNING:"; + }; + if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { + prefix += "DEBUG:"; } + std::stringstream debugMessage; + debugMessage << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg; + fflush(stdout); + return VK_FALSE; } void PlumageRender::createSurface() @@ -243,17 +221,6 @@ bool PlumageRender::isDeviceSuitable(VkPhysicalDevice device) bool extensionsSupported = checkDeviceExtensionSupport(device); return extensionsSupported; } - else - { // 非无头下在检查扩展支持的同时要检查swapchain - bool extensionsSupported = checkDeviceExtensionSupport(device); - bool swapChainAdequate = false; - QueueFamilyIndices indices = findQueueFamilies(device); - if (extensionsSupported) - { - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device); - swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty(); - } - } } bool PlumageRender::checkDeviceExtensionSupport(VkPhysicalDevice device) @@ -274,54 +241,7 @@ bool PlumageRender::checkDeviceExtensionSupport(VkPhysicalDevice device) return requiredExtensions.empty(); } -PlumageRender::QueueFamilyIndices PlumageRender::findQueueFamilies(VkPhysicalDevice device) -{ - QueueFamilyIndices indices; - uint32_t queueFamilyCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); - - std::vector queueFamilies(queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); - - VkBool32 presentSupport = false; - - // 检查显示队列支持 - int i = 0; - if (!settings.headless) - { - vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport); - } - - for (const auto& queueFamily : queueFamilies) - { - if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) { - indices.graphicsFamily = i; - } - // 无头下不需要检查present queue - if (settings.headless) - { - if (indices.isGraphicsFamilyComplete()) - { - break; - } - } - else - { - if (indices.isGraphicsFamilyComplete() && indices.isPresentFamilyComplete()) - { - break; - } - } - if (presentSupport) - { - indices.presentFamily = i; - } - i++; - } - - return indices; -} PlumageRender::SwapChainSupportDetails PlumageRender::querySwapChainSupport(VkPhysicalDevice device) { @@ -353,35 +273,20 @@ PlumageRender::SwapChainSupportDetails PlumageRender::querySwapChainSupport(VkPh void PlumageRender::createLogicalDevice() { - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); + std::vector queueCreateInfos; if (settings.headless) { VkDeviceQueueCreateInfo queueCreateInfo{}; queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = indices.graphicsFamily.value(); + queueCreateInfo.queueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics; queueCreateInfo.queueCount = 1; float queuePriority = 1.0f; queueCreateInfo.pQueuePriorities = &queuePriority; queueCreateInfos.push_back(queueCreateInfo); } - else - { - - std::set uniqueQueueFamilies = { indices.graphicsFamily.value(),indices.presentFamily.value() }; - - float queuePriority = 1.0f; - for (uint32_t queueFamily : uniqueQueueFamilies) - { - VkDeviceQueueCreateInfo queueCreateInfo{}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = queueFamily; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &queuePriority; - queueCreateInfos.push_back(queueCreateInfo); - } - } + VkPhysicalDeviceFeatures enableFeatures{}; if (deviceFeatures.samplerAnisotropy) { @@ -421,173 +326,19 @@ void PlumageRender::createLogicalDevice() throw std::runtime_error("failed to create logical device"); } - vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicQueue); - if (!settings.headless) - { - vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue); - } -} - -void PlumageRender::createSwapChain() -{ - if (settings.headless) - { - return; - } - - SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); - - VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); - VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); - VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); - - uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1; - - if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) - { - imageCount = swapChainSupport.capabilities.maxImageCount; - } - - VkSwapchainCreateInfoKHR createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - createInfo.surface = surface; - - createInfo.minImageCount = imageCount; - createInfo.imageFormat = surfaceFormat.format; - createInfo.imageColorSpace = surfaceFormat.colorSpace; - createInfo.imageExtent = extent; - createInfo.imageArrayLayers = 1; - createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - - QueueFamilyIndices indices = findQueueFamilies(physicalDevice); - uint32_t queueFamilyIndices[] = { indices.graphicsFamily.value(),indices.presentFamily.value() }; - if (indices.graphicsFamily != indices.presentFamily) - { - createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - createInfo.queueFamilyIndexCount = 2; - createInfo.pQueueFamilyIndices = queueFamilyIndices; - - } - else - { - createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - createInfo.queueFamilyIndexCount = 0; - createInfo.pQueueFamilyIndices = nullptr; - } - - createInfo.preTransform = swapChainSupport.capabilities.currentTransform; - createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - createInfo.presentMode = presentMode; - createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = VK_NULL_HANDLE; - - - if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChainKHR) != VK_SUCCESS) - { - throw std::runtime_error("failed to create swap chain !"); - } - - vkGetSwapchainImagesKHR(device, swapChainKHR, &imageCount, nullptr); - swapChainImages.resize(imageCount); - vkGetSwapchainImagesKHR(device, swapChainKHR, &imageCount, swapChainImages.data()); - // store swap format and swap extent to member variable - swapChainImageFormat = surfaceFormat.format; - swapChainExtent = extent; -} - -VkSurfaceFormatKHR PlumageRender::chooseSwapSurfaceFormat(const std::vector& availableFormats) -{ - for (const auto& availableFormat : availableFormats) { - if (availableFormat.format == VK_FORMAT_B8G8R8_SRGB && availableFormat.colorSpace == VK_COLORSPACE_SRGB_NONLINEAR_KHR) - { - return availableFormat; - } - } - - return availableFormats[0]; -} - -VkPresentModeKHR PlumageRender::chooseSwapPresentMode(const std::vector& availablePresentModes) -{ - // Get available present modes - uint32_t presentModeCount; - VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, NULL)); - assert(presentModeCount > 0); - - std::vector presentModes(presentModeCount); - VK_CHECK_RESULT(fpGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModes.data())); - // The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec - // This mode waits for the vertical blank ("v-sync") - // 垂直同步模式 - VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; - - // If v-sync is not requested, try to find a mailbox mode - // It's the lowest latency non-tearing present mode available - if (!settings.vsync) - { - for (size_t i = 0; i < presentModeCount; i++) - { - if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) - { - swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR; - break; - } - if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) - { - swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; - } - } - } -} - -VkExtent2D PlumageRender::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) -{ - if (capabilities.currentExtent.width != std::numeric_limits::max()) - { - return capabilities.currentExtent; - } - else - { - int width, height; - //glfwGetFramebufferSize(window, &width, &height); - - VkExtent2D actualExtent = { - static_cast(width), - static_cast(height) - }; - - actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); - actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); - - return actualExtent; - } -} - -void PlumageRender::cleanupSwapChain() -{ - for (auto framebuffer : framebuffers) - { - vkDestroyFramebuffer(device, framebuffer, nullptr); - } - - for (auto imageView : swapChainImageViews) - { - vkDestroyImageView(device, imageView, nullptr); - } - - vkDestroySwapchainKHR(device, swapChainKHR, nullptr); + vkGetDeviceQueue(device, vulkanDevice->queueFamilyIndices.graphics, 0, &graphicQueue); + } void PlumageRender::createCommandPool() { - QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); + VkCommandPoolCreateInfo poolInfo{}; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(); + poolInfo.queueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics; - if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) { throw std::runtime_error("failed to create command pool in createCommandpool"); @@ -818,25 +569,29 @@ void PlumageRender::createFramebuffer() { if (settings.headless) { - auto frameRange = settings.endFrameIndex - settings.startFrameCount; + auto frameRange = settings.endFrameIndex - settings.startFrameCount + 1; + framebuffers.resize(frameRange); if (settings.multiSampling) { + VkImageView attachments[4]; + attachments[0] = multisampleTarget.colorAttachment.view; + attachments[1] = multisampleTarget.depthAttachment.view; + attachments[2] = depthAttachment.view; + attachments[3] = colorAttachment.view; + + VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo(); + framebufferCreateInfo.renderPass = renderPass; + framebufferCreateInfo.attachmentCount = 4; + framebufferCreateInfo.pAttachments = attachments; + framebufferCreateInfo.width = settings.width; + framebufferCreateInfo.height = settings.height; + framebufferCreateInfo.layers = 1; + + for (int i = 0; i < frameRange; i++) { - VkImageView attachments[4]; - attachments[0] = multisampleTarget.colorAttachment.view; - attachments[1] = multisampleTarget.depthAttachment.view; - attachments[2] = depthAttachment.view; - attachments[3] = colorAttachment.view; - - VkFramebufferCreateInfo framebufferCreateInfo = vks::initializers::framebufferCreateInfo(); - framebufferCreateInfo.renderPass = renderPass; - framebufferCreateInfo.attachmentCount = 4; - framebufferCreateInfo.pAttachments = attachments; - framebufferCreateInfo.width = settings.width; - framebufferCreateInfo.height = settings.height; - framebufferCreateInfo.layers = 1; + VK_CHECK_RESULT(vkCreateFramebuffer(device, &framebufferCreateInfo, nullptr, &framebuffers[i])); } @@ -862,12 +617,7 @@ void PlumageRender::createFramebuffer() } } - createImageView(); - } - else - { - createSwapChainFramebuffer(); - createImageView(); + } } @@ -913,6 +663,8 @@ void PlumageRender::createSwapChainFramebuffer() } } + + void PlumageRender::createImageView() { VkFormat colorAttachmentFormat = VK_FORMAT_R8G8B8A8_UNORM; @@ -1018,7 +770,7 @@ void PlumageRender::createImageView() imageCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCI.tiling = VK_IMAGE_TILING_OPTIMAL; imageCI.samples = VK_SAMPLE_COUNT_1_BIT; - imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + imageCI.usage = 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, &colorAttachment.image)); @@ -1029,14 +781,10 @@ void PlumageRender::createImageView() VkMemoryAllocateInfo memAllocInfo{}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; - VkBool32 lazyMemTypePresent; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } + memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &colorAttachment.memory)); - vkBindImageMemory(device, multisampleTarget.colorAttachment.image, colorAttachment.memory, 0); + vkBindImageMemory(device, colorAttachment.image, colorAttachment.memory, 0); // Create image view for the color image VkImageViewCreateInfo imageViewCI{}; @@ -1079,7 +827,7 @@ void PlumageRender::createImageView() VkMemoryRequirements depthAttachmentMemReqs; vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs); memAlloc.allocationSize = depthAttachmentMemReqs.size; - memAlloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + memAlloc.memoryTypeIndex = getMemoryTypeIndex(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)); @@ -2793,19 +2541,25 @@ void PlumageRender::prepare() createRenderPass(); + createPipelineCache(); + + createImageView(); + + createFramebuffer(); + camera.type = Camera::CameraType::lookat; camera.setPerspective(45.0f, (float)settings.width / (float)settings.height, 0.1f, 256.0f); camera.rotationSpeed = 0.25f; camera.movementSpeed = 0.1f; - + auto frameRanges = settings.endFrameIndex - settings.startFrameCount + 1; waitFences.resize(renderAhead); presentCompleteSemaphores.resize(renderAhead); renderCompleteSemaphores.resize(renderAhead); - commandBuffers.resize(renderAhead); - uniformBuffers.resize(renderAhead); - descriptorSets.resize(renderAhead); + commandBuffers.resize(frameRanges); + uniformBuffers.resize(frameRanges); + descriptorSets.resize(frameRanges); // Command buffer execution fences for (auto& waitFence : waitFences) { VkFenceCreateInfo fenceCI{ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT }; @@ -2829,6 +2583,7 @@ void PlumageRender::prepare() cmdBufAllocateInfo.commandBufferCount = static_cast(commandBuffers.size()); VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commandBuffers.data())); } + loadAssets(); generateBRDFLUT(); @@ -2845,18 +2600,7 @@ void PlumageRender::prepare() prepared = true; } -void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue) - { - 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(vkQueueSubmit(queue, 1, &submitInfo, fence)); - VK_CHECK_RESULT(vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX)); - vkDestroyFence(device, fence, nullptr); - } + // todo :根据physicalDeviceIndex确定子文件夹路径,frameIndex确定fileName void PlumageRender::writeImageToFile(std::string filePath) @@ -2883,11 +2627,10 @@ void PlumageRender::writeImageToFile(std::string filePath) } // Source for the copy is the last rendered swapchain image - if (settings.headless) - { - VkImage srcImage = colorAttachment.image; - } - VkImage srcImage = swapChainImages[currentBuffer]; + + VkImage srcImage = colorAttachment.image; + + //VkImage srcImage = swapChainImages[currentBuffer]; // Create the linear tiled destination image to copy to and to read the memory from VkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo()); @@ -3240,10 +2983,11 @@ void PlumageRender::render() VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[frameIndex], VK_TRUE, UINT64_MAX)); - framebufferResized = swapChainAcquireNextImage(framebufferResized, imageIndex, frameIndex); + //framebufferResized = swapChainAcquireNextImage(framebufferResized, imageIndex, frameIndex); + outputImageSequence(); VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[frameIndex])); - outputImageSequence(); + imageSequenceToVideo(); // Update UBOs @@ -3255,7 +2999,7 @@ void PlumageRender::render() submitToGraphicQueue(frameIndex,currentBuffer); - imageToQueuePresent(frameIndex, imageIndex, framebufferResized); + //imageToQueuePresent(frameIndex, imageIndex, framebufferResized); frameIndex += 1; @@ -3334,7 +3078,7 @@ void PlumageRender::destroyVulkan() textures.empty.destroy(); delete gui; // Clean up Vulkan resources - cleanupSwapChain(); + vkDestroyDescriptorPool(device, descriptorPool, nullptr); vkDestroyRenderPass(device, renderPass, nullptr); for (uint32_t i = 0; i < framebuffers.size(); i++) { @@ -3358,7 +3102,7 @@ void PlumageRender::destroyVulkan() } delete vulkanDevice; if (settings.validation) { - DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr); + vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr); } vkDestroyInstance(instance, nullptr); } diff --git a/src/render/render.h b/src/render/render.h index 920b6cf..f7c7e09 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -54,6 +54,10 @@ public: bool ToneMapping = true; bool pbrEnabled = true; + PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallback; + PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallback; + VkDebugReportCallbackEXT debugReportCallback; + std::vector args; GLFWwindow* window; @@ -246,7 +250,7 @@ public: bool validation = true; // 校验层开关 bool fullscreen = false; // 全屏开关 bool vsync = false; // 垂直同步开关 - bool multiSampling = true; // 多重采样 + bool multiSampling = false; // 多重采样 bool rotateModel = true; // 模型自旋转(暂时失效) bool headless = true; // 无头开关 bool outputPNGimage = false; @@ -390,20 +394,7 @@ public: VkCommandPool commandPool; - struct QueueFamilyIndices - { - std::optional graphicsFamily; - std::optional presentFamily; - bool isGraphicsFamilyComplete() - { - return graphicsFamily.has_value(); - } - bool isPresentFamilyComplete() - { - return presentFamily.has_value(); - } - }; struct SwapChainSupportDetails { @@ -469,25 +460,21 @@ public: std::vector getRequiredExtensions(); void setupDebugMessager(); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo); - static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback( - VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void* pUserData); + static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData); + VkResult CreateDebugUtilsMessengerEXT( VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger); - void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator); - + void createSurface(); void pickupPhysicalDevice(); bool isDeviceSuitable(VkPhysicalDevice device); bool checkDeviceExtensionSupport(VkPhysicalDevice device); - QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device); + SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device); // 创建程序使用的逻辑设备 @@ -500,7 +487,7 @@ public: VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector& availableFormats); VkPresentModeKHR chooseSwapPresentMode(const std::vector& availablePresentModes); VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities); - void cleanupSwapChain(); + void createCommandPool(); @@ -511,6 +498,9 @@ public: void createPipelineCache(); + uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties); + + void createFramebuffer(); void createSwapChainFramebuffer(); void createImageView(); @@ -543,8 +533,7 @@ public: void updateUniformBuffers(); void updateShaderData(); void initWindow(int Width,int Height); - static void framebufferResizeCallback(GLFWwindow* window, int width, int height); - + void windowResized(); void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue); @@ -553,7 +542,7 @@ public: void imageSequenceToVideo(); void removeImageSequence(); //void outputScreenShot(); - uint32_t getMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties); + virtual void render(); virtual void updateUIOverlay(); virtual void fileDropped(std::string filename); From 98a8b2c715df4c860813616edd2ad108f870e5f0 Mon Sep 17 00:00:00 2001 From: ink-soul Date: Mon, 15 Apr 2024 15:55:08 +0800 Subject: [PATCH 3/4] fix validation no print --- base/VulkanTexture.hpp | 17 +++++++++-------- src/render/render.cpp | 14 ++++++-------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/base/VulkanTexture.hpp b/base/VulkanTexture.hpp index 29b2b5b..bca7d7e 100644 --- a/base/VulkanTexture.hpp +++ b/base/VulkanTexture.hpp @@ -78,8 +78,9 @@ namespace vks VkFormatProperties formatProperties; vkGetPhysicalDeviceFormatProperties(device->physicalDevice, format, &formatProperties); - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + + VkMemoryAllocateInfo texMemAllocInfo{}; + texMemAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; VkMemoryRequirements memReqs; // Use a separate command buffer for texture loading @@ -101,11 +102,11 @@ namespace vks // Get memory requirements for the staging buffer (alignment, memory type bits) vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - memAllocInfo.allocationSize = memReqs.size; + texMemAllocInfo.allocationSize = memReqs.size; // Get memory type index for a host visible buffer - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &stagingMemory)); + VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &stagingMemory)); VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); // Copy texture data into staging buffer @@ -157,10 +158,10 @@ namespace vks vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - memAllocInfo.allocationSize = memReqs.size; + texMemAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &deviceMemory)); + texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &deviceMemory)); VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); VkImageSubresourceRange subresourceRange = {}; diff --git a/src/render/render.cpp b/src/render/render.cpp index 359d1e8..e1e8de6 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -33,9 +33,6 @@ void PlumageRender::initVulkan() setupDebugMessager(); //createSurface(); - - - pickupPhysicalDevice(); createLogicalDevice(); @@ -164,9 +161,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL PlumageRender::debugMessageCallback(VkDebugReport if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { prefix += "DEBUG:"; } - std::stringstream debugMessage; - debugMessage << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg; - fflush(stdout); + std::string debugMessage; + std::string msgCodeString = std::to_string(msgCode); + debugMessage = debugMessage + prefix + " [" + pLayerPrefix + "] Code " + msgCodeString + " : " + pMsg; + std::cout << debugMessage << std::endl; return VK_FALSE; } @@ -825,7 +823,7 @@ void PlumageRender::createImageView() memAlloc.allocationSize = 0; memAlloc.memoryTypeIndex = 0; VkMemoryRequirements depthAttachmentMemReqs; - vkGetImageMemoryRequirements(device, depthAttachment.image, &memReqs); + vkGetImageMemoryRequirements(device, depthAttachment.image, &depthAttachmentMemReqs); memAlloc.allocationSize = depthAttachmentMemReqs.size; memAlloc.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_CHECK_RESULT(vkAllocateMemory(device, &memAlloc, nullptr, &depthAttachment.memory)); @@ -841,7 +839,7 @@ void PlumageRender::createImageView() depthStencilView.image = depthAttachment.image; depthStencilView.flags = 0; depthStencilView.subresourceRange = {}; - depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; if (depthFormat >= VK_FORMAT_D16_UNORM_S8_UINT) { depthStencilView.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; From 1756c33c9b8afd367f5b3e111ec23f2c7d632b2c Mon Sep 17 00:00:00 2001 From: ink-soul Date: Mon, 15 Apr 2024 17:58:58 +0800 Subject: [PATCH 4/4] switch textureloader --- base/VulkanTexture.cpp | 2 + base/VulkanTexture.hpp | 631 ----------------------------------------- base/ui.hpp | 4 +- src/render/render.cpp | 35 +-- src/render/render.h | 2 +- 5 files changed, 24 insertions(+), 650 deletions(-) delete mode 100644 base/VulkanTexture.hpp diff --git a/base/VulkanTexture.cpp b/base/VulkanTexture.cpp index 039cf59..32c815d 100644 --- a/base/VulkanTexture.cpp +++ b/base/VulkanTexture.cpp @@ -79,6 +79,7 @@ namespace vks ktx_size_t ktxTextureSize = ktxTexture_GetSize(ktxTexture); // Get device properties for the requested texture format + VkFormatProperties formatProperties; vkGetPhysicalDeviceFormatProperties(device->physicalDevice, format, &formatProperties); @@ -87,6 +88,7 @@ namespace vks // optimal tiling instead // On most implementations linear tiling will only support a very // limited amount of formats and features (mip maps, cubemaps, arrays, etc.) + VkBool32 useStaging = !forceLinear; VkMemoryAllocateInfo memAllocInfo = vks::initializers::memoryAllocateInfo(); diff --git a/base/VulkanTexture.hpp b/base/VulkanTexture.hpp deleted file mode 100644 index bca7d7e..0000000 --- a/base/VulkanTexture.hpp +++ /dev/null @@ -1,631 +0,0 @@ -/* -* Vulkan texture loader -* -* Copyright(C) 2016-2017 by Sascha Willems - www.saschawillems.de -* -* This code is licensed under the MIT license(MIT) (http://opensource.org/licenses/MIT) -*/ - -#pragma once - -#include -#include -#include -#include - -#include "vulkan/vulkan.h" -#include "VulkanTools.h" -#include "VulkanDevice.hpp" -#define GLM_ENABLE_EXPERIMENTAL -#include - - -namespace vks -{ - class Texture { - public: - vks::VulkanDevice *device; - VkImage image = VK_NULL_HANDLE; - VkImageLayout imageLayout; - VkDeviceMemory deviceMemory; - VkImageView view; - uint32_t width, height; - uint32_t mipLevels; - uint32_t layerCount; - VkDescriptorImageInfo descriptor; - VkSampler sampler; - - void updateDescriptor() - { - descriptor.sampler = sampler; - descriptor.imageView = view; - descriptor.imageLayout = imageLayout; - } - - void destroy() - { - vkDestroyImageView(device->logicalDevice, view, nullptr); - vkDestroyImage(device->logicalDevice, image, nullptr); - if (sampler) - { - vkDestroySampler(device->logicalDevice, sampler, nullptr); - } - vkFreeMemory(device->logicalDevice, deviceMemory, nullptr); - } - }; - - class Texture2D : public Texture { - public: - void loadFromFile( - std::string filename, - VkFormat format, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - - gli::texture2d tex2D(gli::load(filename.c_str())); - - assert(!tex2D.empty()); - - this->device = device; - width = static_cast(tex2D[0].extent().x); - height = static_cast(tex2D[0].extent().y); - mipLevels = static_cast(tex2D.levels()); - - // Get device properites for the requested texture format - VkFormatProperties formatProperties; - vkGetPhysicalDeviceFormatProperties(device->physicalDevice, format, &formatProperties); - - - VkMemoryAllocateInfo texMemAllocInfo{}; - texMemAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = tex2D.size(); - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - texMemAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, tex2D.data(), tex2D.size()); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - // Setup buffer copy regions for each mip level - std::vector bufferCopyRegions; - uint32_t offset = 0; - - for (uint32_t i = 0; i < mipLevels; i++) - { - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = i; - bufferCopyRegion.imageSubresource.baseArrayLayer = 0; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = static_cast(tex2D[i].extent().x); - bufferCopyRegion.imageExtent.height = static_cast(tex2D[i].extent().y); - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = offset; - - bufferCopyRegions.push_back(bufferCopyRegion); - - offset += static_cast(tex2D[i].size()); - } - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - texMemAllocInfo.allocationSize = memReqs.size; - - texMemAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &texMemAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 1; - - // Image barrier for optimal image (target) - // Optimal image will be used as destination for the copy - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - // Copy mip levels from staging buffer - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(bufferCopyRegions.size()), - bufferCopyRegions.data() - ); - - // Change texture image layout to shader read after all mip levels have been copied - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = VK_FILTER_LINEAR; - samplerCreateInfo.minFilter = VK_FILTER_LINEAR; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = (float)mipLevels; - samplerCreateInfo.maxAnisotropy = device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f; - samplerCreateInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy; - samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - VkImageViewCreateInfo viewCreateInfo{}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.levelCount = mipLevels; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - updateDescriptor(); - } - - void loadFromBuffer( - void* buffer, - VkDeviceSize bufferSize, - VkFormat format, - uint32_t width, - uint32_t height, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkFilter filter = VK_FILTER_LINEAR, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { - assert(buffer); - - this->device = device; - width = width; - height = height; - mipLevels = 1; - - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = bufferSize; - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, buffer, bufferSize); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = 0; - bufferCopyRegion.imageSubresource.baseArrayLayer = 0; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = width; - bufferCopyRegion.imageExtent.height = height; - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = 0; - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 1; - - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, - &bufferCopyRegion - ); - - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - // Create sampler - VkSamplerCreateInfo samplerCreateInfo = {}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = filter; - samplerCreateInfo.minFilter = filter; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = 0.0f; - samplerCreateInfo.maxAnisotropy = 1.0f; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - // Create image view - VkImageViewCreateInfo viewCreateInfo = {}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.pNext = NULL; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.levelCount = 1; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - // Update descriptor image info member that can be used for setting up descriptor sets - updateDescriptor(); - } - }; - - class TextureCubeMap : public Texture { - public: - void loadFromFile( - std::string filename, - VkFormat format, - vks::VulkanDevice *device, - VkQueue copyQueue, - VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT, - VkImageLayout imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - { -#if defined(__ANDROID__) - // Textures are stored inside the apk on Android (compressed) - // So they need to be loaded via the asset manager - AAsset* asset = AAssetManager_open(androidApp->activity->assetManager, filename.c_str(), AASSET_MODE_STREAMING); - if (!asset) { - LOGE("Could not load texture %s", filename.c_str()); - exit(-1); - } - size_t size = AAsset_getLength(asset); - assert(size > 0); - - void *textureData = malloc(size); - AAsset_read(asset, textureData, size); - AAsset_close(asset); - - gli::texture_cube texCube(gli::load((const char*)textureData, size)); - - free(textureData); -#else - gli::texture_cube texCube(gli::load(filename)); -#endif - assert(!texCube.empty()); - - this->device = device; - width = static_cast(texCube.extent().x); - height = static_cast(texCube.extent().y); - mipLevels = static_cast(texCube.levels()); - - VkMemoryAllocateInfo memAllocInfo{}; - memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - VkMemoryRequirements memReqs; - - // Create a host-visible staging buffer that contains the raw image data - VkBuffer stagingBuffer; - VkDeviceMemory stagingMemory; - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = texCube.size(); - // This buffer is used as a transfer source for the buffer copy - bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - VK_CHECK_RESULT(vkCreateBuffer(device->logicalDevice, &bufferCreateInfo, nullptr, &stagingBuffer)); - - // Get memory requirements for the staging buffer (alignment, memory type bits) - vkGetBufferMemoryRequirements(device->logicalDevice, stagingBuffer, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - // Get memory type index for a host visible buffer - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &stagingMemory)); - VK_CHECK_RESULT(vkBindBufferMemory(device->logicalDevice, stagingBuffer, stagingMemory, 0)); - - // Copy texture data into staging buffer - uint8_t *data; - VK_CHECK_RESULT(vkMapMemory(device->logicalDevice, stagingMemory, 0, memReqs.size, 0, (void **)&data)); - memcpy(data, texCube.data(), texCube.size()); - vkUnmapMemory(device->logicalDevice, stagingMemory); - - // Setup buffer copy regions for each face including all of it's miplevels - std::vector bufferCopyRegions; - size_t offset = 0; - - for (uint32_t face = 0; face < 6; face++) { - for (uint32_t level = 0; level < mipLevels; level++) { - VkBufferImageCopy bufferCopyRegion = {}; - bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - bufferCopyRegion.imageSubresource.mipLevel = level; - bufferCopyRegion.imageSubresource.baseArrayLayer = face; - bufferCopyRegion.imageSubresource.layerCount = 1; - bufferCopyRegion.imageExtent.width = static_cast(texCube[face][level].extent().x); - bufferCopyRegion.imageExtent.height = static_cast(texCube[face][level].extent().y); - bufferCopyRegion.imageExtent.depth = 1; - bufferCopyRegion.bufferOffset = offset; - - bufferCopyRegions.push_back(bufferCopyRegion); - - // Increase offset into staging buffer for next level / face - offset += texCube[face][level].size(); - } - } - - // Create optimal tiled target image - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imageCreateInfo.format = format; - imageCreateInfo.mipLevels = mipLevels; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageCreateInfo.extent = { width, height, 1 }; - imageCreateInfo.usage = imageUsageFlags; - // Ensure that the TRANSFER_DST bit is set for staging - if (!(imageCreateInfo.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { - imageCreateInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; - } - // Cube faces count as array layers in Vulkan - imageCreateInfo.arrayLayers = 6; - // This flag is required for cube map images - imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - - - VK_CHECK_RESULT(vkCreateImage(device->logicalDevice, &imageCreateInfo, nullptr, &image)); - - vkGetImageMemoryRequirements(device->logicalDevice, image, &memReqs); - - memAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - VK_CHECK_RESULT(vkAllocateMemory(device->logicalDevice, &memAllocInfo, nullptr, &deviceMemory)); - VK_CHECK_RESULT(vkBindImageMemory(device->logicalDevice, image, deviceMemory, 0)); - - // Use a separate command buffer for texture loading - VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); - - // Image barrier for optimal image (target) - // Set initial layout for all array layers (faces) of the optimal (target) tiled texture - VkImageSubresourceRange subresourceRange = {}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseMipLevel = 0; - subresourceRange.levelCount = mipLevels; - subresourceRange.layerCount = 6; - - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.srcAccessMask = 0; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - // Copy the cube map faces from the staging buffer to the optimal tiled image - vkCmdCopyBufferToImage( - copyCmd, - stagingBuffer, - image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - static_cast(bufferCopyRegions.size()), - bufferCopyRegions.data()); - - // Change texture image layout to shader read after all faces have been copied - this->imageLayout = imageLayout; - { - VkImageMemoryBarrier imageMemoryBarrier{}; - imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - imageMemoryBarrier.newLayout = imageLayout; - imageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - imageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - imageMemoryBarrier.image = image; - imageMemoryBarrier.subresourceRange = subresourceRange; - vkCmdPipelineBarrier(copyCmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1, &imageMemoryBarrier); - } - - device->flushCommandBuffer(copyCmd, copyQueue); - - // Create sampler - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = VK_FILTER_LINEAR; - samplerCreateInfo.minFilter = VK_FILTER_LINEAR; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerCreateInfo.addressModeV = samplerCreateInfo.addressModeU; - samplerCreateInfo.addressModeW = samplerCreateInfo.addressModeU; - samplerCreateInfo.mipLodBias = 0.0f; - samplerCreateInfo.maxAnisotropy = device->enabledFeatures.samplerAnisotropy ? device->properties.limits.maxSamplerAnisotropy : 1.0f; - samplerCreateInfo.anisotropyEnable = device->enabledFeatures.samplerAnisotropy; - samplerCreateInfo.compareOp = VK_COMPARE_OP_NEVER; - samplerCreateInfo.minLod = 0.0f; - samplerCreateInfo.maxLod = (float)mipLevels; - samplerCreateInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - VK_CHECK_RESULT(vkCreateSampler(device->logicalDevice, &samplerCreateInfo, nullptr, &sampler)); - - // Create image view - VkImageViewCreateInfo viewCreateInfo{}; - viewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_CUBE; - viewCreateInfo.format = format; - viewCreateInfo.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - viewCreateInfo.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; - viewCreateInfo.subresourceRange.layerCount = 6; - viewCreateInfo.subresourceRange.levelCount = mipLevels; - viewCreateInfo.image = image; - VK_CHECK_RESULT(vkCreateImageView(device->logicalDevice, &viewCreateInfo, nullptr, &view)); - - // Clean up staging resources - vkFreeMemory(device->logicalDevice, stagingMemory, nullptr); - vkDestroyBuffer(device->logicalDevice, stagingBuffer, nullptr); - - // Update descriptor image info member that can be used for setting up descriptor sets - updateDescriptor(); - } - }; - -} \ No newline at end of file diff --git a/base/ui.hpp b/base/ui.hpp index fe4340c..0647742 100644 --- a/base/ui.hpp +++ b/base/ui.hpp @@ -7,7 +7,7 @@ #include "imgui/imgui.h" #include "VulkanDevice.hpp" #include "VulkanUtils.hpp" -#include "VulkanTexture.hpp" +#include "VulkanTexture.h" #if defined(__ANDROID__) #include @@ -64,7 +64,7 @@ public: io.Fonts->AddFontFromFileTTF(ttfFilePath.data(), 16.0f,NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon()); #endif io.Fonts->GetTexDataAsRGBA32(&fontData, &texWidth, &texHeight); - fontTexture.loadFromBuffer(fontData, texWidth * texHeight * 4 * sizeof(char), VK_FORMAT_R8G8B8A8_UNORM, texWidth, texHeight, vulkanDevice, queue); + fontTexture.fromBuffer(fontData, texWidth * texHeight * 4 * sizeof(char), VK_FORMAT_R8G8B8A8_UNORM, texWidth, texHeight, vulkanDevice, queue); /* Setup diff --git a/src/render/render.cpp b/src/render/render.cpp index e1e8de6..7e83d05 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -694,11 +694,10 @@ void PlumageRender::createImageView() VkMemoryAllocateInfo memAllocInfo{}; memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; - VkBool32 lazyMemTypePresent; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } + + + memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.colorAttachment.memory)); vkBindImageMemory(device, multisampleTarget.colorAttachment.image, multisampleTarget.colorAttachment.memory, 0); @@ -735,10 +734,9 @@ void PlumageRender::createImageView() vkGetImageMemoryRequirements(device, multisampleTarget.depthAttachment.image, &memReqs); memAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllocInfo.allocationSize = memReqs.size; - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, &lazyMemTypePresent); - if (!lazyMemTypePresent) { - memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } + + memAllocInfo.memoryTypeIndex = getMemoryTypeIndex(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &multisampleTarget.depthAttachment.memory)); vkBindImageMemory(device, multisampleTarget.depthAttachment.image, multisampleTarget.depthAttachment.memory, 0); @@ -1220,8 +1218,7 @@ void PlumageRender::loadAssets() readDirectory(assetpath + "environments", "*.ktx", environments, false); - textures.empty.loadFromFile(PlumageRender::filePath.emptyEnvmapFilePath, VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, graphicQueue); - + std::string sceneFile = filePath.glTFModelFilePath; std::string envMapFile = filePath.envMapFilePath; for (size_t i = 0; i < args.size(); i++) { @@ -1245,9 +1242,13 @@ void PlumageRender::loadAssets() } } - loadScene(sceneFile.c_str()); - models.skybox.loadFromFile(PlumageRender::filePath.skyboxModleFilePath, vulkanDevice, graphicQueue); + + + models.skybox.loadFromFile(PlumageRender::filePath.skyboxModleFilePath, vulkanDevice, graphicQueue); + loadScene(sceneFile.c_str()); + + textures.empty.loadFromFile(PlumageRender::filePath.emptyEnvmapFilePath, VK_FORMAT_R8G8B8A8_UNORM, vulkanDevice, graphicQueue); loadEnvironment(envMapFile.c_str()); } @@ -2542,9 +2543,10 @@ void PlumageRender::prepare() createPipelineCache(); createImageView(); - createFramebuffer(); + + camera.type = Camera::CameraType::lookat; camera.setPerspective(45.0f, (float)settings.width / (float)settings.height, 0.1f, 256.0f); @@ -2582,14 +2584,15 @@ void PlumageRender::prepare() VK_CHECK_RESULT(vkAllocateCommandBuffers(device, &cmdBufAllocateInfo, commandBuffers.data())); } - + + loadAssets(); generateBRDFLUT(); generateCubemaps(); prepareUniformBuffers(); setupDescriptors(); preparePipelines(); - + //gui = new UI(vulkanDevice, renderPass, graphicQueue, pipelineCache, settings.sampleCount); //updateUIOverlay(); diff --git a/src/render/render.h b/src/render/render.h index f7c7e09..18560ac 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -38,7 +38,7 @@ #include //#include "VulkanExampleBase.h" #include "glTFModel.h" -#include +#include #include "VulkanDevice.hpp" #include "ui.hpp" #include