Using Vulkan C API
This commit is contained in:
parent
b3e6d84807
commit
e642e9dc3a
83 changed files with 8015 additions and 8163 deletions
|
|
@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.9.6 FATAL_ERROR)
|
|||
#--------------------------------------------------------------------------------------------------
|
||||
# Project setting
|
||||
get_filename_component(PROJNAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
SET(PROJNAME vk_${PROJNAME}_KHR)
|
||||
set(PROJNAME vk_${PROJNAME}_KHR)
|
||||
project(${PROJNAME} LANGUAGES C CXX)
|
||||
message(STATUS "-------------------------------")
|
||||
message(STATUS "Processing Project ${PROJNAME}:")
|
||||
|
|
|
|||
|
|
@ -62,17 +62,20 @@ void HelloVulkan::animationInstances(float time)
|
|||
Next, we update the buffer that describes the scene, which is used by the rasterizer to set each object's position, and also by the ray tracer to compute shading normals.
|
||||
~~~~ C++
|
||||
// Update the buffer
|
||||
vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
|
||||
nvvkBuffer stagingBuffer = m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible);
|
||||
VkDeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
|
||||
nvvk::Buffer stagingBuffer =
|
||||
m_alloc.createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
// Copy data to staging buffer
|
||||
auto* gInst = m_alloc.map(stagingBuffer);
|
||||
memcpy(gInst, m_objInstance.data(), bufferSize);
|
||||
m_alloc.unmap(stagingBuffer);
|
||||
// Copy staging buffer to the Scene Description buffer
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
cmdBuf.copyBuffer(stagingBuffer.buffer, m_sceneDesc.buffer, vk::BufferCopy(0, 0, bufferSize));
|
||||
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
|
||||
VkBufferCopy region{0, 0, bufferSize};
|
||||
vkCmdCopyBuffer(cmdBuf, stagingBuffer.buffer, m_sceneDesc.buffer, 1, ®ion);
|
||||
|
||||
m_debug.endLabel(cmdBuf);
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
m_alloc.destroy(stagingBuffer);
|
||||
|
|
@ -115,7 +118,7 @@ std::vector<nvvk::RaytracingBuilder::Instance> m_tlas;
|
|||
|
||||
Make sure to rename it to `m_tlas`, instead of `tlas`.
|
||||
|
||||
One important point is that we need to set the TLAS build flags to allow updates, by adding the`vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate` flag.
|
||||
One important point is that we need to set the TLAS build flags to allow updates, by adding the`VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR` flag.
|
||||
This is absolutely needed, since otherwise the TLAS cannot be updated.
|
||||
|
||||
~~~~ C++
|
||||
|
|
@ -124,16 +127,17 @@ void HelloVulkan::createTopLevelAS()
|
|||
m_tlas.reserve(m_objInstance.size());
|
||||
for(uint32_t i = 0; i < static_cast<uint32_t>(m_objInstance.size()); i++)
|
||||
{
|
||||
nvvk::RaytracingBuilder::Instance rayInst;
|
||||
nvvk::RaytracingBuilderKHR::Instance rayInst;
|
||||
rayInst.transform = m_objInstance[i].transform; // Position of the instance
|
||||
rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT
|
||||
rayInst.blasId = m_objInstance[i].objIndex;
|
||||
rayInst.hitGroupId = m_objInstance[i].hitgroup;
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV;
|
||||
rayInst.hitGroupId = 0;
|
||||
rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
|
||||
m_tlas.emplace_back(rayInst);
|
||||
}
|
||||
m_rtBuilder.buildTlas(m_tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace
|
||||
| vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate);
|
||||
|
||||
m_rtFlags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR | VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
|
||||
m_rtBuilder.buildTlas(m_tlas, m_rtFlags);
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -203,11 +207,11 @@ Add all of the following members to the `HelloVulkan` class:
|
|||
void createCompPipelines();
|
||||
|
||||
nvvk::DescriptorSetBindings m_compDescSetLayoutBind;
|
||||
vk::DescriptorPool m_compDescPool;
|
||||
vk::DescriptorSetLayout m_compDescSetLayout;
|
||||
vk::DescriptorSet m_compDescSet;
|
||||
vk::Pipeline m_compPipeline;
|
||||
vk::PipelineLayout m_compPipelineLayout;
|
||||
VkDescriptorPool m_compDescPool;
|
||||
VkDescriptorSetLayout m_compDescSetLayout;
|
||||
VkDescriptorSet m_compDescSet;
|
||||
VkPipeline m_compPipeline;
|
||||
VkPipelineLayout m_compPipelineLayout;
|
||||
~~~~
|
||||
|
||||
The compute shader will work on a single `VertexObj` buffer.
|
||||
|
|
@ -215,8 +219,7 @@ The compute shader will work on a single `VertexObj` buffer.
|
|||
~~~~ C++
|
||||
void HelloVulkan::createCompDescriptors()
|
||||
{
|
||||
m_compDescSetLayoutBind.addBinding(vk::DescriptorSetLayoutBinding(
|
||||
0, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eCompute));
|
||||
m_compDescSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
|
||||
m_compDescSetLayout = m_compDescSetLayoutBind.createLayout(m_device);
|
||||
m_compDescPool = m_compDescSetLayoutBind.createPool(m_device, 1);
|
||||
|
|
@ -227,12 +230,12 @@ void HelloVulkan::createCompDescriptors()
|
|||
`updateCompDescriptors` will set the set the descriptor to the buffer of `VertexObj` objects to which the animation will be applied.
|
||||
|
||||
~~~~ C++
|
||||
void HelloVulkan::updateCompDescriptors(nvvkBuffer& vertex)
|
||||
void HelloVulkan::updateCompDescriptors(nvvk::Buffer& vertex)
|
||||
{
|
||||
std::vector<vk::WriteDescriptorSet> writes;
|
||||
vk::DescriptorBufferInfo dbiUnif{vertex.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_compDescSetLayoutBind.makeWrite(m_compDescSet, 0, dbiUnif));
|
||||
m_device.updateDescriptorSets(static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
std::vector<VkWriteDescriptorSet> writes;
|
||||
VkDescriptorBufferInfo dbiUnif{vertex.buffer, 0, VK_WHOLE_SIZE};
|
||||
writes.emplace_back(m_compDescSetLayoutBind.makeWrite(m_compDescSet, 0, &dbiUnif));
|
||||
vkUpdateDescriptorSets(m_device, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -243,27 +246,37 @@ to set the animation time.
|
|||
void HelloVulkan::createCompPipelines()
|
||||
{
|
||||
// pushing time
|
||||
vk::PushConstantRange push_constants = {vk::ShaderStageFlagBits::eCompute, 0, sizeof(float)};
|
||||
vk::PipelineLayoutCreateInfo layout_info{{}, 1, &m_compDescSetLayout, 1, &push_constants};
|
||||
m_compPipelineLayout = m_device.createPipelineLayout(layout_info);
|
||||
vk::ComputePipelineCreateInfo computePipelineCreateInfo{{}, {}, m_compPipelineLayout};
|
||||
VkPushConstantRange push_constants = {VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(float)};
|
||||
|
||||
VkPipelineLayoutCreateInfo createInfo{VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO};
|
||||
createInfo.setLayoutCount = 1;
|
||||
createInfo.pSetLayouts = &m_compDescSetLayout;
|
||||
createInfo.pushConstantRangeCount = 1;
|
||||
createInfo.pPushConstantRanges = &push_constants;
|
||||
vkCreatePipelineLayout(m_device, &createInfo, nullptr, &m_compPipelineLayout);
|
||||
|
||||
|
||||
VkComputePipelineCreateInfo computePipelineCreateInfo{VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO};
|
||||
computePipelineCreateInfo.layout = m_compPipelineLayout;
|
||||
|
||||
computePipelineCreateInfo.stage =
|
||||
nvvk::createShaderStageInfo(m_device,
|
||||
nvh::loadFile("shaders/anim.comp.spv", true, defaultSearchPaths),
|
||||
nvvk::createShaderStageInfo(m_device, nvh::loadFile("spv/anim.comp.spv", true, defaultSearchPaths, true),
|
||||
VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
m_compPipeline = m_device.createComputePipeline({}, computePipelineCreateInfo, nullptr);
|
||||
m_device.destroy(computePipelineCreateInfo.stage.module);
|
||||
|
||||
vkCreateComputePipelines(m_device, {}, 1, &computePipelineCreateInfo, nullptr, &m_compPipeline);
|
||||
|
||||
vkDestroyShaderModule(m_device, computePipelineCreateInfo.stage.module, nullptr);
|
||||
}
|
||||
~~~~
|
||||
|
||||
Finally, destroy the resources in `HelloVulkan::destroyResources()`:
|
||||
|
||||
~~~~ C++
|
||||
m_device.destroy(m_compDescPool);
|
||||
m_device.destroy(m_compDescSetLayout);
|
||||
m_device.destroy(m_compPipeline);
|
||||
m_device.destroy(m_compPipelineLayout);
|
||||
// #VK_compute
|
||||
vkDestroyPipeline(m_device, m_compPipeline, nullptr);
|
||||
vkDestroyPipelineLayout(m_device, m_compPipelineLayout, nullptr);
|
||||
vkDestroyDescriptorPool(m_device, m_compDescPool, nullptr);
|
||||
vkDestroyDescriptorSetLayout(m_device, m_compDescSetLayout, nullptr);
|
||||
~~~~
|
||||
|
||||
### `anim.comp`
|
||||
|
|
@ -338,14 +351,13 @@ void HelloVulkan::animationObject(float time)
|
|||
updateCompDescriptors(model.vertexBuffer);
|
||||
|
||||
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex);
|
||||
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
|
||||
|
||||
vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, m_compPipeline);
|
||||
vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_COMPUTE, m_compPipelineLayout, 0, 1, &m_compDescSet, 0, nullptr);
|
||||
vkCmdPushConstants(cmdBuf, m_compPipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(float), &time);
|
||||
vkCmdDispatch(cmdBuf, model.nbVertices, 1, 1);
|
||||
|
||||
cmdBuf.bindPipeline(vk::PipelineBindPoint::eCompute, m_compPipeline);
|
||||
cmdBuf.bindDescriptorSets(vk::PipelineBindPoint::eCompute, m_compPipelineLayout, 0,
|
||||
{m_compDescSet}, {});
|
||||
cmdBuf.pushConstants(m_compPipelineLayout, vk::ShaderStageFlagBits::eCompute, 0, sizeof(float),
|
||||
&time);
|
||||
cmdBuf.dispatch(model.nbVertices, 1, 1);
|
||||
genCmdBuf.submitAndWait(cmdBuf);
|
||||
}
|
||||
~~~~
|
||||
|
|
@ -450,15 +462,15 @@ void HelloVulkan::createBottomLevelAS()
|
|||
{
|
||||
// BLAS - Storing each primitive in a geometry
|
||||
m_blas.reserve(m_objModel.size());
|
||||
for(const auto & obj : m_objModel)
|
||||
for(const auto& obj : m_objModel)
|
||||
{
|
||||
auto blas = objectToVkGeometryKHR(obj);
|
||||
|
||||
// We could add more geometry in each BLAS, but we add only one for now
|
||||
m_blas.push_back(blas);
|
||||
}
|
||||
m_rtBuilder.buildBlas(m_blas, vk::BuildAccelerationStructureFlagBitsKHR::eAllowUpdate
|
||||
| vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastBuild);
|
||||
m_rtBuilder.buildBlas(m_blas, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR
|
||||
| VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR);
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -19,11 +19,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/appbase_vk.hpp"
|
||||
#include "nvvk/debug_util_vk.hpp"
|
||||
#include "nvvk/descriptorsets_vk.hpp"
|
||||
#include "nvvk/memallocator_dma_vk.hpp"
|
||||
#include "nvvk/resourceallocator_vk.hpp"
|
||||
|
||||
// #VKRay
|
||||
#include "nvvk/raytraceKHR_vk.hpp"
|
||||
|
|
@ -36,25 +36,21 @@
|
|||
// - Rendering is done in an offscreen framebuffer
|
||||
// - The image of the framebuffer is displayed in post-process in a full-screen quad
|
||||
//
|
||||
class HelloVulkan : public nvvk::AppBase
|
||||
class HelloVulkan : public nvvk::AppBaseVk
|
||||
{
|
||||
public:
|
||||
void setup(const vk::Instance& instance,
|
||||
const vk::Device& device,
|
||||
const vk::PhysicalDevice& physicalDevice,
|
||||
uint32_t queueFamily) override;
|
||||
void setup(const VkInstance& instance, const VkDevice& device, const VkPhysicalDevice& physicalDevice, uint32_t queueFamily) override;
|
||||
void createDescriptorSetLayout();
|
||||
void createGraphicsPipeline();
|
||||
void loadModel(const std::string& filename, nvmath::mat4f transform = nvmath::mat4f(1));
|
||||
void updateDescriptorSet();
|
||||
void createUniformBuffer();
|
||||
void createSceneDescriptionBuffer();
|
||||
void createTextureImages(const vk::CommandBuffer& cmdBuf,
|
||||
const std::vector<std::string>& textures);
|
||||
void updateUniformBuffer(const vk::CommandBuffer& cmdBuf);
|
||||
void createTextureImages(const VkCommandBuffer& cmdBuf, const std::vector<std::string>& textures);
|
||||
void updateUniformBuffer(const VkCommandBuffer& cmdBuf);
|
||||
void onResize(int /*w*/, int /*h*/) override;
|
||||
void destroyResources();
|
||||
void rasterize(const vk::CommandBuffer& cmdBuff);
|
||||
void rasterize(const VkCommandBuffer& cmdBuff);
|
||||
|
||||
// The OBJ model
|
||||
struct ObjModel
|
||||
|
|
@ -91,39 +87,41 @@ public:
|
|||
std::vector<ObjInstance> m_objInstance;
|
||||
|
||||
// Graphic pipeline
|
||||
vk::PipelineLayout m_pipelineLayout;
|
||||
vk::Pipeline m_graphicsPipeline;
|
||||
VkPipelineLayout m_pipelineLayout;
|
||||
VkPipeline m_graphicsPipeline;
|
||||
nvvk::DescriptorSetBindings m_descSetLayoutBind;
|
||||
vk::DescriptorPool m_descPool;
|
||||
vk::DescriptorSetLayout m_descSetLayout;
|
||||
vk::DescriptorSet m_descSet;
|
||||
VkDescriptorPool m_descPool;
|
||||
VkDescriptorSetLayout m_descSetLayout;
|
||||
VkDescriptorSet m_descSet;
|
||||
|
||||
nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices
|
||||
nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances
|
||||
std::vector<nvvk::Texture> m_textures; // vector of all textures of the scene
|
||||
|
||||
|
||||
nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures
|
||||
nvvk::DebugUtil m_debug; // Utility to name objects
|
||||
|
||||
|
||||
// #Post
|
||||
void createOffscreenRender();
|
||||
void createPostPipeline();
|
||||
void createPostDescriptor();
|
||||
void updatePostDescriptorSet();
|
||||
void drawPost(vk::CommandBuffer cmdBuf);
|
||||
void drawPost(VkCommandBuffer cmdBuf);
|
||||
|
||||
nvvk::DescriptorSetBindings m_postDescSetLayoutBind;
|
||||
vk::DescriptorPool m_postDescPool;
|
||||
vk::DescriptorSetLayout m_postDescSetLayout;
|
||||
vk::DescriptorSet m_postDescSet;
|
||||
vk::Pipeline m_postPipeline;
|
||||
vk::PipelineLayout m_postPipelineLayout;
|
||||
vk::RenderPass m_offscreenRenderPass;
|
||||
vk::Framebuffer m_offscreenFramebuffer;
|
||||
VkDescriptorPool m_postDescPool{VK_NULL_HANDLE};
|
||||
VkDescriptorSetLayout m_postDescSetLayout{VK_NULL_HANDLE};
|
||||
VkDescriptorSet m_postDescSet{VK_NULL_HANDLE};
|
||||
VkPipeline m_postPipeline{VK_NULL_HANDLE};
|
||||
VkPipelineLayout m_postPipelineLayout{VK_NULL_HANDLE};
|
||||
VkRenderPass m_offscreenRenderPass{VK_NULL_HANDLE};
|
||||
VkFramebuffer m_offscreenFramebuffer{VK_NULL_HANDLE};
|
||||
nvvk::Texture m_offscreenColor;
|
||||
vk::Format m_offscreenColorFormat{vk::Format::eR32G32B32A32Sfloat};
|
||||
nvvk::Texture m_offscreenDepth;
|
||||
vk::Format m_offscreenDepthFormat{vk::Format::eX8D24UnormPack32};
|
||||
VkFormat m_offscreenColorFormat{VK_FORMAT_R32G32B32A32_SFLOAT};
|
||||
VkFormat m_offscreenDepthFormat{VK_FORMAT_X8_D24_UNORM_PACK32};
|
||||
|
||||
// #VKRay
|
||||
void initRayTracing();
|
||||
|
|
@ -133,19 +131,19 @@ public:
|
|||
void createRtDescriptorSet();
|
||||
void updateRtDescriptorSet();
|
||||
void createRtPipeline();
|
||||
void raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& clearColor);
|
||||
void raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& clearColor);
|
||||
|
||||
|
||||
vk::PhysicalDeviceRayTracingPipelinePropertiesKHR m_rtProperties;
|
||||
nvvk::RaytracingBuilderKHR m_rtBuilder;
|
||||
nvvk::DescriptorSetBindings m_rtDescSetLayoutBind;
|
||||
vk::DescriptorPool m_rtDescPool;
|
||||
vk::DescriptorSetLayout m_rtDescSetLayout;
|
||||
vk::DescriptorSet m_rtDescSet;
|
||||
std::vector<vk::RayTracingShaderGroupCreateInfoKHR> m_rtShaderGroups;
|
||||
vk::PipelineLayout m_rtPipelineLayout;
|
||||
vk::Pipeline m_rtPipeline;
|
||||
nvvk::SBTWrapper m_sbtWrapper;
|
||||
VkPhysicalDeviceRayTracingPipelinePropertiesKHR m_rtProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR};
|
||||
nvvk::RaytracingBuilderKHR m_rtBuilder;
|
||||
nvvk::DescriptorSetBindings m_rtDescSetLayoutBind;
|
||||
VkDescriptorPool m_rtDescPool;
|
||||
VkDescriptorSetLayout m_rtDescSetLayout;
|
||||
VkDescriptorSet m_rtDescSet;
|
||||
std::vector<VkRayTracingShaderGroupCreateInfoKHR> m_rtShaderGroups;
|
||||
VkPipelineLayout m_rtPipelineLayout;
|
||||
VkPipeline m_rtPipeline;
|
||||
nvvk::SBTWrapper m_sbtWrapper;
|
||||
|
||||
std::vector<nvvk::RaytracingBuilderKHR::Instance> m_tlas;
|
||||
std::vector<nvvk::RaytracingBuilderKHR::BlasInput> m_blas;
|
||||
|
|
@ -168,11 +166,11 @@ public:
|
|||
void createCompPipelines();
|
||||
|
||||
nvvk::DescriptorSetBindings m_compDescSetLayoutBind;
|
||||
vk::DescriptorPool m_compDescPool;
|
||||
vk::DescriptorSetLayout m_compDescSetLayout;
|
||||
vk::DescriptorSet m_compDescSet;
|
||||
vk::Pipeline m_compPipeline;
|
||||
vk::PipelineLayout m_compPipelineLayout;
|
||||
VkDescriptorPool m_compDescPool;
|
||||
VkDescriptorSetLayout m_compDescSetLayout;
|
||||
VkDescriptorSet m_compDescSet;
|
||||
VkPipeline m_compPipeline;
|
||||
VkPipelineLayout m_compPipelineLayout;
|
||||
|
||||
vk::BuildAccelerationStructureFlagsKHR m_rtFlags;
|
||||
VkBuildAccelerationStructureFlagsKHR m_rtFlags;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
// at the top of imgui.cpp.
|
||||
|
||||
#include <array>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "backends/imgui_impl_glfw.h"
|
||||
#include "imgui.h"
|
||||
|
|
@ -33,13 +32,10 @@
|
|||
#include "nvh/cameramanipulator.hpp"
|
||||
#include "nvh/fileoperations.hpp"
|
||||
#include "nvpsystem.hpp"
|
||||
#include "nvvk/appbase_vkpp.hpp"
|
||||
#include "nvvk/commands_vk.hpp"
|
||||
#include "nvvk/context_vk.hpp"
|
||||
|
||||
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#define UNUSED(x) (void)(x)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,6 +43,7 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
|||
// Default search path for shaders
|
||||
std::vector<std::string> defaultSearchPaths;
|
||||
|
||||
|
||||
// GLFW Callback functions
|
||||
static void onErrorCallback(int error, const char* description)
|
||||
{
|
||||
|
|
@ -74,6 +71,7 @@ void renderUI(HelloVulkan& helloVk)
|
|||
static int const SAMPLE_WIDTH = 1280;
|
||||
static int const SAMPLE_HEIGHT = 720;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Application Entry
|
||||
//
|
||||
|
|
@ -88,12 +86,11 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window =
|
||||
glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
||||
GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr);
|
||||
|
||||
// Setup camera
|
||||
CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
||||
CameraManip.setLookat(nvmath::vec3f(4, 4, 4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||
CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0));
|
||||
|
||||
// Setup Vulkan
|
||||
if(!glfwVulkanSupported())
|
||||
|
|
@ -131,16 +128,14 @@ int main(int argc, char** argv)
|
|||
contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
||||
contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
|
||||
// #VKRay: Activate the ray tracing extension
|
||||
VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR};
|
||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature);
|
||||
VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR};
|
||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature);
|
||||
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME);
|
||||
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
|
||||
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
|
||||
vk::PhysicalDeviceAccelerationStructureFeaturesKHR accelFeature;
|
||||
contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false,
|
||||
&accelFeature);
|
||||
vk::PhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature;
|
||||
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false,
|
||||
&rtPipelineFeature);
|
||||
|
||||
// Creating Vulkan base application
|
||||
nvvk::Context vkctx{};
|
||||
|
|
@ -155,11 +150,10 @@ int main(int argc, char** argv)
|
|||
HelloVulkan helloVk;
|
||||
|
||||
// Window need to be opened to get the surface on which to draw
|
||||
const vk::SurfaceKHR surface = helloVk.getVkSurface(vkctx.m_instance, window);
|
||||
const VkSurfaceKHR surface = helloVk.getVkSurface(vkctx.m_instance, window);
|
||||
vkctx.setGCTQueueWithPresent(surface);
|
||||
|
||||
helloVk.setup(vkctx.m_instance, vkctx.m_device, vkctx.m_physicalDevice,
|
||||
vkctx.m_queueGCT.familyIndex);
|
||||
helloVk.setup(vkctx.m_instance, vkctx.m_device, vkctx.m_physicalDevice, vkctx.m_queueGCT.familyIndex);
|
||||
helloVk.createSwapchain(surface, SAMPLE_WIDTH, SAMPLE_HEIGHT);
|
||||
helloVk.createDepthBuffer();
|
||||
helloVk.createRenderPass();
|
||||
|
|
@ -229,8 +223,7 @@ int main(int argc, char** argv)
|
|||
ImGui::Checkbox("Ray Tracer mode", &useRaytracer); // Switch between raster and ray tracing
|
||||
|
||||
renderUI(helloVk);
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
|
||||
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
ImGuiH::Control::Info("", "", "(F10) Toggle Pane", ImGuiH::Control::Flags::Disabled);
|
||||
ImGuiH::Panel::End();
|
||||
}
|
||||
|
|
@ -244,28 +237,29 @@ int main(int argc, char** argv)
|
|||
helloVk.prepareFrame();
|
||||
|
||||
// Start command buffer of this frame
|
||||
auto curFrame = helloVk.getCurFrame();
|
||||
const vk::CommandBuffer& cmdBuf = helloVk.getCommandBuffers()[curFrame];
|
||||
auto curFrame = helloVk.getCurFrame();
|
||||
const VkCommandBuffer& cmdBuf = helloVk.getCommandBuffers()[curFrame];
|
||||
|
||||
cmdBuf.begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit});
|
||||
VkCommandBufferBeginInfo beginInfo{VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO};
|
||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
vkBeginCommandBuffer(cmdBuf, &beginInfo);
|
||||
|
||||
// Updating camera buffer
|
||||
helloVk.updateUniformBuffer(cmdBuf);
|
||||
|
||||
// Clearing screen
|
||||
std::array<vk::ClearValue, 2> clearValues;
|
||||
clearValues[0].setColor(
|
||||
std::array<float, 4>({clearColor[0], clearColor[1], clearColor[2], clearColor[3]}));
|
||||
clearValues[1].setDepthStencil({1.0f, 0});
|
||||
std::array<VkClearValue, 2> clearValues{};
|
||||
clearValues[0].color = {{clearColor[0], clearColor[1], clearColor[2], clearColor[3]}};
|
||||
clearValues[1].depthStencil = {1.0f, 0};
|
||||
|
||||
// Offscreen render pass
|
||||
{
|
||||
vk::RenderPassBeginInfo offscreenRenderPassBeginInfo;
|
||||
offscreenRenderPassBeginInfo.setClearValueCount(2);
|
||||
offscreenRenderPassBeginInfo.setPClearValues(clearValues.data());
|
||||
offscreenRenderPassBeginInfo.setRenderPass(helloVk.m_offscreenRenderPass);
|
||||
offscreenRenderPassBeginInfo.setFramebuffer(helloVk.m_offscreenFramebuffer);
|
||||
offscreenRenderPassBeginInfo.setRenderArea({{}, helloVk.getSize()});
|
||||
VkRenderPassBeginInfo offscreenRenderPassBeginInfo{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO};
|
||||
offscreenRenderPassBeginInfo.clearValueCount = 2;
|
||||
offscreenRenderPassBeginInfo.pClearValues = clearValues.data();
|
||||
offscreenRenderPassBeginInfo.renderPass = helloVk.m_offscreenRenderPass;
|
||||
offscreenRenderPassBeginInfo.framebuffer = helloVk.m_offscreenFramebuffer;
|
||||
offscreenRenderPassBeginInfo.renderArea = {{0, 0}, helloVk.getSize()};
|
||||
|
||||
// Rendering Scene
|
||||
if(useRaytracer)
|
||||
|
|
@ -274,40 +268,40 @@ int main(int argc, char** argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
cmdBuf.beginRenderPass(offscreenRenderPassBeginInfo, vk::SubpassContents::eInline);
|
||||
vkCmdBeginRenderPass(cmdBuf, &offscreenRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
helloVk.rasterize(cmdBuf);
|
||||
cmdBuf.endRenderPass();
|
||||
vkCmdEndRenderPass(cmdBuf);
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd rendering pass: tone mapper, UI
|
||||
{
|
||||
vk::RenderPassBeginInfo postRenderPassBeginInfo;
|
||||
postRenderPassBeginInfo.setClearValueCount(2);
|
||||
postRenderPassBeginInfo.setPClearValues(clearValues.data());
|
||||
postRenderPassBeginInfo.setRenderPass(helloVk.getRenderPass());
|
||||
postRenderPassBeginInfo.setFramebuffer(helloVk.getFramebuffers()[curFrame]);
|
||||
postRenderPassBeginInfo.setRenderArea({{}, helloVk.getSize()});
|
||||
VkRenderPassBeginInfo postRenderPassBeginInfo{VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO};
|
||||
postRenderPassBeginInfo.clearValueCount = 2;
|
||||
postRenderPassBeginInfo.pClearValues = clearValues.data();
|
||||
postRenderPassBeginInfo.renderPass = helloVk.getRenderPass();
|
||||
postRenderPassBeginInfo.framebuffer = helloVk.getFramebuffers()[curFrame];
|
||||
postRenderPassBeginInfo.renderArea = {{0, 0}, helloVk.getSize()};
|
||||
|
||||
cmdBuf.beginRenderPass(postRenderPassBeginInfo, vk::SubpassContents::eInline);
|
||||
// Rendering tonemapper
|
||||
vkCmdBeginRenderPass(cmdBuf, &postRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
helloVk.drawPost(cmdBuf);
|
||||
// Rendering UI
|
||||
ImGui::Render();
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuf);
|
||||
cmdBuf.endRenderPass();
|
||||
vkCmdEndRenderPass(cmdBuf);
|
||||
}
|
||||
|
||||
// Submit for display
|
||||
cmdBuf.end();
|
||||
vkEndCommandBuffer(cmdBuf);
|
||||
helloVk.submitFrame();
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
helloVk.getDevice().waitIdle();
|
||||
vkDeviceWaitIdle(helloVk.getDevice());
|
||||
|
||||
helloVk.destroyResources();
|
||||
helloVk.destroy();
|
||||
|
||||
vkctx.deinit();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue