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 * +-- 📂 shared_sources
* | * |
* +-- 📂 vk_raytracing_tutorial * +-- 📂 vk_raytracing_tutorial_KHR
* | | * | |
* | +-- 📂 ray_tracing__simple (<-- Start here) * | +-- 📂 ray_tracing__simple (<-- Start here)
* | | * | |
@ -47,7 +47,7 @@ The directory structure should be looking like:
!!! Warning !!! Warning
**Run CMake** in vk_raytracing_tutorial. **Run CMake** in vk_raytracing_tutorial_KHR.
!!! Warning Beta !!! Warning Beta
Modify `VULKAN > VULKAN_HEADERS_OVERRIDE_INCLUDE_DIR` to the path to beta vulkan headers. 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 // Object of this instance
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // 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 of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
if (mat.illum != 4) if (mat.illum != 4)
return; 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`. `nvvk::ContextCreateInfo`.
To request ray tracing capabilities, we need to explicitly To request ray tracing capabilities, we need to explicitly
add the add the
[VK_KHR_ray_tracing](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VK_KHR_ray_tracing) [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 dependency extension as well as its various dependencies.
[VK_KHR_maintenance3](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VK_KHR_maintenance3.html):
```` C ```` C
// #VKRay: Activate the ray tracing extension // #VKRay: Activate the ray tracing extension
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature; vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &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_PIPELINE_LIBRARY_EXTENSION_NAME);
contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); contextInfo.addDeviceExtension(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME);
contextInfo.addDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_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 In the `HelloVulkan` class in `hello_vulkan.h`, add an initialization function and a member storing the capabilities of
the GPU for ray tracing: 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 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. 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 ```` C
// Estimate the amount of scratch memory required to build the BLAS, and // 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); 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 ```` C
// Query size of compact BLAS // Query size of compact BLAS
@ -406,9 +424,15 @@ VkQueryPool queryPool;
vkCreateQueryPool(m_device, &qpci, nullptr, &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 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 ```` C
// Query size of compact BLAS // Query size of compact BLAS
@ -421,10 +445,14 @@ vkCreateQueryPool(m_device, &qpci, nullptr, &queryPool);
// Create a command buffer containing all the BLAS builds // Create a command buffer containing all the BLAS builds
nvvk::CommandPool genCmdBuf(m_device, m_queueIndex); nvvk::CommandPool genCmdBuf(m_device, m_queueIndex);
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
int ctr{0}; int ctr{0};
std::vector<VkCommandBuffer> allCmdBufs;
allCmdBufs.reserve(m_blas.size());
for(auto& blas : m_blas) for(auto& blas : m_blas)
{ {
VkCommandBuffer cmdBuf = genCmdBuf.createCommandBuffer();
allCmdBufs.push_back(cmdBuf);
const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data(); const VkAccelerationStructureGeometryKHR* pGeometry = blas.asGeometry.data();
VkAccelerationStructureBuildGeometryInfoKHR bottomASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR}; VkAccelerationStructureBuildGeometryInfoKHR bottomASInfo{VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR};
bottomASInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_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++); 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 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 require allocating a larger scratch buffer, and launch several builds simultaneously. This current tutorial
does not use compaction, which could reduce significantly the memory footprint of the acceleration structures. Both 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. 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. are constructred, to make a copy in the more fitted memory space.
```` C ```` C
@ -490,7 +518,7 @@ if(doCompaction)
uint32_t totOriginalSize{0}, totCompactSize{0}; uint32_t totOriginalSize{0}, totCompactSize{0};
for(int i = 0; i < m_blas.size(); i++) 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]; totOriginalSize += (uint32_t)originalSizes[i];
totCompactSize += (uint32_t)compactSizes[i]; totCompactSize += (uint32_t)compactSizes[i];
@ -1646,13 +1674,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
```` ````
Using the hit point's barycentric coordinates, we can interpolate the normal: Using the hit point's barycentric coordinates, we can interpolate the normal:
@ -1745,8 +1773,8 @@ and fetch the material definition instead:
```` C ```` C
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
```` ````
!!! Note Note !!! Note Note
@ -1764,7 +1792,7 @@ supports textures to modulate the surface albedo.
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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 // Specular

View file

@ -421,23 +421,29 @@ void Raytracer::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc->createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc->createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc->map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); auto* pData = reinterpret_cast<uint8_t*>(mapped);
for(uint32_t g = 0; g < groupCount; g++)
{
genCmdBuf.submitAndWait(cmdBuf); memcpy(pData, shaderHandleStorage.data() + g * groupHandleSize, groupHandleSize); // raygen
pData += baseAligment;
}
m_alloc->unmap(m_rtSBTBuffer);
m_alloc->finalizeAndReleaseStaging(); m_alloc->finalizeAndReleaseStaging();
} }
@ -472,7 +478,8 @@ void Raytracer::raytrace(const vk::CommandBuffer& cmdBuf,
| vk::ShaderStageFlagBits::eCallableKHR, | vk::ShaderStageFlagBits::eCallableKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -84,7 +84,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -22,8 +22,8 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
if(mat.illum != 4) if(mat.illum != 4)
return; return;

View file

@ -45,13 +45,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -101,8 +101,8 @@ void main()
#endif #endif
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -112,7 +112,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -19,7 +19,7 @@ void main()
{ {
// Material of the object // Material of the object
Implicit impl = allImplicits.i[gl_PrimitiveID]; 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) if(mat.illum != 4)
return; return;

View file

@ -74,7 +74,7 @@ void main()
executeCallableEXT(pushC.lightType, 0); executeCallableEXT(pushC.lightType, 0);
// Material of the object // Material of the object
WaveFrontMaterial mat = materials[gl_InstanceCustomIndexEXT].m[impl.matId]; WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceCustomIndexEXT)].m[impl.matId];
// Diffuse // Diffuse

View file

@ -40,8 +40,8 @@ void main()
int objId = scnDesc.i[pushC.instanceId].objId; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -855,24 +855,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -897,7 +904,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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("../"), NVPSystem::exePath() + std::string(PROJECT_RELDIRECTORY) + std::string("../"),
}; };
// Enabling the extension feature
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
// Requesting Vulkan extensions and layers // Requesting Vulkan extensions and layers
nvvk::ContextCreateInfo contextInfo(true); 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_DEDICATED_ALLOCATION_EXTENSION_NAME);
contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME); contextInfo.addDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
// #VKRay: Activate the ray tracing extension // #VKRay: Activate the ray tracing extension
vk::PhysicalDeviceRayTracingFeaturesKHR raytracingFeature;
contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature); contextInfo.addDeviceExtension(VK_KHR_RAY_TRACING_EXTENSION_NAME, false, &raytracingFeature);
contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME); contextInfo.addDeviceExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
contextInfo.addDeviceExtension(VK_KHR_PIPELINE_LIBRARY_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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -38,13 +38,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -77,8 +77,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -88,7 +88,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -851,24 +851,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -893,7 +900,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders
@ -939,7 +947,8 @@ void HelloVulkan::animationInstances(float time)
// Update the buffer // Update the buffer
vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance); vk::DeviceSize bufferSize = m_objInstance.size() * sizeof(ObjInstance);
nvvk::Buffer stagingBuffer = m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc, nvvk::Buffer stagingBuffer =
m_alloc.createBuffer(bufferSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostVisible); vk::MemoryPropertyFlagBits::eHostVisible);
// Copy data to staging buffer // Copy data to staging buffer
auto* gInst = m_alloc.map(stagingBuffer); auto* gInst = m_alloc.map(stagingBuffer);

View file

@ -40,8 +40,8 @@ void main()
int objId = scnDesc.i[pushC.instanceId].objId; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -853,24 +853,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -899,7 +906,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -23,13 +23,13 @@ void main()
// Object of this instance // Object of this instance
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // 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 of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
if(mat.illum != 4) if(mat.illum != 4)
return; return;

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -871,24 +871,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -917,7 +924,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eCallableKHR, | vk::ShaderStageFlagBits::eCallableKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -85,7 +85,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -45,13 +45,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -101,8 +101,8 @@ void main()
#endif #endif
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -112,7 +112,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -864,24 +864,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -906,7 +913,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -1001,24 +1001,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -1043,7 +1050,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -72,8 +72,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[gl_InstanceID].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(gl_InstanceID)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[gl_InstanceID].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(gl_InstanceID)].m[matIdx];
// Diffuse // Diffuse
vec3 diffuse = computeDiffuse(mat, L, normal); vec3 diffuse = computeDiffuse(mat, L, normal);

View file

@ -842,24 +842,31 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
@ -888,7 +895,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -44,6 +44,10 @@ extern std::vector<std::string> defaultSearchPaths;
#include "nvvk/renderpasses_vk.hpp" #include "nvvk/renderpasses_vk.hpp"
#include "nvvk/shaders_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 // Holding the camera matrices
struct CameraMatrices struct CameraMatrices
@ -850,9 +854,10 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
@ -866,9 +871,10 @@ void HelloVulkan::createRtShaderBindingTable()
} }
// Sizes // Sizes
uint32_t rayGenSize = groupHandleSize; uint32_t rayGenSize = groupAlignSize;
uint32_t missSize = groupHandleSize; uint32_t missSize = groupAlignSize;
uint32_t hitSize = groupHandleSize + sizeof(HitRecordBuffer); uint32_t hitSize =
ROUND_UP(groupHandleSize + static_cast<int>(sizeof(HitRecordBuffer)), groupAlignSize);
uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize; uint32_t newSbtSize = rayGenSize + 2 * missSize + 3 * hitSize;
std::vector<uint8_t> sbtBuffer(newSbtSize); std::vector<uint8_t> sbtBuffer(newSbtSize);
@ -882,19 +888,22 @@ void HelloVulkan::createRtShaderBindingTable()
memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1 memcpy(pBuffer, handles[2], groupHandleSize); // Miss 1
pBuffer += missSize; pBuffer += missSize;
memcpy(pBuffer, handles[3], groupHandleSize); // Hit 0 uint8_t* pHitBuffer = pBuffer;
pBuffer += groupHandleSize; memcpy(pHitBuffer, handles[3], groupHandleSize); // Hit 0
pBuffer += sizeof(HitRecordBuffer); // No data // No data
pBuffer += hitSize;
memcpy(pBuffer, handles[4], groupHandleSize); // Hit 1 pHitBuffer = pBuffer;
pBuffer += groupHandleSize; memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 1
memcpy(pBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data pHitBuffer += groupHandleSize;
pBuffer += sizeof(HitRecordBuffer); memcpy(pHitBuffer, &m_hitShaderRecord[0], sizeof(HitRecordBuffer)); // Hit 1 data
pBuffer += hitSize;
memcpy(pBuffer, handles[4], groupHandleSize); // Hit 2 pHitBuffer = pBuffer;
pBuffer += groupHandleSize; memcpy(pHitBuffer, handles[4], groupHandleSize); // Hit 2
memcpy(pBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data pHitBuffer += groupHandleSize;
pBuffer += sizeof(HitRecordBuffer); memcpy(pHitBuffer, &m_hitShaderRecord[1], sizeof(HitRecordBuffer)); // Hit 2 data
pBuffer += hitSize;
} }
// Write the handles in the SBT // Write the handles in the SBT
@ -933,12 +942,14 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
0, m_rtPushConstants); 0, m_rtPushConstants);
vk::DeviceSize progSize = m_rtProperties.shaderGroupHandleSize; // Size of a program identifier 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 alignSize = m_rtProperties.shaderGroupBaseAlignment;
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 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... // m_sbtBuffer holds all the shader handles: raygen, n-miss, hit...
const vk::StridedBufferRegionKHR raygenShaderBindingTable = {m_rtSBTBuffer.buffer, rayGenOffset, const vk::StridedBufferRegionKHR raygenShaderBindingTable = {m_rtSBTBuffer.buffer, rayGenOffset,

View file

@ -40,8 +40,8 @@ void main()
int objId = scnDesc.i[pushC.instanceId].objId; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);

View file

@ -43,8 +43,8 @@ void main()
int objId = scnDesc.i[pushC.instanceId].objId; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -73,7 +73,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -842,27 +842,33 @@ void HelloVulkan::createRtShaderBindingTable()
auto groupCount = auto groupCount =
static_cast<uint32_t>(m_rtShaderGroups.size()); // 3 shaders: raygen, miss, chit 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 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 // 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); std::vector<uint8_t> shaderHandleStorage(sbtSize);
m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize, m_device.getRayTracingShaderGroupHandlesKHR(m_rtPipeline, 0, groupCount, sbtSize,
shaderHandleStorage.data()); shaderHandleStorage.data());
// Write the handles in the SBT // Write the handles in the SBT
nvvk::CommandPool genCmdBuf(m_device, m_graphicsQueueIndex); m_rtSBTBuffer = m_alloc.createBuffer(sbtSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::CommandBuffer cmdBuf = genCmdBuf.createCommandBuffer(); vk::MemoryPropertyFlagBits::eHostVisible
| vk::MemoryPropertyFlagBits::eHostCoherent);
m_debug.setObjectName(m_rtSBTBuffer.buffer, std::string("SBT").c_str());
m_rtSBTBuffer = // Write the handles in the SBT
m_alloc.createBuffer(cmdBuf, shaderHandleStorage, vk::BufferUsageFlagBits::eRayTracingKHR); void* mapped = m_alloc.map(m_rtSBTBuffer);
m_debug.setObjectName(m_rtSBTBuffer.buffer, "SBT"); 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(); m_alloc.finalizeAndReleaseStaging();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Ray Tracing the scene // Ray Tracing the scene
// //
@ -884,7 +890,8 @@ void HelloVulkan::raytrace(const vk::CommandBuffer& cmdBuf, const nvmath::vec4f&
| vk::ShaderStageFlagBits::eMissKHR, | vk::ShaderStageFlagBits::eMissKHR,
0, m_rtPushConstants); 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 rayGenOffset = 0u * progSize; // Start at the beginning of m_sbtBuffer
vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen vk::DeviceSize missOffset = 1u * progSize; // Jump over raygen
vk::DeviceSize hitGroupOffset = 3u * progSize; // Jump over the previous shaders 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; int objId = scnDesc.i[pushC.instanceId].objId;
// Material of the object // Material of the object
int matIndex = matIdx[objId].i[gl_PrimitiveID]; int matIndex = matIdx[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIndex]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIndex];
vec3 N = normalize(fragNormal); vec3 N = normalize(fragNormal);
@ -67,7 +67,7 @@ void main()
{ {
int txtOffset = scnDesc.i[pushC.instanceId].txtOffset; int txtOffset = scnDesc.i[pushC.instanceId].txtOffset;
uint txtId = txtOffset + mat.textureId; uint txtId = txtOffset + mat.textureId;
vec3 diffuseTxt = texture(textureSamplers[txtId], fragTexCoord).xyz; vec3 diffuseTxt = texture(textureSamplers[nonuniformEXT(txtId)], fragTexCoord).xyz;
diffuse *= diffuseTxt; diffuse *= diffuseTxt;
} }

View file

@ -40,13 +40,13 @@ void main()
uint objId = scnDesc.i[gl_InstanceID].objId; uint objId = scnDesc.i[gl_InstanceID].objId;
// Indices of the triangle // Indices of the triangle
ivec3 ind = ivec3(indices[objId].i[3 * gl_PrimitiveID + 0], // ivec3 ind = ivec3(indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 0], //
indices[objId].i[3 * gl_PrimitiveID + 1], // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 1], //
indices[objId].i[3 * gl_PrimitiveID + 2]); // indices[nonuniformEXT(objId)].i[3 * gl_PrimitiveID + 2]); //
// Vertex of the triangle // Vertex of the triangle
Vertex v0 = vertices[objId].v[ind.x]; Vertex v0 = vertices[nonuniformEXT(objId)].v[ind.x];
Vertex v1 = vertices[objId].v[ind.y]; Vertex v1 = vertices[nonuniformEXT(objId)].v[ind.y];
Vertex v2 = vertices[objId].v[ind.z]; Vertex v2 = vertices[nonuniformEXT(objId)].v[ind.z];
const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y); const vec3 barycentrics = vec3(1.0 - attribs.x - attribs.y, attribs.x, attribs.y);
@ -79,8 +79,8 @@ void main()
} }
// Material of the object // Material of the object
int matIdx = matIndex[objId].i[gl_PrimitiveID]; int matIdx = matIndex[nonuniformEXT(objId)].i[gl_PrimitiveID];
WaveFrontMaterial mat = materials[objId].m[matIdx]; WaveFrontMaterial mat = materials[nonuniformEXT(objId)].m[matIdx];
// Diffuse // Diffuse
@ -90,7 +90,7 @@ void main()
uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset; uint txtId = mat.textureId + scnDesc.i[gl_InstanceID].txtOffset;
vec2 texCoord = vec2 texCoord =
v0.texCoord * barycentrics.x + v1.texCoord * barycentrics.y + v2.texCoord * barycentrics.z; 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); vec3 specular = vec3(0);