From ccdc90f35ca3990b60428fbf2c8ce6353373cad0 Mon Sep 17 00:00:00 2001 From: mklefrancois <38076163+mklefrancois@users.noreply.github.com> Date: Wed, 27 May 2020 14:43:05 +0200 Subject: [PATCH] Fixing access to nonuniform elements + SBT alignment --- docs/setup.md.html | 4 +- docs/vkrt_tuto_anyhit.md.htm | 8 +-- docs/vkrt_tutorial.md.htm | 72 +++++++++++++------ ray_tracing__advance/raytrace.cpp | 29 +++++--- ray_tracing__advance/shaders/frag_shader.frag | 6 +- ray_tracing__advance/shaders/raytrace.rahit | 4 +- ray_tracing__advance/shaders/raytrace.rchit | 18 ++--- ray_tracing__advance/shaders/raytrace2.rahit | 2 +- ray_tracing__advance/shaders/raytrace2.rchit | 2 +- ray_tracing__before/shaders/frag_shader.frag | 6 +- ray_tracing__simple/hello_vulkan.cpp | 28 +++++--- ray_tracing__simple/main.cpp | 3 +- ray_tracing__simple/shaders/frag_shader.frag | 6 +- ray_tracing__simple/shaders/raytrace.rchit | 18 ++--- ray_tracing_animation/hello_vulkan.cpp | 31 +++++--- .../shaders/frag_shader.frag | 6 +- ray_tracing_animation/shaders/raytrace.rchit | 18 ++--- ray_tracing_anyhit/hello_vulkan.cpp | 26 ++++--- ray_tracing_anyhit/shaders/frag_shader.frag | 6 +- ray_tracing_anyhit/shaders/raytrace.rahit | 8 +-- ray_tracing_anyhit/shaders/raytrace.rchit | 18 ++--- ray_tracing_callable/hello_vulkan.cpp | 26 ++++--- ray_tracing_callable/shaders/frag_shader.frag | 6 +- ray_tracing_callable/shaders/raytrace.rchit | 18 ++--- ray_tracing_instances/hello_vulkan.cpp | 28 +++++--- .../shaders/frag_shader.frag | 6 +- ray_tracing_instances/shaders/raytrace.rchit | 18 ++--- ray_tracing_intersection/hello_vulkan.cpp | 28 +++++--- .../shaders/frag_shader.frag | 6 +- .../shaders/raytrace.rchit | 18 ++--- .../shaders/raytrace2.rchit | 4 +- ray_tracing_jitter_cam/hello_vulkan.cpp | 28 +++++--- .../shaders/frag_shader.frag | 6 +- ray_tracing_jitter_cam/shaders/raytrace.rchit | 18 ++--- ray_tracing_manyhits/hello_vulkan.cpp | 55 ++++++++------ ray_tracing_manyhits/shaders/frag_shader.frag | 6 +- ray_tracing_manyhits/shaders/raytrace.rchit | 18 ++--- ray_tracing_rayquery/shaders/frag_shader.frag | 6 +- ray_tracing_reflections/hello_vulkan.cpp | 29 +++++--- .../shaders/frag_shader.frag | 6 +- .../shaders/raytrace.rchit | 18 ++--- 41 files changed, 388 insertions(+), 279 deletions(-) diff --git a/docs/setup.md.html b/docs/setup.md.html index 1bd54b0..7aebe8a 100644 --- a/docs/setup.md.html +++ b/docs/setup.md.html @@ -34,7 +34,7 @@ The directory structure should be looking like: * | * +-- 📂 shared_sources * | -* +-- 📂 vk_raytracing_tutorial +* +-- 📂 vk_raytracing_tutorial_KHR * | | * | +-- 📂 ray_tracing__simple (<-- Start here) * | | @@ -47,7 +47,7 @@ The directory structure should be looking like: !!! Warning - **Run CMake** in vk_raytracing_tutorial. + **Run CMake** in vk_raytracing_tutorial_KHR. !!! Warning Beta Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers. diff --git a/docs/vkrt_tuto_anyhit.md.htm b/docs/vkrt_tuto_anyhit.md.htm index 19ab296..611e8c1 100644 --- a/docs/vkrt_tuto_anyhit.md.htm +++ b/docs/vkrt_tuto_anyhit.md.htm @@ -64,13 +64,13 @@ void main() // Object of this instance uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - uint ind = indices[objId].i[3 * gl_PrimitiveID + 0]; + uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle - Vertex v0 = vertices[objId].v[ind.x]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; if (mat.illum != 4) return; diff --git a/docs/vkrt_tutorial.md.htm b/docs/vkrt_tutorial.md.htm index 4215f54..718a8c7 100644 --- a/docs/vkrt_tutorial.md.htm +++ b/docs/vkrt_tutorial.md.htm @@ -101,20 +101,26 @@ Go to the `main` function of the `main.cpp` file, and find where we request Vulk `nvvk::ContextCreateInfo`. To request ray tracing capabilities, we need to explicitly add the -[VK_KHR_ray_tracing](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_KHR_ray_tracing) -extension as well as its dependency -[VK_KHR_maintenance3](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VK_KHR_maintenance3.html): +[VK_KHR_ray_tracing](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_ray_tracing.html) +extension as well as its various dependencies. ```` C // #VKRay: Activate the ray tracing extension vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature; contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature); +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); ```` +Before creating the device, a linked structure of features must past. Not all extensions requires a set of features, but +ray tracing features must be enabled before the creation of the device. By providing +`raytracingFeature`, the context creation will query the capable features for ray tracing and will use the +filled structure to create the device. + + In the `HelloVulkan` class in `hello_vulkan.h`, add an initialization function and a member storing the capabilities of the GPU for ray tracing: @@ -356,6 +362,14 @@ m_debug.setObjectName(blas.as.accel, (std::string("Blas" + std::to_string(idx)). The acceleration structure builder requires some scratch memory to generate the BLAS. Since we generate all the BLAS's in a batch, we query the scratch memory requirements for each BLAS, and find the maximum such requirement. +The amount of memory for the scratch is determined by filling the memory requirement structure, and setting +the previous created acceleration structure. At the time to write those lines, only the device can be use +for building the acceleration structure. The same scratch buffer is used by each BLAS, which is the reason to +allocate the largest size, to avoid any realocation. At the end of building all BLAS, we can dispose the scratch +buffer. + +We are querying the size the acceleration structure is taking on the device as well. This has no real use except +for statistics and to compare it to the compact size which can happen in a second step. ```` C // Estimate the amount of scratch memory required to build the BLAS, and @@ -395,7 +409,11 @@ bufferInfo.buffer = scratchBuffer.buffer; VkDeviceAddress scratchAddress = vkGetBufferDeviceAddress(m_device, &bufferInfo); ```` -To know the size that the BLAS is really taking, we use queries. +To know the size that the BLAS is really taking, we use queries and setting the type to `VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR`. +This is needed if we want to compact the acceleration structure in a second step. By default, the +memory allocated by the creation of the acceleration structure has the size of the worst case. After creation, +the real space can be smaller, and it is possible to copy the acceleration structure to one that is +using exactly what is needed. This could save over 50% of the device memory usage. ```` C // Query size of compact BLAS @@ -406,9 +424,15 @@ VkQueryPool queryPool; vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool); ```` -We then use a one-time command buffer to launch all the BLAS builds. Note the barrier after each +We then use multiple command buffers to launch all the BLAS builds. We are using multiple +command buffers instead of one, to allow the driver to allow system interuption and avoid a +TDR if the job was to heavy. + +Note the barrier after each build call: this is required as we reuse the scratch space across builds, and hence need to ensure -the previous build has completed before starting the next. +the previous build has completed before starting the next. We could have used multiple scratch buffers, +but it would have been expensive memory wise, and the device can only build one BLAS at a time, so we +wouldn't be faster. ```` C // Query size of compact BLAS @@ -421,10 +445,14 @@ vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool); // Create a command buffer containing all the BLAS builds nvvk::CommandPool genCmdBuf(m_device, m_queueIndex); -VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); int ctr{0}; +std::vector allCmdBufs; +allCmdBufs.reserve(m_blas.size()); for(auto& blas : m_blas) { + VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + allCmdBufs.push_back(cmdBuf); + const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data(); VkAccelerationStructureBuildGeometryInfoKHR bottomASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}; bottomASInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR; @@ -460,16 +488,16 @@ for(auto& blas : m_blas) VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryPool, ctr++); } } -genCmdBuf.submitAndWait(cmdBuf); +genCmdBuf.submitAndWait(allCmdBufs); +allCmdBufs.clear(); ```` While this approach has the advantage of keeping all BLAS's independent, building many BLAS's efficiently would -require allocating a larger scratch buffer, and launch several builds simultaneously. This tutorial also -does not use compaction, which could reduce significantly the memory footprint of the acceleration structures. Both +require allocating a larger scratch buffer, and launch several builds simultaneously. This current tutorial +does not make use of compaction, which could reduce significantly the memory footprint of the acceleration structures. Both of those aspects will be part of a future advanced tutorial. -We finally execute the command buffer and clean up the allocator's scratch memory and staging buffer: -This part, which is optional, will compact the BLAS in the memory that it is really using. It needs to wait that all BLASes +The following is when compation flag is enabled. This part, which is optional, will compact the BLAS in the memory that it is really using. It needs to wait that all BLASes are constructred, to make a copy in the more fitted memory space. ```` C @@ -490,7 +518,7 @@ if(doCompaction) uint32_t totOriginalSize{0}, totCompactSize{0}; for(int i = 0; i < m_blas.size(); i++) { - LOGI("Reducing %i, from %d to %d \n", i, originalSizes[i], compactSizes[i]); + // LOGI("Reducing %i, from %d to %d \n", i, originalSizes[i], compactSizes[i]); totOriginalSize += (uint32_t)originalSizes[i]; totCompactSize += (uint32_t)compactSizes[i]; @@ -1646,13 +1674,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; ```` Using the hit point's barycentric coordinates, we can interpolate the normal: @@ -1745,8 +1773,8 @@ and fetch the material definition instead: ```` C // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; ```` !!! Note Note @@ -1764,7 +1792,7 @@ supports textures to modulate the surface albedo. uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } // Specular diff --git a/ray_tracing__advance/raytrace.cpp b/ray_tracing__advance/raytrace.cpp index a0926c1..d4694a1 100644 --- a/ray_tracing__advance/raytrace.cpp +++ b/ray_tracing__advance/raytrace.cpp @@ -38,7 +38,7 @@ extern std::vector defaultSearchPaths; void Raytracer::setup(const vk::Device& device, const vk::PhysicalDevice& physicalDevice, - nvvk::Allocator* allocator, + nvvk::Allocator* allocator, uint32_t queueFamily) { m_device = device; @@ -421,23 +421,29 @@ void Raytracer::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc->createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc->createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); - - - genCmdBuf.submitAndWait(cmdBuf); + // Write the handles in the SBT + void* mapped = m_alloc->map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc->unmap(m_rtSBTBuffer); m_alloc->finalizeAndReleaseStaging(); } @@ -472,7 +478,8 @@ void Raytracer::raytrace(const vk::CommandBuffer& cmdBuf, | vk::ShaderStageFlagBits::eCallableKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing__advance/shaders/frag_shader.frag b/ray_tracing__advance/shaders/frag_shader.frag index 2f564c0..45572b8 100644 --- a/ray_tracing__advance/shaders/frag_shader.frag +++ b/ray_tracing__advance/shaders/frag_shader.frag @@ -43,8 +43,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -84,7 +84,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing__advance/shaders/raytrace.rahit b/ray_tracing__advance/shaders/raytrace.rahit index 8b79f60..57d0d56 100644 --- a/ray_tracing__advance/shaders/raytrace.rahit +++ b/ray_tracing__advance/shaders/raytrace.rahit @@ -22,8 +22,8 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; if(mat.illum != 4) return; diff --git a/ray_tracing__advance/shaders/raytrace.rchit b/ray_tracing__advance/shaders/raytrace.rchit index 4aeb750..503032b 100644 --- a/ray_tracing__advance/shaders/raytrace.rchit +++ b/ray_tracing__advance/shaders/raytrace.rchit @@ -45,13 +45,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -101,8 +101,8 @@ void main() #endif // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -112,7 +112,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing__advance/shaders/raytrace2.rahit b/ray_tracing__advance/shaders/raytrace2.rahit index 4d291a1..c1f52a4 100644 --- a/ray_tracing__advance/shaders/raytrace2.rahit +++ b/ray_tracing__advance/shaders/raytrace2.rahit @@ -19,7 +19,7 @@ void main() { // Material of the object Implicit impl = allImplicits.i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[gl_InstanceCustomIndexEXT].m[impl.matId]; + WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].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 474c751..e267a5d 100644 --- a/ray_tracing__advance/shaders/raytrace2.rchit +++ b/ray_tracing__advance/shaders/raytrace2.rchit @@ -74,7 +74,7 @@ void main() executeCallableEXT(pushC.lightType, 0); // Material of the object - WaveFrontMaterial mat = materials[gl_InstanceCustomIndexEXT].m[impl.matId]; + WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId]; // Diffuse diff --git a/ray_tracing__before/shaders/frag_shader.frag b/ray_tracing__before/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing__before/shaders/frag_shader.frag +++ b/ray_tracing__before/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing__simple/hello_vulkan.cpp b/ray_tracing__simple/hello_vulkan.cpp index aba3d5c..d5a526e 100644 --- a/ray_tracing__simple/hello_vulkan.cpp +++ b/ray_tracing__simple/hello_vulkan.cpp @@ -471,7 +471,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -855,24 +855,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -897,7 +904,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing__simple/main.cpp b/ray_tracing__simple/main.cpp index f21669a..f645120 100644 --- a/ray_tracing__simple/main.cpp +++ b/ray_tracing__simple/main.cpp @@ -121,8 +121,6 @@ int main(int argc, char** argv) NVPSystem::exePath() + std::string(PROJECT_RELDIRECTORY) + std::string("../"), }; - // Enabling the extension feature - vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature; // Requesting Vulkan extensions and layers nvvk::ContextCreateInfo contextInfo(true); @@ -140,6 +138,7 @@ int main(int argc, char** argv) contextInfo.addDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); // #VKRay: Activate the ray tracing extension + vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature; contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature); contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); diff --git a/ray_tracing__simple/shaders/frag_shader.frag b/ray_tracing__simple/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing__simple/shaders/frag_shader.frag +++ b/ray_tracing__simple/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing__simple/shaders/raytrace.rchit b/ray_tracing__simple/shaders/raytrace.rchit index 2fe28ad..7897700 100644 --- a/ray_tracing__simple/shaders/raytrace.rchit +++ b/ray_tracing__simple/shaders/raytrace.rchit @@ -38,13 +38,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -77,8 +77,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -88,7 +88,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_animation/hello_vulkan.cpp b/ray_tracing_animation/hello_vulkan.cpp index f50a7e6..83a2730 100644 --- a/ray_tracing_animation/hello_vulkan.cpp +++ b/ray_tracing_animation/hello_vulkan.cpp @@ -851,24 +851,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -893,7 +900,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders @@ -939,8 +947,9 @@ void HelloVulkan::animationInstances(float time) // Update the buffer vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance); - nvvk::Buffer stagingBuffer = m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc, - vk::MemoryPropertyFlagBits::eHostVisible); + nvvk::Buffer stagingBuffer = + m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible); // Copy data to staging buffer auto* gInst = m_alloc.map(stagingBuffer); memcpy(gInst, m_objInstance.data(), bufferSize); diff --git a/ray_tracing_animation/shaders/frag_shader.frag b/ray_tracing_animation/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_animation/shaders/frag_shader.frag +++ b/ray_tracing_animation/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_animation/shaders/raytrace.rchit b/ray_tracing_animation/shaders/raytrace.rchit index 3ecb9b9..130ecd3 100644 --- a/ray_tracing_animation/shaders/raytrace.rchit +++ b/ray_tracing_animation/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_anyhit/hello_vulkan.cpp b/ray_tracing_anyhit/hello_vulkan.cpp index 22f2925..86112ad 100644 --- a/ray_tracing_anyhit/hello_vulkan.cpp +++ b/ray_tracing_anyhit/hello_vulkan.cpp @@ -853,24 +853,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -899,7 +906,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_anyhit/shaders/frag_shader.frag b/ray_tracing_anyhit/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_anyhit/shaders/frag_shader.frag +++ b/ray_tracing_anyhit/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_anyhit/shaders/raytrace.rahit b/ray_tracing_anyhit/shaders/raytrace.rahit index 0dd169d..6af0802 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rahit +++ b/ray_tracing_anyhit/shaders/raytrace.rahit @@ -23,13 +23,13 @@ void main() // Object of this instance uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - uint ind = indices[objId].i[3 * gl_PrimitiveID + 0]; + uint ind = indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0]; // Vertex of the triangle - Vertex v0 = vertices[objId].v[ind.x]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; if(mat.illum != 4) return; diff --git a/ray_tracing_anyhit/shaders/raytrace.rchit b/ray_tracing_anyhit/shaders/raytrace.rchit index be28b7b..6b21fc6 100644 --- a/ray_tracing_anyhit/shaders/raytrace.rchit +++ b/ray_tracing_anyhit/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_callable/hello_vulkan.cpp b/ray_tracing_callable/hello_vulkan.cpp index 1c2f8bc..c173b04 100644 --- a/ray_tracing_callable/hello_vulkan.cpp +++ b/ray_tracing_callable/hello_vulkan.cpp @@ -871,24 +871,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -917,7 +924,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eCallableKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_callable/shaders/frag_shader.frag b/ray_tracing_callable/shaders/frag_shader.frag index bfef11e..f5e4ab1 100644 --- a/ray_tracing_callable/shaders/frag_shader.frag +++ b/ray_tracing_callable/shaders/frag_shader.frag @@ -43,8 +43,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -85,7 +85,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_callable/shaders/raytrace.rchit b/ray_tracing_callable/shaders/raytrace.rchit index a78d5ba..8207b74 100644 --- a/ray_tracing_callable/shaders/raytrace.rchit +++ b/ray_tracing_callable/shaders/raytrace.rchit @@ -45,13 +45,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -101,8 +101,8 @@ void main() #endif // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -112,7 +112,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_instances/hello_vulkan.cpp b/ray_tracing_instances/hello_vulkan.cpp index da2dfe1..77f99f2 100644 --- a/ray_tracing_instances/hello_vulkan.cpp +++ b/ray_tracing_instances/hello_vulkan.cpp @@ -493,7 +493,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -864,24 +864,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -906,7 +913,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_instances/shaders/frag_shader.frag b/ray_tracing_instances/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_instances/shaders/frag_shader.frag +++ b/ray_tracing_instances/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_instances/shaders/raytrace.rchit b/ray_tracing_instances/shaders/raytrace.rchit index 3ecb9b9..130ecd3 100644 --- a/ray_tracing_instances/shaders/raytrace.rchit +++ b/ray_tracing_instances/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_intersection/hello_vulkan.cpp b/ray_tracing_intersection/hello_vulkan.cpp index 141e0b2..402b4c2 100644 --- a/ray_tracing_intersection/hello_vulkan.cpp +++ b/ray_tracing_intersection/hello_vulkan.cpp @@ -486,7 +486,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -1001,24 +1001,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -1043,7 +1050,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_intersection/shaders/frag_shader.frag b/ray_tracing_intersection/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_intersection/shaders/frag_shader.frag +++ b/ray_tracing_intersection/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_intersection/shaders/raytrace.rchit b/ray_tracing_intersection/shaders/raytrace.rchit index 3ecb9b9..130ecd3 100644 --- a/ray_tracing_intersection/shaders/raytrace.rchit +++ b/ray_tracing_intersection/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_intersection/shaders/raytrace2.rchit b/ray_tracing_intersection/shaders/raytrace2.rchit index 5b804b1..c4f574a 100644 --- a/ray_tracing_intersection/shaders/raytrace2.rchit +++ b/ray_tracing_intersection/shaders/raytrace2.rchit @@ -72,8 +72,8 @@ void main() } // Material of the object - int matIdx = matIndex[gl_InstanceID].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[gl_InstanceID].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(gl_InstanceID)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceID)].m[matIdx]; // Diffuse vec3 diffuse = computeDiffuse(mat, L, normal); diff --git a/ray_tracing_jitter_cam/hello_vulkan.cpp b/ray_tracing_jitter_cam/hello_vulkan.cpp index f6acdaa..9307c6e 100644 --- a/ray_tracing_jitter_cam/hello_vulkan.cpp +++ b/ray_tracing_jitter_cam/hello_vulkan.cpp @@ -471,7 +471,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -842,24 +842,31 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } @@ -888,7 +895,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_jitter_cam/shaders/frag_shader.frag b/ray_tracing_jitter_cam/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_jitter_cam/shaders/frag_shader.frag +++ b/ray_tracing_jitter_cam/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_jitter_cam/shaders/raytrace.rchit b/ray_tracing_jitter_cam/shaders/raytrace.rchit index 3ecb9b9..130ecd3 100644 --- a/ray_tracing_jitter_cam/shaders/raytrace.rchit +++ b/ray_tracing_jitter_cam/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_manyhits/hello_vulkan.cpp b/ray_tracing_manyhits/hello_vulkan.cpp index 4c6f095..4b4e37e 100644 --- a/ray_tracing_manyhits/hello_vulkan.cpp +++ b/ray_tracing_manyhits/hello_vulkan.cpp @@ -44,6 +44,10 @@ extern std::vector defaultSearchPaths; #include "nvvk/renderpasses_vk.hpp" #include "nvvk/shaders_vk.hpp" +#ifndef ROUND_UP +#define ROUND_UP(v, powerOf2Alignment) (((v) + (powerOf2Alignment)-1) & ~((powerOf2Alignment)-1)) +#endif + // Holding the camera matrices struct CameraMatrices @@ -471,7 +475,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -850,9 +854,10 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t groupAlignSize = m_rtProperties.shaderGroupBaseAlignment; // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * groupAlignSize; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, @@ -866,9 +871,10 @@ void HelloVulkan::createRtShaderBindingTable() } // Sizes - uint32_t rayGenSize = groupHandleSize; - uint32_t missSize = groupHandleSize; - uint32_t hitSize = groupHandleSize + sizeof(HitRecordBuffer); + uint32_t rayGenSize = groupAlignSize; + uint32_t missSize = groupAlignSize; + uint32_t hitSize = + ROUND_UP(groupHandleSize + static_cast(sizeof(HitRecordBuffer)), groupAlignSize); uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize; std::vector sbtBuffer(newSbtSize); @@ -882,19 +888,22 @@ void HelloVulkan::createRtShaderBindingTable() memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1 pBuffer += missSize; - memcpy(pBuffer, handles[3], groupHandleSize); // Hit 0 - pBuffer += groupHandleSize; - pBuffer += sizeof(HitRecordBuffer); // No data + uint8_t* pHitBuffer = pBuffer; + memcpy(pHitBuffer, handles[3], groupHandleSize); // Hit 0 + // No data + pBuffer += hitSize; - memcpy(pBuffer, handles[4], groupHandleSize); // Hit 1 - pBuffer += groupHandleSize; - memcpy(pBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data - pBuffer += sizeof(HitRecordBuffer); + pHitBuffer = pBuffer; + memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 1 + pHitBuffer += groupHandleSize; + memcpy(pHitBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data + pBuffer += hitSize; - memcpy(pBuffer, handles[4], groupHandleSize); // Hit 2 - pBuffer += groupHandleSize; - memcpy(pBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data - pBuffer += sizeof(HitRecordBuffer); + pHitBuffer = pBuffer; + memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 2 + pHitBuffer += groupHandleSize; + memcpy(pHitBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data + pBuffer += hitSize; } // Write the handles in the SBT @@ -932,13 +941,15 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier - vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer - vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen - vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders - vk::DeviceSize sbtSize = progSize * (vk::DeviceSize)m_rtShaderGroups.size(); + vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize alignSize = m_rtProperties.shaderGroupBaseAlignment; - vk::DeviceSize hitGroupStride = progSize + sizeof(HitRecordBuffer); + vk::DeviceSize rayGenOffset = 0u * alignSize; // Start at the beginning of m_sbtBuffer + vk::DeviceSize missOffset = 1u * alignSize; // Jump over raygen + vk::DeviceSize hitGroupOffset = 3u * alignSize; // Jump over the previous shaders + vk::DeviceSize sbtSize = alignSize * (vk::DeviceSize)m_rtShaderGroups.size(); + + vk::DeviceSize hitGroupStride = ROUND_UP(progSize + sizeof(HitRecordBuffer), alignSize); // m_sbtBuffer holds all the shader handles: raygen, n-miss, hit... const vk::StridedBufferRegionKHR raygenShaderBindingTable = {m_rtSBTBuffer.buffer, rayGenOffset, diff --git a/ray_tracing_manyhits/shaders/frag_shader.frag b/ray_tracing_manyhits/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_manyhits/shaders/frag_shader.frag +++ b/ray_tracing_manyhits/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_manyhits/shaders/raytrace.rchit b/ray_tracing_manyhits/shaders/raytrace.rchit index 3ecb9b9..130ecd3 100644 --- a/ray_tracing_manyhits/shaders/raytrace.rchit +++ b/ray_tracing_manyhits/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0); diff --git a/ray_tracing_rayquery/shaders/frag_shader.frag b/ray_tracing_rayquery/shaders/frag_shader.frag index 6331c27..8199bb4 100644 --- a/ray_tracing_rayquery/shaders/frag_shader.frag +++ b/ray_tracing_rayquery/shaders/frag_shader.frag @@ -43,8 +43,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -73,7 +73,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_reflections/hello_vulkan.cpp b/ray_tracing_reflections/hello_vulkan.cpp index 1c271b9..1df486a 100644 --- a/ray_tracing_reflections/hello_vulkan.cpp +++ b/ray_tracing_reflections/hello_vulkan.cpp @@ -471,7 +471,7 @@ void HelloVulkan::createOffscreenRender() | vk::ImageUsageFlagBits::eStorage); - nvvk::Image image = m_alloc.createImage(colorCreateInfo); + nvvk::Image image = m_alloc.createImage(colorCreateInfo); vk::ImageViewCreateInfo ivInfo = nvvk::makeImageViewCreateInfo(image.image, colorCreateInfo); m_offscreenColor = m_alloc.createTexture(image, ivInfo, vk::SamplerCreateInfo()); m_offscreenColor.descriptor.imageLayout = VK_IMAGE_LAYOUT_GENERAL; @@ -842,27 +842,33 @@ void HelloVulkan::createRtShaderBindingTable() auto groupCount = static_cast(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit uint32_t groupHandleSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + uint32_t baseAligment = m_rtProperties.shaderGroupBaseAlignment; // Size of shader alignment // Fetch all the shader handles used in the pipeline, so that they can be written in the SBT - uint32_t sbtSize = groupCount * groupHandleSize; + uint32_t sbtSize = groupCount * baseAligment; std::vector shaderHandleStorage(sbtSize); m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, shaderHandleStorage.data()); // Write the handles in the SBT - nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); - vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); + m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc, + vk::MemoryPropertyFlagBits::eHostVisible + | vk::MemoryPropertyFlagBits::eHostCoherent); + m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str()); - m_rtSBTBuffer = - m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); - m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); + // Write the handles in the SBT + void* mapped = m_alloc.map(m_rtSBTBuffer); + auto* pData = reinterpret_cast(mapped); + for(uint32_t g = 0; g < groupCount; g++) + { + memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen + pData += baseAligment; + } + m_alloc.unmap(m_rtSBTBuffer); - genCmdBuf.submitAndWait(cmdBuf); - m_alloc.finalizeAndReleaseStaging(); } - //-------------------------------------------------------------------------------------------------- // Ray Tracing the scene // @@ -884,7 +890,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f& | vk::ShaderStageFlagBits::eMissKHR, 0, m_rtPushConstants); - vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier + vk::DeviceSize progSize = + m_rtProperties.shaderGroupBaseAlignment; // Size of a program identifier vk::DeviceSize rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders diff --git a/ray_tracing_reflections/shaders/frag_shader.frag b/ray_tracing_reflections/shaders/frag_shader.frag index 03cb75b..d1c55f7 100644 --- a/ray_tracing_reflections/shaders/frag_shader.frag +++ b/ray_tracing_reflections/shaders/frag_shader.frag @@ -40,8 +40,8 @@ void main() int objId = scnDesc.i[pushC.instanceId].objId; // Material of the object - int matIndex = matIdx[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIndex]; + int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex]; vec3 N = normalize(fragNormal); @@ -67,7 +67,7 @@ void main() { int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; uint txtId = txtOffset + mat.textureId; - vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; + vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz; diffuse *= diffuseTxt; } diff --git a/ray_tracing_reflections/shaders/raytrace.rchit b/ray_tracing_reflections/shaders/raytrace.rchit index e436252..bb7ed55 100644 --- a/ray_tracing_reflections/shaders/raytrace.rchit +++ b/ray_tracing_reflections/shaders/raytrace.rchit @@ -40,13 +40,13 @@ void main() uint objId = scnDesc.i[gl_InstanceID].objId; // Indices of the triangle - ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // - indices[objId].i[3 * gl_PrimitiveID + 1], // - indices[objId].i[3 * gl_PrimitiveID + 2]); // + 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[objId].v[ind.x]; - Vertex v1 = vertices[objId].v[ind.y]; - Vertex v2 = vertices[objId].v[ind.z]; + Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x]; + Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y]; + Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z]; const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); @@ -79,8 +79,8 @@ void main() } // Material of the object - int matIdx = matIndex[objId].i[gl_PrimitiveID]; - WaveFrontMaterial mat = materials[objId].m[matIdx]; + int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID]; + WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx]; // Diffuse @@ -90,7 +90,7 @@ void main() uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; vec2 texCoord = v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; - diffuse *= texture(textureSamplers[txtId], texCoord).xyz; + diffuse *= texture(textureSamplers[nonuniformEXT(txtId)], texCoord).xyz; } vec3 specular = vec3(0);