CgContext.Rasterization.cpp 12 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#define GLM_FORCE_RADIANS
#include <algorithm>
#include <chrono>
#include <cmath>
#include <filesystem>
#include <iostream>
#include <iterator>
#include <limits>
#include <set>
#include <random>

#include "Config.hpp"
#include "Core/CameraModel.hpp"
#include "Core/CgContext.hpp"
#include "Core/CoreInitException.hpp"
#include "Core/Model/AssimpModel.hpp"
#include "Core/Model/Object.hpp"
#include "Core/Model/SceneDescription.hpp"
#include "Util/Logging.hpp"
#include "Util/NameList.hpp"
#include "Util/PredefinedMeshes.hpp"
#include "Util/Utils.hpp"
#include "VkUtil/VkUtil.hpp"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "imgui_impl_vulkan.h"
#include "imgui_impl_glfw.h"

29 30 31 32
using lib::log::Debug;
using lib::log::Error;
using lib::log::Info;
using lib::log::Warning;
33 34 35 36 37 38 39 40 41 42

bool lib::CgContext::TryCreateRasterizerPipeline()
{
    auto success = true;
    auto vertexModule = this->LoadShader(this->appInfo.shaderTable.postProcessingVertexShader);

    success = success && vertexModule;

    auto fragmentModule = this->LoadShader(this->appInfo.shaderTable.postProcessingFragmentShader);

43
    success = success && fragmentModule;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

    if (success)
    {
        std::vector<vk::PipelineShaderStageCreateInfo> shaderStages{
            vk::PipelineShaderStageCreateInfo{
                vk::PipelineShaderStageCreateFlags{},
                vk::ShaderStageFlagBits::eVertex,
                vertexModule,
                "main",
            },
            vk::PipelineShaderStageCreateInfo{
                vk::PipelineShaderStageCreateFlags{},
                vk::ShaderStageFlagBits::eFragment,
                fragmentModule,
                "main",
            },
        };

        vk::PipelineVertexInputStateCreateInfo emptyInputCreateInfo;

        vk::PipelineInputAssemblyStateCreateInfo inputAssemblyCreateInfo;
        inputAssemblyCreateInfo.topology = vk::PrimitiveTopology::eTriangleList;
        inputAssemblyCreateInfo.primitiveRestartEnable = false;

        vk::Viewport viewport;
69 70
        viewport.x = 0.f;
        viewport.y = 0.f;
71 72 73 74 75 76
        viewport.width = static_cast<float>(this->swapChainExtent.width);
        viewport.height = static_cast<float>(this->swapChainExtent.height);
        viewport.minDepth = 0.f;
        viewport.maxDepth = 1.f;

        vk::Rect2D scissor;
77
        scissor.offset = {0, 0};
78 79 80 81 82 83 84 85 86
        scissor.extent = this->swapChainExtent;

        vk::PipelineViewportStateCreateInfo viewportStateCreateInfo;
        viewportStateCreateInfo.viewportCount = 1;
        viewportStateCreateInfo.pViewports = &viewport;
        viewportStateCreateInfo.scissorCount = 1;
        viewportStateCreateInfo.pScissors = &scissor;

        vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo;
87 88
        rasterizationStateCreateInfo.depthClampEnable = false;
        rasterizationStateCreateInfo.rasterizerDiscardEnable = false;
89
        rasterizationStateCreateInfo.polygonMode = vk::PolygonMode::eFill;
90 91 92 93
        rasterizationStateCreateInfo.lineWidth = 1.f;
        rasterizationStateCreateInfo.frontFace = vk::FrontFace::eCounterClockwise;
        rasterizationStateCreateInfo.cullMode = vk::CullModeFlagBits::eBack;
        rasterizationStateCreateInfo.depthBiasEnable = false;
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

        vk::PipelineMultisampleStateCreateInfo multiSampleStageCreateInfo;
        multiSampleStageCreateInfo.sampleShadingEnable = false;
        multiSampleStageCreateInfo.rasterizationSamples = vk::SampleCountFlagBits::e1;

        vk::PipelineColorBlendAttachmentState colorBlendAttachmentState;
        colorBlendAttachmentState.colorWriteMask = vk::ColorComponentFlagBits::eR |
                                                   vk::ColorComponentFlagBits::eG |
                                                   vk::ColorComponentFlagBits::eB |
                                                   vk::ColorComponentFlagBits::eA;
        colorBlendAttachmentState.blendEnable = false;

        vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo;
        colorBlendStateCreateInfo.logicOpEnable = false;
        colorBlendStateCreateInfo.logicOp = vk::LogicOp::eCopy;
        colorBlendStateCreateInfo.attachmentCount = 1;
        colorBlendStateCreateInfo.pAttachments = &colorBlendAttachmentState;

        vk::PipelineLayoutCreateInfo layoutCreateInfo;
        layoutCreateInfo.setLayoutCount = 1;
        layoutCreateInfo.pSetLayouts = &this->rasterizationStep.descriptorSetLayout;

        this->rasterizationStep.pipelineLayout = this->logicalDevice.createPipelineLayout(layoutCreateInfo);

        vk::GraphicsPipelineCreateInfo createInfo;
        createInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
        createInfo.pStages = shaderStages.data();
        createInfo.pVertexInputState = &emptyInputCreateInfo;
        createInfo.pInputAssemblyState = &inputAssemblyCreateInfo;
        createInfo.pViewportState = &viewportStateCreateInfo;
        createInfo.pRasterizationState = &rasterizationStateCreateInfo;
        createInfo.pMultisampleState = &multiSampleStageCreateInfo;
        createInfo.pColorBlendState = &colorBlendStateCreateInfo;
127
        createInfo.renderPass = this->rasterizationStep.renderPass;
128 129
        createInfo.layout = this->rasterizationStep.pipelineLayout;

Lukas Tietze's avatar
Lukas Tietze committed
130
        const auto result = this->logicalDevice.createGraphicsPipeline(nullptr, createInfo);
131 132 133 134 135 136 137 138 139 140 141

        if (result.result == vk::Result::eSuccess)
        {
            this->rasterizationStep.pipeline = result.value;
        }
        else
        {
            Error("Failed to create Graphicspipeline!");

            success = false;
        }
142 143 144 145 146 147 148 149 150 151 152 153
    }

    if (vertexModule)
    {
        this->logicalDevice.destroyShaderModule(vertexModule);
    }

    if (fragmentModule)
    {
        this->logicalDevice.destroyShaderModule(fragmentModule);
    }

154 155
    lib::log::Info("Successfully create rasterization pipeline!");

156 157 158 159 160
    return success;
}

