重构至debugCallBack

ink-soul 2024-04-01 18:05:17 +08:00
parent 1d6521570e
commit 77e93d01d1
5 changed files with 256 additions and 56 deletions

View File

@ -1801,6 +1801,7 @@ void VulkanExampleBase::setupFrameBuffer()
imageCI.samples = settings.sampleCount;
imageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
imageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
VK_CHECK_RESULT(vkCreateImage(device, &imageCI, nullptr, &multisampleTarget.color.image));
VkMemoryRequirements memReqs;

View File

@ -43,6 +43,8 @@ void PlumageRender::framebufferResizeCallback(GLFWwindow* window, int width, int
app->framebufferResized = true;
}
// 重构至gltfModel中
void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode) {
if (node->mesh) {
// Render mesh primitives
@ -121,7 +123,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
}
void PlumageRender::buildCommandBuffers()
void PlumageRender::buildCommandBuffers()
{
VkCommandBufferBeginInfo cmdBufferBeginInfo{};
cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@ -213,7 +215,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
void PlumageRender::loadScene(std::string filename)
void PlumageRender::loadScene(std::string filename)
{
std::cout << "Loading scene from " << filename << std::endl;
models.scene.destroy(device);
@ -227,7 +229,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
camera.setRotation({ 0.0f, 0.0f, 0.0f });
}
void PlumageRender::loadEnvironment(std::string filename)
void PlumageRender::loadEnvironment(std::string filename)
{
std::cout << "Loading environment from " << filename << std::endl;
if (textures.environmentCube.image) {
@ -239,7 +241,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
generateCubemaps();
}
void PlumageRender::loadAssets()
void PlumageRender::loadAssets()
{
const std::string assetpath = getAssetPath();
@ -268,7 +270,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
loadEnvironment(envMapFile.c_str());
}
void PlumageRender::setupNodeDescriptorSet(glTFModel::Node* node)
void PlumageRender::setupNodeDescriptorSet(glTFModel::Node* node)
{
/*
This sample uses separate descriptor sets (and layouts) for the matrices and materials (textures)
@ -296,7 +298,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
}
void PlumageRender::setupDescriptors()
void PlumageRender::setupDescriptors()
{
/*
Descriptor Pool
@ -519,7 +521,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
}
void PlumageRender::preparePipelines()
void PlumageRender::preparePipelines()
{
VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCI{};
inputAssemblyStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
@ -667,10 +669,11 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
// generate two cube maps
// irradiance cube map
// prefileter environment cube map
void PlumageRender::generateCubemaps()
// generate two cube maps
// irradiance cube map
// prefileter environment cube map
// 重构到PBR中
void PlumageRender::generateCubemaps()
{
enum Target { IRRADIANCE = 0, PREFILTEREDENV = 1 };
@ -1207,8 +1210,9 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
std::cout << "Generating cube map with " << numMips << " mip levels took " << tDiff << " ms" << std::endl;
}
}
// generate BRDF integration map for roughness/NdotV
void PlumageRender::generateBRDFLUT()
// generate BRDF integration map for roughness/NdotV
// 重构到PBR
void PlumageRender::generateBRDFLUT()
{
auto tStart = std::chrono::high_resolution_clock::now();
@ -1465,8 +1469,8 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
std::cout << "Generating BRDF LUT took " << tDiff << " ms" << std::endl;
}
// Prepare and initialize uniform buffer containing shader uniforms
void PlumageRender::prepareUniformBuffers()
// Prepare and initialize uniform buffer containing shader uniforms
void PlumageRender::prepareUniformBuffers()
{
for (auto& uniformBuffer : uniformBuffers) {
uniformBuffer.scene.create(vulkanDevice, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(shaderDataScene));
@ -1475,8 +1479,8 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
updateUniformBuffers();
}
void PlumageRender::updateUniformBuffers()
// 更新统一缓冲区
void PlumageRender::updateUniformBuffers()
{
// Scene
shaderDataScene.projection = camera.matrices.perspective;
@ -1505,7 +1509,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
shaderDataSkybox.model = glm::mat4(glm::mat3(camera.matrices.view));
}
void PlumageRender::updateShaderData()
void PlumageRender::updateShaderData()
{
shaderData.lightDir = glm::vec4(
sin(glm::radians(lightSource.rotation.x)) * cos(glm::radians(lightSource.rotation.y)),
@ -1513,8 +1517,8 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
cos(glm::radians(lightSource.rotation.x)) * cos(glm::radians(lightSource.rotation.y)),
0.0f);
}
void PlumageRender::windowResized()
// todo重写成glfw的
void PlumageRender::windowResized()
{
buildCommandBuffers();
vkDeviceWaitIdle(device);
@ -1523,7 +1527,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
updateUIOverlay();
}
void PlumageRender::prepare()
void PlumageRender::prepare()
{
VulkanExampleBase::prepare();
@ -1587,7 +1591,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
prepared = true;
}
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue)
void PlumageRender::submitWork(VkCommandBuffer cmdBuffer, VkQueue queue)
{
VkSubmitInfo submitInfo = vks::initializers::submitInfo();
submitInfo.commandBufferCount = 1;
@ -1600,8 +1604,9 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
vkDestroyFence(device, fence, nullptr);
}
// todo :根据physicalDeviceIndex确定子文件夹路径frameIndex确定fileName
void PlumageRender::writeImageToFile(std::string filePath)
// todo :根据physicalDeviceIndex确定子文件夹路径frameIndex确定fileName
// 移动到fileSystem里
void PlumageRender::writeImageToFile(std::string filePath)
{
bool screenshotSaved = false;
@ -1834,7 +1839,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
void PlumageRender::outputImageSequence()
void PlumageRender::outputImageSequence()
{
// 比较已保存的帧数和设置里的开始帧数,在生成前清理上一次生成的图片序列
if (savedFrameCounter == setter.settings.startFrameCount)
@ -1874,7 +1879,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
savedFrameCounter++;
}
void PlumageRender::imageSequenceToVideo()
void PlumageRender::imageSequenceToVideo()
{
// 边界条件,图片序列输出未完成
if (!signal.imageSequenceOutputComplete)
@ -1914,7 +1919,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
removeImageSequence();
}
void PlumageRender::removeImageSequence()
void PlumageRender::removeImageSequence()
{
// 函数非第一次运行的边界条件
if (savedFrameCounter != setter.settings.startFrameCount)
@ -1949,7 +1954,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
void PlumageRender::render()
void PlumageRender::render()
{
if (!prepared) {
return;
@ -2042,7 +2047,7 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
void PlumageRender::fileDropped(std::string filename)
void PlumageRender::fileDropped(std::string filename)
{
vkDeviceWaitIdle(device);
loadScene(filename);
@ -2050,8 +2055,8 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
buildCommandBuffers();
}
void PlumageRender::updateUIOverlay()
// 重构到单独的UI里
void PlumageRender::updateUIOverlay()
{
ImGuiIO& io = ImGui::GetIO();
@ -2265,9 +2270,9 @@ void PlumageRender::renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFMode
}
PlumageRender* plumageRender;
// OS specific macros for the example main entry points
// 完全重写避免OS specific
PlumageRender* plumageRender;
// OS specific macros for the example main entry points
#if defined(_WIN32)
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

View File

@ -300,19 +300,19 @@ public:
void renderNode(glTFModel::Node* node, uint32_t cbIndex, glTFModel::Material::AlphaMode alphaMode);
void loadScene(std::string filename);
void loadEnvironment(std::string filename);
void buildCommandBuffers();
void loadAssets();
void buildCommandBuffers();
void loadAssets();
void setupNodeDescriptorSet(glTFModel::Node* node);
void setupDescriptors();
void preparePipelines();
void preparePipelines();
// void tonemappingPipelin();
void generateCubemaps();
void generateBRDFLUT();
void prepareUniformBuffers();
void updateUniformBuffers();
void prepareUniformBuffers();
void updateUniformBuffers();
void updateShaderData();
void windowResized();
void prepare();
void prepare();
void submitWork(VkCommandBuffer cmdBuffer, VkQueue queue);
void writeImageToFile(std::string filePath);

View File

@ -1,5 +1,125 @@
#include "vulkanFoundation.h"
VKAPI_ATTR VkBool32 VKAPI_CALL VulkanBackend::VulkanFondation::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData)
{
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
return VK_FALSE;
}
void VulkanBackend::VulkanFondation::createInstance()
{
// check validation layers
if (setter.settings.validation && !checkValidationLayerSupport())
{
throw std::runtime_error("validation layers requsted,but not available");
}
//setup appliaction info
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Hello Triangle";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No_Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
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<uint32_t>(requiredExtensions.size());
createInfo.ppEnabledExtensionNames = requiredExtensions.data();
// enable validation layer if available in createInfo
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
if (setter.settings.validation)
{
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
populateDebugMessengerCreateInfo(debugCreateInfo);
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*)&debugCreateInfo;
}
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");
}
}
bool VulkanBackend::VulkanFondation::checkValidationLayerSupport()
{
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
// check if validationLayers can be found in availableLayers
for (const char* layerName : validationLayers)
{
bool layerFound = false;
for (const auto& layerProperties : availableLayers) {
if (strcmp(layerName, layerProperties.layerName) == 0)
{
layerFound = true;
break;
}
}
if (!layerFound)
{
return false;
}
}
return true;
}
std::vector<const char*> VulkanBackend::VulkanFondation::getRequiredExtensions()
{
std::vector<const char*> extensions;
if (!setter.settings.headless)
{
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
}
if (setter.settings.validation)
{
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
return extensions;
}
void VulkanBackend::VulkanFondation::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo)
{
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;
}
void VulkanBackend::VulkanFondation::createSurface()
{
@ -45,7 +165,7 @@ bool VulkanBackend::VulkanFondation::isDeviceSuitable(VkPhysicalDevice device)
return extensionsSupported;
}
else
{
{ // 非无头下在检查扩展支持的同时要检查swapchain
bool extensionsSupported = checkDeviceExtensionSupport(device);
bool swapChainAdequate = false;
QueueFamilyIndices indices = findQueueFamilies(device);
@ -59,7 +179,21 @@ bool VulkanBackend::VulkanFondation::isDeviceSuitable(VkPhysicalDevice device)
bool VulkanBackend::VulkanFondation::checkDeviceExtensionSupport(VkPhysicalDevice device)
{
return false;
uint32_t extensionCount;
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
std::set<std::string> requiredExtensions(swapchainExtensions.begin(), swapchainExtensions.end());
for (const auto& extension : availableExtensions)
{
requiredExtensions.erase(extension.extensionName);
}
return requiredExtensions.empty();
}
VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondation::findQueueFamilies(VkPhysicalDevice device)
@ -74,17 +208,31 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
VkBool32 presentSupport = false;
// 检查队列支持
int i = 0;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
if (!setter.settings.headless)
{
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
}
for (const auto& queueFamily : queueFamilies)
{
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily = i;
}
if (indices.isComplete())
// 无头下不需要检查present queue
if (setter.settings.headless)
{
break;
if (indices.isGraphicsFamilyComplete())
{
break;
}
}
else
{
if (indices.isGraphicsFamilyComplete() && indices.isPresentFamilyComplete())
{
break;
}
}
if (presentSupport)
{
@ -100,5 +248,28 @@ VulkanBackend::VulkanFondation::QueueFamilyIndices VulkanBackend::VulkanFondatio
VulkanBackend::VulkanFondation::SwapChainSupportDetails VulkanBackend::VulkanFondation::querySwapChainSupport(VkPhysicalDevice device)
{
// 获得surface细节
SwapChainSupportDetails details;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
// 检查格式支持image
uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
if (formatCount != 0)
{
details.formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
}
// 检查显示模式支持
uint32_t presentModeCount;
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
if (presentModeCount != 0)
{
details.presentModes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
}
return details;
}

View File

@ -5,6 +5,7 @@
#include <stdexcept>
#include <vector>
#include <optional>
#include <set>
#include "renderSetter.h"
@ -16,13 +17,25 @@ namespace VulkanBackend
VulkanFondation();
~VulkanFondation();
const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
};
const std::vector<const char*> swapchainExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
//"VK_EXT_headless_surface"
};
VulkanBackend::Setter setter;
VkInstance instance;
private:
VkInstance instance;
VkDebugUtilsMessengerEXT debugMessenger;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkDevice device;
VkSurfaceKHR surface;
@ -31,8 +44,13 @@ namespace VulkanBackend
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentFamily;
bool isComplete() {
return graphicsFamily.has_value() && presentFamily.has_value();
bool isGraphicsFamilyComplete()
{
return graphicsFamily.has_value();
}
bool isPresentFamilyComplete()
{
return presentFamily.has_value();
}
};
@ -43,14 +61,19 @@ namespace VulkanBackend
std::vector<VkPresentModeKHR> presentModes;
};
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
void createInstance();
bool checkValidationLayerSupport();
std::vector<const char*> getRequiredExtensions();
void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& debugCreateInfo);
void pickPhysicalDevice();
void createSurface();
void pickPhysicalDevice();
bool isDeviceSuitable(VkPhysicalDevice device);
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
VulkanBackend::VulkanFondation::QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);