Corrected image layout and descriptor set handling in RayTracing sample. (#460)

This commit is contained in:
Andreas Süßenbach 2019-12-19 13:59:48 +01:00 committed by Markus Tavenrath
parent 7da1c8baf0
commit 0280efc78c
2 changed files with 34 additions and 21 deletions

View File

@ -837,36 +837,48 @@ int main(int /*argc*/, char** /*argv*/)
bindings.push_back(vk::DescriptorSetLayoutBinding(3, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // vertex buffer bindings.push_back(vk::DescriptorSetLayoutBinding(3, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // vertex buffer
bindings.push_back(vk::DescriptorSetLayoutBinding(4, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // index buffer bindings.push_back(vk::DescriptorSetLayoutBinding(4, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // index buffer
bindings.push_back(vk::DescriptorSetLayoutBinding(5, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // material buffer bindings.push_back(vk::DescriptorSetLayoutBinding(5, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlagBits::eClosestHitNV)); // material buffer
bindings.push_back(vk::DescriptorSetLayoutBinding(6, vk::DescriptorType::eCombinedImageSampler, static_cast<uint32_t>(textures.size()), vk::ShaderStageFlagBits::eClosestHitNV)); // textures bindings.push_back(vk::DescriptorSetLayoutBinding(6, vk::DescriptorType::eCombinedImageSampler, vk::su::checked_cast<uint32_t>(textures.size()), vk::ShaderStageFlagBits::eClosestHitNV)); // textures
std::vector<vk::DescriptorPoolSize> descriptorPoolSizes; std::vector<vk::DescriptorPoolSize> descriptorPoolSizes;
descriptorPoolSizes.reserve(bindings.size()); descriptorPoolSizes.reserve(bindings.size());
for (const auto& b : bindings) for (const auto& b : bindings)
{ {
descriptorPoolSizes.push_back(vk::DescriptorPoolSize(b.descriptorType, b.descriptorCount)); descriptorPoolSizes.push_back(vk::DescriptorPoolSize(b.descriptorType, vk::su::checked_cast<uint32_t>(swapChainData.images.size()) * b.descriptorCount));
} }
vk::UniqueDescriptorPool rayTracingDescriptorPool = device->createDescriptorPoolUnique(vk::DescriptorPoolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, 1, vk::DescriptorPoolCreateInfo descriptorPoolCreateInfo(vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, vk::su::checked_cast<uint32_t>(swapChainData.images.size()),
static_cast<uint32_t>(descriptorPoolSizes.size()), vk::su::checked_cast<uint32_t>(descriptorPoolSizes.size()), descriptorPoolSizes.data());
descriptorPoolSizes.data())); vk::UniqueDescriptorPool rayTracingDescriptorPool = device->createDescriptorPoolUnique(descriptorPoolCreateInfo);
vk::UniqueDescriptorSetLayout rayTracingDescriptorSetLayout = device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo({}, static_cast<uint32_t>(bindings.size()), vk::UniqueDescriptorSetLayout rayTracingDescriptorSetLayout = device->createDescriptorSetLayoutUnique(vk::DescriptorSetLayoutCreateInfo({}, static_cast<uint32_t>(bindings.size()),
bindings.data())); bindings.data()));
vk::UniqueDescriptorSet rayTracingDescriptorSet = std::move(device->allocateDescriptorSetsUnique(vk::DescriptorSetAllocateInfo(*rayTracingDescriptorPool, 1, std::vector<vk::DescriptorSetLayout> layouts;
&*rayTracingDescriptorSetLayout)).front()); for (size_t i = 0; i < swapChainData.images.size(); i++)
{
layouts.push_back(*rayTracingDescriptorSetLayout);
}
vk::DescriptorSetAllocateInfo descriptorSetAllocateInfo(*rayTracingDescriptorPool, vk::su::checked_cast<uint32_t>(layouts.size()), layouts.data());
std::vector<vk::UniqueDescriptorSet> rayTracingDescriptorSets = device->allocateDescriptorSetsUnique(descriptorSetAllocateInfo);
// Bind ray tracing specific descriptor sets into pNext of a vk::WriteDescriptorSet // Bind ray tracing specific descriptor sets into pNext of a vk::WriteDescriptorSet
vk::WriteDescriptorSetAccelerationStructureNV writeDescriptorSetAcceleration(1, &*topLevelAS.acclerationStructure); vk::WriteDescriptorSetAccelerationStructureNV writeDescriptorSetAcceleration(1, &*topLevelAS.acclerationStructure);
vk::WriteDescriptorSet accelerationDescriptionSet(*rayTracingDescriptorSet, 0, 0, 1, bindings[0].descriptorType); std::vector<vk::WriteDescriptorSet> accelerationDescriptionSets;
accelerationDescriptionSet.pNext = &writeDescriptorSetAcceleration; for (size_t i = 0; i < rayTracingDescriptorSets.size(); i++)
device->updateDescriptorSets(accelerationDescriptionSet, {}); {
accelerationDescriptionSets.push_back(vk::WriteDescriptorSet(*rayTracingDescriptorSets[i], 0, 0, 1, bindings[0].descriptorType));
accelerationDescriptionSets.back().pNext = &writeDescriptorSetAcceleration;
}
device->updateDescriptorSets(accelerationDescriptionSets, {});
// Bind all the other buffers and images, starting with dstBinding == 2 (dstBinding == 1 is used by the backBuffer view) // Bind all the other buffers and images, starting with dstBinding == 2 (dstBinding == 1 is used by the backBuffer view)
vk::su::updateDescriptorSets(device, rayTracingDescriptorSet, for (size_t i = 0; i < rayTracingDescriptorSets.size(); i++)
{
vk::su::updateDescriptorSets(device, rayTracingDescriptorSets[i],
{ {
{ bindings[2].descriptorType, uniformBufferData.buffer, vk::UniqueBufferView() }, { bindings[2].descriptorType, uniformBufferData.buffer, vk::UniqueBufferView() },
{ bindings[3].descriptorType, vertexBufferData.buffer, vk::UniqueBufferView() }, { bindings[3].descriptorType, vertexBufferData.buffer, vk::UniqueBufferView() },
{ bindings[4].descriptorType, indexBufferData.buffer, vk::UniqueBufferView() }, { bindings[4].descriptorType, indexBufferData.buffer, vk::UniqueBufferView() },
{ bindings[5].descriptorType, materialBufferData.buffer, vk::UniqueBufferView() } { bindings[5].descriptorType, materialBufferData.buffer, vk::UniqueBufferView() }
}, textures, 2); }, textures, 2);
}
// create the ray-tracing shader modules // create the ray-tracing shader modules
glslang::InitializeProcess(); glslang::InitializeProcess();
@ -998,22 +1010,19 @@ int main(int /*argc*/, char** /*argv*/)
commandBuffer->bindVertexBuffers(0, *vertexBufferData.buffer, {0}); commandBuffer->bindVertexBuffers(0, *vertexBufferData.buffer, {0});
commandBuffer->bindIndexBuffer(*indexBufferData.buffer, 0, vk::IndexType::eUint32); commandBuffer->bindIndexBuffer(*indexBufferData.buffer, 0, vk::IndexType::eUint32);
commandBuffer->drawIndexed(vk::su::checked_cast<uint32_t>(indices.size()), 1, 0, 0, 0); commandBuffer->drawIndexed(vk::su::checked_cast<uint32_t>(indices.size()), 1, 0, 0, 0);
commandBuffer->endRenderPass();
} }
else else
{ {
vk::ImageMemoryBarrier imageMemoryBarrier({}, vk::AccessFlagBits::eShaderWrite, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR, VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED, swapChainData.images[backBufferIndex], vk::ImageSubresourceRange(vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
commandBuffer->pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, nullptr, nullptr, imageMemoryBarrier);
vk::DescriptorImageInfo imageInfo(nullptr, *swapChainData.imageViews[backBufferIndex], vk::ImageLayout::eGeneral); vk::DescriptorImageInfo imageInfo(nullptr, *swapChainData.imageViews[backBufferIndex], vk::ImageLayout::eGeneral);
device->updateDescriptorSets(vk::WriteDescriptorSet(*rayTracingDescriptorSet, 1, 0, 1, bindings[1].descriptorType, &imageInfo), {}); device->updateDescriptorSets(vk::WriteDescriptorSet(*rayTracingDescriptorSets[backBufferIndex], 1, 0, 1, bindings[1].descriptorType, &imageInfo), {});
commandBuffer->beginRenderPass(vk::RenderPassBeginInfo(*renderPass, *framebuffers[backBufferIndex], vk::Rect2D(vk::Offset2D(0, 0), windowExtent), vk::su::setImageLayout(commandBuffer, swapChainData.images[backBufferIndex], surfaceFormat.format, vk::ImageLayout::eUndefined, vk::ImageLayout::eGeneral);
static_cast<uint32_t>(clearValues.size()), clearValues.data()), vk::SubpassContents::eInline);
commandBuffer->bindPipeline(vk::PipelineBindPoint::eRayTracingNV, *rayTracingPipeline); commandBuffer->bindPipeline(vk::PipelineBindPoint::eRayTracingNV, *rayTracingPipeline);
commandBuffer->bindDescriptorSets(vk::PipelineBindPoint::eRayTracingNV, *rayTracingPipelineLayout, 0, *rayTracingDescriptorSet, nullptr); commandBuffer->bindDescriptorSets(vk::PipelineBindPoint::eRayTracingNV, *rayTracingPipelineLayout, 0, *rayTracingDescriptorSets[backBufferIndex], nullptr);
VkDeviceSize rayGenOffset = 0; // starting with raygen VkDeviceSize rayGenOffset = 0; // starting with raygen
VkDeviceSize missOffset = shaderGroupHandleSize; // after raygen VkDeviceSize missOffset = shaderGroupHandleSize; // after raygen
@ -1023,9 +1032,9 @@ int main(int /*argc*/, char** /*argv*/)
commandBuffer->traceRaysNV(*shaderBindingTableBufferData.buffer, rayGenOffset, *shaderBindingTableBufferData.buffer, missOffset, missStride, *shaderBindingTableBufferData.buffer, commandBuffer->traceRaysNV(*shaderBindingTableBufferData.buffer, rayGenOffset, *shaderBindingTableBufferData.buffer, missOffset, missStride, *shaderBindingTableBufferData.buffer,
hitGroupOffset, hitGroupStride, nullptr, 0, 0, windowExtent.width, windowExtent.height, 1); hitGroupOffset, hitGroupStride, nullptr, 0, 0, windowExtent.width, windowExtent.height, 1);
}
commandBuffer->endRenderPass(); vk::su::setImageLayout(commandBuffer, swapChainData.images[backBufferIndex], surfaceFormat.format, vk::ImageLayout::eGeneral, vk::ImageLayout::ePresentSrcKHR);
}
// frame end // frame end
commandBuffer->end(); commandBuffer->end();

View File

@ -517,6 +517,7 @@ namespace vk
destinationAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; destinationAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
break; break;
case vk::ImageLayout::eGeneral: // empty destinationAccessMask case vk::ImageLayout::eGeneral: // empty destinationAccessMask
case vk::ImageLayout::ePresentSrcKHR:
break; break;
case vk::ImageLayout::eShaderReadOnlyOptimal: case vk::ImageLayout::eShaderReadOnlyOptimal:
destinationAccessMask = vk::AccessFlagBits::eShaderRead; destinationAccessMask = vk::AccessFlagBits::eShaderRead;
@ -544,6 +545,9 @@ namespace vk
case vk::ImageLayout::eGeneral: case vk::ImageLayout::eGeneral:
destinationStage = vk::PipelineStageFlagBits::eHost; destinationStage = vk::PipelineStageFlagBits::eHost;
break; break;
case vk::ImageLayout::ePresentSrcKHR:
destinationStage = vk::PipelineStageFlagBits::eBottomOfPipe;
break;
case vk::ImageLayout::eShaderReadOnlyOptimal: case vk::ImageLayout::eShaderReadOnlyOptimal:
destinationStage = vk::PipelineStageFlagBits::eFragmentShader; destinationStage = vk::PipelineStageFlagBits::eFragmentShader;
break; break;