void lib::CgContext::CreateRasterizationDescriptorSets()
{
Lukas Tietze's avatar
Lukas Tietze committed
161 162 163 164 165 166 167 168 169
    const auto count = static_cast<uint32_t>(this->frames.size());

    std::vector<vk::DescriptorSetLayout> layouts(count, this->rasterizationStep.descriptorSetLayout);

    vk::DescriptorSetAllocateInfo allocateInfo;
    allocateInfo.descriptorPool = this->rasterizationStep.descriptorPool;
    allocateInfo.descriptorSetCount = count;
    allocateInfo.pSetLayouts = layouts.data();

Lukas Tietze's avatar
Lukas Tietze committed
170 171
    auto sets = this->logicalDevice.allocateDescriptorSets(allocateInfo);
    auto setsIt = std::begin(sets);
Lukas Tietze's avatar
Lukas Tietze committed
172

Lukas Tietze's avatar
Lukas Tietze committed
173
    for (auto &frame : this->frames)
Lukas Tietze's avatar
Lukas Tietze committed
174
    {
Lukas Tietze's avatar
Lukas Tietze committed
175 176
        frame.rasterizationDescriptorSet = *setsIt++;

Lukas Tietze's avatar
Lukas Tietze committed
177 178
        vk::DescriptorImageInfo rtImageInfo;
        rtImageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
Lukas Tietze's avatar
Lukas Tietze committed
179 180 181 182 183
        // rtImageInfo.imageView = frame.raytracingTexture->GetView();
        // rtImageInfo.sampler = frame.raytracingTexture->GetSampler();

        rtImageInfo.imageView = this->dummyTexture->GetView();
        rtImageInfo.sampler = this->dummyTexture->GetSampler();
Lukas Tietze's avatar
Lukas Tietze committed
184 185 186 187 188 189 190

        vk::WriteDescriptorSet rtImageWrite;
        rtImageWrite.descriptorCount = 1;
        rtImageWrite.descriptorType = vk::DescriptorType::eCombinedImageSampler;
        rtImageWrite.dstArrayElement = 0;
        rtImageWrite.dstBinding = 0;
        rtImageWrite.pImageInfo = &rtImageInfo;
Lukas Tietze's avatar
Lukas Tietze committed
191
        rtImageWrite.dstSet = frame.rasterizationDescriptorSet;
Lukas Tietze's avatar
Lukas Tietze committed
192 193 194

        this->logicalDevice.updateDescriptorSets(rtImageWrite, {});
    }
195 196

    lib::log::Info("Successfully created rasterization descriptor sets!");
197 198 199 200
}

void lib::CgContext::CreateRasterizationDescriptorPool()
{
Lukas Tietze's avatar
Lukas Tietze committed
201 202 203
    const auto count = static_cast<uint32_t>(this->frames.size());

    std::vector<vk::DescriptorPoolSize> poolSizes{
Lukas Tietze's avatar
Lukas Tietze committed
204
        {vk::DescriptorType::eCombinedImageSampler, count},
Lukas Tietze's avatar
Lukas Tietze committed
205 206 207 208 209 210 211 212
    };

    vk::DescriptorPoolCreateInfo createInfo;
    createInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
    createInfo.pPoolSizes = poolSizes.data();
    createInfo.maxSets = count;

    this->rasterizationStep.descriptorPool = this->logicalDevice.createDescriptorPool(createInfo);
213 214

    lib::log::Info("Successfully created rasterization descriptor pool!");
215 216 217 218 219
}

