From c8a0122dd636439a0095ca8ba13d21b18a84b098 Mon Sep 17 00:00:00 2001 From: mklefrancois Date: Fri, 11 Jun 2021 12:25:06 +0200 Subject: [PATCH] Using buffer reference instead of un-sized array --- docs/vkrt_tutorial.md.html | 125 +++++++---------- ray_tracing__advance/CMakeLists.txt | 4 +- ray_tracing__advance/hello_vulkan.cpp | 94 ++++++------- ray_tracing__advance/hello_vulkan.h | 18 +-- ray_tracing__advance/main.cpp | 41 +++--- ray_tracing__advance/obj.hpp | 12 +- ray_tracing__advance/offscreen.cpp | 2 +- ray_tracing__advance/offscreen.hpp | 2 +- ray_tracing__advance/raytrace.cpp | 11 +- ray_tracing__advance/shaders/frag_shader.frag | 32 +++-- ray_tracing__advance/shaders/light_inf.rcall | 2 +- .../shaders/light_point.rcall | 2 +- ray_tracing__advance/shaders/light_spot.rcall | 2 +- ray_tracing__advance/shaders/passthrough.vert | 6 +- ray_tracing__advance/shaders/post.frag | 2 +- ray_tracing__advance/shaders/random.glsl | 2 +- ray_tracing__advance/shaders/raytrace.rahit | 21 +-- ray_tracing__advance/shaders/raytrace.rchit | 64 ++++----- ray_tracing__advance/shaders/raytrace.rgen | 7 +- ray_tracing__advance/shaders/raytrace.rint | 7 +- ray_tracing__advance/shaders/raytrace.rmiss | 2 +- ray_tracing__advance/shaders/raytrace2.rahit | 20 ++- ray_tracing__advance/shaders/raytrace2.rchit | 22 +-- .../shaders/raytraceShadow.rmiss | 2 +- ray_tracing__advance/shaders/vert_shader.vert | 10 +- ray_tracing__advance/shaders/wavefront.glsl | 11 +- ray_tracing__before/CMakeLists.txt | 4 +- ray_tracing__before/hello_vulkan.cpp | 62 ++++----- ray_tracing__before/hello_vulkan.h | 19 ++- ray_tracing__before/main.cpp | 27 ++-- ray_tracing__before/shaders/frag_shader.frag | 30 ++-- ray_tracing__before/shaders/passthrough.vert | 6 +- ray_tracing__before/shaders/post.frag | 2 +- ray_tracing__before/shaders/vert_shader.vert | 10 +- ray_tracing__before/shaders/wavefront.glsl | 11 +- ray_tracing__simple/CMakeLists.txt | 4 +- ray_tracing__simple/hello_vulkan.cpp | 87 +++++------- ray_tracing__simple/hello_vulkan.h | 19 ++- ray_tracing__simple/main.cpp | 40 +++--- ray_tracing__simple/shaders/frag_shader.frag | 31 +++-- ray_tracing__simple/shaders/passthrough.vert | 6 +- ray_tracing__simple/shaders/post.frag | 2 +- ray_tracing__simple/shaders/raytrace.rchit | 56 ++++---- ray_tracing__simple/shaders/raytrace.rgen | 2 +- ray_tracing__simple/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- ray_tracing__simple/shaders/vert_shader.vert | 10 +- ray_tracing__simple/shaders/wavefront.glsl | 11 +- .../CMakeLists.txt | 4 +- ray_tracing_advanced_compilation/README.md | 7 +- .../hello_vulkan.cpp | 83 ++++-------- .../hello_vulkan.h | 22 +-- ray_tracing_advanced_compilation/main.cpp | 36 ++--- .../shaders/frag_shader.frag | 30 ++-- .../shaders/passthrough.vert | 6 +- .../shaders/post.frag | 2 +- .../shaders/raytrace.rchit | 55 ++++---- .../shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- .../shaders/wavefront.glsl | 11 +- ray_tracing_animation/CMakeLists.txt | 4 +- ray_tracing_animation/README.md | 1 + ray_tracing_animation/hello_vulkan.cpp | 81 ++++------- ray_tracing_animation/hello_vulkan.h | 19 ++- ray_tracing_animation/main.cpp | 40 +++--- ray_tracing_animation/shaders/anim.comp | 3 +- .../shaders/frag_shader.frag | 30 ++-- .../shaders/passthrough.vert | 6 +- ray_tracing_animation/shaders/post.frag | 2 +- ray_tracing_animation/shaders/raytrace.rchit | 58 ++++---- ray_tracing_animation/shaders/raytrace.rgen | 2 +- ray_tracing_animation/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- ray_tracing_animation/shaders/wavefront.glsl | 11 +- ray_tracing_anyhit/CMakeLists.txt | 4 +- ray_tracing_anyhit/README.md | 54 +++----- ray_tracing_anyhit/hello_vulkan.cpp | 88 ++++-------- ray_tracing_anyhit/hello_vulkan.h | 19 ++- ray_tracing_anyhit/main.cpp | 40 +++--- ray_tracing_anyhit/shaders/frag_shader.frag | 31 +++-- ray_tracing_anyhit/shaders/passthrough.vert | 6 +- ray_tracing_anyhit/shaders/post.frag | 2 +- ray_tracing_anyhit/shaders/random.glsl | 2 +- ray_tracing_anyhit/shaders/raytrace.rahit | 31 ++--- ray_tracing_anyhit/shaders/raytrace.rchit | 53 ++++---- ray_tracing_anyhit/shaders/raytrace.rgen | 2 +- ray_tracing_anyhit/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/raytrace_rahit.glsl | 31 ++--- ray_tracing_anyhit/shaders/vert_shader.vert | 10 +- ray_tracing_anyhit/shaders/wavefront.glsl | 11 +- ray_tracing_ao/CMakeLists.txt | 6 +- ray_tracing_ao/hello_vulkan.cpp | 74 ++++------ ray_tracing_ao/hello_vulkan.h | 19 ++- ray_tracing_ao/main.cpp | 41 +++--- ray_tracing_ao/shaders/frag_shader.frag | 37 ++--- ray_tracing_ao/shaders/passthrough.vert | 6 +- ray_tracing_ao/shaders/post.frag | 2 +- ray_tracing_ao/shaders/raycommon.glsl | 4 +- ray_tracing_ao/shaders/vert_shader.vert | 10 +- ray_tracing_ao/shaders/wavefront.glsl | 11 +- ray_tracing_callable/CMakeLists.txt | 4 +- ray_tracing_callable/hello_vulkan.cpp | 81 ++++------- ray_tracing_callable/hello_vulkan.h | 19 ++- ray_tracing_callable/main.cpp | 40 +++--- ray_tracing_callable/shaders/frag_shader.frag | 32 +++-- ray_tracing_callable/shaders/light_inf.rcall | 2 +- .../shaders/light_point.rcall | 2 +- ray_tracing_callable/shaders/light_spot.rcall | 2 +- ray_tracing_callable/shaders/passthrough.vert | 6 +- ray_tracing_callable/shaders/post.frag | 2 +- ray_tracing_callable/shaders/raytrace.rchit | 70 +++++----- ray_tracing_callable/shaders/raytrace.rgen | 2 +- ray_tracing_callable/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- ray_tracing_callable/shaders/vert_shader.vert | 10 +- ray_tracing_callable/shaders/wavefront.glsl | 14 +- ray_tracing_gltf/CMakeLists.txt | 4 +- ray_tracing_gltf/README.md | 110 ++++++++++++--- ray_tracing_gltf/hello_vulkan.cpp | 78 ++++++----- ray_tracing_gltf/hello_vulkan.h | 11 ++ ray_tracing_gltf/shaders/binding.glsl | 9 +- ray_tracing_gltf/shaders/frag_shader.frag | 15 +- ray_tracing_gltf/shaders/gltf.glsl | 13 +- ray_tracing_gltf/shaders/passthrough.vert | 6 +- ray_tracing_gltf/shaders/pathtrace.rchit | 82 +++++------ ray_tracing_gltf/shaders/pathtrace.rgen | 2 +- ray_tracing_gltf/shaders/pathtrace.rmiss | 2 +- ray_tracing_gltf/shaders/post.frag | 2 +- ray_tracing_gltf/shaders/raytrace.rchit | 88 +++++------- ray_tracing_gltf/shaders/raytrace.rgen | 2 +- ray_tracing_gltf/shaders/raytrace.rmiss | 2 +- ray_tracing_gltf/shaders/raytraceShadow.rmiss | 2 +- ray_tracing_gltf/shaders/sampling.glsl | 4 +- ray_tracing_gltf/shaders/vert_shader.vert | 15 +- ray_tracing_indirect_scissor/CMakeLists.txt | 4 +- ray_tracing_indirect_scissor/hello_vulkan.cpp | 73 ++++------ ray_tracing_indirect_scissor/hello_vulkan.h | 19 ++- ray_tracing_indirect_scissor/main.cpp | 39 +++--- .../shaders/frag_shader.frag | 31 +++-- .../shaders/lantern.rchit | 6 +- .../shaders/lanternShadow.rmiss | 2 +- .../shaders/lanternShadowLantern.rchit | 2 +- .../shaders/lanternShadowObj.rchit | 2 +- .../shaders/passthrough.vert | 6 +- .../shaders/post.frag | 2 +- .../shaders/raycommon.glsl | 4 +- .../shaders/raytrace.rchit | 113 ++++++++-------- .../shaders/raytrace.rgen | 19 ++- .../shaders/raytrace.rmiss | 4 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- .../shaders/wavefront.glsl | 14 +- ray_tracing_instances/CMakeLists.txt | 4 +- ray_tracing_instances/README.md | 4 +- ray_tracing_instances/hello_vulkan.cpp | 81 ++++------- ray_tracing_instances/hello_vulkan.h | 20 ++- ray_tracing_instances/main.cpp | 38 ++---- .../shaders/frag_shader.frag | 31 +++-- .../shaders/passthrough.vert | 6 +- ray_tracing_instances/shaders/post.frag | 2 +- ray_tracing_instances/shaders/raytrace.rchit | 58 ++++---- ray_tracing_instances/shaders/raytrace.rgen | 2 +- ray_tracing_instances/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- ray_tracing_instances/shaders/wavefront.glsl | 14 +- ray_tracing_intersection/CMakeLists.txt | 4 +- ray_tracing_intersection/README.md | 80 +++++------ ray_tracing_intersection/hello_vulkan.cpp | 128 ++++++++---------- ray_tracing_intersection/hello_vulkan.h | 19 ++- ray_tracing_intersection/main.cpp | 40 +++--- .../shaders/frag_shader.frag | 31 +++-- .../shaders/passthrough.vert | 6 +- ray_tracing_intersection/shaders/post.frag | 2 +- .../shaders/raytrace.rchit | 58 ++++---- .../shaders/raytrace.rgen | 2 +- .../shaders/raytrace.rint | 6 +- .../shaders/raytrace.rmiss | 2 +- .../shaders/raytrace2.rchit | 41 +++--- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- .../shaders/wavefront.glsl | 14 +- ray_tracing_jitter_cam/CMakeLists.txt | 4 +- ray_tracing_jitter_cam/hello_vulkan.cpp | 87 +++++------- ray_tracing_jitter_cam/hello_vulkan.h | 19 ++- ray_tracing_jitter_cam/main.cpp | 39 ++---- .../shaders/frag_shader.frag | 31 +++-- .../shaders/passthrough.vert | 6 +- ray_tracing_jitter_cam/shaders/post.frag | 2 +- ray_tracing_jitter_cam/shaders/raytrace.rchit | 58 ++++---- ray_tracing_jitter_cam/shaders/raytrace.rgen | 2 +- ray_tracing_jitter_cam/shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- ray_tracing_jitter_cam/shaders/wavefront.glsl | 14 +- ray_tracing_manyhits/CMakeLists.txt | 4 +- ray_tracing_manyhits/README.md | 16 ++- ray_tracing_manyhits/hello_vulkan.cpp | 83 ++++-------- ray_tracing_manyhits/hello_vulkan.h | 22 +-- ray_tracing_manyhits/main.cpp | 39 ++---- ray_tracing_manyhits/shaders/frag_shader.frag | 31 +++-- ray_tracing_manyhits/shaders/passthrough.vert | 6 +- ray_tracing_manyhits/shaders/post.frag | 2 +- ray_tracing_manyhits/shaders/raytrace.rchit | 58 ++++---- ray_tracing_manyhits/shaders/raytrace.rgen | 2 +- ray_tracing_manyhits/shaders/raytrace.rmiss | 2 +- ray_tracing_manyhits/shaders/raytrace2.rchit | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- ray_tracing_manyhits/shaders/vert_shader.vert | 11 +- ray_tracing_manyhits/shaders/wavefront.glsl | 16 ++- ray_tracing_rayquery/CMakeLists.txt | 4 +- ray_tracing_rayquery/README.md | 9 +- ray_tracing_rayquery/hello_vulkan.cpp | 90 +++++------- ray_tracing_rayquery/hello_vulkan.h | 19 ++- ray_tracing_rayquery/main.cpp | 37 ++--- ray_tracing_rayquery/shaders/frag_shader.frag | 36 ++--- ray_tracing_rayquery/shaders/passthrough.vert | 6 +- ray_tracing_rayquery/shaders/post.frag | 2 +- ray_tracing_rayquery/shaders/vert_shader.vert | 10 +- ray_tracing_rayquery/shaders/wavefront.glsl | 14 +- ray_tracing_reflections/CMakeLists.txt | 4 +- ray_tracing_reflections/hello_vulkan.cpp | 87 +++++------- ray_tracing_reflections/hello_vulkan.h | 19 ++- ray_tracing_reflections/main.cpp | 39 ++---- .../shaders/frag_shader.frag | 31 +++-- .../shaders/passthrough.vert | 6 +- ray_tracing_reflections/shaders/post.frag | 2 +- .../shaders/raytrace.rchit | 58 ++++---- ray_tracing_reflections/shaders/raytrace.rgen | 2 +- .../shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- .../shaders/wavefront.glsl | 14 +- ray_tracing_specialization/CMakeLists.txt | 4 +- ray_tracing_specialization/hello_vulkan.cpp | 83 ++++-------- ray_tracing_specialization/hello_vulkan.h | 19 ++- ray_tracing_specialization/main.cpp | 38 ++---- .../shaders/frag_shader.frag | 31 +++-- .../shaders/passthrough.vert | 6 +- ray_tracing_specialization/shaders/post.frag | 2 +- .../shaders/raytrace.rchit | 54 ++++---- .../shaders/raytrace.rmiss | 2 +- .../shaders/raytraceShadow.rmiss | 2 +- .../shaders/vert_shader.vert | 10 +- .../shaders/wavefront.glsl | 14 +- 248 files changed, 2593 insertions(+), 2660 deletions(-) diff --git a/docs/vkrt_tutorial.md.html b/docs/vkrt_tutorial.md.html index 675e57b..07aad85 100644 --- a/docs/vkrt_tutorial.md.html +++ b/docs/vkrt_tutorial.md.html @@ -116,14 +116,10 @@ extensions will need to be added. ```` C // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; -contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); +contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; -contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); -contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); -contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); -contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); -contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); - +contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR +contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline ```` Behind the scenes, the helper is selecting a physical device supporting the required `VK_KHR_*` extensions, @@ -293,11 +289,8 @@ potential optimization. (More specifically, this disables calls to the anyhit sh auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -974,61 +967,31 @@ descriptor set as they semantically fit the Scene descriptor set. ```` C // Camera matrices (binding = 0) - m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); -```` - -We set the actual contents of the descriptor set by adding those buffers in `updateDescriptorSet()`: - -```` C -// All material buffers, 1 buffer per OBJ -std::vector dbiMat; -std::vector dbiMatIdx; -std::vector dbiVert; -std::vector dbiIdx; -for(auto& m : m_objModel) -{ - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); -} -writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); -writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); -writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); -writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); +m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); +// Scene description (binding = 1) +m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); +// Textures (binding = 2) +m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); ```` Originally the buffers containing the vertices and indices were only used by the rasterization pipeline. The ray tracing will need to use those buffers as storage buffers, so we add `VK_BUFFER_USAGE_STORAGE_BUFFER_BIT`; additionally, the buffers will be read by the acceleration structure builder, which requires raw device addresses (in `VkAccelerationStructureGeometryTrianglesDataKHR`), so the buffer also needs -the `VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR` -and `VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT` bits. + `VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR` bits. We update the usage of the buffers in `loadModel`: ```` C -VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; -model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); -model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - +VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; +VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; +model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); +model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); +model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); +model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); ```` !!! Note: Array of Buffers @@ -1949,6 +1912,8 @@ We first include the payload definition and the OBJ-Wavefront structures ```` C #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "raycommon.glsl" #include "wavefront.glsl" ```` @@ -1958,9 +1923,12 @@ Then we describe the resources according to the descriptor set layout ```` C layout(location = 0) rayPayloadInEXT hitPayload prd; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; ```` In the Hit shader we need all the members of the push constant block: @@ -1976,22 +1944,25 @@ layout(push_constant) uniform Constants pushC; ```` -In the `main` function, the `gl_PrimitiveID` allows us to find the vertices of the triangle hit by the ray: +In the `main` function, the `gl_InstanceCustomIndexEXT` tells which object was hit, and the `gl_PrimitiveID` allows us to find the vertices of the triangle hit by the ray: ```` C void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; - - // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // - // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); + + // Indices of the triangle + ivec3 ind = indices.i[gl_PrimitiveID]; + + // Vertex of the triangle + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; ```` Using the hit point's barycentric coordinates, we can interpolate the normal: @@ -2060,12 +2031,10 @@ simplified Alias Wavefront material definitions. These materials define their basic reflectance properties using simple color coefficients, and also support texturing. The buffer containing the materials has already been created for rasterization, and has also been added into the ray -tracing descriptor set. Add the binding of the material buffer and the array of texture samplers: +tracing descriptor set. Add the binding of the array of texture samplers: ```` C -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; ```` The declaration of the material is the same as that used for the rasterizer and is defined in @@ -2084,8 +2053,8 @@ and fetch the material definition instead: ```` C // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; ```` !!! Note Note diff --git a/ray_tracing__advance/CMakeLists.txt b/ray_tracing__advance/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing__advance/CMakeLists.txt +++ b/ray_tracing__advance/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing__advance/hello_vulkan.cpp b/ray_tracing__advance/hello_vulkan.cpp index cbedb4c..55c0dff 100644 --- a/ray_tracing__advance/hello_vulkan.cpp +++ b/ray_tracing__advance/hello_vulkan.cpp @@ -38,6 +38,7 @@ #include "nvvk/commands_vk.hpp" #include "nvvk/renderpasses_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -119,30 +120,19 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj + 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT - | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing implicit obj (binding = 7) - m_descSetLayoutBind.addBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + + // Storing implicit obj (binding = 3) + m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); @@ -162,26 +152,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - dbiMat.push_back({m_implObjects.implMatBuf.buffer, 0, VK_WHOLE_SIZE}); // Adding implicit mat - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -189,10 +162,10 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); VkDescriptorBufferInfo dbiImplDesc{m_implObjects.implBuf.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &dbiImplDesc)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &dbiImplDesc)); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -250,36 +223,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -573,9 +552,16 @@ void HelloVulkan::createImplictBuffers() m_implObjects.implBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.objImpl, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); - m_implObjects.implMatBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.implMat, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_implObjects.implMatBuf = m_alloc.createBuffer(cmdBuf, m_implObjects.implMat, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); cmdGen.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); m_debug.setObjectName(m_implObjects.implBuf.buffer, "implicitObj"); m_debug.setObjectName(m_implObjects.implMatBuf.buffer, "implicitMat"); + + // Adding an instance to hold the buffer address of implicit materials + ObjInstance instance{}; + instance.objIndex = static_cast(m_objModel.size()); + instance.materials = nvvk::getBufferDeviceAddress(m_device, m_implObjects.implMatBuf.buffer); + m_objInstance.emplace_back(instance); } diff --git a/ray_tracing__advance/hello_vulkan.h b/ray_tracing__advance/hello_vulkan.h index fe138a0..8a628f5 100644 --- a/ray_tracing__advance/hello_vulkan.h +++ b/ray_tracing__advance/hello_vulkan.h @@ -75,6 +75,7 @@ public: Offscreen& offscreen() { return m_offscreen; } Raytracer& raytracer() { return m_raytrace; } + ObjPushConstants m_pushConstants; // Array of objects and instances in the scene @@ -83,20 +84,21 @@ public: // Graphic pipeline - VkPipelineLayout m_pipelineLayout; - VkPipeline m_graphicsPipeline; + VkPipelineLayout m_pipelineLayout; + VkPipeline m_graphicsPipeline; nvvk::DescriptorSetBindings m_descSetLayoutBind; - VkDescriptorPool m_descPool; - VkDescriptorSetLayout m_descSetLayout; - VkDescriptorSet m_descSet; + VkDescriptorPool m_descPool; + VkDescriptorSetLayout m_descSetLayout; + VkDescriptorSet m_descSet; int m_maxFrames{10}; void resetFrame(); void updateFrame(); - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::DebugUtil m_debug; // Utility to name objects diff --git a/ray_tracing__advance/main.cpp b/ray_tracing__advance/main.cpp index 6eb565c..ef2d7e0 100644 --- a/ray_tracing__advance/main.cpp +++ b/ray_tracing__advance/main.cpp @@ -102,6 +102,7 @@ void renderUI(HelloVulkan& helloVk) static int const SAMPLE_WIDTH = 1280; static int const SAMPLE_HEIGHT = 720; + //-------------------------------------------------------------------------------------------------- // Application Entry // @@ -139,34 +140,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -342,7 +335,7 @@ int main(int argc, char** argv) // Rendering tonemapper vkCmdBeginRenderPass(cmdBuf, &postRenderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); offscreen.draw(cmdBuf, helloVk.getSize()); - + // Rendering UI ImGui::Render(); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmdBuf); diff --git a/ray_tracing__advance/obj.hpp b/ray_tracing__advance/obj.hpp index 555c3b9..a89ee3d 100644 --- a/ray_tracing__advance/obj.hpp +++ b/ray_tracing__advance/obj.hpp @@ -34,10 +34,14 @@ struct ObjModel // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call diff --git a/ray_tracing__advance/offscreen.cpp b/ray_tracing__advance/offscreen.cpp index 0f8c3b3..7c898e4 100644 --- a/ray_tracing__advance/offscreen.cpp +++ b/ray_tracing__advance/offscreen.cpp @@ -171,7 +171,7 @@ void Offscreen::updateDescriptorSet() //-------------------------------------------------------------------------------------------------- // Draw a full screen quad with the attached image // -void Offscreen::draw(VkCommandBuffer cmdBuf, VkExtent2D& size) +void Offscreen::draw(VkCommandBuffer cmdBuf, const VkExtent2D& size) { m_debug.beginLabel(cmdBuf, "Post"); diff --git a/ray_tracing__advance/offscreen.hpp b/ray_tracing__advance/offscreen.hpp index 61bc16a..fd70210 100644 --- a/ray_tracing__advance/offscreen.hpp +++ b/ray_tracing__advance/offscreen.hpp @@ -38,7 +38,7 @@ public: void createPipeline(VkRenderPass& renderPass); void createDescriptor(); void updateDescriptorSet(); - void draw(VkCommandBuffer cmdBuf, VkExtent2D& size); + void draw(VkCommandBuffer cmdBuf, const VkExtent2D& size); const VkRenderPass& renderPass() { return m_renderPass; } const VkFramebuffer& frameBuffer() { return m_framebuffer; } diff --git a/ray_tracing__advance/raytrace.cpp b/ray_tracing__advance/raytrace.cpp index 94a15e3..d7d7cc1 100644 --- a/ray_tracing__advance/raytrace.cpp +++ b/ray_tracing__advance/raytrace.cpp @@ -157,12 +157,15 @@ void Raytracer::createBottomLevelAS(std::vector& models, ImplInst& imp void Raytracer::createTopLevelAS(std::vector& instances, ImplInst& implicitObj) { std::vector tlas; + + + auto nbObj = static_cast(instances.size()) - 1; // minus the implicit (for material) tlas.reserve(instances.size()); - for(int i = 0; i < static_cast(instances.size()); i++) + for(uint32_t i = 0; i < nbObj; i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; rayInst.transform = instances[i].transform; // Position of the instance - rayInst.instanceCustomId = i; // gl_InstanceCustomIndexEXT + rayInst.instanceCustomId = instances[i].objIndex; // gl_InstanceCustomIndexEXT rayInst.blasId = instances[i].objIndex; rayInst.hitGroupId = 0; // We will use the same hit group for all objects rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; @@ -173,8 +176,8 @@ void Raytracer::createTopLevelAS(std::vector& instances, ImplInst& if(!implicitObj.objImpl.empty()) { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = implicitObj.transform; // Position of the instance - rayInst.instanceCustomId = static_cast(implicitObj.blasId); // Same for material index + rayInst.transform = implicitObj.transform; // Position of the instance + rayInst.instanceCustomId = nbObj; // Same for material index rayInst.blasId = static_cast(implicitObj.blasId); rayInst.hitGroupId = 1; // We will use the same hit group for all objects (the second one) rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; diff --git a/ray_tracing__advance/shaders/frag_shader.frag b/ray_tracing__advance/shaders/frag_shader.frag index d7f44e1..d0bec87 100644 --- a/ray_tracing__advance/shaders/frag_shader.frag +++ b/ray_tracing__advance/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -40,37 +43,38 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); // Vector toward light vec3 LightDir; float lightIntensity; - ; // Point light if(pushC.lightType == 0) @@ -101,7 +105,7 @@ void main() vec3 diffuse = computeDiffuse(mat, LightDir, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing__advance/shaders/light_inf.rcall b/ray_tracing__advance/shaders/light_inf.rcall index 4905dbb..e92a591 100644 --- a/ray_tracing__advance/shaders/light_inf.rcall +++ b/ray_tracing__advance/shaders/light_inf.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__advance/shaders/light_point.rcall b/ray_tracing__advance/shaders/light_point.rcall index cce7d44..dd9d7ca 100644 --- a/ray_tracing__advance/shaders/light_point.rcall +++ b/ray_tracing__advance/shaders/light_point.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__advance/shaders/light_spot.rcall b/ray_tracing__advance/shaders/light_spot.rcall index 4436b63..3198f19 100644 --- a/ray_tracing__advance/shaders/light_spot.rcall +++ b/ray_tracing__advance/shaders/light_spot.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__advance/shaders/passthrough.vert b/ray_tracing__advance/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing__advance/shaders/passthrough.vert +++ b/ray_tracing__advance/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing__advance/shaders/post.frag b/ray_tracing__advance/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing__advance/shaders/post.frag +++ b/ray_tracing__advance/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing__advance/shaders/random.glsl b/ray_tracing__advance/shaders/random.glsl index 6216c3b..ef41f54 100644 --- a/ray_tracing__advance/shaders/random.glsl +++ b/ray_tracing__advance/shaders/random.glsl @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + // Generate a random unsigned int from two unsigned int values, using 16 pairs // of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis, // "GPU Random Numbers via the Tiny Encryption Algorithm" diff --git a/ray_tracing__advance/shaders/raytrace.rahit b/ray_tracing__advance/shaders/raytrace.rahit index d003a42..ac65427 100644 --- a/ray_tracing__advance/shaders/raytrace.rahit +++ b/ray_tracing__advance/shaders/raytrace.rahit @@ -16,12 +16,14 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "random.glsl" #include "raycommon.glsl" @@ -30,19 +32,22 @@ // clang-format off layout(location = 0) rayPayloadInEXT hitPayload prd; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on void main() { // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); - // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; if(mat.illum != 4) return; diff --git a/ray_tracing__advance/shaders/raytrace.rchit b/ray_tracing__advance/shaders/raytrace.rchit index 530d539..b3da007 100644 --- a/ray_tracing__advance/shaders/raytrace.rchit +++ b/ray_tracing__advance/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -60,30 +61,33 @@ layout(location = 3) callableDataEXT rayLight cLight; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); cLight.inHitPosition = worldPos; //#define DONT_USE_CALLABLE @@ -101,12 +105,11 @@ void main() { vec3 lDir = pushC.lightPosition - cLight.inHitPosition; cLight.outLightDistance = length(lDir); - cLight.outIntensity = - pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance); - cLight.outLightDir = normalize(lDir); - float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection)); - float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff; - float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0); + cLight.outIntensity = pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance); + cLight.outLightDir = normalize(lDir); + float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection)); + float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff; + float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0); cLight.outIntensity *= spotIntensity; } else // Directional light @@ -120,17 +123,16 @@ void main() #endif // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } diff --git a/ray_tracing__advance/shaders/raytrace.rgen b/ray_tracing__advance/shaders/raytrace.rgen index cba5e84..3fbddc8 100644 --- a/ray_tracing__advance/shaders/raytrace.rgen +++ b/ray_tracing__advance/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable @@ -55,9 +55,8 @@ const int NBSAMPLES = 5; void main() { // Initialize the random number - uint seed = - tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame * NBSAMPLES); - prd.seed = seed; + uint seed = tea(gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x, pushC.frame * NBSAMPLES); + prd.seed = seed; vec3 hitValues = vec3(0); diff --git a/ray_tracing__advance/shaders/raytrace.rint b/ray_tracing__advance/shaders/raytrace.rint index 1bd8622..8c163c7 100644 --- a/ray_tracing__advance/shaders/raytrace.rint +++ b/ray_tracing__advance/shaders/raytrace.rint @@ -16,18 +16,21 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" hitAttributeEXT vec3 HitAttribute; -layout(binding = 7, set = 1, scalar) buffer allImpl_ +layout(binding = 3, set = 1, scalar) buffer allImpl_ { Implicit i[]; } diff --git a/ray_tracing__advance/shaders/raytrace.rmiss b/ray_tracing__advance/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing__advance/shaders/raytrace.rmiss +++ b/ray_tracing__advance/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__advance/shaders/raytrace2.rahit b/ray_tracing__advance/shaders/raytrace2.rahit index 6031174..38ce667 100644 --- a/ray_tracing__advance/shaders/raytrace2.rahit +++ b/ray_tracing__advance/shaders/raytrace2.rahit @@ -16,12 +16,14 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "random.glsl" #include "raycommon.glsl" @@ -30,15 +32,23 @@ // clang-format off layout(location = 0) rayPayloadInEXT hitPayload prd; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 7, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits; // clang-format on void main() { // Material of the object - Implicit impl = allImplicits.i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId]; + Implicit impl = allImplicits.i[gl_PrimitiveID]; + + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + Materials materials = Materials(objResource.materialAddress); + + WaveFrontMaterial mat = materials.m[impl.matId]; if(mat.illum != 4) return; diff --git a/ray_tracing__advance/shaders/raytrace2.rchit b/ray_tracing__advance/shaders/raytrace2.rchit index f9ac36d..70f440f 100644 --- a/ray_tracing__advance/shaders/raytrace2.rchit +++ b/ray_tracing__advance/shaders/raytrace2.rchit @@ -16,12 +16,15 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -33,14 +36,13 @@ layout(location = 1) rayPayloadEXT bool isShadowed; layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 7, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 3, set = 1, scalar) buffer allImplicits_ {Implicit i[];} allImplicits; // clang-format on @@ -93,7 +95,9 @@ void main() executeCallableEXT(pushC.lightType, 3); // Material of the object - WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId]; + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + Materials materials = Materials(objResource.materialAddress); + WaveFrontMaterial mat = materials.m[impl.matId]; // Diffuse diff --git a/ray_tracing__advance/shaders/raytraceShadow.rmiss b/ray_tracing__advance/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing__advance/shaders/raytraceShadow.rmiss +++ b/ray_tracing__advance/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing__advance/shaders/vert_shader.vert b/ray_tracing__advance/shaders/vert_shader.vert index d0e58ff..a46389c 100644 --- a/ray_tracing__advance/shaders/vert_shader.vert +++ b/ray_tracing__advance/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -68,8 +70,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing__advance/shaders/wavefront.glsl b/ray_tracing__advance/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing__advance/shaders/wavefront.glsl +++ b/ray_tracing__advance/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing__before/CMakeLists.txt b/ray_tracing__before/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing__before/CMakeLists.txt +++ b/ray_tracing__before/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing__before/hello_vulkan.cpp b/ray_tracing__before/hello_vulkan.cpp index 7485fb3..28448d0 100644 --- a/ray_tracing__before/hello_vulkan.cpp +++ b/ray_tracing__before/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -108,18 +109,13 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -137,19 +133,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -157,7 +143,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -215,34 +201,40 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials - nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | flag); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | flag); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } diff --git a/ray_tracing__before/hello_vulkan.h b/ray_tracing__before/hello_vulkan.h index e429d1e..66e10de 100644 --- a/ray_tracing__before/hello_vulkan.h +++ b/ray_tracing__before/hello_vulkan.h @@ -62,10 +62,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -90,9 +94,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing__before/main.cpp b/ray_tracing__before/main.cpp index dac10d6..f9c0e6b 100644 --- a/ray_tracing__before/main.cpp +++ b/ray_tracing__before/main.cpp @@ -110,24 +110,19 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers nvvk::ContextCreateInfo contextInfo; - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing__before/shaders/frag_shader.frag b/ray_tracing__before/shaders/frag_shader.frag index 425c866..7a01408 100644 --- a/ray_tracing__before/shaders/frag_shader.frag +++ b/ray_tracing__before/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,35 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; + int objId = sceneDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +92,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing__before/shaders/passthrough.vert b/ray_tracing__before/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing__before/shaders/passthrough.vert +++ b/ray_tracing__before/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing__before/shaders/post.frag b/ray_tracing__before/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing__before/shaders/post.frag +++ b/ray_tracing__before/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing__before/shaders/vert_shader.vert b/ray_tracing__before/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing__before/shaders/vert_shader.vert +++ b/ray_tracing__before/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing__before/shaders/wavefront.glsl b/ray_tracing__before/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing__before/shaders/wavefront.glsl +++ b/ray_tracing__before/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing__simple/CMakeLists.txt b/ray_tracing__simple/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing__simple/CMakeLists.txt +++ b/ray_tracing__simple/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing__simple/hello_vulkan.cpp b/ray_tracing__simple/hello_vulkan.cpp index bb64a80..deb2dbb 100644 --- a/ray_tracing__simple/hello_vulkan.cpp +++ b/ray_tracing__simple/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -625,11 +605,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -928,9 +905,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment); uint32_t groupStride = groupSize; - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_rtSBTBuffer.buffer; - VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer); using Stride = VkStridedDeviceAddressRegionKHR; std::array strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen diff --git a/ray_tracing__simple/hello_vulkan.h b/ray_tracing__simple/hello_vulkan.h index 0702a8d..4379cd6 100644 --- a/ray_tracing__simple/hello_vulkan.h +++ b/ray_tracing__simple/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing__simple/main.cpp b/ray_tracing__simple/main.cpp index 912c6c4..8e161f8 100644 --- a/ray_tracing__simple/main.cpp +++ b/ray_tracing__simple/main.cpp @@ -88,6 +88,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr); + // Setup camera CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT); CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0)); @@ -109,34 +110,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -167,7 +160,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true)); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing__simple/shaders/frag_shader.frag b/ray_tracing__simple/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing__simple/shaders/frag_shader.frag +++ b/ray_tracing__simple/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing__simple/shaders/passthrough.vert b/ray_tracing__simple/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing__simple/shaders/passthrough.vert +++ b/ray_tracing__simple/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing__simple/shaders/post.frag b/ray_tracing__simple/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing__simple/shaders/post.frag +++ b/ray_tracing__simple/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing__simple/shaders/raytrace.rchit b/ray_tracing__simple/shaders/raytrace.rchit index 098dfa7..2b523a7 100644 --- a/ray_tracing__simple/shaders/raytrace.rchit +++ b/ray_tracing__simple/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,14 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -53,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -96,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -120,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing__simple/shaders/raytrace.rgen b/ray_tracing__simple/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing__simple/shaders/raytrace.rgen +++ b/ray_tracing__simple/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__simple/shaders/raytrace.rmiss b/ray_tracing__simple/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing__simple/shaders/raytrace.rmiss +++ b/ray_tracing__simple/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing__simple/shaders/raytraceShadow.rmiss b/ray_tracing__simple/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing__simple/shaders/raytraceShadow.rmiss +++ b/ray_tracing__simple/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing__simple/shaders/vert_shader.vert b/ray_tracing__simple/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing__simple/shaders/vert_shader.vert +++ b/ray_tracing__simple/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing__simple/shaders/wavefront.glsl b/ray_tracing__simple/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing__simple/shaders/wavefront.glsl +++ b/ray_tracing__simple/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_advanced_compilation/CMakeLists.txt b/ray_tracing_advanced_compilation/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_advanced_compilation/CMakeLists.txt +++ b/ray_tracing_advanced_compilation/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_advanced_compilation/README.md b/ray_tracing_advanced_compilation/README.md index 3ae5b1d..ed7e2de 100644 --- a/ray_tracing_advanced_compilation/README.md +++ b/ray_tracing_advanced_compilation/README.md @@ -21,7 +21,12 @@ Using monolithic pipeline definitions all stages are compiled for each pipeline, Pipeline libraries are `VkPipeline` objects that cannot be bound directly. Instead, they can be compiled once and linked into as many pipelines as necessary. The Shader Binding Table of the resulting pipeline references the shader groups of the library as if they had been appended to the groups and stages in the main `VkRayTracingPipelineCreateInfo` ![](images/library.png) - We start by adding a new member in the `HelloVulkan` class: +We start by adding the device extension in main() +~~~~ C + contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); +~~~~ + +Following by adding a new member in the `HelloVulkan` class: ~~~~ C // Ray tracing shader library VkPipeline m_rtShaderLibrary; diff --git a/ray_tracing_advanced_compilation/hello_vulkan.cpp b/ray_tracing_advanced_compilation/hello_vulkan.cpp index 2e6f12b..b553d6f 100644 --- a/ray_tracing_advanced_compilation/hello_vulkan.cpp +++ b/ray_tracing_advanced_compilation/hello_vulkan.cpp @@ -36,6 +36,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" // Support for C++ multithreading #include @@ -116,26 +117,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -153,25 +143,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -179,7 +153,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -237,36 +211,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -631,11 +611,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -920,7 +897,7 @@ void HelloVulkan::createRtPipeline() pipelineLibraryInfo.layout = m_rtPipelineLayout; // As for the interface the maximum recursion depth must also be consistent across the pipeline pipelineLibraryInfo.maxPipelineRayRecursionDepth = 2; - + // Pipeline libraries need to define an interface, defined by the maximum hit attribute size (typically 2 for // the built-in triangle intersector) and the maximum payload size (3 floating-point values in this sample). // Pipeline libraries can be linked into a final pipeline only if their interface matches diff --git a/ray_tracing_advanced_compilation/hello_vulkan.h b/ray_tracing_advanced_compilation/hello_vulkan.h index 6016ca9..093f21b 100644 --- a/ray_tracing_advanced_compilation/hello_vulkan.h +++ b/ray_tracing_advanced_compilation/hello_vulkan.h @@ -66,10 +66,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -95,9 +99,11 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + nvvk::Buffer m_bufReference; // Buffer references of the OBJ + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures @@ -146,7 +152,7 @@ public: VkPipeline m_rtPipeline; nvvk::SBTWrapper m_sbtWrapper; // Ray tracing shader library - VkPipeline m_rtShaderLibrary; + VkPipeline m_rtShaderLibrary; struct RtPushConstant { diff --git a/ray_tracing_advanced_compilation/main.cpp b/ray_tracing_advanced_compilation/main.cpp index d0e1e8a..9ca5b37 100644 --- a/ray_tracing_advanced_compilation/main.cpp +++ b/ray_tracing_advanced_compilation/main.cpp @@ -120,34 +120,27 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers nvvk::ContextCreateInfo contextInfo; - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); // Creating Vulkan base application nvvk::Context vkctx{}; @@ -178,7 +171,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true)); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_advanced_compilation/shaders/frag_shader.frag b/ray_tracing_advanced_compilation/shaders/frag_shader.frag index 425c866..7a01408 100644 --- a/ray_tracing_advanced_compilation/shaders/frag_shader.frag +++ b/ray_tracing_advanced_compilation/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,35 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; + int objId = sceneDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +92,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_advanced_compilation/shaders/passthrough.vert b/ray_tracing_advanced_compilation/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_advanced_compilation/shaders/passthrough.vert +++ b/ray_tracing_advanced_compilation/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_advanced_compilation/shaders/post.frag b/ray_tracing_advanced_compilation/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_advanced_compilation/shaders/post.frag +++ b/ray_tracing_advanced_compilation/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_advanced_compilation/shaders/raytrace.rchit b/ray_tracing_advanced_compilation/shaders/raytrace.rchit index e4ad9d0..a933e4f 100644 --- a/ray_tracing_advanced_compilation/shaders/raytrace.rchit +++ b/ray_tracing_advanced_compilation/shaders/raytrace.rchit @@ -22,6 +22,10 @@ #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,15 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; layout(constant_id = 0) const int USE_DIFFUSE = 1; layout(constant_id = 1) const int USE_SPECULAR = 1; layout(constant_id = 2) const int TRACE_SHADOW = 1; @@ -59,30 +61,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -102,8 +107,8 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse @@ -113,9 +118,8 @@ void main() diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y - + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } } @@ -132,9 +136,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_advanced_compilation/shaders/raytrace.rmiss b/ray_tracing_advanced_compilation/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_advanced_compilation/shaders/raytrace.rmiss +++ b/ray_tracing_advanced_compilation/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_advanced_compilation/shaders/raytraceShadow.rmiss b/ray_tracing_advanced_compilation/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_advanced_compilation/shaders/raytraceShadow.rmiss +++ b/ray_tracing_advanced_compilation/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_advanced_compilation/shaders/vert_shader.vert b/ray_tracing_advanced_compilation/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_advanced_compilation/shaders/vert_shader.vert +++ b/ray_tracing_advanced_compilation/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_advanced_compilation/shaders/wavefront.glsl b/ray_tracing_advanced_compilation/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing_advanced_compilation/shaders/wavefront.glsl +++ b/ray_tracing_advanced_compilation/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_animation/CMakeLists.txt b/ray_tracing_animation/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_animation/CMakeLists.txt +++ b/ray_tracing_animation/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_animation/README.md b/ray_tracing_animation/README.md index 7a89f71..6529d55 100644 --- a/ray_tracing_animation/README.md +++ b/ray_tracing_animation/README.md @@ -290,6 +290,7 @@ This will move each vertex up and down over time. #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require #include "wavefront.glsl" layout(binding = 0, scalar) buffer Vertices diff --git a/ray_tracing_animation/hello_vulkan.cpp b/ray_tracing_animation/hello_vulkan.cpp index 287ac4f..31478dd 100644 --- a/ray_tracing_animation/hello_vulkan.cpp +++ b/ray_tracing_animation/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -633,11 +613,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_animation/hello_vulkan.h b/ray_tracing_animation/hello_vulkan.h index 1e868ee..8524f22 100644 --- a/ray_tracing_animation/hello_vulkan.h +++ b/ray_tracing_animation/hello_vulkan.h @@ -66,10 +66,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -94,9 +98,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_animation/main.cpp b/ray_tracing_animation/main.cpp index 1acd8d1..99cb618 100644 --- a/ray_tracing_animation/main.cpp +++ b/ray_tracing_animation/main.cpp @@ -109,33 +109,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering + // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -171,7 +164,6 @@ int main(int argc, char** argv) helloVk.m_objInstance.push_back(inst); helloVk.loadModel(nvh::findFile("media/scenes/sphere.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_animation/shaders/anim.comp b/ray_tracing_animation/shaders/anim.comp index f5dd6e8..41c7c77 100644 --- a/ray_tracing_animation/shaders/anim.comp +++ b/ray_tracing_animation/shaders/anim.comp @@ -21,9 +21,10 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require #include "wavefront.glsl" -layout(binding = 0, scalar) buffer Vertices +layout(binding = 0, scalar) buffer Vertices_ { Vertex v[]; } diff --git a/ray_tracing_animation/shaders/frag_shader.frag b/ray_tracing_animation/shaders/frag_shader.frag index 425c866..139aca6 100644 --- a/ray_tracing_animation/shaders/frag_shader.frag +++ b/ray_tracing_animation/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,33 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +90,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_animation/shaders/passthrough.vert b/ray_tracing_animation/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_animation/shaders/passthrough.vert +++ b/ray_tracing_animation/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_animation/shaders/post.frag b/ray_tracing_animation/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_animation/shaders/post.frag +++ b/ray_tracing_animation/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_animation/shaders/raytrace.rchit b/ray_tracing_animation/shaders/raytrace.rchit index cc6be5f..2b523a7 100644 --- a/ray_tracing_animation/shaders/raytrace.rchit +++ b/ray_tracing_animation/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_animation/shaders/raytrace.rgen b/ray_tracing_animation/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing_animation/shaders/raytrace.rgen +++ b/ray_tracing_animation/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_animation/shaders/raytrace.rmiss b/ray_tracing_animation/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_animation/shaders/raytrace.rmiss +++ b/ray_tracing_animation/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_animation/shaders/raytraceShadow.rmiss b/ray_tracing_animation/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_animation/shaders/raytraceShadow.rmiss +++ b/ray_tracing_animation/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_animation/shaders/vert_shader.vert b/ray_tracing_animation/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_animation/shaders/vert_shader.vert +++ b/ray_tracing_animation/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_animation/shaders/wavefront.glsl b/ray_tracing_animation/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing_animation/shaders/wavefront.glsl +++ b/ray_tracing_animation/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_anyhit/CMakeLists.txt b/ray_tracing_anyhit/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_anyhit/CMakeLists.txt +++ b/ray_tracing_anyhit/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_anyhit/README.md b/ray_tracing_anyhit/README.md index bfa40a3..f489313 100644 --- a/ray_tracing_anyhit/README.md +++ b/ray_tracing_anyhit/README.md @@ -34,18 +34,20 @@ This shader starts like `raytrace.chit`, but uses less information. #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "random.glsl" #include "raycommon.glsl" #include "wavefront.glsl" // clang-format off layout(location = 0) rayPayloadInEXT hitPayload prd; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on ~~~~ @@ -59,16 +61,14 @@ opaque, we simply return, which means that the hit will be accepted. ~~~~ C++ void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; - // Indices of the triangle - uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; - // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; if (mat.illum != 4) return; @@ -136,33 +136,13 @@ add the Any Hit stage index and push back the shader module to the stages. ## Give access of the buffers to the Any Hit shader -In `createDescriptorSetLayout()`, we need to allow the Any Hit shader to access some buffers. - -This is the case for the material and scene description buffers +In `createDescriptorSetLayout()`, we need to allow the Any Hit shader to access the scene description buffer ~~~~ C++ - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT - | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); -~~~~ - -and also for the vertex, index and material index buffers: - -~~~~ C++ - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); ~~~~ ## Opaque Flag diff --git a/ray_tracing_anyhit/hello_vulkan.cpp b/ray_tracing_anyhit/hello_vulkan.cpp index 6b33283..3929a4d 100644 --- a/ray_tracing_anyhit/hello_vulkan.cpp +++ b/ray_tracing_anyhit/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,30 +114,16 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT - | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -154,25 +141,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -180,7 +151,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -238,36 +209,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -630,11 +607,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -950,9 +924,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment); uint32_t groupStride = groupSize; - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_rtSBTBuffer.buffer; - VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer); using Stride = VkStridedDeviceAddressRegionKHR; std::array strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen diff --git a/ray_tracing_anyhit/hello_vulkan.h b/ray_tracing_anyhit/hello_vulkan.h index 9d11ec8..1b79818 100644 --- a/ray_tracing_anyhit/hello_vulkan.h +++ b/ray_tracing_anyhit/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_anyhit/main.cpp b/ray_tracing_anyhit/main.cpp index 3158978..7ff464b 100644 --- a/ray_tracing_anyhit/main.cpp +++ b/ray_tracing_anyhit/main.cpp @@ -88,6 +88,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr); + // Setup camera CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT); CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0)); @@ -109,34 +110,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -169,7 +162,6 @@ int main(int argc, char** argv) nvmath::scale_mat4(nvmath::vec3f(1.5f)) * nvmath::translation_mat4(nvmath::vec3f(0.0f, 1.0f, 0.0f))); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_anyhit/shaders/frag_shader.frag b/ray_tracing_anyhit/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_anyhit/shaders/frag_shader.frag +++ b/ray_tracing_anyhit/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_anyhit/shaders/passthrough.vert b/ray_tracing_anyhit/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_anyhit/shaders/passthrough.vert +++ b/ray_tracing_anyhit/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_anyhit/shaders/post.frag b/ray_tracing_anyhit/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_anyhit/shaders/post.frag +++ b/ray_tracing_anyhit/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_anyhit/shaders/random.glsl b/ray_tracing_anyhit/shaders/random.glsl index 6216c3b..ef41f54 100644 --- a/ray_tracing_anyhit/shaders/random.glsl +++ b/ray_tracing_anyhit/shaders/random.glsl @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + // Generate a random unsigned int from two unsigned int values, using 16 pairs // of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis, // "GPU Random Numbers via the Tiny Encryption Algorithm" diff --git a/ray_tracing_anyhit/shaders/raytrace.rahit b/ray_tracing_anyhit/shaders/raytrace.rahit index d703f5f..31f9e99 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rahit +++ b/ray_tracing_anyhit/shaders/raytrace.rahit @@ -16,39 +16,38 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require -#extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "random.glsl" #include "raycommon.glsl" #include "wavefront.glsl" // clang-format off layout(location = 0) rayPayloadInEXT hitPayload prd; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; - // Indices of the triangle - uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; - // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; if(mat.illum != 4) return; diff --git a/ray_tracing_anyhit/shaders/raytrace.rchit b/ray_tracing_anyhit/shaders/raytrace.rchit index 542649b..d370d22 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rchit +++ b/ray_tracing_anyhit/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT shadowPayload prdShadow; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } diff --git a/ray_tracing_anyhit/shaders/raytrace.rgen b/ray_tracing_anyhit/shaders/raytrace.rgen index 96730fd..31fc449 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rgen +++ b/ray_tracing_anyhit/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_anyhit/shaders/raytrace.rmiss b/ray_tracing_anyhit/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rmiss +++ b/ray_tracing_anyhit/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_anyhit/shaders/raytraceShadow.rmiss b/ray_tracing_anyhit/shaders/raytraceShadow.rmiss index abe7454..0378e62 100644 --- a/ray_tracing_anyhit/shaders/raytraceShadow.rmiss +++ b/ray_tracing_anyhit/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_anyhit/shaders/raytrace_rahit.glsl b/ray_tracing_anyhit/shaders/raytrace_rahit.glsl index bbcee67..001063e 100644 --- a/ray_tracing_anyhit/shaders/raytrace_rahit.glsl +++ b/ray_tracing_anyhit/shaders/raytrace_rahit.glsl @@ -16,12 +16,13 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + //#version 460 #extension GL_EXT_ray_tracing : require -#extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable -//#extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "random.glsl" #include "raycommon.glsl" @@ -34,25 +35,23 @@ layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadInEXT shadowPayload prd; #endif -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; - // Indices of the triangle - uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; - // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; if(mat.illum != 4) return; diff --git a/ray_tracing_anyhit/shaders/vert_shader.vert b/ray_tracing_anyhit/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_anyhit/shaders/vert_shader.vert +++ b/ray_tracing_anyhit/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_anyhit/shaders/wavefront.glsl b/ray_tracing_anyhit/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing_anyhit/shaders/wavefront.glsl +++ b/ray_tracing_anyhit/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_ao/CMakeLists.txt b/ray_tracing_ao/CMakeLists.txt index 7af427f..1bf130c 100644 --- a/ray_tracing_ao/CMakeLists.txt +++ b/ray_tracing_ao/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.9.6 FATAL_ERROR) #-------------------------------------------------------------------------------------------------- # Project setting get_filename_component(PROJNAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) -SET(PROJNAME vk_${PROJNAME}_KHR) +set(PROJNAME vk_${PROJNAME}_KHR) project(${PROJNAME} LANGUAGES C CXX) message(STATUS "-------------------------------") message(STATUS "Processing Project ${PROJNAME}:") @@ -53,8 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shaders Src" FILES ${GLSL_SOURCES}) -source_group("Shaders Hdr" FILES ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_ao/hello_vulkan.cpp b/ray_tracing_ao/hello_vulkan.cpp index f573c10..e59c173 100644 --- a/ray_tracing_ao/hello_vulkan.cpp +++ b/ray_tracing_ao/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -109,18 +110,13 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -138,23 +134,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -162,12 +144,13 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); } + //-------------------------------------------------------------------------------------------------- // Creating the pipeline layout // @@ -224,36 +207,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -653,11 +642,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_ao/hello_vulkan.h b/ray_tracing_ao/hello_vulkan.h index 031ef2f..35864e4 100644 --- a/ray_tracing_ao/hello_vulkan.h +++ b/ray_tracing_ao/hello_vulkan.h @@ -76,10 +76,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -104,9 +108,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_ao/main.cpp b/ray_tracing_ao/main.cpp index f3a5533..63e293d 100644 --- a/ray_tracing_ao/main.cpp +++ b/ray_tracing_ao/main.cpp @@ -110,35 +110,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); - // #VKRay: Activate the ray tracing extension - VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeatures); + VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME, false, &rayQueryFeatures); + contextInfo.addDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME, false, &rayQueryFeatures); // Ray tracing in compute shader + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing_ao/shaders/frag_shader.frag b/ray_tracing_ao/shaders/frag_shader.frag index 7f86ec6..19be660 100644 --- a/ray_tracing_ao/shaders/frag_shader.frag +++ b/ray_tracing_ao/shaders/frag_shader.frag @@ -16,18 +16,20 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - -#version 460 + +#version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable -#extension GL_EXT_ray_tracing : enable -#extension GL_EXT_ray_query : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "raycommon.glsl" #include "wavefront.glsl" + layout(push_constant) uniform shaderInformation { vec3 lightPosition; @@ -39,7 +41,6 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; @@ -47,24 +48,26 @@ layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; layout(location = 1) out vec4 outGbuffer; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; -//layout(binding = 7, set = 0) uniform accelerationStructureEXT topLevelAS; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -92,7 +95,7 @@ void main() diffuse = vec3(1); // if(mat.textureId >= 0) // { - // int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + // int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; // uint txtId = txtOffset + mat.textureId; // vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; // diffuse *= diffuseTxt; diff --git a/ray_tracing_ao/shaders/passthrough.vert b/ray_tracing_ao/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_ao/shaders/passthrough.vert +++ b/ray_tracing_ao/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_ao/shaders/post.frag b/ray_tracing_ao/shaders/post.frag index b83132e..cc0857a 100644 --- a/ray_tracing_ao/shaders/post.frag +++ b/ray_tracing_ao/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_ao/shaders/raycommon.glsl b/ray_tracing_ao/shaders/raycommon.glsl index 11444e3..5e4ff63 100644 --- a/ray_tracing_ao/shaders/raycommon.glsl +++ b/ray_tracing_ao/shaders/raycommon.glsl @@ -18,7 +18,6 @@ */ - //- // This utility compresses a normal(x,y,z) to a uint and decompresses it @@ -119,8 +118,7 @@ void ComputeDefaultBasis(const vec3 normal, out vec3 x, out vec3 y) // ZAP's default coordinate system for compatibility vec3 z = normal; const float yz = -z.y * z.z; - y = normalize(((abs(z.z) > 0.99999f) ? vec3(-z.x * z.y, 1.0f - z.y * z.y, yz) : - vec3(-z.x * z.z, yz, 1.0f - z.z * z.z))); + y = normalize(((abs(z.z) > 0.99999f) ? vec3(-z.x * z.y, 1.0f - z.y * z.y, yz) : vec3(-z.x * z.z, yz, 1.0f - z.z * z.z))); x = cross(y, z); } diff --git a/ray_tracing_ao/shaders/vert_shader.vert b/ray_tracing_ao/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_ao/shaders/vert_shader.vert +++ b/ray_tracing_ao/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_ao/shaders/wavefront.glsl b/ray_tracing_ao/shaders/wavefront.glsl index b4a58e4..76149d4 100644 --- a/ray_tracing_ao/shaders/wavefront.glsl +++ b/ray_tracing_ao/shaders/wavefront.glsl @@ -39,12 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; mat4 transfo; mat4 transfoIT; + int objId; + int txtOffset; + + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_callable/CMakeLists.txt b/ray_tracing_callable/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_callable/CMakeLists.txt +++ b/ray_tracing_callable/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_callable/hello_vulkan.cpp b/ray_tracing_callable/hello_vulkan.cpp index a882a88..de0d4cb 100644 --- a/ray_tracing_callable/hello_vulkan.cpp +++ b/ray_tracing_callable/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -624,11 +604,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_callable/hello_vulkan.h b/ray_tracing_callable/hello_vulkan.h index 2e1dc7f..67c101d 100644 --- a/ray_tracing_callable/hello_vulkan.h +++ b/ray_tracing_callable/hello_vulkan.h @@ -66,10 +66,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -97,9 +101,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_callable/main.cpp b/ray_tracing_callable/main.cpp index 4dcd750..72c73f5 100644 --- a/ray_tracing_callable/main.cpp +++ b/ray_tracing_callable/main.cpp @@ -104,6 +104,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr); + // Setup camera CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT); CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0)); @@ -125,34 +126,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -183,7 +176,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true)); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_callable/shaders/frag_shader.frag b/ray_tracing_callable/shaders/frag_shader.frag index 930ebf5..ddd4881 100644 --- a/ray_tracing_callable/shaders/frag_shader.frag +++ b/ray_tracing_callable/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -40,37 +43,38 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); // Vector toward light vec3 LightDir; float lightIntensity; - ; // Point light if(pushC.lightType == 0) @@ -102,7 +106,7 @@ void main() vec3 diffuse = computeDiffuse(mat, LightDir, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_callable/shaders/light_inf.rcall b/ray_tracing_callable/shaders/light_inf.rcall index 38e918f..08fa09c 100644 --- a/ray_tracing_callable/shaders/light_inf.rcall +++ b/ray_tracing_callable/shaders/light_inf.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_callable/shaders/light_point.rcall b/ray_tracing_callable/shaders/light_point.rcall index 6232c1a..014db67 100644 --- a/ray_tracing_callable/shaders/light_point.rcall +++ b/ray_tracing_callable/shaders/light_point.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_callable/shaders/light_spot.rcall b/ray_tracing_callable/shaders/light_spot.rcall index 7f4cdb9..78813f9 100644 --- a/ray_tracing_callable/shaders/light_spot.rcall +++ b/ray_tracing_callable/shaders/light_spot.rcall @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 core #extension GL_EXT_ray_tracing : enable #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_callable/shaders/passthrough.vert b/ray_tracing_callable/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_callable/shaders/passthrough.vert +++ b/ray_tracing_callable/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_callable/shaders/post.frag b/ray_tracing_callable/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_callable/shaders/post.frag +++ b/ray_tracing_callable/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_callable/shaders/raytrace.rchit b/ray_tracing_callable/shaders/raytrace.rchit index cb485fe..7b140fe 100644 --- a/ray_tracing_callable/shaders/raytrace.rchit +++ b/ray_tracing_callable/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -57,33 +58,35 @@ pushC; layout(location = 0) callableDataEXT rayLight cLight; - void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); cLight.inHitPosition = worldPos; //#define DONT_USE_CALLABLE @@ -101,12 +104,11 @@ void main() { vec3 lDir = pushC.lightPosition - cLight.inHitPosition; cLight.outLightDistance = length(lDir); - cLight.outIntensity = - pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance); - cLight.outLightDir = normalize(lDir); - float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection)); - float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff; - float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0); + cLight.outIntensity = pushC.lightIntensity / (cLight.outLightDistance * cLight.outLightDistance); + cLight.outLightDir = normalize(lDir); + float theta = dot(cLight.outLightDir, normalize(-pushC.lightDirection)); + float epsilon = pushC.lightSpotCutoff - pushC.lightSpotOuterCutoff; + float spotIntensity = clamp((theta - pushC.lightSpotOuterCutoff) / epsilon, 0.0, 1.0); cLight.outIntensity *= spotIntensity; } else // Directional light @@ -120,17 +122,16 @@ void main() #endif // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, cLight.outLightDir, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -144,9 +145,8 @@ void main() float tMax = cLight.outLightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = cLight.outLightDir; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_callable/shaders/raytrace.rgen b/ray_tracing_callable/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing_callable/shaders/raytrace.rgen +++ b/ray_tracing_callable/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_callable/shaders/raytrace.rmiss b/ray_tracing_callable/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_callable/shaders/raytrace.rmiss +++ b/ray_tracing_callable/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_callable/shaders/raytraceShadow.rmiss b/ray_tracing_callable/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_callable/shaders/raytraceShadow.rmiss +++ b/ray_tracing_callable/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_callable/shaders/vert_shader.vert b/ray_tracing_callable/shaders/vert_shader.vert index d0e58ff..a46389c 100644 --- a/ray_tracing_callable/shaders/vert_shader.vert +++ b/ray_tracing_callable/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -68,8 +70,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_callable/shaders/wavefront.glsl b/ray_tracing_callable/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_callable/shaders/wavefront.glsl +++ b/ray_tracing_callable/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_gltf/CMakeLists.txt b/ray_tracing_gltf/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_gltf/CMakeLists.txt +++ b/ray_tracing_gltf/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_gltf/README.md b/ray_tracing_gltf/README.md index 2a18b14..26e14f4 100644 --- a/ray_tracing_gltf/README.md +++ b/ray_tracing_gltf/README.md @@ -65,8 +65,24 @@ But instead, we will use this following structure to retrieve the information of nvvk::Buffer m_materialBuffer; nvvk::Buffer m_matrixBuffer; nvvk::Buffer m_rtPrimLookup; + nvvk::Buffer m_sceneDesc; ~~~~ +And a structure to retrieve all buffers of the scene + +~~~~ C++ + struct SceneDescription + { + uint64_t vertexAddress; + uint64_t normalAddress; + uint64_t uvAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t matrixAddress; + uint64_t rtPrimAddress; + }; + ~~~~ + ## Loading glTF scene To load the scene, we will be using [TinyGLTF](https://github.com/syoyo/tinygltf) from Syoyo Fujita, then to avoid traversing @@ -98,27 +114,50 @@ Then we will flatten the scene graph and grab the information we will need using The next part is to allocate the buffers to hold the information, such as the positions, normals, texture coordinates, etc. ~~~~C - m_vertexBuffer = - m_alloc.createBuffer(cmdBuf, m_gltfScene.m_positions, - vkBU::eVertexBuffer | vkBU::eStorageBuffer | vkBU::eShaderDeviceAddress); - m_indexBuffer = - m_alloc.createBuffer(cmdBuf, m_gltfScene.m_indices, - vkBU::eIndexBuffer | vkBU::eStorageBuffer | vkBU::eShaderDeviceAddress); - m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals, - vkBU::eVertexBuffer | vkBU::eStorageBuffer); - m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0, - vkBU::eVertexBuffer | vkBU::eStorageBuffer); - m_materialBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_materials, vkBU::eStorageBuffer); + // Create the buffers on Device and copy vertices, indices and materials + nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + + m_vertexBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_positions, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT + | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR); + m_indexBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_indices, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT + | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR); + m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); ~~~~ +We are making a simple material, extracting only a few members from the glTF material. + +~~~~ C++ + // Copying all materials, only the elements we need + std::vector shadeMaterials; + for(auto& m : m_gltfScene.m_materials) + { + shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.emissiveFactor, m.baseColorTexture}); + } + m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); +~~~~ + + We could use `push_constant` to set the matrix of the node, but instead, we will push the index of the node to draw and fetch the matrix from a buffer. ~~~~C + // Instance Matrices used by rasterizer std::vector nodeMatrices; for(auto& node : m_gltfScene.m_nodes) + { nodeMatrices.emplace_back(node.worldMatrix); - m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, vkBU::eStorageBuffer); + } + m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); ~~~~ To find the positions of the triangle hit in the closest hit shader, as well as the other @@ -131,9 +170,47 @@ attributes, we will store the offsets information of that geometry. { primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex}); } - m_rtPrimLookup = m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_rtPrimLookup = + m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); ~~~~ +Finally, we are creating a buffer holding the address of all buffers + +~~~~ C++ + SceneDescription sceneDesc; + sceneDesc.vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer); + sceneDesc.indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer); + sceneDesc.normalAddress = nvvk::getBufferDeviceAddress(m_device, m_normalBuffer.buffer); + sceneDesc.uvAddress = nvvk::getBufferDeviceAddress(m_device, m_uvBuffer.buffer); + sceneDesc.materialAddress = nvvk::getBufferDeviceAddress(m_device, m_materialBuffer.buffer); + sceneDesc.matrixAddress = nvvk::getBufferDeviceAddress(m_device, m_matrixBuffer.buffer); + sceneDesc.rtPrimAddress = nvvk::getBufferDeviceAddress(m_device, m_rtPrimLookup.buffer); + m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDescription), &sceneDesc, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); +~~~~ + +Before closing the function, we will create textures (none in default scene) and submitting the command buffer. +The finalize and releasing staging is waiting for the copy of all data to the GPU. + +~~~~ C + // Creates all textures found + createTextureImages(cmdBuf, tmodel); + cmdBufGet.submitAndWait(cmdBuf); + m_alloc.finalizeAndReleaseStaging(); + + + NAME_VK(m_vertexBuffer.buffer); + NAME_VK(m_indexBuffer.buffer); + NAME_VK(m_normalBuffer.buffer); + NAME_VK(m_uvBuffer.buffer); + NAME_VK(m_materialBuffer.buffer); + NAME_VK(m_matrixBuffer.buffer); + NAME_VK(m_rtPrimLookup.buffer); + NAME_VK(m_sceneDesc.buffer); +} +~~~~ + +**NOTE**: the macro `NAME_VK` is a convenience to name Vulkan object to easily identify them in Nsight Graphics and to know where it was created. ## Converting geometry to BLAS @@ -147,11 +224,8 @@ The function is similar, only the input is different. auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = m_indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer); uint32_t maxPrimitiveCount = prim.indexCount / 3; diff --git a/ray_tracing_gltf/hello_vulkan.cpp b/ray_tracing_gltf/hello_vulkan.cpp index 07d06f6..5efaa2e 100644 --- a/ray_tracing_gltf/hello_vulkan.cpp +++ b/ray_tracing_gltf/hello_vulkan.cpp @@ -41,6 +41,7 @@ #include "nvh/alignment.hpp" #include "shaders/binding.glsl" #include "shaders/gltf.glsl" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -120,18 +121,14 @@ void HelloVulkan::createDescriptorSetLayout() auto& bind = m_descSetLayoutBind; // Camera matrices (binding = 0) bind.addBinding(B_CAMERA, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - bind.addBinding(B_VERTICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - bind.addBinding(B_INDICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - bind.addBinding(B_NORMALS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - bind.addBinding(B_TEXCOORDS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - bind.addBinding(B_MATERIALS, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); - bind.addBinding(B_MATRICES, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); auto nbTextures = static_cast(m_textures.size()); bind.addBinding(B_TEXTURES, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTextures, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); + bind.addBinding(B_SCENEDESC, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR + | VK_SHADER_STAGE_ANY_HIT_BIT_KHR); + m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); m_descPool = m_descSetLayoutBind.createPool(m_device, 1); m_descSet = nvvk::allocateDescriptorSet(m_device, m_descPool, m_descSetLayout); @@ -146,20 +143,10 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo vertexDesc{m_vertexBuffer.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo indexDesc{m_indexBuffer.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo normalDesc{m_normalBuffer.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo uvDesc{m_uvBuffer.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo materialDesc{m_materialBuffer.buffer, 0, VK_WHOLE_SIZE}; - VkDescriptorBufferInfo matrixDesc{m_matrixBuffer.buffer, 0, VK_WHOLE_SIZE}; + VkDescriptorBufferInfo sceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_CAMERA, &dbiUnif)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_VERTICES, &vertexDesc)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_INDICES, &indexDesc)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_NORMALS, &normalDesc)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_TEXCOORDS, &uvDesc)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_MATERIALS, &materialDesc)); - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_MATRICES, &matrixDesc)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, B_SCENEDESC, &sceneDesc)); // All texture samplers std::vector diit; @@ -237,17 +224,20 @@ void HelloVulkan::loadScene(const std::string& filename) VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR); m_normalBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_normals, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); m_uvBuffer = m_alloc.createBuffer(cmdBuf, m_gltfScene.m_texcoords0, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); // Copying all materials, only the elements we need std::vector shadeMaterials; for(auto& m : m_gltfScene.m_materials) { - shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.baseColorTexture, m.emissiveFactor}); + shadeMaterials.emplace_back(GltfShadeMaterial{m.baseColorFactor, m.emissiveFactor, m.baseColorTexture}); } - m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_materialBuffer = m_alloc.createBuffer(cmdBuf, shadeMaterials, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); // Instance Matrices used by rasterizer std::vector nodeMatrices; @@ -255,7 +245,8 @@ void HelloVulkan::loadScene(const std::string& filename) { nodeMatrices.emplace_back(node.worldMatrix); } - m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_matrixBuffer = m_alloc.createBuffer(cmdBuf, nodeMatrices, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); // The following is used to find the primitive mesh information in the CHIT std::vector primLookup; @@ -263,20 +254,35 @@ void HelloVulkan::loadScene(const std::string& filename) { primLookup.push_back({primMesh.firstIndex, primMesh.vertexOffset, primMesh.materialIndex}); } - m_rtPrimLookup = m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_rtPrimLookup = + m_alloc.createBuffer(cmdBuf, primLookup, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + SceneDescription sceneDesc; + sceneDesc.vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer); + sceneDesc.indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer); + sceneDesc.normalAddress = nvvk::getBufferDeviceAddress(m_device, m_normalBuffer.buffer); + sceneDesc.uvAddress = nvvk::getBufferDeviceAddress(m_device, m_uvBuffer.buffer); + sceneDesc.materialAddress = nvvk::getBufferDeviceAddress(m_device, m_materialBuffer.buffer); + sceneDesc.matrixAddress = nvvk::getBufferDeviceAddress(m_device, m_matrixBuffer.buffer); + sceneDesc.rtPrimAddress = nvvk::getBufferDeviceAddress(m_device, m_rtPrimLookup.buffer); + m_sceneDesc = m_alloc.createBuffer(cmdBuf, sizeof(SceneDescription), &sceneDesc, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + // Creates all textures found createTextureImages(cmdBuf, tmodel); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - m_debug.setObjectName(m_vertexBuffer.buffer, "Vertex"); - m_debug.setObjectName(m_indexBuffer.buffer, "Index"); - m_debug.setObjectName(m_normalBuffer.buffer, "Normal"); - m_debug.setObjectName(m_uvBuffer.buffer, "TexCoord"); - m_debug.setObjectName(m_materialBuffer.buffer, "Material"); - m_debug.setObjectName(m_matrixBuffer.buffer, "Matrix"); + + NAME_VK(m_vertexBuffer.buffer); + NAME_VK(m_indexBuffer.buffer); + NAME_VK(m_normalBuffer.buffer); + NAME_VK(m_uvBuffer.buffer); + NAME_VK(m_materialBuffer.buffer); + NAME_VK(m_matrixBuffer.buffer); + NAME_VK(m_rtPrimLookup.buffer); + NAME_VK(m_sceneDesc.buffer); } @@ -364,6 +370,7 @@ void HelloVulkan::destroyResources() m_alloc.destroy(m_materialBuffer); m_alloc.destroy(m_matrixBuffer); m_alloc.destroy(m_rtPrimLookup); + m_alloc.destroy(m_sceneDesc); for(auto& t : m_textures) { @@ -606,11 +613,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::primitiveToGeometry(const nvh::GltfPrimMesh& prim) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = m_indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, m_vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, m_indexBuffer.buffer); uint32_t maxPrimitiveCount = prim.indexCount / 3; diff --git a/ray_tracing_gltf/hello_vulkan.h b/ray_tracing_gltf/hello_vulkan.h index 2a73041..14995eb 100644 --- a/ray_tracing_gltf/hello_vulkan.h +++ b/ray_tracing_gltf/hello_vulkan.h @@ -61,6 +61,16 @@ public: int materialIndex; }; + struct SceneDescription + { + uint64_t vertexAddress; + uint64_t normalAddress; + uint64_t uvAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t matrixAddress; + uint64_t rtPrimAddress; + }; nvh::GltfScene m_gltfScene; nvvk::Buffer m_vertexBuffer; @@ -70,6 +80,7 @@ public: nvvk::Buffer m_materialBuffer; nvvk::Buffer m_matrixBuffer; nvvk::Buffer m_rtPrimLookup; + nvvk::Buffer m_sceneDesc; // Information pushed at each draw call struct ObjPushConstant diff --git a/ray_tracing_gltf/shaders/binding.glsl b/ray_tracing_gltf/shaders/binding.glsl index 036cf82..8bfad9a 100644 --- a/ray_tracing_gltf/shaders/binding.glsl +++ b/ray_tracing_gltf/shaders/binding.glsl @@ -19,10 +19,5 @@ #define B_CAMERA 0 -#define B_VERTICES 1 -#define B_NORMALS 2 -#define B_TEXCOORDS 3 -#define B_INDICES 4 -#define B_MATERIALS 5 -#define B_MATRICES 6 -#define B_TEXTURES 7 +#define B_SCENEDESC 1 +#define B_TEXTURES 2 diff --git a/ray_tracing_gltf/shaders/frag_shader.frag b/ray_tracing_gltf/shaders/frag_shader.frag index 1f8521b..9e9fc39 100644 --- a/ray_tracing_gltf/shaders/frag_shader.frag +++ b/ray_tracing_gltf/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "binding.glsl" #include "gltf.glsl" @@ -39,7 +42,6 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; @@ -47,16 +49,19 @@ layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; // Buffers -layout(set = 0, binding = B_MATERIALS) buffer _GltfMaterial { GltfShadeMaterial materials[]; }; -layout(set = 0, binding = B_TEXTURES) uniform sampler2D[] textureSamplers; +layout(buffer_reference, scalar) buffer Matrices { mat4 m[]; }; +layout(buffer_reference, scalar) buffer GltfMaterial { GltfShadeMaterial m[]; }; +layout(set = 0, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; } ; +layout(set = 0, binding = B_TEXTURES) uniform sampler2D[] textureSamplers; // clang-format on void main() { // Material of the object - GltfShadeMaterial mat = materials[nonuniformEXT(pushC.matetrialId)]; + GltfMaterial gltfMat = GltfMaterial(sceneDesc.materialAddress); + GltfShadeMaterial mat = gltfMat.m[pushC.matetrialId]; vec3 N = normalize(fragNormal); diff --git a/ray_tracing_gltf/shaders/gltf.glsl b/ray_tracing_gltf/shaders/gltf.glsl index 6611be8..229ad1b 100644 --- a/ray_tracing_gltf/shaders/gltf.glsl +++ b/ray_tracing_gltf/shaders/gltf.glsl @@ -20,8 +20,8 @@ struct GltfShadeMaterial { vec4 pbrBaseColorFactor; - int pbrBaseColorTexture; vec3 emissiveFactor; + int pbrBaseColorTexture; }; #ifndef __cplusplus @@ -32,6 +32,17 @@ struct PrimMeshInfo int materialIndex; }; +struct SceneDesc +{ + uint64_t vertexAddress; + uint64_t normalAddress; + uint64_t uvAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t matrixAddress; + uint64_t rtPrimAddress; +}; + vec3 computeDiffuse(GltfShadeMaterial mat, vec3 lightDir, vec3 normal) { diff --git a/ray_tracing_gltf/shaders/passthrough.vert b/ray_tracing_gltf/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_gltf/shaders/passthrough.vert +++ b/ray_tracing_gltf/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_gltf/shaders/pathtrace.rchit b/ray_tracing_gltf/shaders/pathtrace.rchit index 7de91cd..40035e8 100644 --- a/ray_tracing_gltf/shaders/pathtrace.rchit +++ b/ray_tracing_gltf/shaders/pathtrace.rchit @@ -16,13 +16,17 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + + #include "binding.glsl" #include "gltf.glsl" #include "raycommon.glsl" @@ -38,13 +42,15 @@ layout(location = 1) rayPayloadEXT bool isShadowed; layout(set = 0, binding = 0 ) uniform accelerationStructureEXT topLevelAS; layout(set = 0, binding = 2) readonly buffer _InstanceInfo {PrimMeshInfo primInfo[];}; -layout(set = 1, binding = B_VERTICES) readonly buffer _VertexBuf {float vertices[];}; -layout(set = 1, binding = B_INDICES) readonly buffer _Indices {uint indices[];}; -layout(set = 1, binding = B_NORMALS) readonly buffer _NormalBuf {float normals[];}; -layout(set = 1, binding = B_TEXCOORDS) readonly buffer _TexCoordBuf {float texcoord0[];}; -layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];}; -layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures +layout(buffer_reference, scalar) readonly buffer Vertices { vec3 v[]; }; +layout(buffer_reference, scalar) readonly buffer Indices { ivec3 i[]; }; +layout(buffer_reference, scalar) readonly buffer Normals { vec3 n[]; }; +layout(buffer_reference, scalar) readonly buffer TexCoords { vec2 t[]; }; +layout(buffer_reference, scalar) readonly buffer Materials { GltfShadeMaterial m[]; }; + +layout(set = 1, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; }; +layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures // clang-format on @@ -57,33 +63,6 @@ layout(push_constant) uniform Constants } pushC; -// Return the vertex position -vec3 getVertex(uint index) -{ - vec3 vp; - vp.x = vertices[3 * index + 0]; - vp.y = vertices[3 * index + 1]; - vp.z = vertices[3 * index + 2]; - return vp; -} - -vec3 getNormal(uint index) -{ - vec3 vp; - vp.x = normals[3 * index + 0]; - vp.y = normals[3 * index + 1]; - vp.z = normals[3 * index + 2]; - return vp; -} - -vec2 getTexCoord(uint index) -{ - vec2 vp; - vp.x = texcoord0[2 * index + 0]; - vp.y = texcoord0[2 * index + 1]; - return vp; -} - void main() { @@ -91,42 +70,47 @@ void main() PrimMeshInfo pinfo = primInfo[gl_InstanceCustomIndexEXT]; // Getting the 'first index' for this mesh (offset of the mesh + offset of the triangle) - uint indexOffset = pinfo.indexOffset + (3 * gl_PrimitiveID); + uint indexOffset = (pinfo.indexOffset / 3) + gl_PrimitiveID; uint vertexOffset = pinfo.vertexOffset; // Vertex offset as defined in glTF uint matIndex = max(0, pinfo.materialIndex); // material of primitive mesh + Materials gltfMat = Materials(sceneDesc.materialAddress); + Vertices vertices = Vertices(sceneDesc.vertexAddress); + Indices indices = Indices(sceneDesc.indexAddress); + Normals normals = Normals(sceneDesc.normalAddress); + TexCoords texCoords = TexCoords(sceneDesc.uvAddress); + Materials materials = Materials(sceneDesc.materialAddress); + // Getting the 3 indices of the triangle (local) - ivec3 triangleIndex = ivec3(indices[nonuniformEXT(indexOffset + 0)], // - indices[nonuniformEXT(indexOffset + 1)], // - indices[nonuniformEXT(indexOffset + 2)]); + ivec3 triangleIndex = indices.i[indexOffset]; triangleIndex += ivec3(vertexOffset); // (global) const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Vertex of the triangle - const vec3 pos0 = getVertex(triangleIndex.x); - const vec3 pos1 = getVertex(triangleIndex.y); - const vec3 pos2 = getVertex(triangleIndex.z); + const vec3 pos0 = vertices.v[triangleIndex.x]; + const vec3 pos1 = vertices.v[triangleIndex.y]; + const vec3 pos2 = vertices.v[triangleIndex.z]; const vec3 position = pos0 * barycentrics.x + pos1 * barycentrics.y + pos2 * barycentrics.z; const vec3 world_position = vec3(gl_ObjectToWorldEXT * vec4(position, 1.0)); // Normal - const vec3 nrm0 = getNormal(triangleIndex.x); - const vec3 nrm1 = getNormal(triangleIndex.y); - const vec3 nrm2 = getNormal(triangleIndex.z); - vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z); + const vec3 nrm0 = normals.n[triangleIndex.x]; + const vec3 nrm1 = normals.n[triangleIndex.y]; + const vec3 nrm2 = normals.n[triangleIndex.z]; + vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z); const vec3 world_normal = normalize(vec3(normal * gl_WorldToObjectEXT)); const vec3 geom_normal = normalize(cross(pos1 - pos0, pos2 - pos0)); // TexCoord - const vec2 uv0 = getTexCoord(triangleIndex.x); - const vec2 uv1 = getTexCoord(triangleIndex.y); - const vec2 uv2 = getTexCoord(triangleIndex.z); + const vec2 uv0 = texCoords.t[triangleIndex.x]; + const vec2 uv1 = texCoords.t[triangleIndex.y]; + const vec2 uv2 = texCoords.t[triangleIndex.z]; const vec2 texcoord0 = uv0 * barycentrics.x + uv1 * barycentrics.y + uv2 * barycentrics.z; // https://en.wikipedia.org/wiki/Path_tracing // Material of the object - GltfShadeMaterial mat = materials[nonuniformEXT(matIndex)]; + GltfShadeMaterial mat = materials.m[matIndex]; vec3 emittance = mat.emissiveFactor; // Pick a random direction from here and keep going. diff --git a/ray_tracing_gltf/shaders/pathtrace.rgen b/ray_tracing_gltf/shaders/pathtrace.rgen index 7164479..15a4d76 100644 --- a/ray_tracing_gltf/shaders/pathtrace.rgen +++ b/ray_tracing_gltf/shaders/pathtrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_gltf/shaders/pathtrace.rmiss b/ray_tracing_gltf/shaders/pathtrace.rmiss index 8efaac0..05405f5 100644 --- a/ray_tracing_gltf/shaders/pathtrace.rmiss +++ b/ray_tracing_gltf/shaders/pathtrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_gltf/shaders/post.frag b/ray_tracing_gltf/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_gltf/shaders/post.frag +++ b/ray_tracing_gltf/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_gltf/shaders/raytrace.rchit b/ray_tracing_gltf/shaders/raytrace.rchit index 755b861..75aaabe 100644 --- a/ray_tracing_gltf/shaders/raytrace.rchit +++ b/ray_tracing_gltf/shaders/raytrace.rchit @@ -16,13 +16,17 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + + #include "binding.glsl" #include "gltf.glsl" #include "raycommon.glsl" @@ -36,14 +40,18 @@ layout(location = 1) rayPayloadEXT bool isShadowed; layout(set = 0, binding = 0 ) uniform accelerationStructureEXT topLevelAS; layout(set = 0, binding = 2) readonly buffer _InstanceInfo {PrimMeshInfo primInfo[];}; -layout(set = 1, binding = B_VERTICES) readonly buffer _VertexBuf {float vertices[];}; -layout(set = 1, binding = B_INDICES) readonly buffer _Indices {uint indices[];}; -layout(set = 1, binding = B_NORMALS) readonly buffer _NormalBuf {float normals[];}; -layout(set = 1, binding = B_TEXCOORDS) readonly buffer _TexCoordBuf {float texcoord0[];}; -layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];}; -layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures +//layout(set = 1, binding = B_MATERIALS) readonly buffer _MaterialBuffer {GltfShadeMaterial materials[];}; +layout(buffer_reference, scalar) readonly buffer Vertices { vec3 v[]; }; +layout(buffer_reference, scalar) readonly buffer Indices { uint i[]; }; +layout(buffer_reference, scalar) readonly buffer Normals { vec3 n[]; }; +layout(buffer_reference, scalar) readonly buffer TexCoords { vec2 t[]; }; +layout(buffer_reference, scalar) readonly buffer Materials { GltfShadeMaterial m[]; }; + +layout(set = 1, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; }; +layout(set = 1, binding = B_TEXTURES) uniform sampler2D texturesMap[]; // all textures + // clang-format on layout(push_constant) uniform Constants @@ -55,33 +63,6 @@ layout(push_constant) uniform Constants } pushC; -// Return the vertex position -vec3 getVertex(uint index) -{ - vec3 vp; - vp.x = vertices[3 * index + 0]; - vp.y = vertices[3 * index + 1]; - vp.z = vertices[3 * index + 2]; - return vp; -} - -vec3 getNormal(uint index) -{ - vec3 vp; - vp.x = normals[3 * index + 0]; - vp.y = normals[3 * index + 1]; - vp.z = normals[3 * index + 2]; - return vp; -} - -vec2 getTexCoord(uint index) -{ - vec2 vp; - vp.x = texcoord0[2 * index + 0]; - vp.y = texcoord0[2 * index + 1]; - return vp; -} - void main() { @@ -93,33 +74,39 @@ void main() uint vertexOffset = pinfo.vertexOffset; // Vertex offset as defined in glTF uint matIndex = max(0, pinfo.materialIndex); // material of primitive mesh + Materials gltfMat = Materials(sceneDesc.materialAddress); + Vertices vertices = Vertices(sceneDesc.vertexAddress); + Indices indices = Indices(sceneDesc.indexAddress); + Normals normals = Normals(sceneDesc.normalAddress); + TexCoords texCoords = TexCoords(sceneDesc.uvAddress); + Materials materials = Materials(sceneDesc.materialAddress); + + // Getting the 3 indices of the triangle (local) - ivec3 triangleIndex = ivec3(indices[nonuniformEXT(indexOffset + 0)], // - indices[nonuniformEXT(indexOffset + 1)], // - indices[nonuniformEXT(indexOffset + 2)]); + ivec3 triangleIndex = ivec3(indices.i[indexOffset + 0], indices.i[indexOffset + 1], indices.i[indexOffset + 2]); triangleIndex += ivec3(vertexOffset); // (global) const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Vertex of the triangle - const vec3 pos0 = getVertex(triangleIndex.x); - const vec3 pos1 = getVertex(triangleIndex.y); - const vec3 pos2 = getVertex(triangleIndex.z); + const vec3 pos0 = vertices.v[triangleIndex.x]; + const vec3 pos1 = vertices.v[triangleIndex.y]; + const vec3 pos2 = vertices.v[triangleIndex.z]; const vec3 position = pos0 * barycentrics.x + pos1 * barycentrics.y + pos2 * barycentrics.z; const vec3 world_position = vec3(gl_ObjectToWorldEXT * vec4(position, 1.0)); // Normal - const vec3 nrm0 = getNormal(triangleIndex.x); - const vec3 nrm1 = getNormal(triangleIndex.y); - const vec3 nrm2 = getNormal(triangleIndex.z); - vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z); + const vec3 nrm0 = normals.n[triangleIndex.x]; + const vec3 nrm1 = normals.n[triangleIndex.y]; + const vec3 nrm2 = normals.n[triangleIndex.z]; + vec3 normal = normalize(nrm0 * barycentrics.x + nrm1 * barycentrics.y + nrm2 * barycentrics.z); const vec3 world_normal = normalize(vec3(normal * gl_WorldToObjectEXT)); const vec3 geom_normal = normalize(cross(pos1 - pos0, pos2 - pos0)); // TexCoord - const vec2 uv0 = getTexCoord(triangleIndex.x); - const vec2 uv1 = getTexCoord(triangleIndex.y); - const vec2 uv2 = getTexCoord(triangleIndex.z); + const vec2 uv0 = texCoords.t[triangleIndex.x]; + const vec2 uv1 = texCoords.t[triangleIndex.y]; + const vec2 uv2 = texCoords.t[triangleIndex.z]; const vec2 texcoord0 = uv0 * barycentrics.x + uv1 * barycentrics.y + uv2 * barycentrics.z; // Vector toward the light @@ -140,7 +127,7 @@ void main() } // Material of the object - GltfShadeMaterial mat = materials[nonuniformEXT(matIndex)]; + GltfShadeMaterial mat = materials.m[matIndex]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, world_normal); @@ -160,9 +147,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_gltf/shaders/raytrace.rgen b/ray_tracing_gltf/shaders/raytrace.rgen index e04d41b..811f888 100644 --- a/ray_tracing_gltf/shaders/raytrace.rgen +++ b/ray_tracing_gltf/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_gltf/shaders/raytrace.rmiss b/ray_tracing_gltf/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_gltf/shaders/raytrace.rmiss +++ b/ray_tracing_gltf/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_gltf/shaders/raytraceShadow.rmiss b/ray_tracing_gltf/shaders/raytraceShadow.rmiss index 36ea7bb..6bbe3a4 100644 --- a/ray_tracing_gltf/shaders/raytraceShadow.rmiss +++ b/ray_tracing_gltf/shaders/raytraceShadow.rmiss @@ -17,7 +17,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_gltf/shaders/sampling.glsl b/ray_tracing_gltf/shaders/sampling.glsl index 7666687..67285dd 100644 --- a/ray_tracing_gltf/shaders/sampling.glsl +++ b/ray_tracing_gltf/shaders/sampling.glsl @@ -16,8 +16,8 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - - // Generate a random unsigned int from two unsigned int values, using 16 pairs + +// Generate a random unsigned int from two unsigned int values, using 16 pairs // of rounds of the Tiny Encryption Algorithm. See Zafar, Olano, and Curtis, // "GPU Random Numbers via the Tiny Encryption Algorithm" uint tea(uint val0, uint val1) diff --git a/ray_tracing_gltf/shaders/vert_shader.vert b/ray_tracing_gltf/shaders/vert_shader.vert index c561f50..dbacfc1 100644 --- a/ray_tracing_gltf/shaders/vert_shader.vert +++ b/ray_tracing_gltf/shaders/vert_shader.vert @@ -16,16 +16,21 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "binding.glsl" +#include "gltf.glsl" // clang-format off -layout( set = 0, binding = B_MATRICES) readonly buffer _Matrix { mat4 matrices[]; }; +layout(buffer_reference, scalar) buffer Matrices { mat4 m[]; }; +layout( set = 0, binding = B_SCENEDESC ) readonly buffer SceneDesc_ { SceneDesc sceneDesc; }; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -42,7 +47,7 @@ layout(push_constant) uniform shaderInformation uint instanceId; float lightIntensity; int lightType; - int materialId; + int materialId; } pushC; @@ -65,7 +70,9 @@ out gl_PerVertex void main() { - mat4 objMatrix = matrices[pushC.instanceId]; + Matrices matrices = Matrices(sceneDesc.matrixAddress); + mat4 objMatrix = matrices.m[pushC.instanceId]; + mat4 objMatrixIT = transpose(inverse(objMatrix)); vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_indirect_scissor/CMakeLists.txt b/ray_tracing_indirect_scissor/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_indirect_scissor/CMakeLists.txt +++ b/ray_tracing_indirect_scissor/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_indirect_scissor/hello_vulkan.cpp b/ray_tracing_indirect_scissor/hello_vulkan.cpp index fc27dcc..bff76eb 100644 --- a/ray_tracing_indirect_scissor/hello_vulkan.cpp +++ b/ray_tracing_indirect_scissor/hello_vulkan.cpp @@ -114,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -151,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -177,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -235,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } diff --git a/ray_tracing_indirect_scissor/hello_vulkan.h b/ray_tracing_indirect_scissor/hello_vulkan.h index 179722e..15ad451 100644 --- a/ray_tracing_indirect_scissor/hello_vulkan.h +++ b/ray_tracing_indirect_scissor/hello_vulkan.h @@ -76,10 +76,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -132,9 +136,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_indirect_scissor/main.cpp b/ray_tracing_indirect_scissor/main.cpp index 231855f..b025ab9 100644 --- a/ray_tracing_indirect_scissor/main.cpp +++ b/ray_tracing_indirect_scissor/main.cpp @@ -89,6 +89,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr); + // Setup camera CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT); CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0)); @@ -110,34 +111,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing_indirect_scissor/shaders/frag_shader.frag b/ray_tracing_indirect_scissor/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_indirect_scissor/shaders/frag_shader.frag +++ b/ray_tracing_indirect_scissor/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_indirect_scissor/shaders/lantern.rchit b/ray_tracing_indirect_scissor/shaders/lantern.rchit index 35367be..38ed2db 100644 --- a/ray_tracing_indirect_scissor/shaders/lantern.rchit +++ b/ray_tracing_indirect_scissor/shaders/lantern.rchit @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable @@ -37,6 +37,6 @@ void main() { // Just look up this lantern's color. Self-illuminating, so no lighting calculations. LanternIndirectEntry lantern = lanterns.lanterns[nonuniformEXT(gl_InstanceCustomIndexEXT)]; - prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue); - prd.additiveBlending = false; + prd.hitValue = vec3(lantern.red, lantern.green, lantern.blue); + prd.additiveBlending = false; } diff --git a/ray_tracing_indirect_scissor/shaders/lanternShadow.rmiss b/ray_tracing_indirect_scissor/shaders/lanternShadow.rmiss index 61236ee..907b331 100644 --- a/ray_tracing_indirect_scissor/shaders/lanternShadow.rmiss +++ b/ray_tracing_indirect_scissor/shaders/lanternShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_indirect_scissor/shaders/lanternShadowLantern.rchit b/ray_tracing_indirect_scissor/shaders/lanternShadowLantern.rchit index bc1dda8..fe7b098 100644 --- a/ray_tracing_indirect_scissor/shaders/lanternShadowLantern.rchit +++ b/ray_tracing_indirect_scissor/shaders/lanternShadowLantern.rchit @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_indirect_scissor/shaders/lanternShadowObj.rchit b/ray_tracing_indirect_scissor/shaders/lanternShadowObj.rchit index 3cde82f..6f33aa0 100644 --- a/ray_tracing_indirect_scissor/shaders/lanternShadowObj.rchit +++ b/ray_tracing_indirect_scissor/shaders/lanternShadowObj.rchit @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_indirect_scissor/shaders/passthrough.vert b/ray_tracing_indirect_scissor/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_indirect_scissor/shaders/passthrough.vert +++ b/ray_tracing_indirect_scissor/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_indirect_scissor/shaders/post.frag b/ray_tracing_indirect_scissor/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_indirect_scissor/shaders/post.frag +++ b/ray_tracing_indirect_scissor/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_indirect_scissor/shaders/raycommon.glsl b/ray_tracing_indirect_scissor/shaders/raycommon.glsl index 2376bf7..3c67956 100644 --- a/ray_tracing_indirect_scissor/shaders/raycommon.glsl +++ b/ray_tracing_indirect_scissor/shaders/raycommon.glsl @@ -30,8 +30,8 @@ layout(push_constant) uniform Constants vec4 clearColor; vec3 lightPosition; float lightIntensity; - int lightType; // 0: point, 1: infinite - int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters. + int lightType; // 0: point, 1: infinite + int lanternPassNumber; // -1 if this is the full-screen pass. Otherwise, used to lookup trace indirect parameters. int screenX; int screenY; int lanternDebug; diff --git a/ray_tracing_indirect_scissor/shaders/raytrace.rchit b/ray_tracing_indirect_scissor/shaders/raytrace.rchit index 670df53..7a1f5dc 100644 --- a/ray_tracing_indirect_scissor/shaders/raytrace.rchit +++ b/ray_tracing_indirect_scissor/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -32,66 +36,65 @@ layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; layout(location = 2) rayPayloadEXT int hitLanternInstance; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; layout(binding = 2, set = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; - vec3 colorIntensity = vec3(pushC.lightIntensity); - float lightDistance = 100000.0; + vec3 colorIntensity = vec3(pushC.lightIntensity); + float lightDistance = 100000.0; // ray direction is towards lantern, if in lantern pass. - if (pushC.lanternPassNumber >= 0) + if(pushC.lanternPassNumber >= 0) { LanternIndirectEntry lantern = lanterns.lanterns[pushC.lanternPassNumber]; - vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos; - lightDistance = length(lDir); - vec3 color = vec3(lantern.red, lantern.green, lantern.blue); + vec3 lDir = vec3(lantern.x, lantern.y, lantern.z) - worldPos; + lightDistance = length(lDir); + vec3 color = vec3(lantern.red, lantern.green, lantern.blue); // Lantern light decreases linearly. Not physically accurate, but looks good // and avoids a hard "edge" at the radius limit. Use a constant value // if lantern debug is enabled to clearly see the covered screen rectangle. - float distanceFade = - pushC.lanternDebug != 0 - ? 0.3 - : max(0, (lantern.radius - lightDistance) / lantern.radius); - colorIntensity = color * lantern.brightness * distanceFade; - L = normalize(lDir); + float distanceFade = pushC.lanternDebug != 0 ? 0.3 : max(0, (lantern.radius - lightDistance) / lantern.radius); + colorIntensity = color * lantern.brightness * distanceFade; + L = normalize(lDir); } // Non-lantern pass may have point light... else if(pushC.lightType == 0) @@ -107,17 +110,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -133,10 +135,10 @@ void main() vec3 rayDir = L; // Ordinary shadow from the simple tutorial. - if (pushC.lanternPassNumber < 0) { + if(pushC.lanternPassNumber < 0) + { isShadowed = true; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask @@ -153,25 +155,28 @@ void main() // Lantern shadow ray. Cast a ray towards the lantern whose lighting is being // added this pass. Only the closest hit shader for lanterns will set // hitLanternInstance (payload 2) to non-negative value. - else { + else + { // Skip ray if no light would be added anyway. - if (colorIntensity == vec3(0)) { + if(colorIntensity == vec3(0)) + { isShadowed = true; } - else { - uint flags = gl_RayFlagsOpaqueEXT; + else + { + uint flags = gl_RayFlagsOpaqueEXT; hitLanternInstance = -1; - traceRayEXT(topLevelAS, // acceleration structure - flags, // rayFlags - 0xFF, // cullMask - 2, // sbtRecordOffset : lantern shadow hit groups start at index 2. - 0, // sbtRecordStride - 2, // missIndex : lantern shadow miss shader is number 2. - origin, // ray origin - tMin, // ray min range - rayDir, // ray direction - tMax, // ray max range - 2 // payload (location = 2) + traceRayEXT(topLevelAS, // acceleration structure + flags, // rayFlags + 0xFF, // cullMask + 2, // sbtRecordOffset : lantern shadow hit groups start at index 2. + 0, // sbtRecordStride + 2, // missIndex : lantern shadow miss shader is number 2. + origin, // ray origin + tMin, // ray min range + rayDir, // ray direction + tMax, // ray max range + 2 // payload (location = 2) ); // Did we hit the lantern we expected? isShadowed = (hitLanternInstance != pushC.lanternPassNumber); @@ -189,6 +194,6 @@ void main() } } - prd.hitValue = colorIntensity * (attenuation * (diffuse + specular)); + prd.hitValue = colorIntensity * (attenuation * (diffuse + specular)); prd.additiveBlending = true; } diff --git a/ray_tracing_indirect_scissor/shaders/raytrace.rgen b/ray_tracing_indirect_scissor/shaders/raytrace.rgen index f2a2a87..ff6c31a 100644 --- a/ray_tracing_indirect_scissor/shaders/raytrace.rgen +++ b/ray_tracing_indirect_scissor/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable @@ -36,23 +36,27 @@ layout(binding = 0, set = 1) uniform CameraProperties } cam; -layout(binding = 2, set = 0) buffer LanternArray { LanternIndirectEntry lanterns[]; } lanterns; +layout(binding = 2, set = 0) buffer LanternArray +{ + LanternIndirectEntry lanterns[]; +} +lanterns; void main() { // Global light pass is a full screen rectangle (lower corner 0,0), but // lantern passes are only run within rectangles that may be offset. ivec2 pixelOffset = ivec2(0); - if (pushC.lanternPassNumber >= 0) + if(pushC.lanternPassNumber >= 0) { pixelOffset.x = lanterns.lanterns[pushC.lanternPassNumber].offsetX; pixelOffset.y = lanterns.lanterns[pushC.lanternPassNumber].offsetY; } const ivec2 pixelIntCoord = ivec2(gl_LaunchIDEXT.xy) + pixelOffset; - const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5); - const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY); - vec2 d = inUV * 2.0 - 1.0; + const vec2 pixelCenter = vec2(pixelIntCoord) + vec2(0.5); + const vec2 inUV = pixelCenter / vec2(pushC.screenX, pushC.screenY); + vec2 d = inUV * 2.0 - 1.0; vec4 origin = cam.viewInverse * vec4(0, 0, 0, 1); vec4 target = cam.projInverse * vec4(d.x, d.y, 1, 1); @@ -83,7 +87,8 @@ void main() // Either add to or replace output image color based on prd.additiveBlending. // Global pass always replaces color as it is the first pass. vec3 oldColor = vec3(0); - if (prd.additiveBlending && pushC.lanternPassNumber >= 0) { + if(prd.additiveBlending && pushC.lanternPassNumber >= 0) + { oldColor = imageLoad(image, pixelIntCoord).rgb; } imageStore(image, pixelIntCoord, vec4(prd.hitValue + oldColor, 1.0)); diff --git a/ray_tracing_indirect_scissor/shaders/raytrace.rmiss b/ray_tracing_indirect_scissor/shaders/raytrace.rmiss index 9d671c9..8e6b740 100644 --- a/ray_tracing_indirect_scissor/shaders/raytrace.rmiss +++ b/ray_tracing_indirect_scissor/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable @@ -26,6 +26,6 @@ layout(location = 0) rayPayloadInEXT hitPayload prd; void main() { - prd.hitValue = pushC.clearColor.xyz * 0.8; + prd.hitValue = pushC.clearColor.xyz * 0.8; prd.additiveBlending = false; } diff --git a/ray_tracing_indirect_scissor/shaders/raytraceShadow.rmiss b/ray_tracing_indirect_scissor/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_indirect_scissor/shaders/raytraceShadow.rmiss +++ b/ray_tracing_indirect_scissor/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_indirect_scissor/shaders/vert_shader.vert b/ray_tracing_indirect_scissor/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_indirect_scissor/shaders/vert_shader.vert +++ b/ray_tracing_indirect_scissor/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_indirect_scissor/shaders/wavefront.glsl b/ray_tracing_indirect_scissor/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_indirect_scissor/shaders/wavefront.glsl +++ b/ray_tracing_indirect_scissor/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_instances/CMakeLists.txt b/ray_tracing_instances/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_instances/CMakeLists.txt +++ b/ray_tracing_instances/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_instances/README.md b/ray_tracing_instances/README.md index c37aa8e..7afb84f 100644 --- a/ray_tracing_instances/README.md +++ b/ray_tracing_instances/README.md @@ -41,9 +41,7 @@ Then replace the calls to `helloVk.loadModel` in `main()` by for(int n = 0; n < 2000; ++n) { - HelloVulkan::ObjInstance inst; - inst.objIndex = n % 2; - inst.txtOffset = 0; + HelloVulkan::ObjInstance inst = helloVk.m_objInstance[n % 2];; float scale = fabsf(disn(gen)); nvmath::mat4f mat = nvmath::translation_mat4(nvmath::vec3f{dis(gen), 2.0f + dis(gen), dis(gen)}); diff --git a/ray_tracing_instances/hello_vulkan.cpp b/ray_tracing_instances/hello_vulkan.cpp index 8ae104a..b8d5041 100644 --- a/ray_tracing_instances/hello_vulkan.cpp +++ b/ray_tracing_instances/hello_vulkan.cpp @@ -37,6 +37,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -115,26 +116,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -152,25 +142,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -178,7 +152,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -236,36 +210,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -628,11 +608,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_instances/hello_vulkan.h b/ray_tracing_instances/hello_vulkan.h index 53bf2da..ec89f98 100644 --- a/ray_tracing_instances/hello_vulkan.h +++ b/ray_tracing_instances/hello_vulkan.h @@ -1,3 +1,4 @@ + /* * Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved. * @@ -82,10 +83,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -110,9 +115,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene // Allocator for buffer, images, acceleration structures Allocator m_alloc; diff --git a/ray_tracing_instances/main.cpp b/ray_tracing_instances/main.cpp index c0c011d..a193839 100644 --- a/ray_tracing_instances/main.cpp +++ b/ray_tracing_instances/main.cpp @@ -137,34 +137,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing_instances/shaders/frag_shader.frag b/ray_tracing_instances/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_instances/shaders/frag_shader.frag +++ b/ray_tracing_instances/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_instances/shaders/passthrough.vert b/ray_tracing_instances/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_instances/shaders/passthrough.vert +++ b/ray_tracing_instances/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_instances/shaders/post.frag b/ray_tracing_instances/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_instances/shaders/post.frag +++ b/ray_tracing_instances/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_instances/shaders/raytrace.rchit b/ray_tracing_instances/shaders/raytrace.rchit index cc6be5f..2b523a7 100644 --- a/ray_tracing_instances/shaders/raytrace.rchit +++ b/ray_tracing_instances/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_instances/shaders/raytrace.rgen b/ray_tracing_instances/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing_instances/shaders/raytrace.rgen +++ b/ray_tracing_instances/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_instances/shaders/raytrace.rmiss b/ray_tracing_instances/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_instances/shaders/raytrace.rmiss +++ b/ray_tracing_instances/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_instances/shaders/raytraceShadow.rmiss b/ray_tracing_instances/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_instances/shaders/raytraceShadow.rmiss +++ b/ray_tracing_instances/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_instances/shaders/vert_shader.vert b/ray_tracing_instances/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_instances/shaders/vert_shader.vert +++ b/ray_tracing_instances/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_instances/shaders/wavefront.glsl b/ray_tracing_instances/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_instances/shaders/wavefront.glsl +++ b/ray_tracing_instances/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_intersection/CMakeLists.txt b/ray_tracing_intersection/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_intersection/CMakeLists.txt +++ b/ray_tracing_intersection/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_intersection/README.md b/ray_tracing_intersection/README.md index 5a27e68..82218ea 100644 --- a/ray_tracing_intersection/README.md +++ b/ray_tracing_intersection/README.md @@ -130,6 +130,13 @@ void HelloVulkan::createSpheres(uint32_t nbSpheres) m_debug.setObjectName(m_spheresAabbBuffer.buffer, "spheresAabb"); m_debug.setObjectName(m_spheresMatColorBuffer.buffer, "spheresMat"); m_debug.setObjectName(m_spheresMatIndexBuffer.buffer, "spheresMatIdx"); + + // Adding an extra instance to get access to the material buffers + ObjInstance instance{}; + instance.objIndex = static_cast(m_objModel.size()); + instance.materials = nvvk::getBufferDeviceAddress(m_device, m_spheresMatColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, m_spheresMatIndexBuffer.buffer); + m_objInstance.emplace_back(instance); } ~~~~ @@ -152,9 +159,7 @@ What is changing compare to triangle primitive is the Aabb data (see Aabb struct // nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::sphereToVkGeometryKHR() { - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_spheresAabbBuffer.buffer; - VkDeviceAddress dataAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress dataAddress = nvvk::getBufferDeviceAddress(m_device, m_spheresAabbBuffer.buffer); VkAccelerationStructureGeometryAabbsDataKHR aabbs{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR}; aabbs.data.deviceAddress = dataAddress; @@ -233,14 +238,26 @@ Similarly in `createTopLevelAS()`, the top level acceleration structure will nee The hitGroupId will be set to 1 instead of 0. We need to add a new hit group for the implicit primitives, since we will need to compute attributes like the normal, since they are not provide like with triangle primitives. -Just before building the TLAS, we need to add the following +Because we have added an extra instance when creating the implicit objects, there is one element less to loop for. Therefore the loop will now look like this: + +~~~~ C++ + auto nbObj = static_cast(m_objInstance.size()) - 1; + tlas.reserve(nbObj); + for(uint32_t i = 0; i < nbObj; i++) + { + ... + } +~~~~ + + +Just after the loop and before building the TLAS, we need to add the following. ~~~~ C++ // Add the blas containing all spheres { nvvk::RaytracingBuilder::Instance rayInst; - rayInst.transform = m_objInstance[0].transform; // Position of the instance - rayInst.instanceCustomId = static_cast(tlas.size()); // gl_InstanceCustomIndexEXT + rayInst.transform = m_objInstance[0].transform; // Position of the instance + rayInst.instanceCustomId = nbObj; // gl_InstanceCustomIndexEXT rayInst.blasId = static_cast(m_objModel.size()); rayInst.hitGroupId = 1; // We will use the same hit group for all objects rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; @@ -248,50 +265,26 @@ Just before building the TLAS, we need to add the following } ~~~~ +The `instanceCustomId` will give us the last element of m_objInstance, and in the shader will will be able to access the materials +assigned to the implicit objects. + ## Descriptors -To access the newly created buffers holding all the spheres and materials, some changes are required to the descriptors. - -In function `createDescriptorSetLayout()`, the addition of the material and material index need to be instructed. +To access the newly created buffers holding all the spheres, some changes are required to the descriptors. +The descriptor need to add an binding to the implicit object buffer. ~~~~ C++ - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj+1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials Index (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj +1, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); -~~~~ - -And the new buffer holding the spheres - -~~~~ C++ - // Storing spheres (binding = 7) - m_descSetLayoutBind.addBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Storing spheres (binding = 3) + m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR); ~~~~ The function `updateDescriptorSet()` which is writing the values of the buffer need also to be modified. - -At the end of the loop on all models, lets add the new material and material index. - -~~~~ C++ - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - dbiMat.push_back({m_spheresMatColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m_spheresMatIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); -~~~~ - -Then write the buffer for the spheres +Then write the buffer for the spheres after the array of textures ~~~~ C++ VkDescriptorBufferInfo dbiSpheres{m_spheresBuffer.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &dbiSpheres)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &dbiSpheres)); ~~~~ ## Intersection Shader @@ -365,6 +358,8 @@ We first declare the extensions and include common files. #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "raycommon.glsl" #include "wavefront.glsl" ~~~~ @@ -373,11 +368,10 @@ We first declare the extensions and include common files. The following is the topology of all spheres, which we will be able to retrieve using `gl_PrimitiveID`. ~~~~ C++ -layout(binding = 7, set = 1, scalar) buffer allSpheres_ +layout(binding = 3, set = 1, scalar) buffer allSpheres_ { - Sphere i[]; -} -allSpheres; + Sphere allSpheres[]; +}; ~~~~ We will implement two intersetion method against the incoming ray. diff --git a/ray_tracing_intersection/hello_vulkan.cpp b/ray_tracing_intersection/hello_vulkan.cpp index e7828e7..a9e5b1e 100644 --- a/ray_tracing_intersection/hello_vulkan.cpp +++ b/ray_tracing_intersection/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" #include extern std::vector defaultSearchPaths; @@ -114,28 +115,17 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj + 1, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials Index (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj + 1, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing spheres (binding = 7) - m_descSetLayoutBind.addBinding(7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + // Storing spheres (binding = 3) + m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR); @@ -154,31 +144,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - dbiMat.push_back({m_spheresMatColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m_spheresMatIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); - - VkDescriptorBufferInfo dbiSpheres{m_spheresBuffer.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &dbiSpheres)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -186,7 +154,10 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); + + VkDescriptorBufferInfo dbiSpheres{m_spheresBuffer.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &dbiSpheres)); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -244,36 +215,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -640,11 +617,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -686,9 +660,7 @@ auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) // nvvk::RaytracingBuilderKHR::BlasInput HelloVulkan::sphereToVkGeometryKHR() { - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_spheresAabbBuffer.buffer; - VkDeviceAddress dataAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress dataAddress = nvvk::getBufferDeviceAddress(m_device, m_spheresAabbBuffer.buffer); VkAccelerationStructureGeometryAabbsDataKHR aabbs{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR}; aabbs.data.deviceAddress = dataAddress; @@ -765,8 +737,10 @@ void HelloVulkan::createSpheres(uint32_t nbSpheres) auto cmdBuf = genCmdBuf.createCommandBuffer(); m_spheresBuffer = m_alloc.createBuffer(cmdBuf, m_spheres, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); m_spheresAabbBuffer = m_alloc.createBuffer(cmdBuf, aabbs, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); - m_spheresMatIndexBuffer = m_alloc.createBuffer(cmdBuf, matIdx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - m_spheresMatColorBuffer = m_alloc.createBuffer(cmdBuf, materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + m_spheresMatIndexBuffer = + m_alloc.createBuffer(cmdBuf, matIdx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + m_spheresMatColorBuffer = + m_alloc.createBuffer(cmdBuf, materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); genCmdBuf.submitAndWait(cmdBuf); // Debug information @@ -774,6 +748,14 @@ void HelloVulkan::createSpheres(uint32_t nbSpheres) m_debug.setObjectName(m_spheresAabbBuffer.buffer, "spheresAabb"); m_debug.setObjectName(m_spheresMatColorBuffer.buffer, "spheresMat"); m_debug.setObjectName(m_spheresMatIndexBuffer.buffer, "spheresMatIdx"); + + + // Adding an extra instance to get access to the material buffers + ObjInstance instance{}; + instance.objIndex = static_cast(m_objModel.size()); + instance.materials = nvvk::getBufferDeviceAddress(m_device, m_spheresMatColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, m_spheresMatIndexBuffer.buffer); + m_objInstance.emplace_back(instance); } void HelloVulkan::createBottomLevelAS() @@ -801,8 +783,10 @@ void HelloVulkan::createBottomLevelAS() void HelloVulkan::createTopLevelAS() { std::vector tlas; - tlas.reserve(m_objInstance.size()); - for(uint32_t i = 0; i < static_cast(m_objInstance.size()); i++) + + auto nbObj = static_cast(m_objInstance.size()) - 1; + tlas.reserve(nbObj); + for(uint32_t i = 0; i < nbObj; i++) { nvvk::RaytracingBuilderKHR::Instance rayInst; rayInst.transform = m_objInstance[i].transform; // Position of the instance @@ -816,8 +800,8 @@ void HelloVulkan::createTopLevelAS() // Add the blas containing all spheres { nvvk::RaytracingBuilderKHR::Instance rayInst; - rayInst.transform = m_objInstance[0].transform; // Position of the instance - rayInst.instanceCustomId = static_cast(tlas.size()); // gl_InstanceCustomIndexEXT + rayInst.transform = m_objInstance[0].transform; // Position of the instance + rayInst.instanceCustomId = nbObj; // gl_InstanceCustomIndexEXT rayInst.blasId = static_cast(m_objModel.size()); rayInst.hitGroupId = 1; // We will use the same hit group for all objects rayInst.flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR; @@ -1064,9 +1048,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment); uint32_t groupStride = groupSize; - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_rtSBTBuffer.buffer; - VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer); using Stride = VkStridedDeviceAddressRegionKHR; std::array strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen diff --git a/ray_tracing_intersection/hello_vulkan.h b/ray_tracing_intersection/hello_vulkan.h index 34a9160..d1f1f95 100644 --- a/ray_tracing_intersection/hello_vulkan.h +++ b/ray_tracing_intersection/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_intersection/main.cpp b/ray_tracing_intersection/main.cpp index 70b49b0..688eb2e 100644 --- a/ray_tracing_intersection/main.cpp +++ b/ray_tracing_intersection/main.cpp @@ -110,34 +110,28 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline + + contextInfo.addDeviceExtension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing_intersection/shaders/frag_shader.frag b/ray_tracing_intersection/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_intersection/shaders/frag_shader.frag +++ b/ray_tracing_intersection/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_intersection/shaders/passthrough.vert b/ray_tracing_intersection/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_intersection/shaders/passthrough.vert +++ b/ray_tracing_intersection/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_intersection/shaders/post.frag b/ray_tracing_intersection/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_intersection/shaders/post.frag +++ b/ray_tracing_intersection/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_intersection/shaders/raytrace.rchit b/ray_tracing_intersection/shaders/raytrace.rchit index cc6be5f..2b523a7 100644 --- a/ray_tracing_intersection/shaders/raytrace.rchit +++ b/ray_tracing_intersection/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_intersection/shaders/raytrace.rgen b/ray_tracing_intersection/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing_intersection/shaders/raytrace.rgen +++ b/ray_tracing_intersection/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_intersection/shaders/raytrace.rint b/ray_tracing_intersection/shaders/raytrace.rint index 0d93303..f7c530d 100644 --- a/ray_tracing_intersection/shaders/raytrace.rint +++ b/ray_tracing_intersection/shaders/raytrace.rint @@ -16,17 +16,19 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #include "raycommon.glsl" #include "wavefront.glsl" -layout(binding = 7, set = 1, scalar) buffer allSpheres_ +layout(binding = 3, set = 1, scalar) buffer allSpheres_ { Sphere allSpheres[]; }; diff --git a/ray_tracing_intersection/shaders/raytrace.rmiss b/ray_tracing_intersection/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_intersection/shaders/raytrace.rmiss +++ b/ray_tracing_intersection/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_intersection/shaders/raytrace2.rchit b/ray_tracing_intersection/shaders/raytrace2.rchit index 0753ed9..fdbdd1c 100644 --- a/ray_tracing_intersection/shaders/raytrace2.rchit +++ b/ray_tracing_intersection/shaders/raytrace2.rchit @@ -16,12 +16,15 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +34,15 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 7, set = 1, scalar) buffer allSpheres_ {Sphere i[];} allSpheres; +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; +layout(binding = 3, set = 1, scalar) buffer allSpheres_ {Sphere i[];} allSpheres; // clang-format on @@ -56,6 +58,11 @@ pushC; void main() { + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + vec3 worldPos = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; Sphere instance = allSpheres.i[gl_PrimitiveID]; @@ -68,9 +75,8 @@ void main() { vec3 absN = abs(normal); float maxC = max(max(absN.x, absN.y), absN.z); - normal = (maxC == absN.x) ? - vec3(sign(normal.x), 0, 0) : - (maxC == absN.y) ? vec3(0, sign(normal.y), 0) : vec3(0, 0, sign(normal.z)); + normal = (maxC == absN.x) ? vec3(sign(normal.x), 0, 0) : + (maxC == absN.y) ? vec3(0, sign(normal.y), 0) : vec3(0, 0, sign(normal.z)); } // Vector toward the light @@ -91,8 +97,8 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(gl_InstanceID)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceID)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); @@ -106,9 +112,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_intersection/shaders/raytraceShadow.rmiss b/ray_tracing_intersection/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_intersection/shaders/raytraceShadow.rmiss +++ b/ray_tracing_intersection/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_intersection/shaders/vert_shader.vert b/ray_tracing_intersection/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_intersection/shaders/vert_shader.vert +++ b/ray_tracing_intersection/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_intersection/shaders/wavefront.glsl b/ray_tracing_intersection/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_intersection/shaders/wavefront.glsl +++ b/ray_tracing_intersection/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_jitter_cam/CMakeLists.txt b/ray_tracing_jitter_cam/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_jitter_cam/CMakeLists.txt +++ b/ray_tracing_jitter_cam/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_jitter_cam/hello_vulkan.cpp b/ray_tracing_jitter_cam/hello_vulkan.cpp index e38addc..ab1d1d2 100644 --- a/ray_tracing_jitter_cam/hello_vulkan.cpp +++ b/ray_tracing_jitter_cam/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -626,11 +606,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -933,9 +910,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment); uint32_t groupStride = groupSize; - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_rtSBTBuffer.buffer; - VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer); using Stride = VkStridedDeviceAddressRegionKHR; std::array strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen diff --git a/ray_tracing_jitter_cam/hello_vulkan.h b/ray_tracing_jitter_cam/hello_vulkan.h index 1696a6d..276f1d9 100644 --- a/ray_tracing_jitter_cam/hello_vulkan.h +++ b/ray_tracing_jitter_cam/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_jitter_cam/main.cpp b/ray_tracing_jitter_cam/main.cpp index 24529fb..47c6dd4 100644 --- a/ray_tracing_jitter_cam/main.cpp +++ b/ray_tracing_jitter_cam/main.cpp @@ -116,34 +116,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -174,7 +166,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true)); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_jitter_cam/shaders/frag_shader.frag b/ray_tracing_jitter_cam/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_jitter_cam/shaders/frag_shader.frag +++ b/ray_tracing_jitter_cam/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_jitter_cam/shaders/passthrough.vert b/ray_tracing_jitter_cam/shaders/passthrough.vert index 22519d7..2f90989 100644 --- a/ray_tracing_jitter_cam/shaders/passthrough.vert +++ b/ray_tracing_jitter_cam/shaders/passthrough.vert @@ -16,10 +16,10 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -30,6 +30,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_jitter_cam/shaders/post.frag b/ray_tracing_jitter_cam/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_jitter_cam/shaders/post.frag +++ b/ray_tracing_jitter_cam/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_jitter_cam/shaders/raytrace.rchit b/ray_tracing_jitter_cam/shaders/raytrace.rchit index cc6be5f..2b523a7 100644 --- a/ray_tracing_jitter_cam/shaders/raytrace.rchit +++ b/ray_tracing_jitter_cam/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_jitter_cam/shaders/raytrace.rgen b/ray_tracing_jitter_cam/shaders/raytrace.rgen index 8d70d6e..740edca 100644 --- a/ray_tracing_jitter_cam/shaders/raytrace.rgen +++ b/ray_tracing_jitter_cam/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_jitter_cam/shaders/raytrace.rmiss b/ray_tracing_jitter_cam/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_jitter_cam/shaders/raytrace.rmiss +++ b/ray_tracing_jitter_cam/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_jitter_cam/shaders/raytraceShadow.rmiss b/ray_tracing_jitter_cam/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_jitter_cam/shaders/raytraceShadow.rmiss +++ b/ray_tracing_jitter_cam/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_jitter_cam/shaders/vert_shader.vert b/ray_tracing_jitter_cam/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_jitter_cam/shaders/vert_shader.vert +++ b/ray_tracing_jitter_cam/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_jitter_cam/shaders/wavefront.glsl b/ray_tracing_jitter_cam/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_jitter_cam/shaders/wavefront.glsl +++ b/ray_tracing_jitter_cam/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_manyhits/CMakeLists.txt b/ray_tracing_manyhits/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_manyhits/CMakeLists.txt +++ b/ray_tracing_manyhits/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_manyhits/README.md b/ray_tracing_manyhits/README.md index f0d90d5..5965fc8 100644 --- a/ray_tracing_manyhits/README.md +++ b/ray_tracing_manyhits/README.md @@ -107,13 +107,17 @@ uint32_t hitgroup{0}; // Hit group of the instance This change also needs to be reflected in the `sceneDesc` structure in `wavefront.glsl`: ~~~~ C++ -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; - int hitGroup; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; + int hitGroup; }; ~~~~ diff --git a/ray_tracing_manyhits/hello_vulkan.cpp b/ray_tracing_manyhits/hello_vulkan.cpp index f29b3ec..849432d 100644 --- a/ray_tracing_manyhits/hello_vulkan.cpp +++ b/ray_tracing_manyhits/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -628,11 +608,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_manyhits/hello_vulkan.h b/ray_tracing_manyhits/hello_vulkan.h index ec222a4..cb0d173 100644 --- a/ray_tracing_manyhits/hello_vulkan.h +++ b/ray_tracing_manyhits/hello_vulkan.h @@ -67,11 +67,15 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose - uint32_t hitgroup{0}; // Hit group of the instance + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; + uint32_t hitgroup{0}; // Hit group of the instance }; // Information pushed at each draw call @@ -96,9 +100,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures @@ -147,6 +152,7 @@ public: VkPipelineLayout m_rtPipelineLayout; VkPipeline m_rtPipeline; nvvk::Buffer m_rtSBTBuffer; + struct RtPushConstant { nvmath::vec4f clearColor; diff --git a/ray_tracing_manyhits/main.cpp b/ray_tracing_manyhits/main.cpp index 75aeace..115e620 100644 --- a/ray_tracing_manyhits/main.cpp +++ b/ray_tracing_manyhits/main.cpp @@ -109,34 +109,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -181,7 +173,6 @@ int main(int argc, char** argv) helloVk.m_objInstance[0].hitgroup = 1; // Wuson 0 helloVk.m_objInstance[1].hitgroup = 2; // Wuson 1 - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_manyhits/shaders/frag_shader.frag b/ray_tracing_manyhits/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_manyhits/shaders/frag_shader.frag +++ b/ray_tracing_manyhits/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_manyhits/shaders/passthrough.vert b/ray_tracing_manyhits/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_manyhits/shaders/passthrough.vert +++ b/ray_tracing_manyhits/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_manyhits/shaders/post.frag b/ray_tracing_manyhits/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_manyhits/shaders/post.frag +++ b/ray_tracing_manyhits/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_manyhits/shaders/raytrace.rchit b/ray_tracing_manyhits/shaders/raytrace.rchit index cc6be5f..2b523a7 100644 --- a/ray_tracing_manyhits/shaders/raytrace.rchit +++ b/ray_tracing_manyhits/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_manyhits/shaders/raytrace.rgen b/ray_tracing_manyhits/shaders/raytrace.rgen index 9531dcb..ebae40a 100644 --- a/ray_tracing_manyhits/shaders/raytrace.rgen +++ b/ray_tracing_manyhits/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_manyhits/shaders/raytrace.rmiss b/ray_tracing_manyhits/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_manyhits/shaders/raytrace.rmiss +++ b/ray_tracing_manyhits/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_manyhits/shaders/raytrace2.rchit b/ray_tracing_manyhits/shaders/raytrace2.rchit index 8660519..2e61de5 100644 --- a/ray_tracing_manyhits/shaders/raytrace2.rchit +++ b/ray_tracing_manyhits/shaders/raytrace2.rchit @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_manyhits/shaders/raytraceShadow.rmiss b/ray_tracing_manyhits/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_manyhits/shaders/raytraceShadow.rmiss +++ b/ray_tracing_manyhits/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_manyhits/shaders/vert_shader.vert b/ray_tracing_manyhits/shaders/vert_shader.vert index 2aa1f82..c79820d 100644 --- a/ray_tracing_manyhits/shaders/vert_shader.vert +++ b/ray_tracing_manyhits/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -33,7 +35,6 @@ layout(binding = 0) uniform UniformBufferObject mat4 view; mat4 proj; mat4 viewI; - mat4 projInverse; } ubo; @@ -66,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_manyhits/shaders/wavefront.glsl b/ray_tracing_manyhits/shaders/wavefront.glsl index 7118517..2e446da 100644 --- a/ray_tracing_manyhits/shaders/wavefront.glsl +++ b/ray_tracing_manyhits/shaders/wavefront.glsl @@ -39,13 +39,17 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; - int hitGroup; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; + int hitGroup; }; diff --git a/ray_tracing_rayquery/CMakeLists.txt b/ray_tracing_rayquery/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_rayquery/CMakeLists.txt +++ b/ray_tracing_rayquery/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_rayquery/README.md b/ray_tracing_rayquery/README.md index d727b1e..c3014ac 100644 --- a/ray_tracing_rayquery/README.md +++ b/ray_tracing_rayquery/README.md @@ -50,9 +50,8 @@ You can safely remove all raytrace.* shaders In `HelloVulkan::createDescriptorSetLayout`, add the acceleration structure to the description layout to have access to the acceleration structure directly in the fragment shader. ~~~~ C++ -// The top level acceleration structure -m_descSetLayoutBind.emplace_back( // - vkDS(7, vkDT::eAccelerationStructureKHR, 1, vkSS::eFragment)); + // The top level acceleration structure + m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT); ~~~~ In `HelloVulkan::updateDescriptorSet`, write the value to the descriptor set. @@ -62,7 +61,7 @@ In `HelloVulkan::updateDescriptorSet`, write the value to the descriptor set. VkWriteDescriptorSetAccelerationStructureKHR descASInfo{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR}; descASInfo.accelerationStructureCount = 1; descASInfo.pAccelerationStructures = &tlas; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &descASInfo)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &descASInfo)); ~~~~ @@ -86,7 +85,7 @@ Then we need to add new extensions We have to add the layout to access the top level acceleration structure. ~~~~ C++ -layout(binding = 7, set = 0) uniform accelerationStructureEXT topLevelAS; +layout(binding = 3, set = 0) uniform accelerationStructureEXT topLevelAS; ~~~~ diff --git a/ray_tracing_rayquery/hello_vulkan.cpp b/ray_tracing_rayquery/hello_vulkan.cpp index a86d748..aa362e3 100644 --- a/ray_tracing_rayquery/hello_vulkan.cpp +++ b/ray_tracing_rayquery/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,24 +114,18 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) - m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_FRAGMENT_BIT); + m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); + // The top level acceleration structure - m_descSetLayoutBind.addBinding(7, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); m_descPool = m_descSetLayoutBind.createPool(m_device, 1); @@ -147,25 +142,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -173,13 +152,13 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); VkAccelerationStructureKHR tlas = m_rtBuilder.getAccelerationStructure(); VkWriteDescriptorSetAccelerationStructureKHR descASInfo{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR}; descASInfo.accelerationStructureCount = 1; descASInfo.pAccelerationStructures = &tlas; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 7, &descASInfo)); + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 3, &descASInfo)); // Writing the information @@ -238,36 +217,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -622,11 +607,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_rayquery/hello_vulkan.h b/ray_tracing_rayquery/hello_vulkan.h index 3642e7d..367f0e9 100644 --- a/ray_tracing_rayquery/hello_vulkan.h +++ b/ray_tracing_rayquery/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_rayquery/main.cpp b/ray_tracing_rayquery/main.cpp index ee561f8..411451d 100644 --- a/ray_tracing_rayquery/main.cpp +++ b/ray_tracing_rayquery/main.cpp @@ -109,35 +109,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR}; - ; contextInfo.addDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME, false, &rayQueryFeatures); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; diff --git a/ray_tracing_rayquery/shaders/frag_shader.frag b/ray_tracing_rayquery/shaders/frag_shader.frag index a847ec3..5ab486b 100644 --- a/ray_tracing_rayquery/shaders/frag_shader.frag +++ b/ray_tracing_rayquery/shaders/frag_shader.frag @@ -16,12 +16,14 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require #extension GL_EXT_ray_tracing : enable #extension GL_EXT_ray_query : enable @@ -39,31 +41,34 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; -layout(binding = 7, set = 0) uniform accelerationStructureEXT topLevelAS; + +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; +layout(binding = 3) uniform accelerationStructureEXT topLevelAS; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -90,7 +95,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; @@ -111,8 +116,7 @@ void main() // Initializes a ray query object but does not start traversal rayQueryEXT rayQuery; - rayQueryInitializeEXT(rayQuery, topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, tMin, - direction, tMax); + rayQueryInitializeEXT(rayQuery, topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, tMin, direction, tMax); // Start traversal: return false if traversal is complete while(rayQueryProceedEXT(rayQuery)) diff --git a/ray_tracing_rayquery/shaders/passthrough.vert b/ray_tracing_rayquery/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_rayquery/shaders/passthrough.vert +++ b/ray_tracing_rayquery/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_rayquery/shaders/post.frag b/ray_tracing_rayquery/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_rayquery/shaders/post.frag +++ b/ray_tracing_rayquery/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_rayquery/shaders/vert_shader.vert b/ray_tracing_rayquery/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_rayquery/shaders/vert_shader.vert +++ b/ray_tracing_rayquery/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_rayquery/shaders/wavefront.glsl b/ray_tracing_rayquery/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_rayquery/shaders/wavefront.glsl +++ b/ray_tracing_rayquery/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_reflections/CMakeLists.txt b/ray_tracing_reflections/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_reflections/CMakeLists.txt +++ b/ray_tracing_reflections/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_reflections/hello_vulkan.cpp b/ray_tracing_reflections/hello_vulkan.cpp index 6511c67..9929561 100644 --- a/ray_tracing_reflections/hello_vulkan.cpp +++ b/ray_tracing_reflections/hello_vulkan.cpp @@ -35,6 +35,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -113,26 +114,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -150,25 +140,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -176,7 +150,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -234,36 +208,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -625,11 +605,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; @@ -922,9 +899,7 @@ void HelloVulkan::raytrace(const VkCommandBuffer& cmdBuf, const nvmath::vec4f& c uint32_t groupSize = nvh::align_up(m_rtProperties.shaderGroupHandleSize, m_rtProperties.shaderGroupBaseAlignment); uint32_t groupStride = groupSize; - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = m_rtSBTBuffer.buffer; - VkDeviceAddress sbtAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress sbtAddress = nvvk::getBufferDeviceAddress(m_device, m_rtSBTBuffer.buffer); using Stride = VkStridedDeviceAddressRegionKHR; std::array strideAddresses{Stride{sbtAddress + 0u * groupSize, groupStride, groupSize * 1}, // raygen diff --git a/ray_tracing_reflections/hello_vulkan.h b/ray_tracing_reflections/hello_vulkan.h index c43554e..9642631 100644 --- a/ray_tracing_reflections/hello_vulkan.h +++ b/ray_tracing_reflections/hello_vulkan.h @@ -65,10 +65,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -93,9 +97,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_reflections/main.cpp b/ray_tracing_reflections/main.cpp index 486839b..43b3a7f 100644 --- a/ray_tracing_reflections/main.cpp +++ b/ray_tracing_reflections/main.cpp @@ -109,34 +109,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers - nvvk::ContextCreateInfo contextInfo(true); - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + nvvk::ContextCreateInfo contextInfo; + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -172,7 +164,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true), nvmath::translation_mat4(nvmath::vec3f(0, -1, 0))); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_reflections/shaders/frag_shader.frag b/ray_tracing_reflections/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_reflections/shaders/frag_shader.frag +++ b/ray_tracing_reflections/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_reflections/shaders/passthrough.vert b/ray_tracing_reflections/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_reflections/shaders/passthrough.vert +++ b/ray_tracing_reflections/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_reflections/shaders/post.frag b/ray_tracing_reflections/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_reflections/shaders/post.frag +++ b/ray_tracing_reflections/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_reflections/shaders/raytrace.rchit b/ray_tracing_reflections/shaders/raytrace.rchit index c1e846a..db13b0b 100644 --- a/ray_tracing_reflections/shaders/raytrace.rchit +++ b/ray_tracing_reflections/shaders/raytrace.rchit @@ -16,12 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,16 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; - -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; // clang-format on layout(push_constant) uniform Constants @@ -55,30 +56,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -98,17 +102,16 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = - v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } @@ -122,9 +125,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_reflections/shaders/raytrace.rgen b/ray_tracing_reflections/shaders/raytrace.rgen index e15b768..e715e86 100644 --- a/ray_tracing_reflections/shaders/raytrace.rgen +++ b/ray_tracing_reflections/shaders/raytrace.rgen @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_reflections/shaders/raytrace.rmiss b/ray_tracing_reflections/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_reflections/shaders/raytrace.rmiss +++ b/ray_tracing_reflections/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_reflections/shaders/raytraceShadow.rmiss b/ray_tracing_reflections/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_reflections/shaders/raytraceShadow.rmiss +++ b/ray_tracing_reflections/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_reflections/shaders/vert_shader.vert b/ray_tracing_reflections/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_reflections/shaders/vert_shader.vert +++ b/ray_tracing_reflections/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_reflections/shaders/wavefront.glsl b/ray_tracing_reflections/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_reflections/shaders/wavefront.glsl +++ b/ray_tracing_reflections/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; }; diff --git a/ray_tracing_specialization/CMakeLists.txt b/ray_tracing_specialization/CMakeLists.txt index 8587db8..1bf130c 100644 --- a/ray_tracing_specialization/CMakeLists.txt +++ b/ray_tracing_specialization/CMakeLists.txt @@ -35,6 +35,7 @@ compile_glsl_directory( SRC "${CMAKE_CURRENT_SOURCE_DIR}/shaders" DST "${CMAKE_CURRENT_SOURCE_DIR}/spv" VULKAN_TARGET "vulkan1.2" + DEPENDENCY ${VULKAN_BUILD_DEPENDENCIES} ) @@ -52,7 +53,8 @@ target_sources(${PROJNAME} PUBLIC ${GLSL_SOURCES} ${GLSL_HEADERS}) source_group("Common" FILES ${COMMON_SOURCE_FILES} ${PACKAGE_SOURCE_FILES}) source_group("Sources" FILES ${SOURCE_FILES}) source_group("Headers" FILES ${HEADER_FILES}) -source_group("Shader_Files" FILES ${GLSL_SOURCES} ${GLSL_HEADERS}) +source_group("Shader Sources" FILES ${GLSL_SOURCES}) +source_group("Shader Headers" FILES ${GLSL_HEADERS}) #-------------------------------------------------------------------------------------------------- diff --git a/ray_tracing_specialization/hello_vulkan.cpp b/ray_tracing_specialization/hello_vulkan.cpp index 7e14367..01a9cae 100644 --- a/ray_tracing_specialization/hello_vulkan.cpp +++ b/ray_tracing_specialization/hello_vulkan.cpp @@ -36,6 +36,7 @@ #include "nvvk/pipeline_vk.hpp" #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#include "nvvk/buffers_vk.hpp" extern std::vector defaultSearchPaths; @@ -114,26 +115,15 @@ void HelloVulkan::updateUniformBuffer(const VkCommandBuffer& cmdBuf) void HelloVulkan::createDescriptorSetLayout() { auto nbTxt = static_cast(m_textures.size()); - auto nbObj = static_cast(m_objModel.size()); // Camera matrices (binding = 0) m_descSetLayoutBind.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_RAYGEN_BIT_KHR); - // Materials (binding = 1) - m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, + // Scene description (binding = 1) + m_descSetLayoutBind.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Scene description (binding = 2) - m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Textures (binding = 3) - m_descSetLayoutBind.addBinding(3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, + // Textures (binding = 2) + m_descSetLayoutBind.addBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nbTxt, VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Materials (binding = 4) - m_descSetLayoutBind.addBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, - VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing vertices (binding = 5) - m_descSetLayoutBind.addBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); - // Storing indices (binding = 6) - m_descSetLayoutBind.addBinding(6, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, nbObj, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR); m_descSetLayout = m_descSetLayoutBind.createLayout(m_device); @@ -151,25 +141,9 @@ void HelloVulkan::updateDescriptorSet() // Camera matrices and scene description VkDescriptorBufferInfo dbiUnif{m_cameraMat.buffer, 0, VK_WHOLE_SIZE}; writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 0, &dbiUnif)); - VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; - writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 2, &dbiSceneDesc)); - // All material buffers, 1 buffer per OBJ - std::vector dbiMat; - std::vector dbiMatIdx; - std::vector dbiVert; - std::vector dbiIdx; - for(auto& m : m_objModel) - { - dbiMat.push_back({m.matColorBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiMatIdx.push_back({m.matIndexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiVert.push_back({m.vertexBuffer.buffer, 0, VK_WHOLE_SIZE}); - dbiIdx.push_back({m.indexBuffer.buffer, 0, VK_WHOLE_SIZE}); - } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 1, dbiMat.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 4, dbiMatIdx.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 5, dbiVert.data())); - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 6, dbiIdx.data())); + VkDescriptorBufferInfo dbiSceneDesc{m_sceneDesc.buffer, 0, VK_WHOLE_SIZE}; + writes.emplace_back(m_descSetLayoutBind.makeWrite(m_descSet, 1, &dbiSceneDesc)); // All texture samplers std::vector diit; @@ -177,7 +151,7 @@ void HelloVulkan::updateDescriptorSet() { diit.emplace_back(texture.descriptor); } - writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 3, diit.data())); + writes.emplace_back(m_descSetLayoutBind.makeWriteArray(m_descSet, 2, diit.data())); // Writing the information vkUpdateDescriptorSets(m_device, static_cast(writes.size()), writes.data(), 0, nullptr); @@ -235,36 +209,42 @@ void HelloVulkan::loadModel(const std::string& filename, nvmath::mat4f transform m.specular = nvmath::pow(m.specular, 2.2f); } - ObjInstance instance; - instance.objIndex = static_cast(m_objModel.size()); - instance.transform = transform; - instance.transformIT = nvmath::transpose(nvmath::invert(transform)); - instance.txtOffset = static_cast(m_textures.size()); - ObjModel model; model.nbIndices = static_cast(loader.m_indices.size()); model.nbVertices = static_cast(loader.m_vertices.size()); // Create the buffers on Device and copy vertices, indices and materials nvvk::CommandPool cmdBufGet(m_device, m_graphicsQueueIndex); - VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); - VkBufferUsageFlags rtUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR; - model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rtUsage); - model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rtUsage); - model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); - model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); + VkCommandBuffer cmdBuf = cmdBufGet.createCommandBuffer(); + VkBufferUsageFlags flag = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + VkBufferUsageFlags rayTracingFlags = // used also for building acceleration structures + flag | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + model.vertexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_vertices, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | rayTracingFlags); + model.indexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_indices, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | rayTracingFlags); + model.matColorBuffer = m_alloc.createBuffer(cmdBuf, loader.m_materials, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); + model.matIndexBuffer = m_alloc.createBuffer(cmdBuf, loader.m_matIndx, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | flag); // Creates all textures found + uint32_t txtOffset = static_cast(m_textures.size()); createTextureImages(cmdBuf, loader.m_textures); cmdBufGet.submitAndWait(cmdBuf); m_alloc.finalizeAndReleaseStaging(); - std::string objNb = std::to_string(instance.objIndex); + std::string objNb = std::to_string(m_objModel.size()); m_debug.setObjectName(model.vertexBuffer.buffer, (std::string("vertex_" + objNb).c_str())); m_debug.setObjectName(model.indexBuffer.buffer, (std::string("index_" + objNb).c_str())); m_debug.setObjectName(model.matColorBuffer.buffer, (std::string("mat_" + objNb).c_str())); m_debug.setObjectName(model.matIndexBuffer.buffer, (std::string("matIdx_" + objNb).c_str())); + ObjInstance instance; + instance.objIndex = static_cast(m_objModel.size()); + instance.transform = transform; + instance.transformIT = nvmath::transpose(nvmath::invert(transform)); + instance.txtOffset = txtOffset; + instance.vertices = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + instance.indices = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); + instance.materials = nvvk::getBufferDeviceAddress(m_device, model.matColorBuffer.buffer); + instance.materialIndices = nvvk::getBufferDeviceAddress(m_device, model.matIndexBuffer.buffer); + m_objModel.emplace_back(model); m_objInstance.emplace_back(instance); } @@ -627,11 +607,8 @@ void HelloVulkan::initRayTracing() auto HelloVulkan::objectToVkGeometryKHR(const ObjModel& model) { // BLAS builder requires raw device addresses. - VkBufferDeviceAddressInfo info{VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO}; - info.buffer = model.vertexBuffer.buffer; - VkDeviceAddress vertexAddress = vkGetBufferDeviceAddress(m_device, &info); - info.buffer = model.indexBuffer.buffer; - VkDeviceAddress indexAddress = vkGetBufferDeviceAddress(m_device, &info); + VkDeviceAddress vertexAddress = nvvk::getBufferDeviceAddress(m_device, model.vertexBuffer.buffer); + VkDeviceAddress indexAddress = nvvk::getBufferDeviceAddress(m_device, model.indexBuffer.buffer); uint32_t maxPrimitiveCount = model.nbIndices / 3; diff --git a/ray_tracing_specialization/hello_vulkan.h b/ray_tracing_specialization/hello_vulkan.h index d2a1ad1..ce1b62b 100644 --- a/ray_tracing_specialization/hello_vulkan.h +++ b/ray_tracing_specialization/hello_vulkan.h @@ -66,10 +66,14 @@ public: // Instance of the OBJ struct ObjInstance { - uint32_t objIndex{0}; // Reference to the `m_objModel` - uint32_t txtOffset{0}; // Offset in `m_textures` - nvmath::mat4f transform{1}; // Position of the instance - nvmath::mat4f transformIT{1}; // Inverse transpose + nvmath::mat4f transform{1}; // Position of the instance + nvmath::mat4f transformIT{1}; // Inverse transpose + uint32_t objIndex{0}; // Reference to the `m_objModel` + uint32_t txtOffset{0}; // Offset in `m_textures` + VkDeviceAddress vertices; + VkDeviceAddress indices; + VkDeviceAddress materials; + VkDeviceAddress materialIndices; }; // Information pushed at each draw call @@ -95,9 +99,10 @@ public: VkDescriptorSetLayout m_descSetLayout; VkDescriptorSet m_descSet; - nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices - nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances - std::vector m_textures; // vector of all textures of the scene + nvvk::Buffer m_cameraMat; // Device-Host of the camera matrices + nvvk::Buffer m_sceneDesc; // Device buffer of the OBJ instances + + std::vector m_textures; // vector of all textures of the scene nvvk::ResourceAllocatorDma m_alloc; // Allocator for buffer, images, acceleration structures diff --git a/ray_tracing_specialization/main.cpp b/ray_tracing_specialization/main.cpp index d0e1e8a..138f06a 100644 --- a/ray_tracing_specialization/main.cpp +++ b/ray_tracing_specialization/main.cpp @@ -99,6 +99,7 @@ int main(int argc, char** argv) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); GLFWwindow* window = glfwCreateWindow(SAMPLE_WIDTH, SAMPLE_HEIGHT, PROJECT_NAME, nullptr, nullptr); + // Setup camera CameraManip.setWindowSize(SAMPLE_WIDTH, SAMPLE_HEIGHT); CameraManip.setLookat(nvmath::vec3f(5, 4, -4), nvmath::vec3f(0, 1, 0), nvmath::vec3f(0, 1, 0)); @@ -120,34 +121,26 @@ int main(int argc, char** argv) std::string(PROJECT_NAME), }; + // Vulkan required extensions + assert(glfwVulkanSupported() == 1); + uint32_t count{0}; + auto reqExtensions = glfwGetRequiredInstanceExtensions(&count); + // Requesting Vulkan extensions and layers nvvk::ContextCreateInfo contextInfo; - contextInfo.setVersion(1, 2); - contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); - contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); - contextInfo.addInstanceExtension(VK_KHR_SURFACE_EXTENSION_NAME); -#ifdef _WIN32 - contextInfo.addInstanceExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); -#else - contextInfo.addInstanceExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); - contextInfo.addInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME); -#endif - contextInfo.addInstanceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME); + contextInfo.setVersion(1, 2); // Using Vulkan 1.2 + for(uint32_t ext_id = 0; ext_id < count; ext_id++) // Adding required extensions (surface, win32, linux, ..) + contextInfo.addInstanceExtension(reqExtensions[ext_id]); + contextInfo.addInstanceLayer("VK_LAYER_LUNARG_monitor", true); // FPS in titlebar + contextInfo.addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, true); // Allow debug names + contextInfo.addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); // Enabling ability to present rendering // #VKRay: Activate the ray tracing extension VkPhysicalDeviceAccelerationStructureFeaturesKHR accelFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); + contextInfo.addDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, false, &accelFeature); // To build acceleration structures VkPhysicalDeviceRayTracingPipelineFeaturesKHR rtPipelineFeature{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR}; - contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); - contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); - contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); + contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, false, &rtPipelineFeature); // To use vkCmdTraceRaysKHR + contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // Required by ray tracing pipeline // Creating Vulkan base application nvvk::Context vkctx{}; @@ -178,7 +171,6 @@ int main(int argc, char** argv) helloVk.loadModel(nvh::findFile("media/scenes/Medieval_building.obj", defaultSearchPaths, true)); helloVk.loadModel(nvh::findFile("media/scenes/plane.obj", defaultSearchPaths, true)); - helloVk.createOffscreenRender(); helloVk.createDescriptorSetLayout(); helloVk.createGraphicsPipeline(); diff --git a/ray_tracing_specialization/shaders/frag_shader.frag b/ray_tracing_specialization/shaders/frag_shader.frag index 425c866..7c3b8bc 100644 --- a/ray_tracing_specialization/shaders/frag_shader.frag +++ b/ray_tracing_specialization/shaders/frag_shader.frag @@ -16,13 +16,16 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_nonuniform_qualifier : enable #extension GL_GOOGLE_include_directive : enable #extension GL_EXT_scalar_block_layout : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "wavefront.glsl" @@ -37,30 +40,32 @@ pushC; // clang-format off // Incoming -//layout(location = 0) flat in int matIndex; layout(location = 1) in vec2 fragTexCoord; layout(location = 2) in vec3 fragNormal; layout(location = 3) in vec3 viewDir; layout(location = 4) in vec3 worldPos; // Outgoing layout(location = 0) out vec4 outColor; -// Buffers -layout(binding = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3) uniform sampler2D[] textureSamplers; -layout(binding = 4, scalar) buffer MatIndex { int i[]; } matIdx[]; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {uint i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle + +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2) uniform sampler2D[] textureSamplers; // clang-format on void main() { - // Object of this instance - int objId = scnDesc.i[pushC.instanceId].objId; - // Material of the object - int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; + SceneDesc objResource = sceneDesc.i[pushC.instanceId]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + + int matIndex = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +89,7 @@ void main() vec3 diffuse = computeDiffuse(mat, L, N); if(mat.textureId >= 0) { - int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; + int txtOffset = sceneDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; diff --git a/ray_tracing_specialization/shaders/passthrough.vert b/ray_tracing_specialization/shaders/passthrough.vert index ed293b8..65c3460 100644 --- a/ray_tracing_specialization/shaders/passthrough.vert +++ b/ray_tracing_specialization/shaders/passthrough.vert @@ -16,9 +16,9 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 -layout (location = 0) out vec2 outUV; +layout(location = 0) out vec2 outUV; out gl_PerVertex @@ -29,6 +29,6 @@ out gl_PerVertex void main() { - outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); gl_Position = vec4(outUV * 2.0f - 1.0f, 1.0f, 1.0f); } diff --git a/ray_tracing_specialization/shaders/post.frag b/ray_tracing_specialization/shaders/post.frag index 847481c..85faa58 100644 --- a/ray_tracing_specialization/shaders/post.frag +++ b/ray_tracing_specialization/shaders/post.frag @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 layout(location = 0) in vec2 outUV; layout(location = 0) out vec4 fragColor; diff --git a/ray_tracing_specialization/shaders/raytrace.rchit b/ray_tracing_specialization/shaders/raytrace.rchit index e4ad9d0..45484aa 100644 --- a/ray_tracing_specialization/shaders/raytrace.rchit +++ b/ray_tracing_specialization/shaders/raytrace.rchit @@ -22,6 +22,10 @@ #extension GL_EXT_nonuniform_qualifier : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable + +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require +#extension GL_EXT_buffer_reference2 : require + #include "raycommon.glsl" #include "wavefront.glsl" @@ -31,14 +35,13 @@ hitAttributeEXT vec2 attribs; layout(location = 0) rayPayloadInEXT hitPayload prd; layout(location = 1) rayPayloadEXT bool isShadowed; +layout(buffer_reference, scalar) buffer Vertices {Vertex v[]; }; // Positions of an object +layout(buffer_reference, scalar) buffer Indices {ivec3 i[]; }; // Triangle indices +layout(buffer_reference, scalar) buffer Materials {WaveFrontMaterial m[]; }; // Array of all materials on an object +layout(buffer_reference, scalar) buffer MatIndices {int i[]; }; // Material ID for each triangle layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS; -layout(binding = 1, set = 1, scalar) buffer MatColorBufferObject { WaveFrontMaterial m[]; } materials[]; -layout(binding = 2, set = 1, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; -layout(binding = 3, set = 1) uniform sampler2D textureSamplers[]; -layout(binding = 4, set = 1) buffer MatIndexColorBuffer { int i[]; } matIndex[]; -layout(binding = 5, set = 1, scalar) buffer Vertices { Vertex v[]; } vertices[]; -layout(binding = 6, set = 1) buffer Indices { uint i[]; } indices[]; - +layout(binding = 1, set = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; +layout(binding = 2, set = 1) uniform sampler2D textureSamplers[]; layout(constant_id = 0) const int USE_DIFFUSE = 1; layout(constant_id = 1) const int USE_SPECULAR = 1; @@ -59,30 +62,33 @@ pushC; void main() { - // Object of this instance - uint objId = scnDesc.i[gl_InstanceCustomIndexEXT].objId; + // Object data + SceneDesc objResource = sceneDesc.i[gl_InstanceCustomIndexEXT]; + MatIndices matIndices = MatIndices(objResource.materialIndexAddress); + Materials materials = Materials(objResource.materialAddress); + Indices indices = Indices(objResource.indexAddress); + Vertices vertices = Vertices(objResource.vertexAddress); // Indices of the triangle - ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], // - indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); // + ivec3 ind = indices.i[gl_PrimitiveID]; + // Vertex of the triangle - Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; - Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; - Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; + Vertex v0 = vertices.v[ind.x]; + Vertex v1 = vertices.v[ind.y]; + Vertex v2 = vertices.v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); // Computing the normal at hit position vec3 normal = v0.nrm * barycentrics.x + v1.nrm * barycentrics.y + v2.nrm * barycentrics.z; // Transforming the normal to world space - normal = normalize(vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); + normal = normalize(vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfoIT * vec4(normal, 0.0))); // Computing the coordinates of the hit position vec3 worldPos = v0.pos * barycentrics.x + v1.pos * barycentrics.y + v2.pos * barycentrics.z; // Transforming the position to world space - worldPos = vec3(scnDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); + worldPos = vec3(sceneDesc.i[gl_InstanceCustomIndexEXT].transfo * vec4(worldPos, 1.0)); // Vector toward the light vec3 L; @@ -102,8 +108,8 @@ void main() } // Material of the object - int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; + int matIdx = matIndices.i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials.m[matIdx]; // Diffuse @@ -113,9 +119,8 @@ void main() diffuse = computeDiffuse(mat, L, normal); if(mat.textureId >= 0) { - uint txtId = mat.textureId + scnDesc.i[gl_InstanceCustomIndexEXT].txtOffset; - vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y - + v2.texCoord * barycentrics.z; + uint txtId = mat.textureId + sceneDesc.i[gl_InstanceCustomIndexEXT].txtOffset; + vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } } @@ -132,9 +137,8 @@ void main() float tMax = lightDistance; vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT; vec3 rayDir = L; - uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT - | gl_RayFlagsSkipClosestHitShaderEXT; - isShadowed = true; + uint flags = gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT; + isShadowed = true; traceRayEXT(topLevelAS, // acceleration structure flags, // rayFlags 0xFF, // cullMask diff --git a/ray_tracing_specialization/shaders/raytrace.rmiss b/ray_tracing_specialization/shaders/raytrace.rmiss index c960eb6..92c7706 100644 --- a/ray_tracing_specialization/shaders/raytrace.rmiss +++ b/ray_tracing_specialization/shaders/raytrace.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require #extension GL_GOOGLE_include_directive : enable diff --git a/ray_tracing_specialization/shaders/raytraceShadow.rmiss b/ray_tracing_specialization/shaders/raytraceShadow.rmiss index 04dd9fc..bf99caf 100644 --- a/ray_tracing_specialization/shaders/raytraceShadow.rmiss +++ b/ray_tracing_specialization/shaders/raytraceShadow.rmiss @@ -16,7 +16,7 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 460 #extension GL_EXT_ray_tracing : require diff --git a/ray_tracing_specialization/shaders/vert_shader.vert b/ray_tracing_specialization/shaders/vert_shader.vert index a1c55ba..c79820d 100644 --- a/ray_tracing_specialization/shaders/vert_shader.vert +++ b/ray_tracing_specialization/shaders/vert_shader.vert @@ -16,16 +16,18 @@ * SPDX-FileCopyrightText: Copyright (c) 2019-2021 NVIDIA CORPORATION * SPDX-License-Identifier: Apache-2.0 */ - + #version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_EXT_scalar_block_layout : enable #extension GL_GOOGLE_include_directive : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require + #include "wavefront.glsl" // clang-format off -layout(binding = 2, set = 0, scalar) buffer ScnDesc { sceneDesc i[]; } scnDesc; +layout(binding = 1, scalar) buffer SceneDesc_ { SceneDesc i[]; } sceneDesc; // clang-format on layout(binding = 0) uniform UniformBufferObject @@ -65,8 +67,8 @@ out gl_PerVertex void main() { - mat4 objMatrix = scnDesc.i[pushC.instanceId].transfo; - mat4 objMatrixIT = scnDesc.i[pushC.instanceId].transfoIT; + mat4 objMatrix = sceneDesc.i[pushC.instanceId].transfo; + mat4 objMatrixIT = sceneDesc.i[pushC.instanceId].transfoIT; vec3 origin = vec3(ubo.viewI * vec4(0, 0, 0, 1)); diff --git a/ray_tracing_specialization/shaders/wavefront.glsl b/ray_tracing_specialization/shaders/wavefront.glsl index b4a58e4..3c321f3 100644 --- a/ray_tracing_specialization/shaders/wavefront.glsl +++ b/ray_tracing_specialization/shaders/wavefront.glsl @@ -39,12 +39,16 @@ struct WaveFrontMaterial int textureId; }; -struct sceneDesc +struct SceneDesc { - int objId; - int txtOffset; - mat4 transfo; - mat4 transfoIT; + mat4 transfo; + mat4 transfoIT; + int objId; + int txtOffset; + uint64_t vertexAddress; + uint64_t indexAddress; + uint64_t materialAddress; + uint64_t materialIndexAddress; };