From 37494f7741c10455ad89356055e5023f1a74ef10 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 20:39:01 +0100 Subject: [PATCH 01/28] Bulk of the work to port from VK_NV_ray_tracing to VK_KHR_ray_tracing (WiP) --- src/Assets/Scene.cpp | 18 +-- src/CMakeLists.txt | 2 + src/Options.cpp | 2 +- src/Vulkan/Application.cpp | 20 ++- src/Vulkan/Application.hpp | 1 + src/Vulkan/Buffer.cpp | 19 ++- src/Vulkan/Buffer.hpp | 4 +- src/Vulkan/DebugUtilsMessenger.cpp | 82 ++++++----- src/Vulkan/DescriptorSets.cpp | 2 +- src/Vulkan/DescriptorSets.hpp | 2 +- src/Vulkan/Device.cpp | 35 +++-- src/Vulkan/Device.hpp | 6 +- src/Vulkan/DeviceMemory.cpp | 17 ++- src/Vulkan/DeviceMemory.hpp | 2 +- src/Vulkan/Image.cpp | 2 +- src/Vulkan/Instance.cpp | 28 ++-- src/Vulkan/Instance.hpp | 9 +- .../RayTracing/AccelerationStructure.cpp | 54 ++++--- .../RayTracing/AccelerationStructure.hpp | 8 +- src/Vulkan/RayTracing/Application.cpp | 72 ++++++---- .../BottomLevelAccelerationStructure.cpp | 111 +++------------ .../BottomLevelAccelerationStructure.hpp | 18 +-- src/Vulkan/RayTracing/BottomLevelGeometry.cpp | 89 ++++++++++++ src/Vulkan/RayTracing/BottomLevelGeometry.hpp | 49 +++++++ src/Vulkan/RayTracing/DeviceProcedures.cpp | 23 ++- src/Vulkan/RayTracing/DeviceProcedures.hpp | 88 +++++------- src/Vulkan/RayTracing/RayTracingPipeline.cpp | 88 ++++++------ .../RayTracing/RayTracingProperties.cpp | 2 +- .../RayTracing/RayTracingProperties.hpp | 5 +- src/Vulkan/RayTracing/ShaderBindingTable.cpp | 4 +- .../TopLevelAccelerationStructure.cpp | 132 ++++++++++-------- .../TopLevelAccelerationStructure.hpp | 27 +--- src/Vulkan/Vulkan.cpp | 80 ++++++----- src/Vulkan/Vulkan.hpp | 1 + src/main.cpp | 42 +++++- 35 files changed, 661 insertions(+), 483 deletions(-) create mode 100644 src/Vulkan/RayTracing/BottomLevelGeometry.cpp create mode 100644 src/Vulkan/RayTracing/BottomLevelGeometry.hpp diff --git a/src/Assets/Scene.cpp b/src/Assets/Scene.cpp index 7cd87e7d..48f8075c 100644 --- a/src/Assets/Scene.cpp +++ b/src/Assets/Scene.cpp @@ -47,9 +47,10 @@ namespace { const auto& device = commandPool.Device(); const auto contentSize = sizeof(content[0]) * content.size(); + const VkMemoryAllocateFlags allocateFlags = usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT ? VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT : 0; buffer.reset(new Vulkan::Buffer(device, contentSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage)); - memory.reset(new Vulkan::DeviceMemory(buffer->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + memory.reset(new Vulkan::DeviceMemory(buffer->AllocateMemory(allocateFlags, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); CopyFromStagingBuffer(commandPool, *buffer, content); } @@ -65,7 +66,7 @@ Scene::Scene(Vulkan::CommandPool& commandPool, std::vector&& models, std: std::vector indices; std::vector materials; std::vector procedurals; - std::vector> aabbs; + std::vector aabbs; std::vector offsets; for (const auto& model : models_) @@ -92,7 +93,8 @@ Scene::Scene(Vulkan::CommandPool& commandPool, std::vector&& models, std: const auto sphere = dynamic_cast(model.Procedural()); if (sphere != nullptr) { - aabbs.push_back(sphere->BoundingBox()); + const auto aabb = sphere->BoundingBox(); + aabbs.push_back({aabb.first.x, aabb.first.y, aabb.first.z, aabb.second.x, aabb.second.y, aabb.second.z}); procedurals.emplace_back(sphere->Center, sphere->Radius); } else @@ -102,15 +104,15 @@ Scene::Scene(Vulkan::CommandPool& commandPool, std::vector&& models, std: } } - const auto flag = usedForRayTracing ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : 0; + const auto flag = usedForRayTracing ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT : 0; CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | flag, vertices, vertexBuffer_, vertexBufferMemory_); CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | flag, indices, indexBuffer_, indexBufferMemory_); - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, materials, materialBuffer_, materialBufferMemory_); - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, offsets, offsetBuffer_, offsetBufferMemory_); + CreateDeviceBuffer(commandPool, flag, materials, materialBuffer_, materialBufferMemory_); + CreateDeviceBuffer(commandPool, flag, offsets, offsetBuffer_, offsetBufferMemory_); - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, aabbs, aabbBuffer_, aabbBufferMemory_); - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, procedurals, proceduralBuffer_, proceduralBufferMemory_); + CreateDeviceBuffer(commandPool, flag, aabbs, aabbBuffer_, aabbBufferMemory_); + CreateDeviceBuffer(commandPool, flag, procedurals, proceduralBuffer_, proceduralBufferMemory_); // Upload all textures textureImages_.reserve(textures_.size()); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f0e9672c..0895ee01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -108,6 +108,8 @@ set(src_files_vulkan_raytracing Vulkan/RayTracing/Application.hpp Vulkan/RayTracing/BottomLevelAccelerationStructure.cpp Vulkan/RayTracing/BottomLevelAccelerationStructure.hpp + Vulkan/RayTracing/BottomLevelGeometry.cpp + Vulkan/RayTracing/BottomLevelGeometry.hpp Vulkan/RayTracing/DeviceProcedures.cpp Vulkan/RayTracing/DeviceProcedures.hpp Vulkan/RayTracing/RayTracingPipeline.cpp diff --git a/src/Options.cpp b/src/Options.cpp index fc284b2f..54542434 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -23,7 +23,7 @@ Options::Options(const int argc, const char* argv[]) options_description scene("Scene options"); scene.add_options() - ("scene", value(&SceneIndex)->default_value(1), "Set the scene to start with.") + ("scene", value(&SceneIndex)->default_value(0), "Set the scene to start with.") ; options_description window("Window options"); diff --git a/src/Vulkan/Application.cpp b/src/Vulkan/Application.cpp index 64b92c1d..5c3749e1 100644 --- a/src/Vulkan/Application.cpp +++ b/src/Vulkan/Application.cpp @@ -31,7 +31,7 @@ Application::Application(const WindowConfig& windowConfig, const bool vsync, con : std::vector(); window_.reset(new class Window(windowConfig)); - instance_.reset(new Instance(*window_, validationLayers)); + instance_.reset(new Instance(*window_, validationLayers, VK_API_VERSION_1_2)); debugUtilsMessenger_.reset(enableValidationLayers ? new DebugUtilsMessenger(*instance_, VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) : nullptr); surface_.reset(new Surface(*instance_)); } @@ -53,6 +53,11 @@ const std::vector& Application::Extensions() const return instance_->Extensions(); } +const std::vector& Application::Layers() const +{ + return instance_->Layers(); +} + const std::vector& Application::PhysicalDevices() const { return instance_->PhysicalDevices(); @@ -65,7 +70,18 @@ void Application::SetPhysicalDevice(VkPhysicalDevice physicalDevice) Throw(std::logic_error("physical device has already been set")); } - device_.reset(new class Device(physicalDevice, *surface_)); + const std::vector requiredExtensions = + { + // VK_KHR_ray_tracing + VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, + VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, + VK_KHR_RAY_TRACING_EXTENSION_NAME, + + // VK_KHR_swapchain + VK_KHR_SWAPCHAIN_EXTENSION_NAME + }; + + device_.reset(new class Device(physicalDevice, *surface_, requiredExtensions)); commandPool_.reset(new class CommandPool(*device_, device_->GraphicsFamilyIndex(), true)); OnDeviceSet(); diff --git a/src/Vulkan/Application.hpp b/src/Vulkan/Application.hpp index 8f714322..5cfdb629 100644 --- a/src/Vulkan/Application.hpp +++ b/src/Vulkan/Application.hpp @@ -23,6 +23,7 @@ namespace Vulkan virtual ~Application(); const std::vector& Extensions() const; + const std::vector& Layers() const; const std::vector& PhysicalDevices() const; void SetPhysicalDevice(VkPhysicalDevice physicalDevice); diff --git a/src/Vulkan/Buffer.cpp b/src/Vulkan/Buffer.cpp index a7a8cbb9..03c1e13e 100644 --- a/src/Vulkan/Buffer.cpp +++ b/src/Vulkan/Buffer.cpp @@ -25,10 +25,15 @@ Buffer::~Buffer() } } -DeviceMemory Buffer::AllocateMemory(const VkMemoryPropertyFlags properties) +DeviceMemory Buffer::AllocateMemory(const VkMemoryPropertyFlags propertyFlags) +{ + return AllocateMemory(0, propertyFlags); +} + +DeviceMemory Buffer::AllocateMemory(const VkMemoryAllocateFlags allocateFlags, const VkMemoryPropertyFlags propertyFlags) { const auto requirements = GetMemoryRequirements(); - DeviceMemory memory(device_, requirements.size, requirements.memoryTypeBits, properties); + DeviceMemory memory(device_, requirements.size, requirements.memoryTypeBits, allocateFlags, propertyFlags); Check(vkBindBufferMemory(device_.Handle(), buffer_, memory.Handle(), 0), "bind buffer memory"); @@ -43,6 +48,16 @@ VkMemoryRequirements Buffer::GetMemoryRequirements() const return requirements; } +VkDeviceAddress Buffer::GetDeviceAddress() const +{ + VkBufferDeviceAddressInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; + info.pNext = nullptr; + info.buffer = Handle(); + + return vkGetBufferDeviceAddress(device_.Handle(), &info); +} + void Buffer::CopyFrom(CommandPool& commandPool, const Buffer& src, VkDeviceSize size) { SingleTimeCommands::Submit(commandPool, [&] (VkCommandBuffer commandBuffer) diff --git a/src/Vulkan/Buffer.hpp b/src/Vulkan/Buffer.hpp index 832aac25..07c50dc1 100644 --- a/src/Vulkan/Buffer.hpp +++ b/src/Vulkan/Buffer.hpp @@ -19,8 +19,10 @@ namespace Vulkan const class Device& Device() const { return device_; } - DeviceMemory AllocateMemory(VkMemoryPropertyFlags properties); + DeviceMemory AllocateMemory(VkMemoryPropertyFlags propertyFlags); + DeviceMemory AllocateMemory(VkMemoryAllocateFlags allocateFlags, VkMemoryPropertyFlags propertyFlags); VkMemoryRequirements GetMemoryRequirements() const; + VkDeviceAddress GetDeviceAddress() const; void CopyFrom(CommandPool& commandPool, const Buffer& src, VkDeviceSize size); diff --git a/src/Vulkan/DebugUtilsMessenger.cpp b/src/Vulkan/DebugUtilsMessenger.cpp index 09272c76..35c59a17 100644 --- a/src/Vulkan/DebugUtilsMessenger.cpp +++ b/src/Vulkan/DebugUtilsMessenger.cpp @@ -8,52 +8,58 @@ namespace Vulkan { namespace { + const char* ObjectTypeToString(const VkObjectType objectType) { switch (objectType) { - case VK_OBJECT_TYPE_UNKNOWN: return "unknown"; - case VK_OBJECT_TYPE_INSTANCE: return "instance"; - case VK_OBJECT_TYPE_PHYSICAL_DEVICE: return "physical device"; - case VK_OBJECT_TYPE_DEVICE: return "device"; - case VK_OBJECT_TYPE_QUEUE: return "queue"; - case VK_OBJECT_TYPE_SEMAPHORE: return "semaphore"; - case VK_OBJECT_TYPE_COMMAND_BUFFER: return "cmd buffer"; - case VK_OBJECT_TYPE_FENCE: return "fence"; - case VK_OBJECT_TYPE_DEVICE_MEMORY: return "memory"; - case VK_OBJECT_TYPE_BUFFER: return "buffer"; - case VK_OBJECT_TYPE_IMAGE: return "image"; - case VK_OBJECT_TYPE_EVENT: return "event"; - case VK_OBJECT_TYPE_QUERY_POOL: return "query pool"; - case VK_OBJECT_TYPE_BUFFER_VIEW: return "buffer view"; - case VK_OBJECT_TYPE_IMAGE_VIEW: return "image view"; - case VK_OBJECT_TYPE_SHADER_MODULE: return "shader module"; - case VK_OBJECT_TYPE_PIPELINE_CACHE: return "pipeline cache"; - case VK_OBJECT_TYPE_PIPELINE_LAYOUT: return "pipeline layout"; - case VK_OBJECT_TYPE_RENDER_PASS: return "render pass"; - case VK_OBJECT_TYPE_PIPELINE: return "pipeline"; - case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: return "descriptor set layout"; - case VK_OBJECT_TYPE_SAMPLER: return "sampler"; - case VK_OBJECT_TYPE_DESCRIPTOR_POOL: return "descriptor pool"; - case VK_OBJECT_TYPE_DESCRIPTOR_SET: return "descriptor set"; - case VK_OBJECT_TYPE_FRAMEBUFFER: return "framebuffer"; - case VK_OBJECT_TYPE_COMMAND_POOL: return "command pool"; - case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION: return "sampler ycbcr conversion"; - case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE: return "descriptor update template"; - case VK_OBJECT_TYPE_SURFACE_KHR: return "surface KHR"; - case VK_OBJECT_TYPE_SWAPCHAIN_KHR: return "swapchain KHR"; - case VK_OBJECT_TYPE_DISPLAY_KHR: return "display KHR"; - case VK_OBJECT_TYPE_DISPLAY_MODE_KHR: return "display mode KHR"; - case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT: return "debug report callback"; - case VK_OBJECT_TYPE_OBJECT_TABLE_NVX: return "object tabke NVX"; - case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX: return "indirect cmd layout NVX"; - case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT: return "debug utils messenger"; - case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT: return "validation cache"; - case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV: return "acceleration structure NV"; +#define STR(e) case VK_OBJECT_TYPE_ ## e: return # e + STR(UNKNOWN); + STR(INSTANCE); + STR(PHYSICAL_DEVICE); + STR(DEVICE); + STR(QUEUE); + STR(SEMAPHORE); + STR(COMMAND_BUFFER); + STR(FENCE); + STR(DEVICE_MEMORY); + STR(BUFFER); + STR(IMAGE); + STR(EVENT); + STR(QUERY_POOL); + STR(BUFFER_VIEW); + STR(IMAGE_VIEW); + STR(SHADER_MODULE); + STR(PIPELINE_CACHE); + STR(PIPELINE_LAYOUT); + STR(RENDER_PASS); + STR(PIPELINE); + STR(DESCRIPTOR_SET_LAYOUT); + STR(SAMPLER); + STR(DESCRIPTOR_POOL); + STR(DESCRIPTOR_SET); + STR(FRAMEBUFFER); + STR(COMMAND_POOL); + STR(SAMPLER_YCBCR_CONVERSION); + STR(DESCRIPTOR_UPDATE_TEMPLATE); + STR(SURFACE_KHR); + STR(SWAPCHAIN_KHR); + STR(DISPLAY_KHR); + STR(DISPLAY_MODE_KHR); + STR(DEBUG_REPORT_CALLBACK_EXT); + STR(DEBUG_UTILS_MESSENGER_EXT); + STR(ACCELERATION_STRUCTURE_KHR); + STR(VALIDATION_CACHE_EXT); + STR(PERFORMANCE_CONFIGURATION_INTEL); + STR(DEFERRED_OPERATION_KHR); + STR(INDIRECT_COMMANDS_LAYOUT_NV); +#undef STR default: return "unknown"; } } + + VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugCallback( const VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, const VkDebugUtilsMessageTypeFlagsEXT messageType, diff --git a/src/Vulkan/DescriptorSets.cpp b/src/Vulkan/DescriptorSets.cpp index b2875a54..35d6f330 100644 --- a/src/Vulkan/DescriptorSets.cpp +++ b/src/Vulkan/DescriptorSets.cpp @@ -72,7 +72,7 @@ VkWriteDescriptorSet DescriptorSets::Bind(const uint32_t index, const uint32_t b return descriptorWrite; } -VkWriteDescriptorSet DescriptorSets::Bind(uint32_t index, uint32_t binding, const VkWriteDescriptorSetAccelerationStructureNV& structureInfo, const uint32_t count) const +VkWriteDescriptorSet DescriptorSets::Bind(uint32_t index, uint32_t binding, const VkWriteDescriptorSetAccelerationStructureKHR& structureInfo, const uint32_t count) const { VkWriteDescriptorSet descriptorWrite = {}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; diff --git a/src/Vulkan/DescriptorSets.hpp b/src/Vulkan/DescriptorSets.hpp index c863f185..101665b6 100644 --- a/src/Vulkan/DescriptorSets.hpp +++ b/src/Vulkan/DescriptorSets.hpp @@ -29,7 +29,7 @@ namespace Vulkan VkWriteDescriptorSet Bind(uint32_t index, uint32_t binding, const VkDescriptorBufferInfo& bufferInfo, uint32_t count = 1) const; VkWriteDescriptorSet Bind(uint32_t index, uint32_t binding, const VkDescriptorImageInfo& imageInfo, uint32_t count = 1) const; - VkWriteDescriptorSet Bind(uint32_t index, uint32_t binding, const VkWriteDescriptorSetAccelerationStructureNV& structureInfo, uint32_t count = 1) const; + VkWriteDescriptorSet Bind(uint32_t index, uint32_t binding, const VkWriteDescriptorSetAccelerationStructureKHR& structureInfo, uint32_t count = 1) const; void UpdateDescriptors(uint32_t index, const std::vector& descriptorWrites); diff --git a/src/Vulkan/Device.cpp b/src/Vulkan/Device.cpp index bf94c730..a2e1147d 100644 --- a/src/Vulkan/Device.cpp +++ b/src/Vulkan/Device.cpp @@ -34,17 +34,11 @@ namespace Vulkan { } -const std::vector Device::RequiredExtensions = -{ - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_NV_RAY_TRACING_EXTENSION_NAME -}; - -Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface) : +Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, const std::vector& requiredExtensions) : physicalDevice_(physicalDevice), surface_(surface) { - CheckRequiredExtensions(physicalDevice); + CheckRequiredExtensions(physicalDevice, requiredExtensions); const auto queueFamilies = GetEnumerateVector(physicalDevice, vkGetPhysicalDeviceQueueFamilyProperties); @@ -100,20 +94,25 @@ Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface) : deviceFeatures.fillModeNonSolid = true; deviceFeatures.samplerAnisotropy = true; - VkPhysicalDeviceDescriptorIndexingFeaturesEXT indexingFeatures = {}; - indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; + VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = {}; + indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; indexingFeatures.runtimeDescriptorArray = true; + VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = {}; + bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; + bufferDeviceAddressFeatures.pNext = &indexingFeatures; + bufferDeviceAddressFeatures.bufferDeviceAddress = true; + VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.pNext = &indexingFeatures; + createInfo.pNext = &bufferDeviceAddressFeatures; createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.pEnabledFeatures = &deviceFeatures; createInfo.enabledLayerCount = static_cast(surface_.Instance().ValidationLayers().size()); createInfo.ppEnabledLayerNames = surface_.Instance().ValidationLayers().data(); - createInfo.enabledExtensionCount = static_cast(RequiredExtensions.size()); - createInfo.ppEnabledExtensionNames = RequiredExtensions.data(); + createInfo.enabledExtensionCount = static_cast(requiredExtensions.size()); + createInfo.ppEnabledExtensionNames = requiredExtensions.data(); Check(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device_), "create logical device"); @@ -139,22 +138,22 @@ void Device::WaitIdle() const "wait for device idle"); } -void Device::CheckRequiredExtensions(VkPhysicalDevice physicalDevice) const +void Device::CheckRequiredExtensions(VkPhysicalDevice physicalDevice, const std::vector& requiredExtensions) const { const auto availableExtensions = GetEnumerateVector(physicalDevice, static_cast(nullptr), vkEnumerateDeviceExtensionProperties); - std::set requiredExtensions(RequiredExtensions.begin(), RequiredExtensions.end()); + std::set required(requiredExtensions.begin(), requiredExtensions.end()); for (const auto& extension : availableExtensions) { - requiredExtensions.erase(extension.extensionName); + required.erase(extension.extensionName); } - if (!requiredExtensions.empty()) + if (!required.empty()) { bool first = true; std::string extensions; - for (const auto& extension : requiredExtensions) + for (const auto& extension : required) { if (!first) { diff --git a/src/Vulkan/Device.hpp b/src/Vulkan/Device.hpp index b1eee8b4..309ac6e9 100644 --- a/src/Vulkan/Device.hpp +++ b/src/Vulkan/Device.hpp @@ -13,7 +13,7 @@ namespace Vulkan VULKAN_NON_COPIABLE(Device) - Device(VkPhysicalDevice physicalDevice, const Surface& surface); + Device(VkPhysicalDevice physicalDevice, const Surface& surface, const std::vector& requiredExtensions); ~Device(); VkPhysicalDevice PhysicalDevice() const { return physicalDevice_; } @@ -32,9 +32,7 @@ namespace Vulkan private: - void CheckRequiredExtensions(VkPhysicalDevice physicalDevice) const; - - static const std::vector RequiredExtensions; + void CheckRequiredExtensions(VkPhysicalDevice physicalDevice, const std::vector& requiredExtensions) const; const VkPhysicalDevice physicalDevice_; const class Surface& surface_; diff --git a/src/Vulkan/DeviceMemory.cpp b/src/Vulkan/DeviceMemory.cpp index 4303206e..6a670afa 100644 --- a/src/Vulkan/DeviceMemory.cpp +++ b/src/Vulkan/DeviceMemory.cpp @@ -7,14 +7,21 @@ namespace Vulkan { DeviceMemory::DeviceMemory( const class Device& device, const size_t size, - const uint32_t memoryTypeBits, - const VkMemoryPropertyFlags properties) : + const uint32_t memoryTypeBits, + const VkMemoryAllocateFlags allocateFLags, + const VkMemoryPropertyFlags propertyFlags) : device_(device) { + VkMemoryAllocateFlagsInfo flagsInfo = {}; + flagsInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO; + flagsInfo.pNext = nullptr; + flagsInfo.flags = allocateFLags; + VkMemoryAllocateInfo allocInfo = {}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.pNext = &flagsInfo; allocInfo.allocationSize = size; - allocInfo.memoryTypeIndex = FindMemoryType(memoryTypeBits, properties); + allocInfo.memoryTypeIndex = FindMemoryType(memoryTypeBits, propertyFlags); Check(vkAllocateMemory(device.Handle(), &allocInfo, nullptr, &memory_), "allocate memory"); @@ -50,14 +57,14 @@ void DeviceMemory::Unmap() vkUnmapMemory(device_.Handle(), memory_); } -uint32_t DeviceMemory::FindMemoryType(const uint32_t typeFilter, const VkMemoryPropertyFlags properties) const +uint32_t DeviceMemory::FindMemoryType(const uint32_t typeFilter, const VkMemoryPropertyFlags propertyFlags) const { VkPhysicalDeviceMemoryProperties memProperties; vkGetPhysicalDeviceMemoryProperties(device_.PhysicalDevice(), &memProperties); for (uint32_t i = 0; i != memProperties.memoryTypeCount; ++i) { - if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) + if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & propertyFlags) == propertyFlags) { return i; } diff --git a/src/Vulkan/DeviceMemory.hpp b/src/Vulkan/DeviceMemory.hpp index 5757fd60..02abb729 100644 --- a/src/Vulkan/DeviceMemory.hpp +++ b/src/Vulkan/DeviceMemory.hpp @@ -14,7 +14,7 @@ namespace Vulkan DeviceMemory& operator = (const DeviceMemory&) = delete; DeviceMemory& operator = (DeviceMemory&&) = delete; - DeviceMemory(const Device& device, size_t size, uint32_t memoryTypeBits, VkMemoryPropertyFlags properties); + DeviceMemory(const Device& device, size_t size, uint32_t memoryTypeBits, VkMemoryAllocateFlags allocateFLags, VkMemoryPropertyFlags propertyFlags); DeviceMemory(DeviceMemory&& other) noexcept; ~DeviceMemory(); diff --git a/src/Vulkan/Image.cpp b/src/Vulkan/Image.cpp index 03c9567a..222f7526 100644 --- a/src/Vulkan/Image.cpp +++ b/src/Vulkan/Image.cpp @@ -65,7 +65,7 @@ Image::~Image() DeviceMemory Image::AllocateMemory(const VkMemoryPropertyFlags properties) const { const auto requirements = GetMemoryRequirements(); - DeviceMemory memory(device_, requirements.size, requirements.memoryTypeBits, properties); + DeviceMemory memory(device_, requirements.size, requirements.memoryTypeBits, 0, properties); Check(vkBindImageMemory(device_.Handle(), image_, memory.Handle(), 0), "bind image memory"); diff --git a/src/Vulkan/Instance.cpp b/src/Vulkan/Instance.cpp index d01752cc..2aea52a2 100644 --- a/src/Vulkan/Instance.cpp +++ b/src/Vulkan/Instance.cpp @@ -8,14 +8,12 @@ namespace Vulkan { -Instance::Instance(const class Window& window, const std::vector& validationLayers) : +Instance::Instance(const class Window& window, const std::vector& validationLayers, uint32_t vulkanVersion) : window_(window), validationLayers_(validationLayers) { // Check the minimum version. - const uint32_t version = VK_API_VERSION_1_1; - - CheckVulkanMinimumVersion(version); + CheckVulkanMinimumVersion(vulkanVersion); // Get the list of required extensions. auto extensions = window.GetRequiredInstanceExtensions(); @@ -35,7 +33,7 @@ Instance::Instance(const class Window& window, const std::vector& v appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.apiVersion = version; + appInfo.apiVersion = vulkanVersion; VkInstanceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; @@ -48,7 +46,8 @@ Instance::Instance(const class Window& window, const std::vector& v Check(vkCreateInstance(&createInfo, nullptr, &instance_), "create instance"); - GetVulkanDevices(); + GetVulkanPhysicalDevices(); + GetVulkanLayers(); GetVulkanExtensions(); } @@ -61,7 +60,17 @@ Instance::~Instance() } } -void Instance::GetVulkanDevices() +void Instance::GetVulkanExtensions() +{ + GetEnumerateVector(static_cast(nullptr), vkEnumerateInstanceExtensionProperties, extensions_); +} + +void Instance::GetVulkanLayers() +{ + GetEnumerateVector(vkEnumerateInstanceLayerProperties, layers_); +} + +void Instance::GetVulkanPhysicalDevices() { GetEnumerateVector(instance_, vkEnumeratePhysicalDevices, physicalDevices_); @@ -71,11 +80,6 @@ void Instance::GetVulkanDevices() } } -void Instance::GetVulkanExtensions() -{ - GetEnumerateVector(static_cast(nullptr), vkEnumerateInstanceExtensionProperties, extensions_); -} - void Instance::CheckVulkanMinimumVersion(const uint32_t minVersion) { uint32_t version; diff --git a/src/Vulkan/Instance.hpp b/src/Vulkan/Instance.hpp index 098baa7b..6ef89db8 100644 --- a/src/Vulkan/Instance.hpp +++ b/src/Vulkan/Instance.hpp @@ -13,19 +13,21 @@ namespace Vulkan VULKAN_NON_COPIABLE(Instance) - Instance(const Window& window, const std::vector& validationLayers); + Instance(const Window& window, const std::vector& validationLayers, uint32_t vulkanVersion); ~Instance(); const class Window& Window() const { return window_; } const std::vector& Extensions() const { return extensions_; } + const std::vector& Layers() const { return layers_; } const std::vector& PhysicalDevices() const { return physicalDevices_; } const std::vector& ValidationLayers() const { return validationLayers_; } private: - void GetVulkanDevices(); void GetVulkanExtensions(); + void GetVulkanLayers(); + void GetVulkanPhysicalDevices(); static void CheckVulkanMinimumVersion(uint32_t minVersion); static void CheckVulkanValidationLayerSupport(const std::vector& validationLayers); @@ -35,8 +37,9 @@ namespace Vulkan VULKAN_HANDLE(VkInstance, instance_) - std::vector physicalDevices_; std::vector extensions_; + std::vector layers_; + std::vector physicalDevices_; }; } diff --git a/src/Vulkan/RayTracing/AccelerationStructure.cpp b/src/Vulkan/RayTracing/AccelerationStructure.cpp index 2297528d..ab65a05d 100644 --- a/src/Vulkan/RayTracing/AccelerationStructure.cpp +++ b/src/Vulkan/RayTracing/AccelerationStructure.cpp @@ -6,12 +6,30 @@ namespace Vulkan::RayTracing { -AccelerationStructure::AccelerationStructure(const class DeviceProcedures& deviceProcedures, const VkAccelerationStructureCreateInfoNV& createInfo) : +AccelerationStructure::AccelerationStructure( + const class DeviceProcedures& deviceProcedures, + const VkAccelerationStructureTypeKHR accelerationStructureType, + const std::vector& geometries, + const bool allowUpdate) : deviceProcedures_(deviceProcedures), - allowUpdate_(createInfo.info.flags & VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV), + allowUpdate_(allowUpdate), device_(deviceProcedures.Device()) { - Check(deviceProcedures.vkCreateAccelerationStructureNV(device_.Handle(), &createInfo, nullptr, &accelerationStructure_), + const auto flags = allowUpdate + ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR + : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; + + VkAccelerationStructureCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR; + createInfo.pNext = nullptr; + createInfo.compactedSize = 0; + createInfo.type = accelerationStructureType; + createInfo.flags = flags; + createInfo.maxGeometryCount = static_cast(geometries.size()); + createInfo.pGeometryInfos = geometries.data(); + createInfo.deviceAddress = 0; + + Check(deviceProcedures.vkCreateAccelerationStructureKHR(device_.Handle(), &createInfo, nullptr, &accelerationStructure_), "create acceleration structure"); } @@ -28,30 +46,34 @@ AccelerationStructure::~AccelerationStructure() { if (accelerationStructure_ != nullptr) { - deviceProcedures_.vkDestroyAccelerationStructureNV(device_.Handle(), accelerationStructure_, nullptr); + deviceProcedures_.vkDestroyAccelerationStructureKHR(device_.Handle(), accelerationStructure_, nullptr); accelerationStructure_ = nullptr; } } AccelerationStructure::MemoryRequirements AccelerationStructure::GetMemoryRequirements() const { - VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo{}; - memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV; + VkAccelerationStructureMemoryRequirementsInfoKHR memoryRequirementsInfo{}; + memoryRequirementsInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_KHR; memoryRequirementsInfo.pNext = nullptr; + memoryRequirementsInfo.buildType = VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR; memoryRequirementsInfo.accelerationStructure = accelerationStructure_; // If the descriptor already contains the geometry info, so we can directly compute the estimated size and required scratch memory. VkMemoryRequirements2 memoryRequirements = {}; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV; - deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsNV(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); + memoryRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; + memoryRequirements.pNext = nullptr; + + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_KHR; + deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsKHR(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); const auto resultRequirements = memoryRequirements.memoryRequirements; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV; - deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsNV(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_KHR; + deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsKHR(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); const auto buildRequirements = memoryRequirements.memoryRequirements; - memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV; - deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsNV(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); + memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_KHR; + deviceProcedures_.vkGetAccelerationStructureMemoryRequirementsKHR(device_.Handle(), &memoryRequirementsInfo, &memoryRequirements); const auto updateRequirements = memoryRequirements.memoryRequirements; return { resultRequirements, buildRequirements, updateRequirements }; @@ -65,13 +87,13 @@ void AccelerationStructure::MemoryBarrier(VkCommandBuffer commandBuffer) VkMemoryBarrier memoryBarrier = {}; memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memoryBarrier.pNext = nullptr; - memoryBarrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV; - memoryBarrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV; + memoryBarrier.srcAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; + memoryBarrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; vkCmdPipelineBarrier( commandBuffer, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); } diff --git a/src/Vulkan/RayTracing/AccelerationStructure.hpp b/src/Vulkan/RayTracing/AccelerationStructure.hpp index c3900099..bc9156e2 100644 --- a/src/Vulkan/RayTracing/AccelerationStructure.hpp +++ b/src/Vulkan/RayTracing/AccelerationStructure.hpp @@ -1,6 +1,7 @@ #pragma once #include "Vulkan/Vulkan.hpp" +#include namespace Vulkan { @@ -40,7 +41,10 @@ namespace Vulkan::RayTracing protected: - AccelerationStructure(const class DeviceProcedures& deviceProcedures, const VkAccelerationStructureCreateInfoNV& createInfo); + AccelerationStructure(const class DeviceProcedures& deviceProcedures, + VkAccelerationStructureTypeKHR accelerationStructureType, + const std::vector& geometries, + bool allowUpdate); const class DeviceProcedures& deviceProcedures_; const bool allowUpdate_; @@ -49,7 +53,7 @@ namespace Vulkan::RayTracing const class Device& device_; - VULKAN_HANDLE(VkAccelerationStructureNV, accelerationStructure_) + VULKAN_HANDLE(VkAccelerationStructureKHR, accelerationStructure_) }; } diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index 88fb39b5..665a0b07 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -130,27 +130,44 @@ void Application::Render(VkCommandBuffer commandBuffer, const uint32_t imageInde VkDescriptorSet descriptorSets[] = { rayTracingPipeline_->DescriptorSet(imageIndex) }; - VkImageSubresourceRange subresourceRange; + VkImageSubresourceRange subresourceRange = {}; subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; subresourceRange.baseArrayLayer = 0; subresourceRange.layerCount = 1; - ImageMemoryBarrier::Insert(commandBuffer, accumulationImage_->Handle(), subresourceRange, 0, + ImageMemoryBarrier::Insert(commandBuffer, accumulationImage_->Handle(), subresourceRange, 0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); - ImageMemoryBarrier::Insert(commandBuffer, outputImage_->Handle(), subresourceRange, 0, + ImageMemoryBarrier::Insert(commandBuffer, outputImage_->Handle(), subresourceRange, 0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); - vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, rayTracingPipeline_->Handle()); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, rayTracingPipeline_->PipelineLayout().Handle(), 0, 1, descriptorSets, 0, nullptr); + vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rayTracingPipeline_->Handle()); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rayTracingPipeline_->PipelineLayout().Handle(), 0, 1, descriptorSets, 0, nullptr); - deviceProcedures_->vkCmdTraceRaysNV(commandBuffer, - shaderBindingTable_->Buffer().Handle(), shaderBindingTable_->RayGenOffset(), - shaderBindingTable_->Buffer().Handle(), shaderBindingTable_->MissOffset(), shaderBindingTable_->MissEntrySize(), - shaderBindingTable_->Buffer().Handle(), shaderBindingTable_->HitGroupOffset(), shaderBindingTable_->HitGroupEntrySize(), - nullptr, 0, 0, + VkStridedBufferRegionKHR raygenShaderBindingTable = {}; + raygenShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); + raygenShaderBindingTable.offset = shaderBindingTable_->RayGenOffset(); + //raygenShaderBindingTable.stride = stride; TODO + //raygenShaderBindingTable.size = size; TODO + + VkStridedBufferRegionKHR missShaderBindingTable = {}; + missShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); + missShaderBindingTable.offset = shaderBindingTable_->MissOffset(); + //missShaderBindingTable.stride = stride; TODO + //missShaderBindingTable.size = size; TODO + + VkStridedBufferRegionKHR hitShaderBindingTable = {}; + hitShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); + hitShaderBindingTable.offset = shaderBindingTable_->HitGroupOffset(); + //hitShaderBindingTable.stride = stride; TODO + //hitShaderBindingTable.size = size; TODO + + VkStridedBufferRegionKHR callableShaderBindingTable = {}; + + deviceProcedures_->vkCmdTraceRaysKHR(commandBuffer, + &raygenShaderBindingTable, &missShaderBindingTable, &hitShaderBindingTable, &callableShaderBindingTable, extent.width, extent.height, 1); ImageMemoryBarrier::Insert(commandBuffer, outputImage_->Handle(), subresourceRange, @@ -191,12 +208,11 @@ void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) { const auto vertexCount = static_cast(model.NumberOfVertices()); const auto indexCount = static_cast(model.NumberOfIndices()); - const std::vector geometries = - { - model.Procedural() - ? BottomLevelAccelerationStructure::CreateGeometryAabb(scene, aabbOffset, 1, true) - : BottomLevelAccelerationStructure::CreateGeometry(scene, vertexOffset, vertexCount, indexOffset, indexCount, true) - }; + BottomLevelGeometry geometries; + + model.Procedural() + ? geometries.AddGeometryAabb(scene, aabbOffset, 1, true) + : geometries.AddGeometryTriangles(scene, vertexOffset, vertexCount, indexOffset, indexCount, true); bottomAs_.emplace_back(*deviceProcedures_, geometries, false); requirements.push_back(bottomAs_.back().GetMemoryRequirements()); @@ -209,11 +225,11 @@ void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) // Allocate the structure memory. const auto total = GetTotalRequirements(requirements); - bottomBuffer_.reset(new Buffer(Device(), total.Result.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV)); + bottomBuffer_.reset(new Buffer(Device(), total.Result.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR)); bottomBufferMemory_.reset(new DeviceMemory(bottomBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); - bottomScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV)); - bottomScratchBufferMemory_.reset(new DeviceMemory(bottomScratchBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + bottomScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); + bottomScratchBufferMemory_.reset(new DeviceMemory(bottomScratchBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); // Generate the structures. VkDeviceSize resultOffset = 0; @@ -232,7 +248,7 @@ void Application::CreateTopLevelStructures(VkCommandBuffer commandBuffer) const auto& scene = GetScene(); // Top level acceleration structure - std::vector geometryInstances; + std::vector instances; std::vector requirements; // Hit group 0: triangles @@ -241,26 +257,26 @@ void Application::CreateTopLevelStructures(VkCommandBuffer commandBuffer) for (const auto& model : scene.Models()) { - geometryInstances.push_back(TopLevelAccelerationStructure::CreateGeometryInstance( + instances.push_back(TopLevelAccelerationStructure::CreateInstance( bottomAs_[instanceId], glm::mat4(1), instanceId, model.Procedural() ? 1 : 0)); instanceId++; } - topAs_.emplace_back(*deviceProcedures_, geometryInstances, false); + topAs_.emplace_back(*deviceProcedures_, instances, false); requirements.push_back(topAs_.back().GetMemoryRequirements()); // Allocate the structure memory. const auto total = GetTotalRequirements(requirements); - topBuffer_.reset(new Buffer(Device(), total.Result.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV)); + topBuffer_.reset(new Buffer(Device(), total.Result.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR)); topBufferMemory_.reset(new DeviceMemory(topBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); - topScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV)); - topScratchBufferMemory_.reset(new DeviceMemory(topScratchBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + topScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); + topScratchBufferMemory_.reset(new DeviceMemory(topScratchBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); - const size_t instancesBufferSize = sizeof(VkGeometryInstance) * geometryInstances.size(); - instancesBuffer_.reset(new Buffer(Device(), instancesBufferSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_NV)); - instancesBufferMemory_.reset(new DeviceMemory(instancesBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))); + const size_t instancesBufferSize = sizeof(VkAccelerationStructureInstanceKHR) * instances.size(); + instancesBuffer_.reset(new Buffer(Device(), instancesBufferSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); + instancesBufferMemory_.reset(new DeviceMemory(instancesBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))); // Generate the structures. topAs_[0].Generate(commandBuffer, *topScratchBuffer_, 0, *topBufferMemory_, 0, *instancesBuffer_, *instancesBufferMemory_, 0, false); diff --git a/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.cpp b/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.cpp index 334d59d4..fb4adee2 100644 --- a/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.cpp +++ b/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.cpp @@ -5,38 +5,14 @@ #include "Utilities/Exception.hpp" #include "Vulkan/Buffer.hpp" #include "Vulkan/Device.hpp" -#include "Vulkan/SingleTimeCommands.hpp" namespace Vulkan::RayTracing { -namespace -{ - VkAccelerationStructureCreateInfoNV GetCreateInfo(const std::vector& geometries, const bool allowUpdate) - { - const auto flags = allowUpdate - ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV - : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV; - - VkAccelerationStructureCreateInfoNV structureInfo = {}; - structureInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; - structureInfo.pNext = nullptr; - structureInfo.compactedSize = 0; - structureInfo.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; - structureInfo.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; - structureInfo.info.flags = flags; - structureInfo.info.instanceCount = 0; // The bottom-level AS can only contain explicit geometry, and no instances - structureInfo.info.geometryCount = static_cast(geometries.size()); - structureInfo.info.pGeometries = geometries.data(); - - return structureInfo; - } -} - BottomLevelAccelerationStructure::BottomLevelAccelerationStructure( const class DeviceProcedures& deviceProcedures, - const std::vector& geometries, + const BottomLevelGeometry& geometries, const bool allowUpdate) : - AccelerationStructure(deviceProcedures, GetCreateInfo(geometries, allowUpdate)), + AccelerationStructure(deviceProcedures, VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, geometries.CreateGeometryTypeInfo(), allowUpdate), geometries_(geometries) { } @@ -64,11 +40,11 @@ void BottomLevelAccelerationStructure::Generate( throw std::invalid_argument("cannot update readonly structure"); } - const VkAccelerationStructureNV previousStructure = updateOnly ? Handle() : nullptr; + const VkAccelerationStructureKHR previousStructure = updateOnly ? Handle() : nullptr; // Bind the acceleration structure descriptor to the actual memory that will contain it - VkBindAccelerationStructureMemoryInfoNV bindInfo = {}; - bindInfo.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV; + VkBindAccelerationStructureMemoryInfoKHR bindInfo = {}; + bindInfo.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR; bindInfo.pNext = nullptr; bindInfo.accelerationStructure = Handle(); bindInfo.memory = resultMemory.Handle(); @@ -76,76 +52,31 @@ void BottomLevelAccelerationStructure::Generate( bindInfo.deviceIndexCount = 0; bindInfo.pDeviceIndices = nullptr; - Check(deviceProcedures_.vkBindAccelerationStructureMemoryNV(Device().Handle(), 1, &bindInfo), + Check(deviceProcedures_.vkBindAccelerationStructureMemoryKHR(Device().Handle(), 1, &bindInfo), "bind acceleration structure"); // Build the actual bottom-level acceleration structure const auto flags = allowUpdate_ - ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV - : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV; + ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR + : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; + + const VkAccelerationStructureGeometryKHR* pGeometry = geometries_.Geometry().data(); + const VkAccelerationStructureBuildOffsetInfoKHR* pBuildOffsetInfo = geometries_.BuildOffsetInfo().data(); - VkAccelerationStructureInfoNV buildInfo = {}; - buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + VkAccelerationStructureBuildGeometryInfoKHR buildInfo = {}; + buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; buildInfo.pNext = nullptr; buildInfo.flags = flags; - buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV; - buildInfo.instanceCount = 0; + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; + buildInfo.update = updateOnly; + buildInfo.srcAccelerationStructure = previousStructure; + buildInfo.dstAccelerationStructure = Handle(), + buildInfo.geometryArrayOfPointers = false; buildInfo.geometryCount = static_cast(geometries_.size()); - buildInfo.pGeometries = geometries_.data(); - - deviceProcedures_.vkCmdBuildAccelerationStructureNV( - commandBuffer, &buildInfo, nullptr, 0, updateOnly, Handle(), previousStructure, scratchBuffer.Handle(), scratchOffset); -} - -VkGeometryNV BottomLevelAccelerationStructure::CreateGeometry( - const Assets::Scene& scene, - const uint32_t vertexOffset, const uint32_t vertexCount, - const uint32_t indexOffset, const uint32_t indexCount, - const bool isOpaque) -{ - VkGeometryNV geometry = {}; - geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV; - geometry.pNext = nullptr; - geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV; - geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV; - geometry.geometry.triangles.pNext = nullptr; - geometry.geometry.triangles.vertexData = scene.VertexBuffer().Handle(); - geometry.geometry.triangles.vertexOffset = vertexOffset; - geometry.geometry.triangles.vertexCount = vertexCount; - geometry.geometry.triangles.vertexStride = sizeof(Assets::Vertex); - geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT; - geometry.geometry.triangles.indexData = scene.IndexBuffer().Handle(); - geometry.geometry.triangles.indexOffset = indexOffset; - geometry.geometry.triangles.indexCount = indexCount; - geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32; - geometry.geometry.triangles.transformData = nullptr; - geometry.geometry.triangles.transformOffset = 0; - geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV; - geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_NV : 0; - - return geometry; -} - -VkGeometryNV BottomLevelAccelerationStructure::CreateGeometryAabb( - const Assets::Scene& scene, - const uint32_t aabbOffset, - const uint32_t aabbCount, - const bool isOpaque) -{ - VkGeometryNV geometry = {}; - geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV; - geometry.pNext = nullptr; - geometry.geometryType = VK_GEOMETRY_TYPE_AABBS_NV; - geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV; - geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV; - geometry.geometry.aabbs.pNext = nullptr; - geometry.geometry.aabbs.aabbData = scene.AabbBuffer().Handle(); - geometry.geometry.aabbs.numAABBs = aabbCount; - geometry.geometry.aabbs.stride = sizeof(glm::vec3) * 2; - geometry.geometry.aabbs.offset = aabbOffset; - geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_NV : 0; + buildInfo.ppGeometries = &pGeometry; + buildInfo.scratchData.deviceAddress = scratchBuffer.GetDeviceAddress() + scratchOffset; - return geometry; + deviceProcedures_.vkCmdBuildAccelerationStructureKHR(commandBuffer, 1, &buildInfo, &pBuildOffsetInfo); } } diff --git a/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.hpp b/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.hpp index bb389748..f3e86eab 100644 --- a/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.hpp +++ b/src/Vulkan/RayTracing/BottomLevelAccelerationStructure.hpp @@ -1,7 +1,7 @@ #pragma once #include "AccelerationStructure.hpp" -#include +#include "BottomLevelGeometry.hpp" namespace Assets { @@ -20,7 +20,7 @@ namespace Vulkan::RayTracing BottomLevelAccelerationStructure& operator = (const BottomLevelAccelerationStructure&) = delete; BottomLevelAccelerationStructure& operator = (BottomLevelAccelerationStructure&&) = delete; - BottomLevelAccelerationStructure(const class DeviceProcedures& deviceProcedures, const std::vector& geometries, bool allowUpdate); + BottomLevelAccelerationStructure(const class DeviceProcedures& deviceProcedures, const BottomLevelGeometry& geometries, bool allowUpdate); BottomLevelAccelerationStructure(BottomLevelAccelerationStructure&& other) noexcept; ~BottomLevelAccelerationStructure(); @@ -32,21 +32,9 @@ namespace Vulkan::RayTracing VkDeviceSize resultOffset, bool updateOnly) const; - static VkGeometryNV CreateGeometry( - const Assets::Scene& scene, - uint32_t vertexOffset, uint32_t vertexCount, - uint32_t indexOffset, uint32_t indexCount, - bool isOpaque); - - static VkGeometryNV CreateGeometryAabb( - const Assets::Scene& scene, - uint32_t aabbOffset, - uint32_t aabbCount, - bool isOpaque); - private: - std::vector geometries_; + BottomLevelGeometry geometries_; }; } diff --git a/src/Vulkan/RayTracing/BottomLevelGeometry.cpp b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp new file mode 100644 index 00000000..fa12905b --- /dev/null +++ b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp @@ -0,0 +1,89 @@ +#include "BottomLevelGeometry.hpp" +#include "DeviceProcedures.hpp" +#include "Assets/Scene.hpp" +#include "Assets/Vertex.hpp" +#include "Vulkan/Buffer.hpp" + +namespace Vulkan::RayTracing { + +void BottomLevelGeometry::AddGeometryTriangles( + const Assets::Scene& scene, + const uint32_t vertexOffset, const uint32_t vertexCount, + const uint32_t indexOffset, const uint32_t indexCount, + const bool isOpaque) +{ + VkAccelerationStructureCreateGeometryTypeInfoKHR createGeometryTypeInfo = {}; + createGeometryTypeInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + createGeometryTypeInfo.pNext = nullptr; + createGeometryTypeInfo.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + createGeometryTypeInfo.maxPrimitiveCount = indexCount / 3; + createGeometryTypeInfo.indexType = VK_INDEX_TYPE_UINT32; + createGeometryTypeInfo.maxVertexCount = vertexCount; + createGeometryTypeInfo.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT; + createGeometryTypeInfo.allowsTransforms = false; + + VkAccelerationStructureGeometryKHR geometry = {}; + geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + geometry.pNext = nullptr; + geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR; + geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; + geometry.geometry.triangles.pNext = nullptr; + geometry.geometry.triangles.vertexData.deviceAddress = scene.VertexBuffer().GetDeviceAddress(); + geometry.geometry.triangles.vertexStride = sizeof(Assets::Vertex); + geometry.geometry.triangles.vertexFormat = createGeometryTypeInfo.vertexFormat; + geometry.geometry.triangles.indexData.deviceAddress = scene.IndexBuffer().GetDeviceAddress(); + geometry.geometry.triangles.indexType = createGeometryTypeInfo.indexType; + geometry.geometry.triangles.transformData = {}; + geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; + geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_KHR : 0; + + VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {}; + buildOffsetInfo.firstVertex = vertexOffset; + buildOffsetInfo.primitiveOffset = indexOffset; + buildOffsetInfo.primitiveCount = indexCount; + buildOffsetInfo.transformOffset = 0; + + createGeometryTypeInfo_.emplace_back(createGeometryTypeInfo); + geometry_.emplace_back(geometry); + buildOffsetInfo_.emplace_back(buildOffsetInfo); +} + +void BottomLevelGeometry::AddGeometryAabb( + const Assets::Scene& scene, + const uint32_t aabbOffset, + const uint32_t aabbCount, + const bool isOpaque) +{ + VkAccelerationStructureCreateGeometryTypeInfoKHR createGeometryTypeInfo = {}; + createGeometryTypeInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + createGeometryTypeInfo.pNext = nullptr; + createGeometryTypeInfo.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; + createGeometryTypeInfo.maxPrimitiveCount = aabbCount; + createGeometryTypeInfo.indexType = VK_INDEX_TYPE_NONE_KHR; + createGeometryTypeInfo.maxVertexCount = 0; + createGeometryTypeInfo.vertexFormat = VK_FORMAT_UNDEFINED; + createGeometryTypeInfo.allowsTransforms = false; + + VkAccelerationStructureGeometryKHR geometry = {}; + geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + geometry.pNext = nullptr; + geometry.geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; + geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR; + geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; + geometry.geometry.aabbs.pNext = nullptr; + geometry.geometry.aabbs.data.deviceAddress = scene.AabbBuffer().GetDeviceAddress(); + geometry.geometry.aabbs.stride = sizeof(VkAabbPositionsKHR) * 2; + geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_KHR : 0; + + VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {}; + buildOffsetInfo.firstVertex = 0; + buildOffsetInfo.primitiveOffset = aabbOffset; + buildOffsetInfo.primitiveCount = aabbCount; + buildOffsetInfo.transformOffset = 0; + + createGeometryTypeInfo_.emplace_back(createGeometryTypeInfo); + geometry_.emplace_back(geometry); + buildOffsetInfo_.emplace_back(buildOffsetInfo); +} + +} diff --git a/src/Vulkan/RayTracing/BottomLevelGeometry.hpp b/src/Vulkan/RayTracing/BottomLevelGeometry.hpp new file mode 100644 index 00000000..e8efc430 --- /dev/null +++ b/src/Vulkan/RayTracing/BottomLevelGeometry.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "Vulkan/Vulkan.hpp" +#include + +namespace Assets +{ + class Procedural; + class Scene; +} + +namespace Vulkan::RayTracing +{ + + class BottomLevelGeometry final + { + public: + + size_t size() const { return geometry_.size(); } + + const std::vector& CreateGeometryTypeInfo() const { return createGeometryTypeInfo_; } + const std::vector& Geometry() const { return geometry_; } + const std::vector& BuildOffsetInfo() const { return buildOffsetInfo_; } + + void AddGeometryTriangles( + const Assets::Scene& scene, + uint32_t vertexOffset, uint32_t vertexCount, + uint32_t indexOffset, uint32_t indexCount, + bool isOpaque); + + void AddGeometryAabb( + const Assets::Scene& scene, + uint32_t aabbOffset, + uint32_t aabbCount, + bool isOpaque); + + private: + + // Describe how the acceleration structure is created. It is an indication how large it could be. + std::vector createGeometryTypeInfo_; + + // The geometry to build, addresses of vertices and indices. + std::vector geometry_; + + // the number of elements to build and offsets + std::vector buildOffsetInfo_; + }; + +} diff --git a/src/Vulkan/RayTracing/DeviceProcedures.cpp b/src/Vulkan/RayTracing/DeviceProcedures.cpp index 69ba01de..e50d9a3f 100644 --- a/src/Vulkan/RayTracing/DeviceProcedures.cpp +++ b/src/Vulkan/RayTracing/DeviceProcedures.cpp @@ -23,18 +23,17 @@ namespace DeviceProcedures::DeviceProcedures(const class Device& device) : - vkCreateAccelerationStructureNV(GetProcedure(device, "vkCreateAccelerationStructureNV")), - vkDestroyAccelerationStructureNV(GetProcedure(device, "vkDestroyAccelerationStructureNV")), - vkGetAccelerationStructureMemoryRequirementsNV(GetProcedure(device, "vkGetAccelerationStructureMemoryRequirementsNV")), - vkBindAccelerationStructureMemoryNV(GetProcedure(device, "vkBindAccelerationStructureMemoryNV")), - vkCmdBuildAccelerationStructureNV(GetProcedure(device, "vkCmdBuildAccelerationStructureNV")), - vkCmdCopyAccelerationStructureNV(GetProcedure(device, "vkCmdCopyAccelerationStructureNV")), - vkCmdTraceRaysNV(GetProcedure(device, "vkCmdTraceRaysNV")), - vkCreateRayTracingPipelinesNV(GetProcedure(device, "vkCreateRayTracingPipelinesNV")), - vkGetRayTracingShaderGroupHandlesNV(GetProcedure(device, "vkGetRayTracingShaderGroupHandlesNV")), - vkGetAccelerationStructureHandleNV(GetProcedure(device, "vkGetAccelerationStructureHandleNV")), - vkCmdWriteAccelerationStructuresPropertiesNV(GetProcedure(device, "vkCmdWriteAccelerationStructuresPropertiesNV")), - vkCompileDeferredNV(GetProcedure(device, "vkCompileDeferredNV")), + vkCreateAccelerationStructureKHR(GetProcedure(device, "vkCreateAccelerationStructureKHR")), + vkDestroyAccelerationStructureKHR(GetProcedure(device, "vkDestroyAccelerationStructureKHR")), + vkGetAccelerationStructureMemoryRequirementsKHR(GetProcedure(device, "vkGetAccelerationStructureMemoryRequirementsKHR")), + vkBindAccelerationStructureMemoryKHR(GetProcedure(device, "vkBindAccelerationStructureMemoryKHR")), + vkCmdBuildAccelerationStructureKHR(GetProcedure(device, "vkCmdBuildAccelerationStructureKHR")), + vkCmdCopyAccelerationStructureKHR(GetProcedure(device, "vkCmdCopyAccelerationStructureKHR")), + vkCmdTraceRaysKHR(GetProcedure(device, "vkCmdTraceRaysKHR")), + vkCreateRayTracingPipelinesKHR(GetProcedure(device, "vkCreateRayTracingPipelinesKHR")), + vkGetRayTracingShaderGroupHandlesKHR(GetProcedure(device, "vkGetRayTracingShaderGroupHandlesKHR")), + vkGetAccelerationStructureDeviceAddressKHR(GetProcedure(device, "vkGetAccelerationStructureDeviceAddressKHR")), + vkCmdWriteAccelerationStructuresPropertiesKHR(GetProcedure(device, "vkCmdWriteAccelerationStructuresPropertiesKHR")), device_(device) { } diff --git a/src/Vulkan/RayTracing/DeviceProcedures.hpp b/src/Vulkan/RayTracing/DeviceProcedures.hpp index 65cc1562..e79965fc 100644 --- a/src/Vulkan/RayTracing/DeviceProcedures.hpp +++ b/src/Vulkan/RayTracing/DeviceProcedures.hpp @@ -19,77 +19,63 @@ namespace Vulkan ~DeviceProcedures(); const class Device& Device() const { return device_; } - + const std::function - vkCreateAccelerationStructureNV; + VkAccelerationStructureKHR* pAccelerationStructure)> + vkCreateAccelerationStructureKHR; const std::function - vkDestroyAccelerationStructureNV; + vkDestroyAccelerationStructureKHR; const std::function - vkGetAccelerationStructureMemoryRequirementsNV; + vkGetAccelerationStructureMemoryRequirementsKHR; const std::function - vkBindAccelerationStructureMemoryNV; + const VkBindAccelerationStructureMemoryInfoKHR* pBindInfos)> + vkBindAccelerationStructureMemoryKHR; const std::function - vkCmdBuildAccelerationStructureNV; + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildOffsetInfoKHR* const* ppOffsetInfos)> + vkCmdBuildAccelerationStructureKHR; const std::function - vkCmdCopyAccelerationStructureNV; + const VkCopyAccelerationStructureInfoKHR* pInfo)> + vkCmdCopyAccelerationStructureKHR; const std::function - vkCmdTraceRaysNV; + vkCmdTraceRaysKHR; const std::function - vkCreateRayTracingPipelinesNV; + vkCreateRayTracingPipelinesKHR; const std::function - vkGetRayTracingShaderGroupHandlesNV; + vkGetRayTracingShaderGroupHandlesKHR; - const std::function - vkGetAccelerationStructureHandleNV; + const std::function + vkGetAccelerationStructureDeviceAddressKHR; const std::function - vkCmdWriteAccelerationStructuresPropertiesNV; - - const std::function - vkCompileDeferredNV; - + vkCmdWriteAccelerationStructuresPropertiesKHR; + private: const class Device& device_; diff --git a/src/Vulkan/RayTracing/RayTracingPipeline.cpp b/src/Vulkan/RayTracing/RayTracingPipeline.cpp index 775698e8..24f87c27 100644 --- a/src/Vulkan/RayTracing/RayTracingPipeline.cpp +++ b/src/Vulkan/RayTracing/RayTracingPipeline.cpp @@ -31,26 +31,26 @@ RayTracingPipeline::RayTracingPipeline( const std::vector descriptorBindings = { // Top level acceleration structure. - {0, 1, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV, VK_SHADER_STAGE_RAYGEN_BIT_NV}, + {0, 1, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_RAYGEN_BIT_KHR}, // Image accumulation & output - {1, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_RAYGEN_BIT_NV}, - {2, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_RAYGEN_BIT_NV}, + {1, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_RAYGEN_BIT_KHR}, + {2, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_RAYGEN_BIT_KHR}, // Camera information & co - {3, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_RAYGEN_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV}, + {3, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR}, // Vertex buffer, Index buffer, Material buffer, Offset buffer - {4, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}, - {5, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}, - {6, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}, - {7, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}, + {4, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}, + {5, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}, + {6, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}, + {7, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}, // Textures and image samplers - {8, static_cast(scene.TextureSamplers().size()), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV}, + {8, static_cast(scene.TextureSamplers().size()), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR}, // The Procedural buffer. - {9, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV | VK_SHADER_STAGE_INTERSECTION_BIT_NV} + {9, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR} }; descriptorSetManager_.reset(new DescriptorSetManager(device, descriptorBindings, uniformBuffers.size())); @@ -61,8 +61,8 @@ RayTracingPipeline::RayTracingPipeline( { // Top level acceleration structure. const auto accelerationStructureHandle = accelerationStructure.Handle(); - VkWriteDescriptorSetAccelerationStructureNV structureInfo = {}; - structureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV; + VkWriteDescriptorSetAccelerationStructureKHR structureInfo = {}; + structureInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; structureInfo.pNext = nullptr; structureInfo.accelerationStructureCount = 1; structureInfo.pAccelerationStructures = &accelerationStructureHandle; @@ -151,55 +151,55 @@ RayTracingPipeline::RayTracingPipeline( std::vector shaderStages = { - rayGenShader.CreateShaderStage(VK_SHADER_STAGE_RAYGEN_BIT_NV), - missShader.CreateShaderStage(VK_SHADER_STAGE_MISS_BIT_NV), - closestHitShader.CreateShaderStage(VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV), - proceduralClosestHitShader.CreateShaderStage(VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV), - proceduralIntersectionShader.CreateShaderStage(VK_SHADER_STAGE_INTERSECTION_BIT_NV) + rayGenShader.CreateShaderStage(VK_SHADER_STAGE_RAYGEN_BIT_KHR), + missShader.CreateShaderStage(VK_SHADER_STAGE_MISS_BIT_KHR), + closestHitShader.CreateShaderStage(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR), + proceduralClosestHitShader.CreateShaderStage(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR), + proceduralIntersectionShader.CreateShaderStage(VK_SHADER_STAGE_INTERSECTION_BIT_KHR) }; // Shader groups - VkRayTracingShaderGroupCreateInfoNV rayGenGroupInfo = {}; - rayGenGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV; + VkRayTracingShaderGroupCreateInfoKHR rayGenGroupInfo = {}; + rayGenGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; rayGenGroupInfo.pNext = nullptr; - rayGenGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV; + rayGenGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; rayGenGroupInfo.generalShader = 0; - rayGenGroupInfo.closestHitShader = VK_SHADER_UNUSED_NV; - rayGenGroupInfo.anyHitShader = VK_SHADER_UNUSED_NV; - rayGenGroupInfo.intersectionShader = VK_SHADER_UNUSED_NV; + rayGenGroupInfo.closestHitShader = VK_SHADER_UNUSED_KHR; + rayGenGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR; + rayGenGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR; rayGenIndex_ = 0; - VkRayTracingShaderGroupCreateInfoNV missGroupInfo = {}; - missGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV; + VkRayTracingShaderGroupCreateInfoKHR missGroupInfo = {}; + missGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; missGroupInfo.pNext = nullptr; - missGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV; + missGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR; missGroupInfo.generalShader = 1; - missGroupInfo.closestHitShader = VK_SHADER_UNUSED_NV; - missGroupInfo.anyHitShader = VK_SHADER_UNUSED_NV; - missGroupInfo.intersectionShader = VK_SHADER_UNUSED_NV; + missGroupInfo.closestHitShader = VK_SHADER_UNUSED_KHR; + missGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR; + missGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR; missIndex_ = 1; - VkRayTracingShaderGroupCreateInfoNV triangleHitGroupInfo = {}; - triangleHitGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV; + VkRayTracingShaderGroupCreateInfoKHR triangleHitGroupInfo = {}; + triangleHitGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; triangleHitGroupInfo.pNext = nullptr; - triangleHitGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV; - triangleHitGroupInfo.generalShader = VK_SHADER_UNUSED_NV; + triangleHitGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; + triangleHitGroupInfo.generalShader = VK_SHADER_UNUSED_KHR; triangleHitGroupInfo.closestHitShader = 2; - triangleHitGroupInfo.anyHitShader = VK_SHADER_UNUSED_NV; - triangleHitGroupInfo.intersectionShader = VK_SHADER_UNUSED_NV; + triangleHitGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR; + triangleHitGroupInfo.intersectionShader = VK_SHADER_UNUSED_KHR; triangleHitGroupIndex_ = 2; - VkRayTracingShaderGroupCreateInfoNV proceduralHitGroupInfo = {}; - proceduralHitGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV; + VkRayTracingShaderGroupCreateInfoKHR proceduralHitGroupInfo = {}; + proceduralHitGroupInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR; proceduralHitGroupInfo.pNext = nullptr; - proceduralHitGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV; - proceduralHitGroupInfo.generalShader = VK_SHADER_UNUSED_NV; + proceduralHitGroupInfo.type = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR; + proceduralHitGroupInfo.generalShader = VK_SHADER_UNUSED_KHR; proceduralHitGroupInfo.closestHitShader = 3; - proceduralHitGroupInfo.anyHitShader = VK_SHADER_UNUSED_NV; + proceduralHitGroupInfo.anyHitShader = VK_SHADER_UNUSED_KHR; proceduralHitGroupInfo.intersectionShader = 4; proceduralHitGroupIndex_ = 3; - std::vector groups = + std::vector groups = { rayGenGroupInfo, missGroupInfo, @@ -208,8 +208,8 @@ RayTracingPipeline::RayTracingPipeline( }; // Create graphic pipeline - VkRayTracingPipelineCreateInfoNV pipelineInfo = {}; - pipelineInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV; + VkRayTracingPipelineCreateInfoKHR pipelineInfo = {}; + pipelineInfo.sType = VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR; pipelineInfo.pNext = nullptr; pipelineInfo.flags = 0; pipelineInfo.stageCount = static_cast(shaderStages.size()); @@ -221,7 +221,7 @@ RayTracingPipeline::RayTracingPipeline( pipelineInfo.basePipelineHandle = nullptr; pipelineInfo.basePipelineIndex = 0; - Check(deviceProcedures.vkCreateRayTracingPipelinesNV(device.Handle(), nullptr, 1, &pipelineInfo, nullptr, &pipeline_), + Check(deviceProcedures.vkCreateRayTracingPipelinesKHR(device.Handle(), nullptr, 1, &pipelineInfo, nullptr, &pipeline_), "create ray tracing pipeline"); } diff --git a/src/Vulkan/RayTracing/RayTracingProperties.cpp b/src/Vulkan/RayTracing/RayTracingProperties.cpp index 95d5c1c3..138b9997 100644 --- a/src/Vulkan/RayTracing/RayTracingProperties.cpp +++ b/src/Vulkan/RayTracing/RayTracingProperties.cpp @@ -6,7 +6,7 @@ namespace Vulkan::RayTracing { RayTracingProperties::RayTracingProperties(const class Device& device) : device_(device) { - props_.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV; + props_.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_KHR; VkPhysicalDeviceProperties2 props = {}; props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; diff --git a/src/Vulkan/RayTracing/RayTracingProperties.hpp b/src/Vulkan/RayTracing/RayTracingProperties.hpp index 35bcceed..12c0212c 100644 --- a/src/Vulkan/RayTracing/RayTracingProperties.hpp +++ b/src/Vulkan/RayTracing/RayTracingProperties.hpp @@ -19,16 +19,17 @@ namespace Vulkan uint32_t MaxDescriptorSetAccelerationStructures() const { return props_.maxDescriptorSetAccelerationStructures; } uint64_t MaxGeometryCount() const { return props_.maxGeometryCount; } uint64_t MaxInstanceCount() const { return props_.maxInstanceCount; } + uint64_t MaxPrimitiveCount() const { return props_.maxPrimitiveCount; } uint32_t MaxRecursionDepth() const { return props_.maxRecursionDepth; } uint32_t MaxShaderGroupStride() const { return props_.maxShaderGroupStride; } - uint64_t MaxTriangleCount() const { return props_.maxTriangleCount; } uint32_t ShaderGroupBaseAlignment() const { return props_.shaderGroupBaseAlignment; } + uint32_t ShaderGroupHandleCaptureReplaySize() { return props_.shaderGroupHandleCaptureReplaySize; } uint32_t ShaderGroupHandleSize() const { return props_.shaderGroupHandleSize; } private: const class Device& device_; - VkPhysicalDeviceRayTracingPropertiesNV props_{}; + VkPhysicalDeviceRayTracingPropertiesKHR props_{}; }; } } diff --git a/src/Vulkan/RayTracing/ShaderBindingTable.cpp b/src/Vulkan/RayTracing/ShaderBindingTable.cpp index 1c50be0d..3ada7437 100644 --- a/src/Vulkan/RayTracing/ShaderBindingTable.cpp +++ b/src/Vulkan/RayTracing/ShaderBindingTable.cpp @@ -46,7 +46,7 @@ namespace for (const auto& entry : entries) { - // Copy the shader identifier that was previously obtained with vkGetRayTracingShaderGroupHandlesNV. + // Copy the shader identifier that was previously obtained with vkGetRayTracingShaderGroupHandlesKHR. std::memcpy(pDst, shaderHandleStorage + entry.GroupIndex * handleSize, handleSize); std::memcpy(pDst + handleSize, entry.InlineData.data(), entry.InlineData.size()); @@ -89,7 +89,7 @@ ShaderBindingTable::ShaderBindingTable( const size_t groupCount = rayGenPrograms.size() + missPrograms.size() + hitGroups.size(); std::vector shaderHandleStorage(groupCount * handleSize); - Check(deviceProcedures.vkGetRayTracingShaderGroupHandlesNV( + Check(deviceProcedures.vkGetRayTracingShaderGroupHandlesKHR( device.Handle(), rayTracingPipeline.Handle(), 0, static_cast(groupCount), diff --git a/src/Vulkan/RayTracing/TopLevelAccelerationStructure.cpp b/src/Vulkan/RayTracing/TopLevelAccelerationStructure.cpp index 19559b08..35fcbf33 100644 --- a/src/Vulkan/RayTracing/TopLevelAccelerationStructure.cpp +++ b/src/Vulkan/RayTracing/TopLevelAccelerationStructure.cpp @@ -11,39 +11,32 @@ namespace Vulkan::RayTracing { namespace { - VkAccelerationStructureCreateInfoNV GetCreateInfo(const size_t instanceCount, const bool allowUpdate) + std::vector GetCreateGeometryTypeInfo(const size_t instanceCount) { - const auto flags = allowUpdate - ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV - : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV; - - VkAccelerationStructureCreateInfoNV structureInfo = {}; - structureInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV; - structureInfo.pNext = nullptr; - structureInfo.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; - structureInfo.info.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV; - structureInfo.info.flags = flags; - structureInfo.compactedSize = 0; - structureInfo.info.instanceCount = static_cast(instanceCount); - structureInfo.info.geometryCount = 0; // Since this is a top-level AS, it does not contain any geometry - structureInfo.info.pGeometries = nullptr; - - return structureInfo; + + VkAccelerationStructureCreateGeometryTypeInfoKHR createGeometryTypeInfo = {}; + createGeometryTypeInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_GEOMETRY_TYPE_INFO_KHR; + createGeometryTypeInfo.pNext = nullptr; + createGeometryTypeInfo.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + createGeometryTypeInfo.maxPrimitiveCount = static_cast(instanceCount); + createGeometryTypeInfo.allowsTransforms = true; + + return std::vector{createGeometryTypeInfo}; } } TopLevelAccelerationStructure::TopLevelAccelerationStructure( const class DeviceProcedures& deviceProcedures, - const std::vector& geometryInstances, + const std::vector& instances, const bool allowUpdate) : - AccelerationStructure(deviceProcedures, GetCreateInfo(geometryInstances.size(), allowUpdate)), - geometryInstances_(geometryInstances) + AccelerationStructure(deviceProcedures, VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, GetCreateGeometryTypeInfo(instances.size()), allowUpdate), + instances_(instances) { } TopLevelAccelerationStructure::TopLevelAccelerationStructure(TopLevelAccelerationStructure&& other) noexcept : AccelerationStructure(std::move(other)), - geometryInstances_(std::move(other.geometryInstances_)) + instances_(std::move(other.instances_)) { } @@ -67,16 +60,16 @@ void TopLevelAccelerationStructure::Generate( throw std::invalid_argument("cannot update readonly structure"); } - const VkAccelerationStructureNV previousStructure = updateOnly ? Handle() : nullptr; + const VkAccelerationStructureKHR previousStructure = updateOnly ? Handle() : nullptr; // Copy the instance descriptors into the provider buffer. - const auto instancesBufferSize = geometryInstances_.size() * sizeof(VkGeometryInstance); + const auto instancesBufferSize = instances_.size() * sizeof(VkAccelerationStructureInstanceKHR); void* data = instanceMemory.Map(0, instancesBufferSize); - std::memcpy(data, geometryInstances_.data(), instancesBufferSize); + std::memcpy(data, instances_.data(), instancesBufferSize); // Bind the acceleration structure descriptor to the actual memory that will contain it - VkBindAccelerationStructureMemoryInfoNV bindInfo = {}; - bindInfo.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV; + VkBindAccelerationStructureMemoryInfoKHR bindInfo = {}; + bindInfo.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_KHR; bindInfo.pNext = nullptr; bindInfo.accelerationStructure = Handle(); bindInfo.memory = resultMemory.Handle(); @@ -84,49 +77,74 @@ void TopLevelAccelerationStructure::Generate( bindInfo.deviceIndexCount = 0; bindInfo.pDeviceIndices = nullptr; - Check(deviceProcedures_.vkBindAccelerationStructureMemoryNV(Device().Handle(), 1, &bindInfo), + Check(deviceProcedures_.vkBindAccelerationStructureMemoryKHR(Device().Handle(), 1, &bindInfo), "bind acceleration structure"); - // Build the actual bottom-level acceleration structure - const auto flags = allowUpdate_ - ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV - : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV; + // Create instance geometry structures + VkAccelerationStructureGeometryKHR geometry = {}; + geometry.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR; + geometry.pNext = nullptr; + geometry.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR; + geometry.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR; + geometry.geometry.instances.arrayOfPointers = false; + geometry.geometry.instances.data.deviceAddress = instanceBuffer.GetDeviceAddress() + instanceOffset; - VkAccelerationStructureInfoNV buildInfo = {}; - buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV; + VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {}; + buildOffsetInfo.primitiveCount = static_cast(instances_.size()); + + // Build the actual bottom-level acceleration structure + const auto flags = allowUpdate_ + ? VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR + : VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR; + + const VkAccelerationStructureGeometryKHR* pGeometry = &geometry; + const VkAccelerationStructureBuildOffsetInfoKHR* pBuildOffsetInfo = &buildOffsetInfo; + + VkAccelerationStructureBuildGeometryInfoKHR buildInfo = {}; + buildInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR; buildInfo.pNext = nullptr; buildInfo.flags = flags; - buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV; - buildInfo.instanceCount = static_cast(geometryInstances_.size()); - buildInfo.geometryCount = 0; - buildInfo.pGeometries = nullptr; - - deviceProcedures_.vkCmdBuildAccelerationStructureNV( - commandBuffer, &buildInfo, instanceBuffer.Handle(), instanceOffset, updateOnly, Handle(), previousStructure, scratchBuffer.Handle(), scratchOffset); + buildInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR; + buildInfo.update = updateOnly; + buildInfo.srcAccelerationStructure = previousStructure; + buildInfo.dstAccelerationStructure = Handle(), + buildInfo.geometryArrayOfPointers = false; + buildInfo.geometryCount = 1; + buildInfo.ppGeometries = &pGeometry; + buildInfo.scratchData.deviceAddress = scratchBuffer.GetDeviceAddress() + scratchOffset; + + deviceProcedures_.vkCmdBuildAccelerationStructureKHR(commandBuffer, 1, &buildInfo, &pBuildOffsetInfo); } -VkGeometryInstance TopLevelAccelerationStructure::CreateGeometryInstance( +VkAccelerationStructureInstanceKHR TopLevelAccelerationStructure::CreateInstance( const BottomLevelAccelerationStructure& bottomLevelAs, const glm::mat4& transform, const uint32_t instanceId, - const uint32_t hitGroupIndex) + const uint32_t hitGroupId) { const auto& device = bottomLevelAs.Device(); - const auto& deviceProcedures = bottomLevelAs.DeviceProcedures(); - - uint64_t accelerationStructureHandle; - Check(deviceProcedures.vkGetAccelerationStructureHandleNV(device.Handle(), bottomLevelAs.Handle(), sizeof(uint64_t), &accelerationStructureHandle), - "get acceleration structure handle"); - - VkGeometryInstance geometryInstance = {}; - std::memcpy(geometryInstance.transform, &transform, sizeof(glm::mat4)); - geometryInstance.instanceCustomIndex = instanceId; - geometryInstance.mask = 0xFF; // The visibility mask is always set of 0xFF, but if some instances would need to be ignored in some cases, this flag should be passed by the application. - geometryInstance.instanceOffset = hitGroupIndex; // Set the hit group index, that will be used to find the shader code to execute when hitting the geometry. - geometryInstance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV; // Disable culling - more fine control could be provided by the application - geometryInstance.accelerationStructureHandle = accelerationStructureHandle; - - return geometryInstance; + const auto& deviceProcedure = bottomLevelAs.DeviceProcedures(); + + VkAccelerationStructureDeviceAddressInfoKHR addressInfo = {}; + addressInfo.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR; + addressInfo.pNext = nullptr; + addressInfo.accelerationStructure = bottomLevelAs.Handle(); + + const VkDeviceAddress address = deviceProcedure.vkGetAccelerationStructureDeviceAddressKHR(device.Handle(), &addressInfo); + + VkAccelerationStructureInstanceKHR instance = {}; + instance.instanceCustomIndex = instanceId; + instance.mask = 0xFF; // The visibility mask is always set of 0xFF, but if some instances would need to be ignored in some cases, this flag should be passed by the application. + instance.instanceShaderBindingTableRecordOffset = hitGroupId; // Set the hit group index, that will be used to find the shader code to execute when hitting the geometry. + instance.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; // Disable culling - more fine control could be provided by the application + instance.accelerationStructureReference = address; + + // The instance.transform value only contains 12 values, corresponding to a 4x3 matrix, + // hence saving the last row that is anyway always (0,0,0,1). + // Since the matrix is row-major, we simply copy the first 12 values of the original 4x4 matrix + std::memcpy(&instance.transform, &transform, sizeof(instance.transform)); + + return instance; } } diff --git a/src/Vulkan/RayTracing/TopLevelAccelerationStructure.hpp b/src/Vulkan/RayTracing/TopLevelAccelerationStructure.hpp index 633e9305..a7d1b320 100644 --- a/src/Vulkan/RayTracing/TopLevelAccelerationStructure.hpp +++ b/src/Vulkan/RayTracing/TopLevelAccelerationStructure.hpp @@ -6,23 +6,6 @@ namespace Vulkan::RayTracing { - /// Geometry instance, with the layout expected by VK_NV_ray_tracing - struct VkGeometryInstance - { - /// Transform matrix, containing only the top 3 rows - float transform[12]; - /// Instance index - uint32_t instanceCustomIndex : 24; - /// Visibility mask - uint32_t mask : 8; - /// Index of the hit group which will be invoked when a ray hits the instance - uint32_t instanceOffset : 24; - /// Instance flags, such as culling - uint32_t flags : 8; - /// Opaque handle of the bottom-level acceleration structure - uint64_t accelerationStructureHandle; - }; - class BottomLevelAccelerationStructure; class TopLevelAccelerationStructure final : public AccelerationStructure @@ -33,11 +16,11 @@ namespace Vulkan::RayTracing TopLevelAccelerationStructure& operator = (const TopLevelAccelerationStructure&) = delete; TopLevelAccelerationStructure& operator = (TopLevelAccelerationStructure&&) = delete; - TopLevelAccelerationStructure(const class DeviceProcedures& deviceProcedures, const std::vector& geometryInstances, bool allowUpdate); + TopLevelAccelerationStructure(const class DeviceProcedures& deviceProcedures, const std::vector& instances, bool allowUpdate); TopLevelAccelerationStructure(TopLevelAccelerationStructure&& other) noexcept; virtual ~TopLevelAccelerationStructure(); - const std::vector& GeometryInstances() const { return geometryInstances_; } + //const std::vector& GeometryInstances() const { return geometryInstances_; } void Generate( VkCommandBuffer commandBuffer, @@ -50,15 +33,15 @@ namespace Vulkan::RayTracing VkDeviceSize instanceOffset, bool updateOnly) const; - static VkGeometryInstance CreateGeometryInstance( + static VkAccelerationStructureInstanceKHR CreateInstance( const BottomLevelAccelerationStructure& bottomLevelAs, const glm::mat4& transform, uint32_t instanceId, - uint32_t hitGroupIndex); + uint32_t hitGroupId); private: - std::vector geometryInstances_; + std::vector instances_; }; } diff --git a/src/Vulkan/Vulkan.cpp b/src/Vulkan/Vulkan.cpp index 83f502e5..92b48626 100644 --- a/src/Vulkan/Vulkan.cpp +++ b/src/Vulkan/Vulkan.cpp @@ -13,44 +13,52 @@ void Check(const VkResult result, const char* const operation) const char* ToString(const VkResult result) { - switch (result) - { + switch (result) + { #define STR(r) case VK_ ##r: return #r - STR(SUCCESS); - STR(NOT_READY); - STR(TIMEOUT); - STR(EVENT_SET); - STR(EVENT_RESET); - STR(INCOMPLETE); - STR(ERROR_OUT_OF_HOST_MEMORY); - STR(ERROR_OUT_OF_DEVICE_MEMORY); - STR(ERROR_INITIALIZATION_FAILED); - STR(ERROR_DEVICE_LOST); - STR(ERROR_MEMORY_MAP_FAILED); - STR(ERROR_LAYER_NOT_PRESENT); - STR(ERROR_EXTENSION_NOT_PRESENT); - STR(ERROR_FEATURE_NOT_PRESENT); - STR(ERROR_INCOMPATIBLE_DRIVER); - STR(ERROR_TOO_MANY_OBJECTS); - STR(ERROR_FORMAT_NOT_SUPPORTED); - STR(ERROR_FRAGMENTED_POOL); - STR(ERROR_OUT_OF_POOL_MEMORY); - STR(ERROR_INVALID_EXTERNAL_HANDLE); - STR(ERROR_SURFACE_LOST_KHR); - STR(ERROR_NATIVE_WINDOW_IN_USE_KHR); - STR(SUBOPTIMAL_KHR); - STR(ERROR_OUT_OF_DATE_KHR); - STR(ERROR_INCOMPATIBLE_DISPLAY_KHR); - STR(ERROR_VALIDATION_FAILED_EXT); - STR(ERROR_INVALID_SHADER_NV); - STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); - STR(ERROR_FRAGMENTATION_EXT); - STR(ERROR_NOT_PERMITTED_EXT); - STR(ERROR_INVALID_DEVICE_ADDRESS_EXT); + STR(SUCCESS); + STR(NOT_READY); + STR(TIMEOUT); + STR(EVENT_SET); + STR(EVENT_RESET); + STR(INCOMPLETE); + STR(ERROR_OUT_OF_HOST_MEMORY); + STR(ERROR_OUT_OF_DEVICE_MEMORY); + STR(ERROR_INITIALIZATION_FAILED); + STR(ERROR_DEVICE_LOST); + STR(ERROR_MEMORY_MAP_FAILED); + STR(ERROR_LAYER_NOT_PRESENT); + STR(ERROR_EXTENSION_NOT_PRESENT); + STR(ERROR_FEATURE_NOT_PRESENT); + STR(ERROR_INCOMPATIBLE_DRIVER); + STR(ERROR_TOO_MANY_OBJECTS); + STR(ERROR_FORMAT_NOT_SUPPORTED); + STR(ERROR_FRAGMENTED_POOL); + STR(ERROR_UNKNOWN); + STR(ERROR_OUT_OF_POOL_MEMORY); + STR(ERROR_INVALID_EXTERNAL_HANDLE); + STR(ERROR_FRAGMENTATION); + STR(ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS); + STR(ERROR_SURFACE_LOST_KHR); + STR(ERROR_NATIVE_WINDOW_IN_USE_KHR); + STR(SUBOPTIMAL_KHR); + STR(ERROR_OUT_OF_DATE_KHR); + STR(ERROR_INCOMPATIBLE_DISPLAY_KHR); + STR(ERROR_VALIDATION_FAILED_EXT); + STR(ERROR_INVALID_SHADER_NV); + STR(ERROR_INCOMPATIBLE_VERSION_KHR); + STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT); + STR(ERROR_NOT_PERMITTED_EXT); + STR(ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT); + STR(THREAD_IDLE_KHR); + STR(THREAD_DONE_KHR); + STR(OPERATION_DEFERRED_KHR); + STR(OPERATION_NOT_DEFERRED_KHR); + STR(ERROR_PIPELINE_COMPILE_REQUIRED_EXT); #undef STR - default: - return "UNKNOWN_ERROR"; - } + default: + return "UNKNOWN_ERROR"; + } } } diff --git a/src/Vulkan/Vulkan.hpp b/src/Vulkan/Vulkan.hpp index 5d7d17f3..0bd6f6c6 100644 --- a/src/Vulkan/Vulkan.hpp +++ b/src/Vulkan/Vulkan.hpp @@ -3,6 +3,7 @@ #define NOMINMAX #define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_VULKAN +#define VK_ENABLE_BETA_EXTENSIONS // Until VK_KHR_ray_tracing is out of beta #include #undef APIENTRY diff --git a/src/main.cpp b/src/main.cpp index bc0d20e7..e4565b04 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ namespace UserSettings CreateUserSettings(const Options& options); void PrintVulkanSdkInformation(); void PrintVulkanInstanceInformation(const Vulkan::Application& application, bool benchmark); + void PrintVulkanLayersInformation(const Vulkan::Application& application, bool benchmark); void PrintVulkanDevices(const Vulkan::Application& application); void SetVulkanDevice(Vulkan::Application& application); } @@ -40,7 +41,9 @@ int main(int argc, const char* argv[]) noexcept PrintVulkanSdkInformation(); PrintVulkanInstanceInformation(application, options.Benchmark); + PrintVulkanLayersInformation(application, options.Benchmark); PrintVulkanDevices(application); + SetVulkanDevice(application); application.Run(); @@ -107,6 +110,7 @@ namespace void PrintVulkanSdkInformation() { std::cout << "Vulkan SDK Header Version: " << VK_HEADER_VERSION << std::endl; + std::cout << std::endl; } void PrintVulkanInstanceInformation(const Vulkan::Application& application, const bool benchmark) @@ -122,6 +126,28 @@ namespace { std::cout << "- " << extension.extensionName << " (" << Vulkan::Version(extension.specVersion) << ")" << std::endl; } + + std::cout << std::endl; + } + + void PrintVulkanLayersInformation(const Vulkan::Application& application, const bool benchmark) + { + if (benchmark) + { + return; + } + + std::cout << "Vulkan Instance Layers: " << std::endl; + + for (const auto& layer : application.Layers()) + { + std::cout + << "- " << layer.layerName + << " (" << Vulkan::Version(layer.specVersion) << ")" + << " : " << layer.description << std::endl; + } + + std::cout << std::endl; } void PrintVulkanDevices(const Vulkan::Application& application) @@ -130,12 +156,20 @@ namespace for (const auto& device : application.PhysicalDevices()) { - VkPhysicalDeviceProperties prop; - vkGetPhysicalDeviceProperties(device, &prop); + VkPhysicalDeviceDriverProperties driverProp{}; + driverProp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + + VkPhysicalDeviceProperties2 deviceProp{}; + deviceProp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + deviceProp.pNext = &driverProp; + + vkGetPhysicalDeviceProperties2(device, &deviceProp); VkPhysicalDeviceFeatures features; vkGetPhysicalDeviceFeatures(device, &features); + const auto& prop = deviceProp.properties; + const Vulkan::Version vulkanVersion(prop.apiVersion); const Vulkan::Version driverVersion(prop.driverVersion, prop.vendorID); @@ -144,9 +178,11 @@ namespace std::cout << "' ("; std::cout << Vulkan::Strings::DeviceType(prop.deviceType) << ": "; std::cout << "vulkan " << vulkanVersion << ", "; - std::cout << "driver " << driverVersion; + std::cout << "driver " << driverProp.driverName << " " << driverProp.driverInfo << " - " << driverVersion; std::cout << ")" << std::endl; } + + std::cout << std::endl; } void SetVulkanDevice(Vulkan::Application& application) From 1d1d44738a9aa12e65f3caa55a076702540f6488 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 20:44:17 +0100 Subject: [PATCH 02/28] Moving shaders to GL_EXT_ray_tracing. --- assets/shaders/RayTracing.Procedural.rchit | 14 +++--- assets/shaders/RayTracing.Procedural.rint | 16 +++---- assets/shaders/RayTracing.rchit | 10 ++-- assets/shaders/RayTracing.rgen | 22 ++++----- assets/shaders/RayTracing.rmiss | 6 +-- src/Vulkan/Device.cpp | 54 ++++++++++++---------- vcpkg_linux.sh | 2 +- vcpkg_windows.bat | 2 +- 8 files changed, 66 insertions(+), 60 deletions(-) diff --git a/assets/shaders/RayTracing.Procedural.rchit b/assets/shaders/RayTracing.Procedural.rchit index 408eadd0..e4a112ba 100644 --- a/assets/shaders/RayTracing.Procedural.rchit +++ b/assets/shaders/RayTracing.Procedural.rchit @@ -1,7 +1,7 @@ #version 460 #extension GL_EXT_nonuniform_qualifier : require #extension GL_GOOGLE_include_directive : require -#extension GL_NV_ray_tracing : require +#extension GL_EXT_ray_tracing : require #include "Material.glsl" layout(binding = 4) readonly buffer VertexArray { float Vertices[]; }; @@ -14,8 +14,8 @@ layout(binding = 9) readonly buffer SphereArray { vec4[] Spheres; }; #include "Scatter.glsl" #include "Vertex.glsl" -hitAttributeNV vec4 Sphere; -rayPayloadInNV RayPayload Ray; +hitAttributeEXT vec4 Sphere; +rayPayloadInEXT RayPayload Ray; vec2 GetSphereTexCoord(const vec3 point) { @@ -33,19 +33,19 @@ vec2 GetSphereTexCoord(const vec3 point) void main() { // Get the material. - const uvec2 offsets = Offsets[gl_InstanceCustomIndexNV]; + const uvec2 offsets = Offsets[gl_InstanceCustomIndexEXT]; const uint indexOffset = offsets.x; const uint vertexOffset = offsets.y; const Vertex v0 = UnpackVertex(vertexOffset + Indices[indexOffset]); const Material material = Materials[v0.MaterialIndex]; // Compute the ray hit point properties. - const vec4 sphere = Spheres[gl_InstanceCustomIndexNV]; + const vec4 sphere = Spheres[gl_InstanceCustomIndexEXT]; const vec3 center = sphere.xyz; const float radius = sphere.w; - const vec3 point = gl_WorldRayOriginNV + gl_HitTNV * gl_WorldRayDirectionNV; + const vec3 point = gl_WorldRayOriginEXT + gl_HitTEXT * gl_WorldRayDirectionEXT; const vec3 normal = (point - center) / radius; const vec2 texCoord = GetSphereTexCoord(normal); - Ray = Scatter(material, gl_WorldRayDirectionNV, normal, texCoord, gl_HitTNV, Ray.RandomSeed); + Ray = Scatter(material, gl_WorldRayDirectionEXT, normal, texCoord, gl_HitTEXT, Ray.RandomSeed); } diff --git a/assets/shaders/RayTracing.Procedural.rint b/assets/shaders/RayTracing.Procedural.rint index c9e46abd..2d706249 100644 --- a/assets/shaders/RayTracing.Procedural.rint +++ b/assets/shaders/RayTracing.Procedural.rint @@ -1,21 +1,21 @@ #version 460 #extension GL_GOOGLE_include_directive : require -#extension GL_NV_ray_tracing : require +#extension GL_EXT_ray_tracing : require layout(binding = 9) readonly buffer SphereArray { vec4[] Spheres; }; -hitAttributeNV vec4 Sphere; +hitAttributeEXT vec4 Sphere; void main() { - const vec4 sphere = Spheres[gl_InstanceCustomIndexNV]; + const vec4 sphere = Spheres[gl_InstanceCustomIndexEXT]; const vec3 center = sphere.xyz; const float radius = sphere.w; - const vec3 origin = gl_WorldRayOriginNV; - const vec3 direction = gl_WorldRayDirectionNV; - const float tMin = gl_RayTminNV; - const float tMax = gl_RayTmaxNV; + const vec3 origin = gl_WorldRayOriginEXT; + const vec3 direction = gl_WorldRayDirectionEXT; + const float tMin = gl_RayTminEXT; + const float tMax = gl_RayTmaxEXT; // https://en.wikipedia.org/wiki/Quadratic_formula @@ -33,7 +33,7 @@ void main() if ((tMin <= t1 && t1 < tMax) || (tMin <= t2 && t2 < tMax)) { Sphere = sphere; - reportIntersectionNV((tMin <= t1 && t1 < tMax) ? t1 : t2, 0); + reportIntersectionEXT((tMin <= t1 && t1 < tMax) ? t1 : t2, 0); } } } diff --git a/assets/shaders/RayTracing.rchit b/assets/shaders/RayTracing.rchit index 1f6e5526..59042ee6 100644 --- a/assets/shaders/RayTracing.rchit +++ b/assets/shaders/RayTracing.rchit @@ -1,7 +1,7 @@ #version 460 #extension GL_EXT_nonuniform_qualifier : require #extension GL_GOOGLE_include_directive : require -#extension GL_NV_ray_tracing : require +#extension GL_EXT_ray_tracing : require #include "Material.glsl" layout(binding = 4) readonly buffer VertexArray { float Vertices[]; }; @@ -13,8 +13,8 @@ layout(binding = 8) uniform sampler2D[] TextureSamplers; #include "Scatter.glsl" #include "Vertex.glsl" -hitAttributeNV vec2 HitAttributes; -rayPayloadInNV RayPayload Ray; +hitAttributeEXT vec2 HitAttributes; +rayPayloadInEXT RayPayload Ray; vec2 Mix(vec2 a, vec2 b, vec2 c, vec3 barycentrics) { @@ -29,7 +29,7 @@ vec3 Mix(vec3 a, vec3 b, vec3 c, vec3 barycentrics) void main() { // Get the material. - const uvec2 offsets = Offsets[gl_InstanceCustomIndexNV]; + const uvec2 offsets = Offsets[gl_InstanceCustomIndexEXT]; const uint indexOffset = offsets.x; const uint vertexOffset = offsets.y; const Vertex v0 = UnpackVertex(vertexOffset + Indices[indexOffset + gl_PrimitiveID * 3 + 0]); @@ -42,5 +42,5 @@ void main() const vec3 normal = normalize(Mix(v0.Normal, v1.Normal, v2.Normal, barycentrics)); const vec2 texCoord = Mix(v0.TexCoord, v1.TexCoord, v2.TexCoord, barycentrics); - Ray = Scatter(material, gl_WorldRayDirectionNV, normal, texCoord, gl_HitTNV, Ray.RandomSeed); + Ray = Scatter(material, gl_WorldRayDirectionEXT, normal, texCoord, gl_HitTEXT, Ray.RandomSeed); } diff --git a/assets/shaders/RayTracing.rgen b/assets/shaders/RayTracing.rgen index 7131e028..c35248be 100644 --- a/assets/shaders/RayTracing.rgen +++ b/assets/shaders/RayTracing.rgen @@ -1,16 +1,16 @@ #version 460 #extension GL_GOOGLE_include_directive : require -#extension GL_NV_ray_tracing : require +#extension GL_EXT_ray_tracing : require #include "Random.glsl" #include "RayPayload.glsl" #include "UniformBufferObject.glsl" -layout(binding = 0, set = 0) uniform accelerationStructureNV Scene; +layout(binding = 0, set = 0) uniform accelerationStructureEXT Scene; layout(binding = 1, rgba32f) uniform image2D AccumulationImage; layout(binding = 2, rgba8) uniform image2D OutputImage; layout(binding = 3) readonly uniform UniformBufferObjectStruct { UniformBufferObject Camera; }; -layout(location = 0) rayPayloadNV RayPayload Ray; +layout(location = 0) rayPayloadEXT RayPayload Ray; void main() { @@ -18,7 +18,7 @@ void main() // - pixel: we want the same random seed for each pixel to get a homogeneous anti-aliasing. // - ray: we want a noisy random seed, different for each pixel. uint pixelRandomSeed = Camera.RandomSeed; - Ray.RandomSeed = InitRandomSeed(InitRandomSeed(gl_LaunchIDNV.x, gl_LaunchIDNV.y), Camera.TotalNumberOfSamples); + Ray.RandomSeed = InitRandomSeed(InitRandomSeed(gl_LaunchIDEXT.x, gl_LaunchIDEXT.y), Camera.TotalNumberOfSamples); vec3 pixelColor = vec3(0); @@ -26,8 +26,8 @@ void main() for (uint s = 0; s < Camera.NumberOfSamples; ++s) { //if (Camera.NumberOfSamples != Camera.TotalNumberOfSamples) break; - const vec2 pixel = vec2(gl_LaunchIDNV.x + RandomFloat(pixelRandomSeed), gl_LaunchIDNV.y + RandomFloat(pixelRandomSeed)); - const vec2 uv = (pixel / gl_LaunchSizeNV.xy) * 2.0 - 1.0; + const vec2 pixel = vec2(gl_LaunchIDEXT.x + RandomFloat(pixelRandomSeed), gl_LaunchIDEXT.y + RandomFloat(pixelRandomSeed)); + const vec2 uv = (pixel / gl_LaunchSizeEXT.xy) * 2.0 - 1.0; vec2 offset = Camera.Aperture/2 * RandomInUnitDisk(Ray.RandomSeed); vec4 origin = Camera.ModelViewInverse * vec4(offset, 0, 1); @@ -41,8 +41,8 @@ void main() const float tMin = 0.001; const float tMax = 10000.0; - traceNV( - Scene, gl_RayFlagsOpaqueNV, 0xff, + traceRayEXT( + Scene, gl_RayFlagsOpaqueEXT, 0xff, 0 /*sbtRecordOffset*/, 0 /*sbtRecordStride*/, 0 /*missIndex*/, origin.xyz, tMin, direction.xyz, tMax, 0 /*payload*/); @@ -67,7 +67,7 @@ void main() } const bool accumulate = Camera.NumberOfSamples != Camera.TotalNumberOfSamples; - const vec3 accumulatedColor = (accumulate ? imageLoad(AccumulationImage, ivec2(gl_LaunchIDNV.xy)) : vec4(0)).rgb + pixelColor; + const vec3 accumulatedColor = (accumulate ? imageLoad(AccumulationImage, ivec2(gl_LaunchIDEXT.xy)) : vec4(0)).rgb + pixelColor; pixelColor = accumulatedColor / Camera.TotalNumberOfSamples; @@ -77,6 +77,6 @@ void main() pixelColor = sqrt(pixelColor); } - imageStore(AccumulationImage, ivec2(gl_LaunchIDNV.xy), vec4(accumulatedColor, 0)); - imageStore(OutputImage, ivec2(gl_LaunchIDNV.xy), vec4(pixelColor, 0)); + imageStore(AccumulationImage, ivec2(gl_LaunchIDEXT.xy), vec4(accumulatedColor, 0)); + imageStore(OutputImage, ivec2(gl_LaunchIDEXT.xy), vec4(pixelColor, 0)); } diff --git a/assets/shaders/RayTracing.rmiss b/assets/shaders/RayTracing.rmiss index 7eaa7af2..612899f3 100644 --- a/assets/shaders/RayTracing.rmiss +++ b/assets/shaders/RayTracing.rmiss @@ -1,19 +1,19 @@ #version 460 #extension GL_GOOGLE_include_directive : require -#extension GL_NV_ray_tracing : require +#extension GL_EXT_ray_tracing : require #include "RayPayload.glsl" #include "UniformBufferObject.glsl" layout(binding = 3) readonly uniform UniformBufferObjectStruct { UniformBufferObject Camera; }; -layout(location = 0) rayPayloadInNV RayPayload Ray; +layout(location = 0) rayPayloadInEXT RayPayload Ray; void main() { if (Camera.HasSky) { // Sky color - const float t = 0.5*(normalize(gl_WorldRayDirectionNV).y + 1); + const float t = 0.5*(normalize(gl_WorldRayDirectionEXT).y + 1); const vec3 skyColor = mix(vec3(1.0), vec3(0.5, 0.7, 1.0), t); Ray.ColorAndDistance = vec4(skyColor, -1); diff --git a/src/Vulkan/Device.cpp b/src/Vulkan/Device.cpp index a2e1147d..185fac13 100644 --- a/src/Vulkan/Device.cpp +++ b/src/Vulkan/Device.cpp @@ -8,31 +8,30 @@ namespace Vulkan { - namespace +namespace +{ + std::vector::const_iterator FindQueue( + const std::vector& queueFamilies, + const std::string& name, + const VkQueueFlags requiredBits, + const VkQueueFlags excludedBits) { - std::vector::const_iterator FindQueue( - const std::vector& queueFamilies, - const std::string& name, - const VkQueueFlags requiredBits, - const VkQueueFlags excludedBits) + const auto family = std::find_if(queueFamilies.begin(), queueFamilies.end(), [requiredBits, excludedBits](const VkQueueFamilyProperties& queueFamily) { - const auto family = std::find_if(queueFamilies.begin(), queueFamilies.end(), [requiredBits, excludedBits](const VkQueueFamilyProperties& queueFamily) - { - return - queueFamily.queueCount > 0 && - queueFamily.queueFlags & requiredBits && - !(queueFamily.queueFlags & excludedBits); - }); + return + queueFamily.queueCount > 0 && + queueFamily.queueFlags & requiredBits && + !(queueFamily.queueFlags & excludedBits); + }); - if (family == queueFamilies.end()) - { - Throw(std::runtime_error("found no matching " + name + " queue")); - } - - return family; + if (family == queueFamilies.end()) + { + Throw(std::runtime_error("found no matching " + name + " queue")); } + return family; } +} Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, const std::vector& requiredExtensions) : physicalDevice_(physicalDevice), @@ -90,22 +89,29 @@ Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, co queueCreateInfos.push_back(queueCreateInfo); } + // Opt-in into mandatory device features. VkPhysicalDeviceFeatures deviceFeatures = {}; deviceFeatures.fillModeNonSolid = true; deviceFeatures.samplerAnisotropy = true; + VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = {}; + bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; + bufferDeviceAddressFeatures.pNext = nullptr; + bufferDeviceAddressFeatures.bufferDeviceAddress = true; + VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = {}; indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; + indexingFeatures.pNext = &bufferDeviceAddressFeatures; indexingFeatures.runtimeDescriptorArray = true; - VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = {}; - bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; - bufferDeviceAddressFeatures.pNext = &indexingFeatures; - bufferDeviceAddressFeatures.bufferDeviceAddress = true; + VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = {}; + rayTracingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR; + rayTracingFeatures.pNext = &indexingFeatures; + rayTracingFeatures.rayTracing = true; VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.pNext = &bufferDeviceAddressFeatures; + createInfo.pNext = &rayTracingFeatures; createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.pEnabledFeatures = &deviceFeatures; diff --git a/vcpkg_linux.sh b/vcpkg_linux.sh index 84482aad..add2d650 100755 --- a/vcpkg_linux.sh +++ b/vcpkg_linux.sh @@ -5,7 +5,7 @@ mkdir -p build cd build git clone https://github.com/Microsoft/vcpkg.git vcpkg.linux cd vcpkg.linux -git checkout 2019.12 +git checkout 2020.01 ./bootstrap-vcpkg.sh ./vcpkg install \ diff --git a/vcpkg_windows.bat b/vcpkg_windows.bat index 8a6d3764..9b55d239 100644 --- a/vcpkg_windows.bat +++ b/vcpkg_windows.bat @@ -2,7 +2,7 @@ mkdir build cd build || goto :error git clone https://github.com/Microsoft/vcpkg.git vcpkg.windows || goto :error cd vcpkg.windows || goto :error -git checkout 2019.12 || goto :error +git checkout 2020.01 || goto :error call bootstrap-vcpkg.bat || goto :error vcpkg.exe install ^ From 08ea76174d7bb4513ff36539d0f1022216ddaaeb Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 22:57:57 +0100 Subject: [PATCH 03/28] Add DebugUtils.SetObjectName() and make good use of it. --- src/Assets/Scene.cpp | 18 ++++-- src/CMakeLists.txt | 6 +- src/Vulkan/DebugUtils.cpp | 15 +++++ src/Vulkan/DebugUtils.hpp | 60 +++++++++++++++++++ src/Vulkan/DepthBuffer.cpp | 6 ++ src/Vulkan/Device.cpp | 5 +- src/Vulkan/Device.hpp | 6 ++ src/Vulkan/RayTracing/Application.cpp | 55 ++++++++++++++--- src/Vulkan/RayTracing/BottomLevelGeometry.cpp | 2 +- src/Vulkan/SwapChain.cpp | 8 +++ src/main.cpp | 2 + 11 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 src/Vulkan/DebugUtils.cpp create mode 100644 src/Vulkan/DebugUtils.hpp diff --git a/src/Assets/Scene.cpp b/src/Assets/Scene.cpp index 48f8075c..336c17bd 100644 --- a/src/Assets/Scene.cpp +++ b/src/Assets/Scene.cpp @@ -4,6 +4,7 @@ #include "Texture.hpp" #include "TextureImage.hpp" #include "Vulkan/Buffer.hpp" +#include "Vulkan/Device.hpp" #include "Vulkan/CommandPool.hpp" #include "Vulkan/ImageView.hpp" #include "Vulkan/Sampler.hpp" @@ -40,18 +41,23 @@ namespace template void CreateDeviceBuffer( Vulkan::CommandPool& commandPool, + const char* const name, const VkBufferUsageFlags usage, const std::vector& content, std::unique_ptr& buffer, std::unique_ptr& memory) { const auto& device = commandPool.Device(); + const auto& debugUtils = device.DebugUtils(); const auto contentSize = sizeof(content[0]) * content.size(); const VkMemoryAllocateFlags allocateFlags = usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT ? VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT : 0; buffer.reset(new Vulkan::Buffer(device, contentSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | usage)); memory.reset(new Vulkan::DeviceMemory(buffer->AllocateMemory(allocateFlags, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + debugUtils.SetObjectName(buffer->Handle(), (name + std::string(" Buffer")).c_str()); + debugUtils.SetObjectName(memory->Handle(), (name + std::string(" Memory")).c_str()); + CopyFromStagingBuffer(commandPool, *buffer, content); } @@ -106,13 +112,13 @@ Scene::Scene(Vulkan::CommandPool& commandPool, std::vector&& models, std: const auto flag = usedForRayTracing ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT : 0; - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | flag, vertices, vertexBuffer_, vertexBufferMemory_); - CreateDeviceBuffer(commandPool, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | flag, indices, indexBuffer_, indexBufferMemory_); - CreateDeviceBuffer(commandPool, flag, materials, materialBuffer_, materialBufferMemory_); - CreateDeviceBuffer(commandPool, flag, offsets, offsetBuffer_, offsetBufferMemory_); + CreateDeviceBuffer(commandPool, "Vertices", VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | flag, vertices, vertexBuffer_, vertexBufferMemory_); + CreateDeviceBuffer(commandPool, "Indices", VK_BUFFER_USAGE_INDEX_BUFFER_BIT | flag, indices, indexBuffer_, indexBufferMemory_); + CreateDeviceBuffer(commandPool, "Materials", flag, materials, materialBuffer_, materialBufferMemory_); + CreateDeviceBuffer(commandPool, "Offsets", flag, offsets, offsetBuffer_, offsetBufferMemory_); - CreateDeviceBuffer(commandPool, flag, aabbs, aabbBuffer_, aabbBufferMemory_); - CreateDeviceBuffer(commandPool, flag, procedurals, proceduralBuffer_, proceduralBufferMemory_); + CreateDeviceBuffer(commandPool, "AABBs", flag, aabbs, aabbBuffer_, aabbBufferMemory_); + CreateDeviceBuffer(commandPool, "Procedurals", flag, procedurals, proceduralBuffer_, proceduralBufferMemory_); // Upload all textures textureImages_.reserve(textures_.size()); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0895ee01..0541ba7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,10 @@ set(src_files_vulkan Vulkan/CommandBuffers.hpp Vulkan/CommandPool.cpp Vulkan/CommandPool.hpp + Vulkan/DebugUtils.cpp + Vulkan/DebugUtils.hpp + Vulkan/DebugUtilsMessenger.cpp + Vulkan/DebugUtilsMessenger.hpp Vulkan/DepthBuffer.cpp Vulkan/DepthBuffer.hpp Vulkan/DescriptorBinding.hpp @@ -60,8 +64,6 @@ set(src_files_vulkan Vulkan/Device.hpp Vulkan/DeviceMemory.cpp Vulkan/DeviceMemory.hpp - Vulkan/DebugUtilsMessenger.cpp - Vulkan/DebugUtilsMessenger.hpp Vulkan/Enumerate.hpp Vulkan/Fence.cpp Vulkan/Fence.hpp diff --git a/src/Vulkan/DebugUtils.cpp b/src/Vulkan/DebugUtils.cpp new file mode 100644 index 00000000..b8192abc --- /dev/null +++ b/src/Vulkan/DebugUtils.cpp @@ -0,0 +1,15 @@ +#include "DebugUtils.hpp" +#include "Utilities/Exception.hpp" + +namespace Vulkan { + +DebugUtils::DebugUtils(VkInstance instance) + : vkSetDebugUtilsObjectNameEXT_(reinterpret_cast(vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"))) +{ + if (vkSetDebugUtilsObjectNameEXT_ == nullptr) + { + Throw(std::runtime_error("failed to get address of 'vkSetDebugUtilsObjectNameEXT'")); + } +} + +} \ No newline at end of file diff --git a/src/Vulkan/DebugUtils.hpp b/src/Vulkan/DebugUtils.hpp new file mode 100644 index 00000000..ac7b16e2 --- /dev/null +++ b/src/Vulkan/DebugUtils.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include "Vulkan/Vulkan.hpp" + +namespace Vulkan +{ + class DebugUtils final + { + public: + + VULKAN_NON_COPIABLE(DebugUtils) + + explicit DebugUtils(VkInstance instance); + ~DebugUtils() = default; + + + void SetDevice(VkDevice device) + { + device_ = device; + } + + void SetObjectName(const VkAccelerationStructureKHR& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR); } + void SetObjectName(const VkBuffer& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_BUFFER); } + void SetObjectName(const VkCommandBuffer& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_COMMAND_BUFFER); } + void SetObjectName(const VkDescriptorSet& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_DESCRIPTOR_SET); } + void SetObjectName(const VkDescriptorSetLayout& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); } + void SetObjectName(const VkDeviceMemory& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_DEVICE_MEMORY); } + void SetObjectName(const VkFramebuffer& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_FRAMEBUFFER); } + void SetObjectName(const VkImage& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_IMAGE); } + void SetObjectName(const VkImageView& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_IMAGE_VIEW); } + void SetObjectName(const VkPipeline& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_PIPELINE); } + void SetObjectName(const VkQueue& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_QUEUE); } + void SetObjectName(const VkRenderPass& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_RENDER_PASS); } + void SetObjectName(const VkSemaphore& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_SEMAPHORE); } + void SetObjectName(const VkShaderModule& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_SHADER_MODULE); } + void SetObjectName(const VkSwapchainKHR& object, const char* name) const { SetObjectName(object, name, VK_OBJECT_TYPE_SWAPCHAIN_KHR); } + + private: + + template + void SetObjectName(const T& object, const char* name, VkObjectType type) const + { +#ifndef NDEBUG + VkDebugUtilsObjectNameInfoEXT info = {}; + info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + info.pNext = nullptr; + info.objectHandle = reinterpret_cast(object); + info.objectType = type; + info.pObjectName = name; + + Check(vkSetDebugUtilsObjectNameEXT_(device_, &info), "set object name"); +#endif + } + + const PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT_; + + VkDevice device_{}; + }; + +} diff --git a/src/Vulkan/DepthBuffer.cpp b/src/Vulkan/DepthBuffer.cpp index 146e6c98..518f4a6b 100644 --- a/src/Vulkan/DepthBuffer.cpp +++ b/src/Vulkan/DepthBuffer.cpp @@ -52,6 +52,12 @@ namespace Vulkan { imageView_.reset(new class ImageView(device, image_->Handle(), format_, VK_IMAGE_ASPECT_DEPTH_BIT)); image_->TransitionImageLayout(commandPool, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + const auto& debugUtils = device.DebugUtils(); + + debugUtils.SetObjectName(image_->Handle(), "Depth Buffer Image"); + debugUtils.SetObjectName(imageMemory_->Handle(), "Depth Buffer Image Memory"); + debugUtils.SetObjectName(imageView_->Handle(), "Depth Buffer ImageView"); } DepthBuffer::~DepthBuffer() diff --git a/src/Vulkan/Device.cpp b/src/Vulkan/Device.cpp index 185fac13..aa54c73f 100644 --- a/src/Vulkan/Device.cpp +++ b/src/Vulkan/Device.cpp @@ -35,7 +35,8 @@ namespace Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, const std::vector& requiredExtensions) : physicalDevice_(physicalDevice), - surface_(surface) + surface_(surface), + debugUtils_(surface.Instance().Handle()) { CheckRequiredExtensions(physicalDevice, requiredExtensions); @@ -123,6 +124,8 @@ Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, co Check(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device_), "create logical device"); + debugUtils_.SetDevice(device_); + vkGetDeviceQueue(device_, graphicsFamilyIndex_, 0, &graphicsQueue_); vkGetDeviceQueue(device_, computeFamilyIndex_, 0, &computeQueue_); vkGetDeviceQueue(device_, presentFamilyIndex_, 0, &presentQueue_); diff --git a/src/Vulkan/Device.hpp b/src/Vulkan/Device.hpp index 309ac6e9..eaee8c76 100644 --- a/src/Vulkan/Device.hpp +++ b/src/Vulkan/Device.hpp @@ -1,5 +1,6 @@ #pragma once +#include "DebugUtils.hpp" #include "Vulkan.hpp" #include @@ -19,10 +20,13 @@ namespace Vulkan VkPhysicalDevice PhysicalDevice() const { return physicalDevice_; } const class Surface& Surface() const { return surface_; } + const DebugUtils& DebugUtils() const { return debugUtils_; } + uint32_t GraphicsFamilyIndex() const { return graphicsFamilyIndex_; } uint32_t ComputeFamilyIndex() const { return computeFamilyIndex_; } uint32_t PresentFamilyIndex() const { return presentFamilyIndex_; } uint32_t TransferFamilyIndex() const { return transferFamilyIndex_; } + VkQueue GraphicsQueue() const { return graphicsQueue_; } VkQueue ComputeQueue() const { return computeQueue_; } VkQueue PresentQueue() const { return presentQueue_; } @@ -39,6 +43,8 @@ namespace Vulkan VULKAN_HANDLE(VkDevice, device_) + Vulkan::DebugUtils debugUtils_; + uint32_t graphicsFamilyIndex_ {}; uint32_t computeFamilyIndex_{}; uint32_t presentFamilyIndex_{}; diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index 665a0b07..184c8243 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -137,45 +137,52 @@ void Application::Render(VkCommandBuffer commandBuffer, const uint32_t imageInde subresourceRange.baseArrayLayer = 0; subresourceRange.layerCount = 1; + // Acquire destination images for rendering. ImageMemoryBarrier::Insert(commandBuffer, accumulationImage_->Handle(), subresourceRange, 0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); ImageMemoryBarrier::Insert(commandBuffer, outputImage_->Handle(), subresourceRange, 0, VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + // Bind ray tracing pipeline. vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rayTracingPipeline_->Handle()); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rayTracingPipeline_->PipelineLayout().Handle(), 0, 1, descriptorSets, 0, nullptr); + // Describe the shader binding table. + //const auto progSize = shaderBindingTable_-> VkStridedBufferRegionKHR raygenShaderBindingTable = {}; raygenShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); raygenShaderBindingTable.offset = shaderBindingTable_->RayGenOffset(); - //raygenShaderBindingTable.stride = stride; TODO - //raygenShaderBindingTable.size = size; TODO + raygenShaderBindingTable.stride = 32; // TODO + raygenShaderBindingTable.size = 32; // TODO VkStridedBufferRegionKHR missShaderBindingTable = {}; missShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); missShaderBindingTable.offset = shaderBindingTable_->MissOffset(); - //missShaderBindingTable.stride = stride; TODO - //missShaderBindingTable.size = size; TODO + missShaderBindingTable.stride = 32; // TODO + missShaderBindingTable.size = 32; //TODO VkStridedBufferRegionKHR hitShaderBindingTable = {}; hitShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); hitShaderBindingTable.offset = shaderBindingTable_->HitGroupOffset(); - //hitShaderBindingTable.stride = stride; TODO - //hitShaderBindingTable.size = size; TODO + hitShaderBindingTable.stride = 32; // TODO + hitShaderBindingTable.size = 64; // TODO VkStridedBufferRegionKHR callableShaderBindingTable = {}; - + + // Execute ray tracing shaders. deviceProcedures_->vkCmdTraceRaysKHR(commandBuffer, &raygenShaderBindingTable, &missShaderBindingTable, &hitShaderBindingTable, &callableShaderBindingTable, extent.width, extent.height, 1); + // Acquire output image and swap-chain image for copying. ImageMemoryBarrier::Insert(commandBuffer, outputImage_->Handle(), subresourceRange, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); ImageMemoryBarrier::Insert(commandBuffer, SwapChain().Images()[imageIndex], subresourceRange, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + // Copy output image into swap-chain image. VkImageCopy copyRegion; copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }; copyRegion.srcOffset = { 0, 0, 0 }; @@ -195,6 +202,7 @@ void Application::Render(VkCommandBuffer commandBuffer, const uint32_t imageInde void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) { const auto& scene = GetScene(); + const auto& debugUtils = Device().DebugUtils(); // Bottom level acceleration structure // Triangles via vertex buffers. Procedurals via AABBs. @@ -219,7 +227,7 @@ void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) vertexOffset += vertexCount * sizeof(Assets::Vertex); indexOffset += indexCount * sizeof(uint32_t); - aabbOffset += sizeof(glm::vec3) * 2; + aabbOffset += sizeof(VkAabbPositionsKHR); } // Allocate the structure memory. @@ -227,10 +235,14 @@ void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) bottomBuffer_.reset(new Buffer(Device(), total.Result.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR)); bottomBufferMemory_.reset(new DeviceMemory(bottomBuffer_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); - bottomScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); bottomScratchBufferMemory_.reset(new DeviceMemory(bottomScratchBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + debugUtils.SetObjectName(bottomBuffer_->Handle(), "BLAS Buffer"); + debugUtils.SetObjectName(bottomBufferMemory_->Handle(), "BLAS Memory"); + debugUtils.SetObjectName(bottomScratchBuffer_->Handle(), "BLAS Scratch Buffer"); + debugUtils.SetObjectName(bottomScratchBufferMemory_->Handle(), "BLAS Scratch Memory"); + // Generate the structures. VkDeviceSize resultOffset = 0; VkDeviceSize scratchOffset = 0; @@ -238,14 +250,18 @@ void Application::CreateBottomLevelStructures(VkCommandBuffer commandBuffer) for (size_t i = 0; i != bottomAs_.size(); ++i) { bottomAs_[i].Generate(commandBuffer, *bottomScratchBuffer_, scratchOffset, *bottomBufferMemory_, resultOffset, false); + resultOffset += requirements[i].Result.size; scratchOffset += requirements[i].Build.size; + + debugUtils.SetObjectName(bottomAs_[i].Handle(), ("BLAS #" + std::to_string(i)).c_str()); } } void Application::CreateTopLevelStructures(VkCommandBuffer commandBuffer) { const auto& scene = GetScene(); + const auto& debugUtils = Device().DebugUtils(); // Top level acceleration structure std::vector instances; @@ -274,12 +290,22 @@ void Application::CreateTopLevelStructures(VkCommandBuffer commandBuffer) topScratchBuffer_.reset(new Buffer(Device(), total.Build.size, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); topScratchBufferMemory_.reset(new DeviceMemory(topScratchBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); + // Instances buffer const size_t instancesBufferSize = sizeof(VkAccelerationStructureInstanceKHR) * instances.size(); instancesBuffer_.reset(new Buffer(Device(), instancesBufferSize, VK_BUFFER_USAGE_RAY_TRACING_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)); instancesBufferMemory_.reset(new DeviceMemory(instancesBuffer_->AllocateMemory(VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))); + debugUtils.SetObjectName(topBuffer_->Handle(), "TLAS Buffer"); + debugUtils.SetObjectName(topBufferMemory_->Handle(), "TLAS Memory"); + debugUtils.SetObjectName(topScratchBuffer_->Handle(), "TLAS Scratch Buffer"); + debugUtils.SetObjectName(topScratchBufferMemory_->Handle(), "TLAS Scratch Memory"); + debugUtils.SetObjectName(instancesBuffer_->Handle(), "TLAS Instances Buffer"); + debugUtils.SetObjectName(instancesBufferMemory_->Handle(), "TLAS Instances Memory"); + // Generate the structures. topAs_[0].Generate(commandBuffer, *topScratchBuffer_, 0, *topBufferMemory_, 0, *instancesBuffer_, *instancesBufferMemory_, 0, false); + + debugUtils.SetObjectName(topAs_[0].Handle(), "TLAS"); } void Application::CreateOutputImage() @@ -295,6 +321,17 @@ void Application::CreateOutputImage() outputImage_.reset(new Image(Device(), extent, format, tiling, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)); outputImageMemory_.reset(new DeviceMemory(outputImage_->AllocateMemory(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))); outputImageView_.reset(new ImageView(Device(), outputImage_->Handle(), format, VK_IMAGE_ASPECT_COLOR_BIT)); + + const auto& debugUtils = Device().DebugUtils(); + + debugUtils.SetObjectName(accumulationImage_->Handle(), "Accumulation Image"); + debugUtils.SetObjectName(accumulationImageMemory_->Handle(), "Accumulation Image Memory"); + debugUtils.SetObjectName(accumulationImageView_->Handle(), "Accumulation ImageView"); + + debugUtils.SetObjectName(outputImage_->Handle(), "Output Image"); + debugUtils.SetObjectName(outputImageMemory_->Handle(), "Output Image Memory"); + debugUtils.SetObjectName(outputImageView_->Handle(), "Output ImageView"); + } } diff --git a/src/Vulkan/RayTracing/BottomLevelGeometry.cpp b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp index fa12905b..9c13d094 100644 --- a/src/Vulkan/RayTracing/BottomLevelGeometry.cpp +++ b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp @@ -72,7 +72,7 @@ void BottomLevelGeometry::AddGeometryAabb( geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR; geometry.geometry.aabbs.pNext = nullptr; geometry.geometry.aabbs.data.deviceAddress = scene.AabbBuffer().GetDeviceAddress(); - geometry.geometry.aabbs.stride = sizeof(VkAabbPositionsKHR) * 2; + geometry.geometry.aabbs.stride = sizeof(VkAabbPositionsKHR); geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_KHR : 0; VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {}; diff --git a/src/Vulkan/SwapChain.cpp b/src/Vulkan/SwapChain.cpp index efab4c3b..6b32fb47 100644 --- a/src/Vulkan/SwapChain.cpp +++ b/src/Vulkan/SwapChain.cpp @@ -72,6 +72,14 @@ SwapChain::SwapChain(const class Device& device, const bool vsync) : { imageViews_.push_back(std::make_unique(device, image, format_, VK_IMAGE_ASPECT_COLOR_BIT)); } + + const auto& debugUtils = device.DebugUtils(); + + for (size_t i = 0; i != images_.size(); ++i) + { + debugUtils.SetObjectName(images_[i], ("Swapchain Image #" + std::to_string(i)).c_str()); + debugUtils.SetObjectName(imageViews_[i]->Handle(), ("Swapchain ImageView #" + std::to_string(i)).c_str()); + } } SwapChain::~SwapChain() diff --git a/src/main.cpp b/src/main.cpp index e4565b04..eed0714e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,6 +79,8 @@ int main(int argc, const char* argv[]) noexcept }); } + std::cin.get(); + return EXIT_FAILURE; } From f41e19178af395e5ea1d3a162cc230824809e188 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:13:28 +0100 Subject: [PATCH 04/28] Fixed incorrect buildOffsetInfo for bottom level triangle geometry. --- src/Options.cpp | 2 +- src/Vulkan/RayTracing/BottomLevelGeometry.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 54542434..fc284b2f 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -23,7 +23,7 @@ Options::Options(const int argc, const char* argv[]) options_description scene("Scene options"); scene.add_options() - ("scene", value(&SceneIndex)->default_value(0), "Set the scene to start with.") + ("scene", value(&SceneIndex)->default_value(1), "Set the scene to start with.") ; options_description window("Window options"); diff --git a/src/Vulkan/RayTracing/BottomLevelGeometry.cpp b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp index 9c13d094..ee27e716 100644 --- a/src/Vulkan/RayTracing/BottomLevelGeometry.cpp +++ b/src/Vulkan/RayTracing/BottomLevelGeometry.cpp @@ -38,9 +38,9 @@ void BottomLevelGeometry::AddGeometryTriangles( geometry.flags = isOpaque ? VK_GEOMETRY_OPAQUE_BIT_KHR : 0; VkAccelerationStructureBuildOffsetInfoKHR buildOffsetInfo = {}; - buildOffsetInfo.firstVertex = vertexOffset; + buildOffsetInfo.firstVertex = vertexOffset / sizeof(Assets::Vertex); buildOffsetInfo.primitiveOffset = indexOffset; - buildOffsetInfo.primitiveCount = indexCount; + buildOffsetInfo.primitiveCount = indexCount / 3; buildOffsetInfo.transformOffset = 0; createGeometryTypeInfo_.emplace_back(createGeometryTypeInfo); From d579d2b3be0145c1b441402e8402f41c403f005a Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:16:34 +0100 Subject: [PATCH 05/28] Fixed validation error. --- src/Vulkan/RayTracing/RayTracingPipeline.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Vulkan/RayTracing/RayTracingPipeline.cpp b/src/Vulkan/RayTracing/RayTracingPipeline.cpp index 24f87c27..0c3958d0 100644 --- a/src/Vulkan/RayTracing/RayTracingPipeline.cpp +++ b/src/Vulkan/RayTracing/RayTracingPipeline.cpp @@ -220,6 +220,7 @@ RayTracingPipeline::RayTracingPipeline( pipelineInfo.layout = pipelineLayout_->Handle(); pipelineInfo.basePipelineHandle = nullptr; pipelineInfo.basePipelineIndex = 0; + pipelineInfo.libraries.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR; Check(deviceProcedures.vkCreateRayTracingPipelinesKHR(device.Handle(), nullptr, 1, &pipelineInfo, nullptr, &pipeline_), "create ray tracing pipeline"); From e45f4e959213dfbff31e9b0ab168e25b348523b5 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:18:49 +0100 Subject: [PATCH 06/28] Fix CI by updating Vulkan SDK to the correct version. --- .github/workflows/linux.yml | 2 +- .github/workflows/windows.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index cddafc53..5f7340f0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -16,7 +16,7 @@ jobs: - name: Install Vulkan SDK run: | wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.131-bionic.list http://packages.lunarg.com/vulkan/1.2.131/lunarg-vulkan-1.2.131-bionic.list + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.135-bionic.list http://packages.lunarg.com/vulkan/1.2.131/lunarg-vulkan-1.2.135-bionic.list sudo apt-get update sudo apt-get install vulkan-sdk - name: Compile vcpkg dependencies diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 59a12283..38c8a160 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,12 +7,12 @@ jobs: runs-on: windows-latest env: - VULKAN_SDK: C:\VulkanSDK\1.2.131.2 + VULKAN_SDK: C:\VulkanSDK\1.2.135.0 steps: - uses: actions/checkout@v2 - name: Download Vulkan SDK - run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/1.2.131.2/windows/VulkanSDK-1.2.131.2-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v + run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/1.2.135.0/windows/VulkanSDK-1.2.135.0-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v - name: Install Vulkan SDK run: .\VulkanSDK.exe /S shell: cmd From e0973c320f3a68bc1acdcacaa5ed7a870fdeacc8 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:21:14 +0100 Subject: [PATCH 07/28] Fix CI by updating Vulkan SDK to the correct version. --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5f7340f0..18e040c9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -16,7 +16,7 @@ jobs: - name: Install Vulkan SDK run: | wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.135-bionic.list http://packages.lunarg.com/vulkan/1.2.131/lunarg-vulkan-1.2.135-bionic.list + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.135-bionic.list http://packages.lunarg.com/vulkan/1.2.135/lunarg-vulkan-1.2.135-bionic.list sudo apt-get update sudo apt-get install vulkan-sdk - name: Compile vcpkg dependencies From 09bb11bc3e14be4a5538179b20227a5c973d9ecc Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:38:52 +0100 Subject: [PATCH 08/28] Fix ShaderBindingTable offsets, strides and sizes. --- src/Vulkan/RayTracing/Application.cpp | 12 ++++++------ src/Vulkan/RayTracing/RayTracingProperties.hpp | 2 +- src/Vulkan/RayTracing/ShaderBindingTable.cpp | 12 +++++++++--- src/Vulkan/RayTracing/ShaderBindingTable.hpp | 8 ++++++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index 184c8243..7ebe818c 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -153,20 +153,20 @@ void Application::Render(VkCommandBuffer commandBuffer, const uint32_t imageInde VkStridedBufferRegionKHR raygenShaderBindingTable = {}; raygenShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); raygenShaderBindingTable.offset = shaderBindingTable_->RayGenOffset(); - raygenShaderBindingTable.stride = 32; // TODO - raygenShaderBindingTable.size = 32; // TODO + raygenShaderBindingTable.stride = shaderBindingTable_->RayGenEntrySize(); + raygenShaderBindingTable.size = shaderBindingTable_->RayGenSize(); VkStridedBufferRegionKHR missShaderBindingTable = {}; missShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); missShaderBindingTable.offset = shaderBindingTable_->MissOffset(); - missShaderBindingTable.stride = 32; // TODO - missShaderBindingTable.size = 32; //TODO + missShaderBindingTable.stride = shaderBindingTable_->MissEntrySize(); + missShaderBindingTable.size = shaderBindingTable_->MissSize(); VkStridedBufferRegionKHR hitShaderBindingTable = {}; hitShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); hitShaderBindingTable.offset = shaderBindingTable_->HitGroupOffset(); - hitShaderBindingTable.stride = 32; // TODO - hitShaderBindingTable.size = 64; // TODO + hitShaderBindingTable.stride = shaderBindingTable_->HitGroupEntrySize(); + hitShaderBindingTable.size = shaderBindingTable_->HitGroupSize(); VkStridedBufferRegionKHR callableShaderBindingTable = {}; diff --git a/src/Vulkan/RayTracing/RayTracingProperties.hpp b/src/Vulkan/RayTracing/RayTracingProperties.hpp index 12c0212c..8f59abdc 100644 --- a/src/Vulkan/RayTracing/RayTracingProperties.hpp +++ b/src/Vulkan/RayTracing/RayTracingProperties.hpp @@ -23,7 +23,7 @@ namespace Vulkan uint32_t MaxRecursionDepth() const { return props_.maxRecursionDepth; } uint32_t MaxShaderGroupStride() const { return props_.maxShaderGroupStride; } uint32_t ShaderGroupBaseAlignment() const { return props_.shaderGroupBaseAlignment; } - uint32_t ShaderGroupHandleCaptureReplaySize() { return props_.shaderGroupHandleCaptureReplaySize; } + uint32_t ShaderGroupHandleCaptureReplaySize() const { return props_.shaderGroupHandleCaptureReplaySize; } uint32_t ShaderGroupHandleSize() const { return props_.shaderGroupHandleSize; } private: diff --git a/src/Vulkan/RayTracing/ShaderBindingTable.cpp b/src/Vulkan/RayTracing/ShaderBindingTable.cpp index 3ada7437..f077fd7d 100644 --- a/src/Vulkan/RayTracing/ShaderBindingTable.cpp +++ b/src/Vulkan/RayTracing/ShaderBindingTable.cpp @@ -29,8 +29,8 @@ namespace } // A SBT entry is made of a program ID and a set of 4-byte parameters (offsets or push constants) - // and must be 16-bytes-aligned. - return RoundUp(rayTracingProperties.ShaderGroupHandleSize() + maxArgs, 16); + // and must be aligned to ShaderGroupBaseAlignment. + return RoundUp(rayTracingProperties.ShaderGroupHandleSize() + maxArgs, rayTracingProperties.ShaderGroupBaseAlignment()); } size_t CopyShaderData( @@ -65,12 +65,18 @@ ShaderBindingTable::ShaderBindingTable( const std::vector& rayGenPrograms, const std::vector& missPrograms, const std::vector& hitGroups) : + rayGenEntrySize_(GetEntrySize(rayTracingProperties, rayGenPrograms)), missEntrySize_(GetEntrySize(rayTracingProperties, missPrograms)), hitGroupEntrySize_(GetEntrySize(rayTracingProperties, hitGroups)), + rayGenOffset_(0), missOffset_(rayGenPrograms.size() * rayGenEntrySize_), - hitGroupOffset_(missOffset_ + missPrograms.size() * missEntrySize_) + hitGroupOffset_(missOffset_ + missPrograms.size() * missEntrySize_), + + rayGenSize_(rayGenPrograms.size() * rayGenEntrySize_), + missSize_(missPrograms.size() * missEntrySize_), + hitGroupSize_(hitGroups.size() * hitGroupEntrySize_) { // Compute the size of the table. const size_t sbtSize = diff --git a/src/Vulkan/RayTracing/ShaderBindingTable.hpp b/src/Vulkan/RayTracing/ShaderBindingTable.hpp index 1592974f..967b942e 100644 --- a/src/Vulkan/RayTracing/ShaderBindingTable.hpp +++ b/src/Vulkan/RayTracing/ShaderBindingTable.hpp @@ -45,6 +45,10 @@ namespace Vulkan::RayTracing size_t MissOffset() const { return missOffset_; } size_t HitGroupOffset() const { return hitGroupOffset_; } + size_t RayGenSize() const { return rayGenSize_; } + size_t MissSize() const { return missSize_; } + size_t HitGroupSize() const { return hitGroupSize_; } + size_t RayGenEntrySize() const { return rayGenEntrySize_; } size_t MissEntrySize() const { return missEntrySize_; } size_t HitGroupEntrySize() const { return hitGroupEntrySize_; } @@ -59,6 +63,10 @@ namespace Vulkan::RayTracing const size_t missOffset_; const size_t hitGroupOffset_; + const size_t rayGenSize_; + const size_t missSize_; + const size_t hitGroupSize_; + std::unique_ptr buffer_; std::unique_ptr bufferMemory_; }; From 05362197610f9dfad962f2a1fe322b3f79771825 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:44:08 +0100 Subject: [PATCH 09/28] Comment: clarify shaderRecordEXT. --- src/Vulkan/RayTracing/ShaderBindingTable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Vulkan/RayTracing/ShaderBindingTable.cpp b/src/Vulkan/RayTracing/ShaderBindingTable.cpp index f077fd7d..2b4ebb58 100644 --- a/src/Vulkan/RayTracing/ShaderBindingTable.cpp +++ b/src/Vulkan/RayTracing/ShaderBindingTable.cpp @@ -28,8 +28,8 @@ namespace maxArgs = std::max(maxArgs, entry.InlineData.size()); } - // A SBT entry is made of a program ID and a set of 4-byte parameters (offsets or push constants) - // and must be aligned to ShaderGroupBaseAlignment. + // A SBT entry is made of a program ID and a set of 4-byte parameters (see shaderRecordEXT). + // Its size is ShaderGroupHandleSize (plus parameters) and must be aligned to ShaderGroupBaseAlignment. return RoundUp(rayTracingProperties.ShaderGroupHandleSize() + maxArgs, rayTracingProperties.ShaderGroupBaseAlignment()); } From 0c868e06487e43f19afa4cbfce29d201d7d83947 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 9 Apr 2020 23:52:31 +0100 Subject: [PATCH 10/28] Fix Linux build. --- src/Vulkan/Device.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Vulkan/Device.hpp b/src/Vulkan/Device.hpp index eaee8c76..963c594a 100644 --- a/src/Vulkan/Device.hpp +++ b/src/Vulkan/Device.hpp @@ -20,7 +20,7 @@ namespace Vulkan VkPhysicalDevice PhysicalDevice() const { return physicalDevice_; } const class Surface& Surface() const { return surface_; } - const DebugUtils& DebugUtils() const { return debugUtils_; } + const class DebugUtils& DebugUtils() const { return debugUtils_; } uint32_t GraphicsFamilyIndex() const { return graphicsFamilyIndex_; } uint32_t ComputeFamilyIndex() const { return computeFamilyIndex_; } @@ -43,7 +43,7 @@ namespace Vulkan VULKAN_HANDLE(VkDevice, device_) - Vulkan::DebugUtils debugUtils_; + class DebugUtils debugUtils_; uint32_t graphicsFamilyIndex_ {}; uint32_t computeFamilyIndex_{}; From 98b5318d8aaf97a81cbb24ce2c88e982b3a47e21 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Fri, 10 Apr 2020 12:04:44 +0100 Subject: [PATCH 11/28] Expose to the derived Vulkan Apllications the responsibility of opting for extensions and device features. --- README.md | 9 ++++--- src/RayTracer.cpp | 13 ++++++++++ src/RayTracer.hpp | 6 +++++ src/Vulkan/Application.cpp | 23 ++++++++++------- src/Vulkan/Application.hpp | 6 +++++ src/Vulkan/Device.cpp | 30 ++++++---------------- src/Vulkan/Device.hpp | 8 +++++- src/Vulkan/RayTracing/Application.cpp | 36 +++++++++++++++++++++++++++ src/Vulkan/RayTracing/Application.hpp | 5 ++++ 9 files changed, 101 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 1527b8d0..d467f5a3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -My implementation of [Peter Shirley's Ray Tracing in One Weekend](https://github.com/RayTracing/raytracing.github.io) books using Vulkan and NVIDIA's RTX extension (VK_NV_ray_tracing). This allows most scenes to be rendered at interactive speed on appropriate hardware. +My implementation of [Peter Shirley's Ray Tracing in One Weekend](https://github.com/RayTracing/raytracing.github.io) books using Vulkan and NVIDIA's RTX extension (VK_NV_ray_tracing, now ported to NV_KHR_ray_tracing). This allows most scenes to be rendered at interactive speed on appropriate hardware. The real-time ray tracer can also load full geometry from OBJ files as well as render the procedural spheres from the book. An accumulation buffer is used to increase the sample count when the camera is not moving while keeping the frame rate interactive. I have added a UI built using [Dear ImGui](https://github.com/ocornut/imgui) to allow changing the renderer parameters on the fly. Unlike projects such as [Q2VKPT](http://brechpunkt.de/q2vkpt/), there is no denoising filter. So the image will get noisy when moving the camera. @@ -68,11 +68,14 @@ If in doubt, please check the GitHub Actions [continuous integration configurati ## References * [Vulkan Tutorial](https://vulkan-tutorial.com/) -* [Introduction to Real-Time Ray Tracing with Vulkan](https://devblogs.nvidia.com/vulkan-raytracing/) +* [Introduction to Real-Time Ray Tracing with Vulkan](https://devblogs.nvidia.com/vulkan-raytracing) * [NVIDIA Vulkan Ray Tracing Tutorial](https://developer.nvidia.com/rtx/raytracing/vkray) * [NVIDIA Vulkan Ray Tracing Helpers: Introduction](https://developer.nvidia.com/rtx/raytracing/vkray_helpers) +* [NVIDIA Vulkan Ray Tracing Tutorial (VK_KHR_ray_tracing)] (https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR) +* [NVIDIA Converting VK_NV_ray_tracing to VK_KHR_ray_tracing ] (https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/NV_to_KHR.md.htm) * [Fast and Fun: My First Real-Time Ray Tracing Demo](https://devblogs.nvidia.com/my-first-ray-tracing-demo/) * [Getting Started with RTX Ray Tracing](https://github.com/NVIDIAGameWorks/GettingStartedWithRTXRayTracing) * [D3D12 Raytracing Samples](https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing) * [George Ouzounoudis's vk_exp](https://github.com/georgeouzou/vk_exp) -* [NVIDIA Vulkan Forums](https://devtalk.nvidia.com/default/board/166/vulkan/) +* [NVIDIA Vulkan Forums](https://devtalk.nvidia.com/default/board/166/vulkan) + diff --git a/src/RayTracer.cpp b/src/RayTracer.cpp index 062efb0d..9bf91bf5 100644 --- a/src/RayTracer.cpp +++ b/src/RayTracer.cpp @@ -64,6 +64,19 @@ Assets::UniformBufferObject RayTracer::GetUniformBufferObject(const VkExtent2D e return ubo; } +void RayTracer::SetPhysicalDevice( + VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures) +{ + // Opt-in into mandatory device features. + deviceFeatures.fillModeNonSolid = true; + deviceFeatures.samplerAnisotropy = true; + + Application::SetPhysicalDevice(physicalDevice, requiredExtensions, deviceFeatures, nextDeviceFeatures); +} + void RayTracer::OnDeviceSet() { Application::OnDeviceSet(); diff --git a/src/RayTracer.hpp b/src/RayTracer.hpp index 939e10e5..bf334f40 100644 --- a/src/RayTracer.hpp +++ b/src/RayTracer.hpp @@ -18,6 +18,12 @@ class RayTracer final : public Vulkan::RayTracing::Application const Assets::Scene& GetScene() const override { return *scene_; } Assets::UniformBufferObject GetUniformBufferObject(VkExtent2D extent) const override; + void SetPhysicalDevice( + VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures) override; + void OnDeviceSet() override; void CreateSwapChain() override; void DeleteSwapChain() override; diff --git a/src/Vulkan/Application.cpp b/src/Vulkan/Application.cpp index 5c3749e1..0f222b17 100644 --- a/src/Vulkan/Application.cpp +++ b/src/Vulkan/Application.cpp @@ -70,20 +70,15 @@ void Application::SetPhysicalDevice(VkPhysicalDevice physicalDevice) Throw(std::logic_error("physical device has already been set")); } - const std::vector requiredExtensions = + std::vector requiredExtensions = { - // VK_KHR_ray_tracing - VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, - VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, - VK_KHR_RAY_TRACING_EXTENSION_NAME, - // VK_KHR_swapchain VK_KHR_SWAPCHAIN_EXTENSION_NAME }; - device_.reset(new class Device(physicalDevice, *surface_, requiredExtensions)); - commandPool_.reset(new class CommandPool(*device_, device_->GraphicsFamilyIndex(), true)); - + VkPhysicalDeviceFeatures deviceFeatures = {}; + + SetPhysicalDevice(physicalDevice, requiredExtensions, deviceFeatures, nullptr); OnDeviceSet(); // Create swap chain and command buffers. @@ -107,6 +102,16 @@ void Application::Run() device_->WaitIdle(); } +void Application::SetPhysicalDevice( + VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures) +{ + device_.reset(new class Device(physicalDevice, *surface_, requiredExtensions, deviceFeatures, nextDeviceFeatures)); + commandPool_.reset(new class CommandPool(*device_, device_->GraphicsFamilyIndex(), true)); +} + void Application::OnDeviceSet() { } diff --git a/src/Vulkan/Application.hpp b/src/Vulkan/Application.hpp index 5cfdb629..4bfb07c7 100644 --- a/src/Vulkan/Application.hpp +++ b/src/Vulkan/Application.hpp @@ -45,6 +45,12 @@ namespace Vulkan virtual const Assets::Scene& GetScene() const = 0; virtual Assets::UniformBufferObject GetUniformBufferObject(VkExtent2D extent) const = 0; + virtual void SetPhysicalDevice( + VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures); + virtual void OnDeviceSet(); virtual void CreateSwapChain(); virtual void DeleteSwapChain(); diff --git a/src/Vulkan/Device.cpp b/src/Vulkan/Device.cpp index aa54c73f..5e76fa76 100644 --- a/src/Vulkan/Device.cpp +++ b/src/Vulkan/Device.cpp @@ -33,7 +33,12 @@ namespace } } -Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, const std::vector& requiredExtensions) : +Device::Device( + VkPhysicalDevice physicalDevice, + const class Surface& surface, + const std::vector& requiredExtensions, + const VkPhysicalDeviceFeatures& deviceFeatures, + const void* nextDeviceFeatures) : physicalDevice_(physicalDevice), surface_(surface), debugUtils_(surface.Instance().Handle()) @@ -90,29 +95,10 @@ Device::Device(VkPhysicalDevice physicalDevice, const class Surface& surface, co queueCreateInfos.push_back(queueCreateInfo); } - // Opt-in into mandatory device features. - VkPhysicalDeviceFeatures deviceFeatures = {}; - deviceFeatures.fillModeNonSolid = true; - deviceFeatures.samplerAnisotropy = true; - - VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = {}; - bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; - bufferDeviceAddressFeatures.pNext = nullptr; - bufferDeviceAddressFeatures.bufferDeviceAddress = true; - - VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = {}; - indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; - indexingFeatures.pNext = &bufferDeviceAddressFeatures; - indexingFeatures.runtimeDescriptorArray = true; - - VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = {}; - rayTracingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR; - rayTracingFeatures.pNext = &indexingFeatures; - rayTracingFeatures.rayTracing = true; - + // Create device VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - createInfo.pNext = &rayTracingFeatures; + createInfo.pNext = nextDeviceFeatures; createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); createInfo.pQueueCreateInfos = queueCreateInfos.data(); createInfo.pEnabledFeatures = &deviceFeatures; diff --git a/src/Vulkan/Device.hpp b/src/Vulkan/Device.hpp index 963c594a..a16dfd59 100644 --- a/src/Vulkan/Device.hpp +++ b/src/Vulkan/Device.hpp @@ -14,7 +14,13 @@ namespace Vulkan VULKAN_NON_COPIABLE(Device) - Device(VkPhysicalDevice physicalDevice, const Surface& surface, const std::vector& requiredExtensions); + Device( + VkPhysicalDevice physicalDevice, + const Surface& surface, + const std::vector& requiredExtensionsconst, + const VkPhysicalDeviceFeatures& deviceFeatures, + const void* nextDeviceFeatures); + ~Device(); VkPhysicalDevice PhysicalDevice() const { return physicalDevice_; } diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index 7ebe818c..1e1d1469 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -51,8 +51,44 @@ Application::~Application() properties_.reset(); } +void Application::SetPhysicalDevice( + VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures) +{ + // Required extensions. + requiredExtensions.insert(requiredExtensions.end(), + { + // VK_KHR_ray_tracing + VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, + VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, + VK_KHR_RAY_TRACING_EXTENSION_NAME, + }); + + // Required device features. + VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = {}; + bufferDeviceAddressFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES; + bufferDeviceAddressFeatures.pNext = nextDeviceFeatures; + bufferDeviceAddressFeatures.bufferDeviceAddress = true; + + VkPhysicalDeviceDescriptorIndexingFeatures indexingFeatures = {}; + indexingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES; + indexingFeatures.pNext = &bufferDeviceAddressFeatures; + indexingFeatures.runtimeDescriptorArray = true; + + VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = {}; + rayTracingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR; + rayTracingFeatures.pNext = &indexingFeatures; + rayTracingFeatures.rayTracing = true; + + Vulkan::Application::SetPhysicalDevice(physicalDevice, requiredExtensions, deviceFeatures, &rayTracingFeatures); +} + void Application::OnDeviceSet() { + Vulkan::Application::OnDeviceSet(); + properties_.reset(new RayTracingProperties(Device())); deviceProcedures_.reset(new DeviceProcedures(Device())); } diff --git a/src/Vulkan/RayTracing/Application.hpp b/src/Vulkan/RayTracing/Application.hpp index a433b1c9..f6090ab2 100644 --- a/src/Vulkan/RayTracing/Application.hpp +++ b/src/Vulkan/RayTracing/Application.hpp @@ -25,6 +25,11 @@ namespace Vulkan::RayTracing Application(const WindowConfig& windowConfig, bool vsync, bool enableValidationLayers); ~Application(); + void SetPhysicalDevice(VkPhysicalDevice physicalDevice, + std::vector& requiredExtensions, + VkPhysicalDeviceFeatures& deviceFeatures, + void* nextDeviceFeatures) override; + void OnDeviceSet() override; void CreateAccelerationStructures(); void DeleteAccelerationStructures(); From 9ca3769ee2ef9514f9ddc4972cb2890527d4e0b0 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Fri, 10 Apr 2020 12:08:45 +0100 Subject: [PATCH 12/28] Fix hyperlinks. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d467f5a3..2461848f 100644 --- a/README.md +++ b/README.md @@ -71,8 +71,8 @@ If in doubt, please check the GitHub Actions [continuous integration configurati * [Introduction to Real-Time Ray Tracing with Vulkan](https://devblogs.nvidia.com/vulkan-raytracing) * [NVIDIA Vulkan Ray Tracing Tutorial](https://developer.nvidia.com/rtx/raytracing/vkray) * [NVIDIA Vulkan Ray Tracing Helpers: Introduction](https://developer.nvidia.com/rtx/raytracing/vkray_helpers) -* [NVIDIA Vulkan Ray Tracing Tutorial (VK_KHR_ray_tracing)] (https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR) -* [NVIDIA Converting VK_NV_ray_tracing to VK_KHR_ray_tracing ] (https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/NV_to_KHR.md.htm) +* [NVIDIA Vulkan Ray Tracing Tutorial (VK_KHR_ray_tracing)](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR) +* [NVIDIA Converting VK_NV_ray_tracing to VK_KHR_ray_tracing](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/NV_to_KHR.md.htm) * [Fast and Fun: My First Real-Time Ray Tracing Demo](https://devblogs.nvidia.com/my-first-ray-tracing-demo/) * [Getting Started with RTX Ray Tracing](https://github.com/NVIDIAGameWorks/GettingStartedWithRTXRayTracing) * [D3D12 Raytracing Samples](https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing) From f41d5013e70469814decf256d3623cf54ca30e33 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Fri, 10 Apr 2020 14:40:25 +0100 Subject: [PATCH 13/28] Reorganise references. --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2461848f..1b0e261c 100644 --- a/README.md +++ b/README.md @@ -67,15 +67,20 @@ If in doubt, please check the GitHub Actions [continuous integration configurati ## References +### Initial Implementation + * [Vulkan Tutorial](https://vulkan-tutorial.com/) * [Introduction to Real-Time Ray Tracing with Vulkan](https://devblogs.nvidia.com/vulkan-raytracing) * [NVIDIA Vulkan Ray Tracing Tutorial](https://developer.nvidia.com/rtx/raytracing/vkray) * [NVIDIA Vulkan Ray Tracing Helpers: Introduction](https://developer.nvidia.com/rtx/raytracing/vkray_helpers) -* [NVIDIA Vulkan Ray Tracing Tutorial (VK_KHR_ray_tracing)](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR) -* [NVIDIA Converting VK_NV_ray_tracing to VK_KHR_ray_tracing](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/NV_to_KHR.md.htm) * [Fast and Fun: My First Real-Time Ray Tracing Demo](https://devblogs.nvidia.com/my-first-ray-tracing-demo/) * [Getting Started with RTX Ray Tracing](https://github.com/NVIDIAGameWorks/GettingStartedWithRTXRayTracing) * [D3D12 Raytracing Samples](https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12Raytracing) * [George Ouzounoudis's vk_exp](https://github.com/georgeouzou/vk_exp) * [NVIDIA Vulkan Forums](https://devtalk.nvidia.com/default/board/166/vulkan) +### VK_KHR_ray_tracing Port + +* [Khronos Vulkan Registry](https://www.khronos.org/registry/vulkan/) +* [NVIDIA Vulkan Ray Tracing Tutorial (VK_KHR_ray_tracing)](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR) +* [NVIDIA Converting VK_NV_ray_tracing to VK_KHR_ray_tracing](https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/NV_to_KHR.md.htm) From 86bb4d08c1a3e4264b53df41cb807f0c755fd8e5 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Fri, 10 Apr 2020 14:54:41 +0100 Subject: [PATCH 14/28] Cleanup. --- assets/shaders/RayTracing.rgen | 2 +- src/Vulkan/RayTracing/AccelerationStructure.hpp | 3 ++- src/Vulkan/RayTracing/Application.cpp | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/shaders/RayTracing.rgen b/assets/shaders/RayTracing.rgen index c35248be..6cc7fecd 100644 --- a/assets/shaders/RayTracing.rgen +++ b/assets/shaders/RayTracing.rgen @@ -35,7 +35,7 @@ void main() vec4 direction = Camera.ModelViewInverse * vec4(normalize(target.xyz * Camera.FocusDistance - vec3(offset, 0)), 0); vec3 rayColor = vec3(1); - // Ray scatters are handled in this loop. There are no recursive traceNV() calls in other shaders. + // Ray scatters are handled in this loop. There are no recursive traceRayEXT() calls in other shaders. for (uint b = 0; b < Camera.NumberOfBounces; ++b) { const float tMin = 0.001; diff --git a/src/Vulkan/RayTracing/AccelerationStructure.hpp b/src/Vulkan/RayTracing/AccelerationStructure.hpp index bc9156e2..99e8dccc 100644 --- a/src/Vulkan/RayTracing/AccelerationStructure.hpp +++ b/src/Vulkan/RayTracing/AccelerationStructure.hpp @@ -41,7 +41,8 @@ namespace Vulkan::RayTracing protected: - AccelerationStructure(const class DeviceProcedures& deviceProcedures, + AccelerationStructure( + const class DeviceProcedures& deviceProcedures, VkAccelerationStructureTypeKHR accelerationStructureType, const std::vector& geometries, bool allowUpdate); diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index 1e1d1469..cfefd0ae 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -185,7 +185,6 @@ void Application::Render(VkCommandBuffer commandBuffer, const uint32_t imageInde vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, rayTracingPipeline_->PipelineLayout().Handle(), 0, 1, descriptorSets, 0, nullptr); // Describe the shader binding table. - //const auto progSize = shaderBindingTable_-> VkStridedBufferRegionKHR raygenShaderBindingTable = {}; raygenShaderBindingTable.buffer = shaderBindingTable_->Buffer().Handle(); raygenShaderBindingTable.offset = shaderBindingTable_->RayGenOffset(); From 27a6323f71973f528a98c0daa40d7ccacfb1907c Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Fri, 10 Apr 2020 14:57:25 +0100 Subject: [PATCH 15/28] Fix Release runtime error. --- src/Vulkan/DebugUtils.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Vulkan/DebugUtils.cpp b/src/Vulkan/DebugUtils.cpp index b8192abc..4a8dd76f 100644 --- a/src/Vulkan/DebugUtils.cpp +++ b/src/Vulkan/DebugUtils.cpp @@ -6,10 +6,12 @@ namespace Vulkan { DebugUtils::DebugUtils(VkInstance instance) : vkSetDebugUtilsObjectNameEXT_(reinterpret_cast(vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"))) { +#ifndef NDEBUG if (vkSetDebugUtilsObjectNameEXT_ == nullptr) { Throw(std::runtime_error("failed to get address of 'vkSetDebugUtilsObjectNameEXT'")); } +#endif } } \ No newline at end of file From 7fb8776c7ffb141f9a6fa7047caf8af0e84695d7 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Wed, 22 Apr 2020 12:35:02 +0100 Subject: [PATCH 16/28] Use environment variables to avoid repeating SDK version in YAML actions. --- .github/workflows/linux.yml | 4 +++- .github/workflows/windows.yml | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 18e040c9..6ef6c1ec 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,6 +6,8 @@ jobs: build: runs-on: ubuntu-18.04 + env: + SDK_VERSION: 1.2.135 steps: - uses: actions/checkout@v2 @@ -16,7 +18,7 @@ jobs: - name: Install Vulkan SDK run: | wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.2.135-bionic.list http://packages.lunarg.com/vulkan/1.2.135/lunarg-vulkan-1.2.135-bionic.list + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-${SDK_VERSION}-bionic.list http://packages.lunarg.com/vulkan/${SDK_VERSION}/lunarg-vulkan-${SDK_VERSION }-bionic.list sudo apt-get update sudo apt-get install vulkan-sdk - name: Compile vcpkg dependencies diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 38c8a160..df09a1e8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,12 +7,13 @@ jobs: runs-on: windows-latest env: - VULKAN_SDK: C:\VulkanSDK\1.2.135.0 + SDK_VERSION: 1.2.135.0 + VULKAN_SDK: C:\VulkanSDK\${{ SDK_VERSION }} steps: - uses: actions/checkout@v2 - name: Download Vulkan SDK - run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/1.2.135.0/windows/VulkanSDK-1.2.135.0-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v + run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/$SDK_VERSION/windows/VulkanSDK-$SDK_VERSION-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v - name: Install Vulkan SDK run: .\VulkanSDK.exe /S shell: cmd From 0434bb5a9a6c29aac0edb23eb836bed59dddeeee Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Wed, 22 Apr 2020 12:44:12 +0100 Subject: [PATCH 17/28] Use environment variables to avoid repeating SDK version in YAML actions. --- .github/workflows/linux.yml | 2 +- .github/workflows/windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6ef6c1ec..bf1600d9 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -18,7 +18,7 @@ jobs: - name: Install Vulkan SDK run: | wget -qO - http://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-${SDK_VERSION}-bionic.list http://packages.lunarg.com/vulkan/${SDK_VERSION}/lunarg-vulkan-${SDK_VERSION }-bionic.list + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-${SDK_VERSION}-bionic.list http://packages.lunarg.com/vulkan/${SDK_VERSION}/lunarg-vulkan-${SDK_VERSION}-bionic.list sudo apt-get update sudo apt-get install vulkan-sdk - name: Compile vcpkg dependencies diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index df09a1e8..b3f8d485 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,7 +8,7 @@ jobs: runs-on: windows-latest env: SDK_VERSION: 1.2.135.0 - VULKAN_SDK: C:\VulkanSDK\${{ SDK_VERSION }} + VULKAN_SDK: C:\VulkanSDK\${{ env.SDK_VERSION }} steps: - uses: actions/checkout@v2 From 1852d3115da1857a398fd7936217bf8de9410db4 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Wed, 22 Apr 2020 12:57:45 +0100 Subject: [PATCH 18/28] Use environment variables to avoid repeating SDK version in YAML actions. --- .github/workflows/windows.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b3f8d485..3583d1f9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,7 +8,6 @@ jobs: runs-on: windows-latest env: SDK_VERSION: 1.2.135.0 - VULKAN_SDK: C:\VulkanSDK\${{ env.SDK_VERSION }} steps: - uses: actions/checkout@v2 @@ -28,5 +27,7 @@ jobs: - name: Setup MSBuild uses: microsoft/setup-msbuild@v1.0.0 - name: Compile raytracer - run: build_windows.bat + run: | + set VULKAN_SDK=C:\VulkanSDK\%SDK_VERSION% + build_windows.bat shell: cmd From e9cf48c29a009abc3e305f6331b2ee6778db99de Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Wed, 22 Apr 2020 13:23:57 +0100 Subject: [PATCH 19/28] Use environment variables to avoid repeating SDK version in YAML actions. --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 3583d1f9..4cd6b38f 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: Download Vulkan SDK - run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/$SDK_VERSION/windows/VulkanSDK-$SDK_VERSION-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v + run: Invoke-WebRequest "https://sdk.lunarg.com/sdk/download/${env:SDK_VERSION}/windows/VulkanSDK-${env:SDK_VERSION}-Installer.exe?Human=true" -OutFile VulkanSDK.exe -v - name: Install Vulkan SDK run: .\VulkanSDK.exe /S shell: cmd From 5c50a25650e5a9e6f23cbd8b275de35a33d91ad1 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Mon, 4 May 2020 12:37:08 +0100 Subject: [PATCH 20/28] Remove empty spaces. --- src/Vulkan/DebugUtilsMessenger.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Vulkan/DebugUtilsMessenger.cpp b/src/Vulkan/DebugUtilsMessenger.cpp index 35c59a17..5059ae69 100644 --- a/src/Vulkan/DebugUtilsMessenger.cpp +++ b/src/Vulkan/DebugUtilsMessenger.cpp @@ -58,8 +58,6 @@ namespace Vulkan { } } - - VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugCallback( const VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, const VkDebugUtilsMessageTypeFlagsEXT messageType, From 86ae97fd210a35221c2fe53704c21792a730f3dc Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Sun, 10 May 2020 20:11:42 +0100 Subject: [PATCH 21/28] Typo and other textual niceties. --- README.md | 2 +- src/Assets/Model.cpp | 2 +- src/Assets/Texture.cpp | 2 +- src/Vulkan/RayTracing/Application.cpp | 3 +-- src/main.cpp | 10 ++++++++++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3b062efe..b4eee197 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -My implementation of [Peter Shirley's Ray Tracing in One Weekend](https://github.com/RayTracing/raytracing.github.io) books using Vulkan and NVIDIA's RTX extension (VK_NV_ray_tracing, now ported to NV_KHR_ray_tracing). This allows most scenes to be rendered at interactive speed on appropriate hardware. +My implementation of [Peter Shirley's Ray Tracing in One Weekend](https://github.com/RayTracing/raytracing.github.io) books using Vulkan and NVIDIA's RTX extension (VK_NV_ray_tracing, now ported to VK_KHR_ray_tracing). This allows most scenes to be rendered at interactive speed on appropriate hardware. The real-time ray tracer can also load full geometry from OBJ files as well as render the procedural spheres from the book. An accumulation buffer is used to increase the sample count when the camera is not moving while keeping the frame rate interactive. I have added a UI built using [Dear ImGui](https://github.com/ocornut/imgui) to allow changing the renderer parameters on the fly. Unlike projects such as [Q2VKPT](http://brechpunkt.de/q2vkpt/), there is no denoising filter. So the image will get noisy when moving the camera. diff --git a/src/Assets/Model.cpp b/src/Assets/Model.cpp index cee34ba8..88f515bc 100644 --- a/src/Assets/Model.cpp +++ b/src/Assets/Model.cpp @@ -44,7 +44,7 @@ namespace Assets { Model Model::LoadModel(const std::string& filename) { - std::cout << "Loading '" << filename << "'... " << std::flush; + std::cout << "- loading '" << filename << "'... " << std::flush; const auto timer = std::chrono::high_resolution_clock::now(); const std::string materialPath = std::filesystem::path(filename).parent_path().string(); diff --git a/src/Assets/Texture.cpp b/src/Assets/Texture.cpp index 3a68916c..12d08d72 100644 --- a/src/Assets/Texture.cpp +++ b/src/Assets/Texture.cpp @@ -8,7 +8,7 @@ namespace Assets { Texture Texture::LoadTexture(const std::string& filename, const Vulkan::SamplerConfig& samplerConfig) { - std::cout << "Loading '" << filename << "'... " << std::flush; + std::cout << "- loading '" << filename << "'... " << std::flush; const auto timer = std::chrono::high_resolution_clock::now(); // Load the texture in normal host memory. diff --git a/src/Vulkan/RayTracing/Application.cpp b/src/Vulkan/RayTracing/Application.cpp index da7f3add..fb2afe65 100644 --- a/src/Vulkan/RayTracing/Application.cpp +++ b/src/Vulkan/RayTracing/Application.cpp @@ -95,7 +95,6 @@ void Application::OnDeviceSet() void Application::CreateAccelerationStructures() { - std::cout << "Building acceleration structures..." << std::endl; const auto timer = std::chrono::high_resolution_clock::now(); SingleTimeCommands::Submit(CommandPool(), [this](VkCommandBuffer commandBuffer) @@ -111,7 +110,7 @@ void Application::CreateAccelerationStructures() bottomScratchBufferMemory_.reset(); const auto elapsed = std::chrono::duration(std::chrono::high_resolution_clock::now() - timer).count(); - std::cout << "Built acceleration structures in " << elapsed << "s" << std::endl; + std::cout << "- built acceleration structures in " << elapsed << "s" << std::endl; } void Application::DeleteAccelerationStructures() diff --git a/src/main.cpp b/src/main.cpp index ba253fdc..c881e8e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,7 @@ int main(int argc, const char* argv[]) noexcept PrintVulkanDevices(application); SetVulkanDevice(application); + PrintVulkanSwapChainInformation(application, options.Benchmark); application.Run(); @@ -197,6 +198,7 @@ namespace std::cout << "Swap Chain: " << std::endl; std::cout << "- image count: " << swapChain.Images().size() << std::endl; std::cout << "- present mode: " << swapChain.PresentMode() << std::endl; + std::cout << std::endl; } void SetVulkanDevice(Vulkan::Application& application) @@ -228,7 +230,15 @@ namespace Throw(std::runtime_error("cannot find a suitable device")); } + VkPhysicalDeviceProperties2 deviceProp{}; + deviceProp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + vkGetPhysicalDeviceProperties2(*result, &deviceProp); + + std::cout << "Setting Device [" << deviceProp.properties.deviceID << "]:" << std::endl; + application.SetPhysicalDevice(*result); + + std::cout << std::endl; } } From 36853ff0e479c241ebf0ab82c451679724946071 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Sun, 10 May 2020 20:40:21 +0100 Subject: [PATCH 22/28] Move Release build argument to build_linux.sh. Remove std::cin.get() used for debugging. --- CMakeLists.txt | 5 ----- build_linux.sh | 2 +- src/main.cpp | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84ccd98b..2936af14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,6 @@ cmake_minimum_required(VERSION 3.10) project(RayTracingInVulkan) -# On Linux, default to Release if not specified. -if (UNIX AND NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Specifies the build type on single-configuration generators" FORCE) -endif () - set(CMAKE_DEBUG_POSTFIX d) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) diff --git a/build_linux.sh b/build_linux.sh index b59bae1b..1394f331 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -3,5 +3,5 @@ set -e mkdir --parents build/linux cd build/linux -cmake -D VCPKG_TARGET_TRIPLET=x64-linux -D CMAKE_TOOLCHAIN_FILE=../vcpkg.linux/scripts/buildsystems/vcpkg.cmake ../.. +cmake -D CMAKE_BUILD_TYPE=Release -D VCPKG_TARGET_TRIPLET=x64-linux -D CMAKE_TOOLCHAIN_FILE=../vcpkg.linux/scripts/buildsystems/vcpkg.cmake ../.. make -j diff --git a/src/main.cpp b/src/main.cpp index c881e8e8..fc3d5498 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -83,8 +83,6 @@ int main(int argc, const char* argv[]) noexcept }); } - std::cin.get(); - return EXIT_FAILURE; } From 352d75a78c30e553ab25737cf2b87ffd4006d2b0 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Sun, 10 May 2020 21:01:41 +0100 Subject: [PATCH 23/28] Cleanup the options help text. --- src/Options.cpp | 14 ++++++++------ src/Options.hpp | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 0b11df7f..820ea22f 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -8,33 +8,35 @@ using namespace boost::program_options; Options::Options(const int argc, const char* argv[]) { - options_description benchmark("Benchmark options"); + const int lineLength = 120; + + options_description benchmark("Benchmark options", lineLength); benchmark.add_options() ("next-scenes", bool_switch(&BenchmarkNextScenes)->default_value(false), "Load the next scene once the sample or time limit is reached.") ("max-time", value(&BenchmarkMaxTime)->default_value(60), "The benchmark time limit per scene (in seconds).") ; - options_description renderer("Renderer options"); + options_description renderer("Renderer options", lineLength); renderer.add_options() ("samples", value(&Samples)->default_value(8), "Set the number of ray samples per pixel.") ("bounces", value(&Bounces)->default_value(16), "Set the maximum number of bounces per ray.") ("max-samples", value(&MaxSamples)->default_value(64 * 1024), "Set the maximum number of accumulated ray samples per pixel.") ; - options_description scene("Scene options"); + options_description scene("Scene options", lineLength); scene.add_options() ("scene", value(&SceneIndex)->default_value(1), "Set the scene to start with.") ; - options_description window("Window options"); + options_description window("Window options", lineLength); window.add_options() ("width", value(&Width)->default_value(1280), "Set framebuffer width.") ("height", value(&Height)->default_value(720), "Set framebuffer height.") + ("present-mode", value(&PresentMode)->default_value(2), "Set present mode (0 = Immediate, 1 = MailBox, 2 = FIFO, 3 = FIFORelaxed).") ("fullscreen", bool_switch(&Fullscreen)->default_value(false), "Toggle fullscreen vs windowed (default: windowed).") - ("present-mode", value(&PresentMode)->default_value(2), "Present Mode (default: 2). 0 = Immediate, 1 = MailBox, 2 = FIFO, 3 = FIFORelaxed.") ; - options_description desc("Application options"); + options_description desc("Application options", lineLength); desc.add_options() ("help", "Display help message.") ("benchmark", bool_switch(&Benchmark)->default_value(false), "Run the application in benchmark mode.") diff --git a/src/Options.hpp b/src/Options.hpp index b1213889..feca185f 100644 --- a/src/Options.hpp +++ b/src/Options.hpp @@ -36,6 +36,6 @@ class Options final // Window options uint32_t Width{}; uint32_t Height{}; - bool Fullscreen{}; uint32_t PresentMode{}; + bool Fullscreen{}; }; From 819a2e773e90681b2a58710ccaac7697c131385c Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Sun, 10 May 2020 21:09:48 +0100 Subject: [PATCH 24/28] Cleanup the options help text. --- src/Options.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 820ea22f..19f72af2 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -18,21 +18,21 @@ Options::Options(const int argc, const char* argv[]) options_description renderer("Renderer options", lineLength); renderer.add_options() - ("samples", value(&Samples)->default_value(8), "Set the number of ray samples per pixel.") - ("bounces", value(&Bounces)->default_value(16), "Set the maximum number of bounces per ray.") - ("max-samples", value(&MaxSamples)->default_value(64 * 1024), "Set the maximum number of accumulated ray samples per pixel.") + ("samples", value(&Samples)->default_value(8), "The number of ray samples per pixel.") + ("bounces", value(&Bounces)->default_value(16), "The maximum number of bounces per ray.") + ("max-samples", value(&MaxSamples)->default_value(64 * 1024), "The maximum number of accumulated ray samples per pixel.") ; options_description scene("Scene options", lineLength); scene.add_options() - ("scene", value(&SceneIndex)->default_value(1), "Set the scene to start with.") + ("scene", value(&SceneIndex)->default_value(1), "The scene to start with.") ; options_description window("Window options", lineLength); window.add_options() - ("width", value(&Width)->default_value(1280), "Set framebuffer width.") - ("height", value(&Height)->default_value(720), "Set framebuffer height.") - ("present-mode", value(&PresentMode)->default_value(2), "Set present mode (0 = Immediate, 1 = MailBox, 2 = FIFO, 3 = FIFORelaxed).") + ("width", value(&Width)->default_value(1280), "The framebuffer width.") + ("height", value(&Height)->default_value(720), "The framebuffer height.") + ("present-mode", value(&PresentMode)->default_value(2), "The present mode (0 = Immediate, 1 = MailBox, 2 = FIFO, 3 = FIFORelaxed).") ("fullscreen", bool_switch(&Fullscreen)->default_value(false), "Toggle fullscreen vs windowed (default: windowed).") ; From 1d917d5faec5db43620d0c04362b0672aab38789 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Sun, 24 May 2020 15:02:56 +0100 Subject: [PATCH 25/28] Fixed camera controls enabled in benchmark mode. --- src/RayTracer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/RayTracer.cpp b/src/RayTracer.cpp index 09515be0..9f60d637 100644 --- a/src/RayTracer.cpp +++ b/src/RayTracer.cpp @@ -194,7 +194,10 @@ void RayTracer::OnKey(int key, int scancode, int action, int mods) } // Camera motions - resetAccumulation_ |= modelViewController_.OnKey(key, scancode, action, mods); + if (!userSettings_.Benchmark) + { + resetAccumulation_ |= modelViewController_.OnKey(key, scancode, action, mods); + } } void RayTracer::OnCursorPosition(const double xpos, const double ypos) From 4dfcebaa38cf3cfee695b456986c0405619727fb Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Mon, 29 Jun 2020 22:12:39 +0100 Subject: [PATCH 26/28] Fix SDK version (older version got pulled from website). --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 01a28790..ed6b4e09 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,7 +7,7 @@ jobs: runs-on: windows-latest env: - SDK_VERSION: 1.2.141.0 + SDK_VERSION: 1.2.141.2 steps: - uses: actions/checkout@v2 From 5ef8fe88c4397966bb5ffae623f56700b9a670d4 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 6 Aug 2020 16:27:10 +0100 Subject: [PATCH 27/28] Target Vulkan 1.2 when compiling shaders. --- assets/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 85ab74b9..da236433 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -20,13 +20,13 @@ foreach(shader ${shader_files}) if (WIN32) add_custom_command( OUTPUT ${output_file} - COMMAND ${Vulkan_GLSLANG_VALIDATOR} -V ${full_path} -o ${output_file} + COMMAND ${Vulkan_GLSLANG_VALIDATOR} --target-env=vulkan1.2 -V ${full_path} -o ${output_file} DEPENDS ${full_path} ) else() add_custom_command( OUTPUT ${output_file} - COMMAND mkdir --parents ${output_dir} && ${Vulkan_GLSLANG_VALIDATOR} -V ${full_path} -o ${output_file} + COMMAND mkdir --parents ${output_dir} && ${Vulkan_GLSLANG_VALIDATOR} --target-env=vulkan1.2 -V ${full_path} -o ${output_file} DEPENDS ${full_path} ) endif() From cfa09453e7303c54eff83bf924f40d68ee518174 Mon Sep 17 00:00:00 2001 From: Tanguy Fautre Date: Thu, 6 Aug 2020 16:37:45 +0100 Subject: [PATCH 28/28] Update CMakeLists.txt --- assets/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index da236433..b8bb8586 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -20,13 +20,13 @@ foreach(shader ${shader_files}) if (WIN32) add_custom_command( OUTPUT ${output_file} - COMMAND ${Vulkan_GLSLANG_VALIDATOR} --target-env=vulkan1.2 -V ${full_path} -o ${output_file} + COMMAND ${Vulkan_GLSLANG_VALIDATOR} --target-env vulkan1.2 -V ${full_path} -o ${output_file} DEPENDS ${full_path} ) else() add_custom_command( OUTPUT ${output_file} - COMMAND mkdir --parents ${output_dir} && ${Vulkan_GLSLANG_VALIDATOR} --target-env=vulkan1.2 -V ${full_path} -o ${output_file} + COMMAND mkdir --parents ${output_dir} && ${Vulkan_GLSLANG_VALIDATOR} --target-env vulkan1.2 -V ${full_path} -o ${output_file} DEPENDS ${full_path} ) endif()