void lib::CgContext::CreateRasterizationDescriptorSetLayout()
{
    std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
Lukas Tietze's avatar
Lukas Tietze committed
220

Lukas Tietze's avatar
Lukas Tietze committed
221
    auto &item = layoutBindings.emplace_back();
Lukas Tietze's avatar
Lukas Tietze committed
222 223
    item.binding = 0;
    item.descriptorType = vk::DescriptorType::eCombinedImageSampler;
Lukas Tietze's avatar
Lukas Tietze committed
224 225 226 227 228 229 230 231
    item.descriptorCount = 1;
    item.stageFlags = vk::ShaderStageFlagBits::eFragment;

    vk::DescriptorSetLayoutCreateInfo createInfo;
    createInfo.bindingCount = static_cast<uint32_t>(layoutBindings.size());
    createInfo.pBindings = layoutBindings.data();

    this->rasterizationStep.descriptorSetLayout = this->logicalDevice.createDescriptorSetLayout(createInfo);
232 233

    lib::log::Info("Successfully created rasterization descriptor set layouts!");
234 235 236 237
}

void lib::CgContext::CreateRasterizationRenderPass()
{
Lukas Tietze's avatar
Lukas Tietze committed
238
    vk::AttachmentDescription colorAttachment;
Lukas Tietze's avatar
Lukas Tietze committed
239 240
    colorAttachment.initialLayout = vk::ImageLayout::eUndefined;
    colorAttachment.finalLayout = vk::ImageLayout::ePresentSrcKHR;
Lukas Tietze's avatar
Lukas Tietze committed
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    colorAttachment.loadOp = vk::AttachmentLoadOp::eDontCare;
    colorAttachment.storeOp = vk::AttachmentStoreOp::eStore;
    colorAttachment.format = this->swapChainImageFormat;
    colorAttachment.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
    colorAttachment.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;

    vk::AttachmentReference colorAttachmentRef;
    colorAttachmentRef.layout = vk::ImageLayout::eColorAttachmentOptimal;
    colorAttachmentRef.attachment = 0;

    vk::SubpassDescription subpassDescription;
    subpassDescription.pipelineBindPoint = vk::PipelineBindPoint::eGraphics;
    subpassDescription.colorAttachmentCount = 1;
    subpassDescription.pColorAttachments = &colorAttachmentRef;

    vk::SubpassDependency subpassDependency;
    subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    subpassDependency.dstSubpass = 0;
    subpassDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
    subpassDependency.srcAccessMask = vk::AccessFlagBits{};
    subpassDependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
    subpassDependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;

264
    vk::RenderPassCreateInfo createInfo;
Lukas Tietze's avatar
Lukas Tietze committed
265 266 267 268 269 270 271 272
    createInfo.subpassCount = 1;
    createInfo.pSubpasses = &subpassDescription;
    createInfo.dependencyCount = 1;
    createInfo.pDependencies = &subpassDependency;
    createInfo.attachmentCount = 1;
    createInfo.pAttachments = &colorAttachment;

    this->rasterizationStep.renderPass = this->logicalDevice.createRenderPass(createInfo);
273 274

    lib::log::Info("Successfully created rasterization render pass!");
275
}
276 277 278 279 280

void lib::CgContext::CreateRasterizationFrameBuffers()
{
    const auto count = static_cast<uint32_t>(frames.size());

Lukas Tietze's avatar
Lukas Tietze committed
281
    for (auto &frame : this->frames)
282
    {
Lukas Tietze's avatar
Lukas Tietze committed
283 284 285 286 287 288 289 290 291
        const lib::TextureCreateInfo textureCreateInfo{
            {
                this->physicalDeviceInfo.GetGraphicsQueueFamily(),
                this->physicalDeviceInfo.GetBufferStagingQueueFamily(),
                this->physicalDeviceInfo.GetComputeQueueFamily(),
                this->physicalDeviceInfo.GetPresentationQueueFamily(),
            },
            this->swapChainImageFormat,
            vk::ImageUsageFlagBits::eSampled |
Lukas Tietze's avatar
Lukas Tietze committed
292
                vk::ImageUsageFlagBits::eStorage,
Lukas Tietze's avatar
Lukas Tietze committed
293 294 295 296 297 298 299 300 301
            vk::ImageLayout::eGeneral};

        auto newTexture = new lib::Texture{this,
                                           this->swapChainExtent.width,
                                           this->swapChainExtent.height,
                                           textureCreateInfo};

        frame.raytracingTexture.reset(newTexture);

302 303 304
        vk::FramebufferCreateInfo createInfo;
        createInfo.renderPass = this->rasterizationStep.renderPass;
        createInfo.attachmentCount = 1;
Lukas Tietze's avatar
Lukas Tietze committed
305
        createInfo.pAttachments = &frame.swapChainImageView;
306 307 308 309
        createInfo.width = this->swapChainExtent.width;
        createInfo.height = this->swapChainExtent.height;
        createInfo.layers = 1;

Lukas Tietze's avatar
Lukas Tietze committed
310
        frame.swapChainFramebufferForRasterizationRenderPass = logicalDevice.createFramebuffer(createInfo);
311
    }
Lukas Tietze's avatar
Lukas Tietze committed
312 313

    lib::log::Info("Successfully created rasterization framebuffers!");
314
}