Fixing access to nonuniform elements + SBT alignment

This commit is contained in:
mklefrancois 2020-05-27 14:43:05 +02:00
parent 4f46136c08
commit ccdc90f35c
41 changed files with 388 additions and 279 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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<VkCommandBuffer> 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

View file

@ -38,7 +38,7 @@ extern std::vector<std::string> 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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -851,24 +851,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount =
static_cast<uint32_t>(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<uint8_t> 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<uint8_t*>(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);

View file

@ -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;
}

View file

@ -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);

View file

@ -853,24 +853,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount =
static_cast<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -871,24 +871,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount =
static_cast<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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);

View file

@ -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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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);

View file

@ -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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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);

View file

@ -44,6 +44,10 @@ extern std::vector<std::string> 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<uint32_t>(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<uint8_t> 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<int>(sizeof(HitRecordBuffer)), groupAlignSize);
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
std::vector<uint8_t> 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,

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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<uint32_t>(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<uint8_t> 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<uint8_t*>(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

View file

@ -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;
}

View file

@ -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);