Commit c3569eb3 authored by Lukas Tietze's avatar Lukas Tietze

Weitere Aufteilung von CgContext

parent b8d74483
......@@ -40,6 +40,8 @@ add_library(
src/Lib/src/Core/CgContext.cpp
src/Lib/src/Core/CgContext.Basics.cpp
src/Lib/src/Core/CgContext.ImGui.cpp
src/Lib/src/Core/CgContext.Rasterization.cpp
src/Lib/src/Core/CgContext.Raytracing.cpp
src/Lib/src/Core/CoreInitException.cpp
src/Lib/src/Core/DeviceInfo.cpp
src/Lib/src/Core/SwapChainInfo.cpp
......
......@@ -216,6 +216,7 @@ namespace lib
void CreateSurface();
void CreateSwapChain();
void CreateImageViews();
void CreateRasterizationRenderPass();
void CreateCommandPool();
void LoadDummyTexture();
......
#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"
using lib::log::Log;
using lib::log::LogDebug;
using lib::log::LogError;
using lib::log::LogWarning;
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);
success = success && vertexModule;
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;
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;
scissor.extent = this->swapChainExtent;
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo;
viewportStateCreateInfo.viewportCount = 1;
viewportStateCreateInfo.pViewports = &viewport;
viewportStateCreateInfo.scissorCount = 1;
viewportStateCreateInfo.pScissors = &scissor;
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo;
rasterizationStateCreateInfo.cullMode = vk::CullModeFlagBits::eFront;
rasterizationStateCreateInfo.frontFace = vk::FrontFace::eCounterClockwise;
rasterizationStateCreateInfo.lineWidth = 1.f;
rasterizationStateCreateInfo.polygonMode = vk::PolygonMode::eFill;
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;
createInfo.layout = this->rasterizationStep.pipelineLayout;
this->rasterizationStep.pipeline = this->logicalDevice.createGraphicsPipeline(nullptr, createInfo);
}
if (vertexModule)
{
this->logicalDevice.destroyShaderModule(vertexModule);
}
if (fragmentModule)
{
this->logicalDevice.destroyShaderModule(fragmentModule);
}
return success;
}
void lib::CgContext::CreateRasterizationDescriptorSets()
{
// TODO
}
void lib::CgContext::CreateRasterizationDescriptorPool()
{
// TODO
}
void lib::CgContext::CreateRasterizationDescriptorSetLayout()
{
// TODO
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
}
void lib::CgContext::CreateRasterizationRenderPass()
{
// TODO
vk::RenderPassCreateInfo createInfo;
}
#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"
using lib::log::Log;
using lib::log::LogDebug;
using lib::log::LogError;
using lib::log::LogWarning;
void lib::CgContext::CreateAccelerationStructures()
{
auto commandBuffer = this->AllocateSingleUseComputeCommandBuffer();
this->topLevelAS = std::make_unique<TopLevelAccelerationStructure>(this);
for (size_t i = 0; i < this->geometryInstances.size(); i++)
{
auto &bas = this->bottomLevelAS.emplace_back(this);
bas.Fill({this->geometryInstances[i]}, sizeof(vertex_t), vertex_t::PositionFormat, IndexTypeOf<index_t>);
bas.ScheduleGeneration(commandBuffer);
this->topLevelAS->AddBottomLevelInstance(bas.getHandle(), this->geometryInstances[i].transformationMatrix,
static_cast<uint32_t>(i), 0);
}
this->topLevelAS->ScheduleGeneration(commandBuffer.GetHandle());
commandBuffer.Run();
Log("Successfully created acceleration structures!");
}
void lib::CgContext::CreateRaytracingDescriptorSetLayout()
{
std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
layoutBindings.reserve(8);
// acceleration structure
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.accelerationStructure;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eAccelerationStructureNV;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eRaygenNV |
vk::ShaderStageFlagBits::eClosestHitNV;
// output image
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.outputImage;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageImage;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eRaygenNV;
// camera UBO
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.cameraAndLightUbo;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eUniformBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eRaygenNV |
vk::ShaderStageFlagBits::eClosestHitNV |
vk::ShaderStageFlagBits::eMissNV;
// vertex buffers
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.vertices;
layoutBindings.back().descriptorCount = static_cast<uint32_t>(this->vertexBuffers.size());
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV;
// index buffers
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.indices;
layoutBindings.back().descriptorCount = static_cast<uint32_t>(this->indexBuffers.size());
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV;
// materials buffers
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.materials;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV;
// object instance buffer
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.objectInstances;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV;
// light sources buffer
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.lightSources;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eStorageBuffer;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV;
// dummy texture
layoutBindings.emplace_back();
layoutBindings.back().binding = this->descriptorBindings.dummyTexture;
layoutBindings.back().descriptorCount = 1;
layoutBindings.back().descriptorType = vk::DescriptorType::eCombinedImageSampler;
layoutBindings.back().stageFlags = vk::ShaderStageFlagBits::eClosestHitNV | vk::ShaderStageFlagBits::eRaygenNV;
vk::DescriptorSetLayoutCreateInfo createInfo;
createInfo.bindingCount = static_cast<uint32_t>(layoutBindings.size());
createInfo.pBindings = layoutBindings.data();
this->raytracingStep.descriptorSetLayout = this->logicalDevice.createDescriptorSetLayout(createInfo);
Log("Successfully created descriptor set layout!");
}
void lib::CgContext::CreateRaytracingDescriptorPool()
{
auto count = static_cast<uint32_t>(this->frames.size());
std::vector<vk::DescriptorPoolSize> sizes{
//Acceleration structure
vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureNV, count),
// output image
vk::DescriptorPoolSize(vk::DescriptorType::eStorageImage, count),
// camera ubo
vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, count),
// materials
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, count),
// object instances
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, count),
// vertices
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, count * static_cast<uint32_t>(this->vertexBuffers.size())),
// indices
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, count * static_cast<uint32_t>(this->indexBuffers.size())),
// dummy texture
vk::DescriptorPoolSize(vk::DescriptorType::eCombinedImageSampler, count),
};
vk::DescriptorPoolCreateInfo createInfo;
createInfo.poolSizeCount = static_cast<uint32_t>(sizes.size());
createInfo.pPoolSizes = sizes.data();
createInfo.maxSets = static_cast<uint32_t>(count);
this->raytracingStep.descriptorPool = this->logicalDevice.createDescriptorPool(createInfo);
}
void lib::CgContext::CreateRaytracingDescriptorSets()
{
auto count = static_cast<uint32_t>(this->frames.size());
std::vector<vk::DescriptorSetLayout> layouts(count, this->raytracingStep.descriptorSetLayout);
vk::DescriptorSetAllocateInfo allocateInfo;
allocateInfo.descriptorPool = this->raytracingStep.descriptorPool;
allocateInfo.pSetLayouts = layouts.data();
allocateInfo.descriptorSetCount = count;
const auto descriptorSets = this->logicalDevice.allocateDescriptorSets(allocateInfo);
for (size_t i = 0; i < count; i++)
{
auto &frame = this->frames[i];
frame.descriptorSet = descriptorSets[i];
vk::StructureChain<vk::WriteDescriptorSet, vk::WriteDescriptorSetAccelerationStructureNV> accelerationStructureWrite;
accelerationStructureWrite.get<vk::WriteDescriptorSet>().dstSet = frame.descriptorSet;
accelerationStructureWrite.get<vk::WriteDescriptorSet>().dstBinding = this->descriptorBindings.accelerationStructure;
accelerationStructureWrite.get<vk::WriteDescriptorSet>().dstArrayElement = 0;
accelerationStructureWrite.get<vk::WriteDescriptorSet>().descriptorType = vk::DescriptorType::eAccelerationStructureNV;
accelerationStructureWrite.get<vk::WriteDescriptorSet>().descriptorCount = 1;
accelerationStructureWrite.get<vk::WriteDescriptorSetAccelerationStructureNV>().accelerationStructureCount = 1;
accelerationStructureWrite.get<vk::WriteDescriptorSetAccelerationStructureNV>().pAccelerationStructures = &this->topLevelAS->getHandle();
vk::DescriptorImageInfo outputImageInfo;
outputImageInfo.imageLayout = vk::ImageLayout::eGeneral;
outputImageInfo.imageView = frame.swapChainImageView;
vk::WriteDescriptorSet outputImageWrite;
outputImageWrite.dstSet = frame.descriptorSet;
outputImageWrite.dstBinding = this->descriptorBindings.outputImage;
outputImageWrite.dstArrayElement = 0;
outputImageWrite.descriptorType = vk::DescriptorType::eStorageImage;
outputImageWrite.descriptorCount = 1;
outputImageWrite.pImageInfo = &outputImageInfo;
vk::DescriptorBufferInfo camInfo;
camInfo.buffer = frame.ubo->GetDeviceBufferHandle();
camInfo.range = sizeof(SceneDescription);
vk::WriteDescriptorSet camWrite;
camWrite.dstSet = frame.descriptorSet;
camWrite.dstBinding = this->descriptorBindings.cameraAndLightUbo;
camWrite.dstArrayElement = 0;
camWrite.descriptorType = vk::DescriptorType::eUniformBuffer;
camWrite.descriptorCount = 1;
camWrite.pBufferInfo = &camInfo;
std::vector<vk::DescriptorBufferInfo> vertexBufferInfos;
vertexBufferInfos.reserve(this->vertexBuffers.size());
for (const auto &vertexBuffer : this->vertexBuffers)
{
vertexBufferInfos.emplace_back();
vertexBufferInfos.back().buffer = vertexBuffer.GetBufferHandle();
vertexBufferInfos.back().range = VK_WHOLE_SIZE;
}
vk::WriteDescriptorSet vertexBufferWrite;
vertexBufferWrite.dstSet = frame.descriptorSet;
vertexBufferWrite.dstBinding = this->descriptorBindings.vertices;
vertexBufferWrite.dstArrayElement = 0;
vertexBufferWrite.descriptorType = vk::DescriptorType::eStorageBuffer;
vertexBufferWrite.descriptorCount = static_cast<uint32_t>(this->vertexBuffers.size());
vertexBufferWrite.pBufferInfo = vertexBufferInfos.data();
std::vector<vk::DescriptorBufferInfo> indexBufferInfos;
indexBufferInfos.reserve(this->indexBuffers.size());
for (const auto &indexBuffer : this->indexBuffers)
{
indexBufferInfos.emplace_back();
indexBufferInfos.back().buffer = indexBuffer.GetBufferHandle();
indexBufferInfos.back().range = VK_WHOLE_SIZE;
}
vk::WriteDescriptorSet indexBufferWrite;
indexBufferWrite.dstSet = frame.descriptorSet;
indexBufferWrite.dstBinding = this->descriptorBindings.indices;
indexBufferWrite.dstArrayElement = 0;
indexBufferWrite.descriptorType = vk::DescriptorType::eStorageBuffer;
indexBufferWrite.descriptorCount = static_cast<uint32_t>(indexBufferInfos.size());
indexBufferWrite.pBufferInfo = indexBufferInfos.data();
vk::DescriptorBufferInfo materialBufferInfo;
materialBufferInfo.buffer = materialsBuffer->GetBufferHandle();
materialBufferInfo.range = VK_WHOLE_SIZE;
vk::WriteDescriptorSet materialBufferWrite;
materialBufferWrite.dstSet = frame.descriptorSet;
materialBufferWrite.dstBinding = this->descriptorBindings.materials;
materialBufferWrite.dstArrayElement = 0;
materialBufferWrite.descriptorType = vk::DescriptorType::eStorageBuffer;
materialBufferWrite.descriptorCount = 1;
materialBufferWrite.pBufferInfo = &materialBufferInfo;
vk::DescriptorBufferInfo objectInstanceInfo;
objectInstanceInfo.buffer = objectInstancesBuffer->GetBufferHandle();
objectInstanceInfo.range = VK_WHOLE_SIZE;
vk::WriteDescriptorSet objectInstanceWrite;
objectInstanceWrite.dstSet = frame.descriptorSet;
objectInstanceWrite.dstBinding = this->descriptorBindings.objectInstances;
objectInstanceWrite.dstArrayElement = 0;
objectInstanceWrite.descriptorType = vk::DescriptorType::eStorageBuffer;
objectInstanceWrite.descriptorCount = 1;
objectInstanceWrite.pBufferInfo = &objectInstanceInfo;
vk::DescriptorImageInfo dummyTextureInfo;
dummyTextureInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
dummyTextureInfo.imageView = this->dummyTexture->GetView();
dummyTextureInfo.sampler = this->dummyTexture->GetSampler();
vk::WriteDescriptorSet dummyTextureWrite;
dummyTextureWrite.dstSet = frame.descriptorSet;
dummyTextureWrite.dstBinding = this->descriptorBindings.dummyTexture;
dummyTextureWrite.dstArrayElement = 0;
dummyTextureWrite.descriptorType = vk::DescriptorType::eCombinedImageSampler;
dummyTextureWrite.descriptorCount = 1;
dummyTextureWrite.pImageInfo = &dummyTextureInfo;
this->logicalDevice.updateDescriptorSets({accelerationStructureWrite.get<vk::WriteDescriptorSet>(),
outputImageWrite,
camWrite,
vertexBufferWrite,
indexBufferWrite,
materialBufferWrite,
objectInstanceWrite,
dummyTextureWrite},
{});
}
Log("Successfully created raytracing descriptor set!");
}
bool lib::CgContext::TryCreateRayTracingPipeline()
{
auto raygenModule = this->LoadShader(this->appInfo.shaderTable.raygenShader);
auto success = static_cast<bool>(raygenModule);
std::vector<vk::ShaderModule> missModules;
missModules.reserve(this->appInfo.shaderTable.missShaders.size());
for (const auto &missModule : this->appInfo.shaderTable.missShaders)
{
missModules.push_back(this->LoadShader(missModule));
success = success && missModules.back();
}
std::vector<vk::ShaderModule> closestHitModules;
closestHitModules.reserve(this->appInfo.shaderTable.closestHitShaders.size());
for (const auto &closestHitModule : this->appInfo.shaderTable.closestHitShaders)
{
closestHitModules.push_back(this->LoadShader(closestHitModule));
success = success && closestHitModules.back();
}
this->shaderOffsets.rayGen = 0;
this->shaderOffsets.miss = 1;
this->shaderOffsets.hitGroup = static_cast<uint32_t>(missModules.size() + this->shaderOffsets.miss);
this->shaderOffsets.count = static_cast<uint32_t>(this->shaderOffsets.hitGroup + closestHitModules.size());
if (success)
{
std::vector<vk::PipelineShaderStageCreateInfo> stageCreateInfos;
std::vector<vk::RayTracingShaderGroupCreateInfoNV> groupInfos;
stageCreateInfos.reserve(this->shaderOffsets.count);
groupInfos.reserve(this->shaderOffsets.count);
vk::PipelineShaderStageCreateInfo raygenStageCreateInfo;
raygenStageCreateInfo.stage = vk::ShaderStageFlagBits::eRaygenNV;
raygenStageCreateInfo.module = raygenModule;
raygenStageCreateInfo.pName = "main";
vk::RayTracingShaderGroupCreateInfoNV raygenGroupInfo;
raygenGroupInfo.type = vk::RayTracingShaderGroupTypeNV::eGeneral;
raygenGroupInfo.generalShader = 0;
raygenGroupInfo.anyHitShader = VK_SHADER_UNUSED_NV;
raygenGroupInfo.intersectionShader = VK_SHADER_UNUSED_NV;
raygenGroupInfo.closestHitShader = VK_SHADER_UNUSED_NV;
stageCreateInfos.push_back(raygenStageCreateInfo);
groupInfos.push_back(raygenGroupInfo);
for (size_t i = 0; i < missModules.size(); i++)
{
vk::PipelineShaderStageCreateInfo stageCreateInfo;
stageCreateInfo.stage = vk::ShaderStageFlagBits::eMissNV;
stageCreateInfo.module = missModules[i];
stageCreateInfo.pName = "main";
stageCreateInfos.push_back(stageCreateInfo);
vk::RayTracingShaderGroupCreateInfoNV groupInfo;
groupInfo.type = vk::RayTracingShaderGroupTypeNV::eGeneral;
groupInfo.generalShader = static_cast<uint32_t>(shaderOffsets.miss + i);
groupInfo.anyHitShader = VK_SHADER_UNUSED_NV;
groupInfo.intersectionShader = VK_SHADER_UNUSED_NV;
groupInfo.closestHitShader = VK_SHADER_UNUSED_NV;
groupInfos.push_back(groupInfo);
}
for (size_t i = 0; i < closestHitModules.size(); i++)
{
vk::PipelineShaderStageCreateInfo stageCreateInfo;
stageCreateInfo.stage = vk::ShaderStageFlagBits::eClosestHitNV;
stageCreateInfo.module = closestHitModules[i];
stageCreateInfo.pName = "main";
stageCreateInfos.push_back(stageCreateInfo);
vk::RayTracingShaderGroupCreateInfoNV groupInfo;
groupInfo.type = vk::RayTracingShaderGroupTypeNV::eTrianglesHitGroup;
groupInfo.closestHitShader = static_cast<uint32_t>(shaderOffsets.hitGroup + i);
groupInfo.anyHitShader = VK_SHADER_UNUSED_NV;
groupInfo.intersectionShader = VK_SHADER_UNUSED_NV;
groupInfo.generalShader = VK_SHADER_UNUSED_NV;
groupInfos.push_back(groupInfo);
}
vk::PushConstantRange pushConstantRange;
pushConstantRange.offset = 0;
pushConstantRange.size = sizeof(this->pushConstant);
pushConstantRange.stageFlags = vk::ShaderStageFlagBits::eRaygenNV | vk::ShaderStageFlagBits::eClosestHitNV;
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
pipelineLayoutCreateInfo.setLayoutCount = 1;
pipelineLayoutCreateInfo.pSetLayouts = &this->raytracingStep.descriptorSetLayout;
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
this->raytracingStep.pipelineLayout = this->logicalDevice.createPipelineLayout(pipelineLayoutCreateInfo);
vk::RayTracingPipelineCreateInfoNV pipelineCreateInfo;
pipelineCreateInfo.stageCount = static_cast<uint32_t>(stageCreateInfos.size());
pipelineCreateInfo.pStages = stageCreateInfos.data();
pipelineCreateInfo.groupCount = static_cast<uint32_t>(groupInfos.size());
pipelineCreateInfo.pGroups = groupInfos.data();
pipelineCreateInfo.maxRecursionDepth = this->physicalDeviceInfo.GetRaytracingProperties().maxRecursionDepth;
pipelineCreateInfo.layout = this->raytracingStep.pipelineLayout;
this->raytracingStep.pipeline = this->logicalDevice.createRayTracingPipelinesNV(vk::PipelineCache(), pipelineCreateInfo)[0];
Log("Successfully created raytracing pipeline!");
success = true;
}
else
{
LogError("Failed to load shaders required for raytracing!");
}
if (raygenModule)
{
this->logicalDevice.destroyShaderModule(raygenModule);
}
for (const auto module : missModules)
{
if (module)
{
this->logicalDevice.destroyShaderModule(module);