28 #define GRAPHICS_GUARD() return;
29 #define COMPUTE_GUARD() return;
30#elif defined(COMPUTE_DEBUG)
31 #define GRAPHICS_GUARD() return;
32 #define COMPUTE_GUARD()
34 #define GRAPHICS_GUARD()
35 #define COMPUTE_GUARD()
40 const auto& renderingDataManager =
renderer->getRenderingDataManager();
41 std::vector<VkDescriptorImageInfo> imageInfos = renderingDataManager->generateTextureDescriptorInfos();
42 PLOGI <<
"Update renderer descriptor sets";
71 PLOGI <<
"Update object culling descriptor sets";
72 const auto& renderingDataManager =
renderer->getRenderingDataManager();
76 VkImageView hiZView = (previousFrameHiZView != VK_NULL_HANDLE)
77 ? previousFrameHiZView
81 VkDescriptorImageInfo hiZImageInfo{
84 .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
89 VkDescriptorImageInfo currentHiZImageInfo{
92 .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
124 .update(
context->getVkDevice());
129 PLOGI <<
"Update binning allocator descriptor sets";
130 const auto& renderingDataManager =
renderer->getRenderingDataManager();
142 .update(
context->getVkDevice());
147 PLOGI <<
"Update meshlet unpacking dispatcher descriptor sets";
152 .update(
context->getVkDevice());
157 PLOGI <<
"Update meshlet unpacking descriptor sets (V2 bindings)";
165 .update(
context->getVkDevice());
173 .update(
context->getVkDevice());
178 const auto& renderingDataManager =
renderer->getRenderingDataManager();
185 .update(
context->getVkDevice());
195 .update(
context->getVkDevice());
200 PLOGI <<
"Update VS binning allocator descriptor sets";
201 const auto& renderingDataManager =
renderer->getRenderingDataManager();
209 .update(
context->getVkDevice());
214 PLOGI <<
"Update VS instance unpacking descriptor sets";
219 .update(
context->getVkDevice());
224 PLOGI <<
"Update VS prepare draw descriptor sets for eye " <<
eyeIndex;
225 const auto& renderingDataManager =
renderer->getRenderingDataManager();
227 PLOGI <<
"[VS_BUFFER_DEBUG] Eye " <<
eyeIndex <<
" VSPrepareDraw descriptor binding:"
235 .update(
context->getVkDevice());
239 PLOGI <<
"Refreshing all descriptor sets for eye " <<
eyeIndex;
253 }
catch (
const std::runtime_error& e) {
259 if (rdm ==
nullptr)
return;
263 PLOGI <<
"RenderProcess " <<
eyeIndex <<
" syncing: version "
313 const glm::mat4 mat = glm::transpose(eyeViewProjection);
322 for (
int i = 0; i < 6; ++i) {
331 for (
int i = 0; i < 6; ++i) {
346 VkDeviceSize uniformBufferOffsetAlignment,
347 VkCommandPool graphicsCommandPool,
348 VkCommandPool transferCommandPool,
349 VkDescriptorPool descriptorPool,
350 VkDescriptorSetLayout graphicsDescriptorSetLayout,
362 staticVertexUniformData.viewProjectionMatrices[0] = glm::mat4(1.0f);
363 staticVertexUniformData.viewProjectionMatrices[1] = glm::mat4(1.0f);
367 VkCommandBufferAllocateInfo commandBufferAllocateInfo{
368 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
369 .commandPool = graphicsCommandPool,
370 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
371 .commandBufferCount = 1u
378 VkCommandBufferAllocateInfo transferBufferAllocInfo{
379 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
380 .commandPool = transferCommandPool,
381 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
382 .commandBufferCount = 1u
389 VkSemaphoreCreateInfo semaphoreCreateInfo{
390 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
394 VulkanHelper::createSemaphore( context->getVkDevice(), &semaphoreCreateInfo,
nullptr, &mirrorViewImageReadySemaphore,
"Mirror View Image Ready" );
396 VkFenceCreateInfo fenceCreateInfo{
397 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
398 .flags = VK_FENCE_CREATE_SIGNALED_BIT
400 VulkanHelper::createFence(context->getVkDevice(), &fenceCreateInfo,
nullptr, &transferCompleteFence,
"Transfer Complete");
401 VulkanHelper::createFence(context->getVkDevice(), &fenceCreateInfo,
nullptr, &graphicsCompleteFence,
"Graphics Complete");
403 PLOGI <<
"Created fences for RenderProcess (eyeIndex=" << eyeIndex <<
")";
409 createCountDispatcherBuffers();
411 createDispatcherDispatchBuffer();
412 createBinnedVisibleMeshletIndexBuffer();
413 createMeshletCounterBuffer();
414 createMeshletToObjectMapBuffer();
415 createViewProjectionBuffer();
416 createPerObjectSSBOBuffer();
417 createObjectMeshletDataBuffer();
418 createMeshRenderingInfoBuffers();
419 createFrustumUBOBuffer();
420 createIndirectDrawBuffer();
421 createVisibleObjectRangesBuffer();
422 createPass1CounterBuffer();
423 createBinningAllocatorBuffers();
424 createCullingFailedBuffers();
425 createHiZViewProjectionBuffer();
426 createVSIndirectDrawBuffers();
427 createVSInstancedDrawingBuffers();
431 const Headset* headset = renderer->getHeadset();
432 createHiZPyramid(context->getVkDevice(), headset->getEyeResolution(0), 2u);
436 const auto& renderingDataManager = renderer->getRenderingDataManager();
442 VkDescriptorSetVariableDescriptorCountAllocateInfo variableDescriptorCountAllocInfo{
443 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
444 .descriptorSetCount = 1u,
445 .pDescriptorCounts = &variableDescriptorCount
449 VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{
450 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
451 .pNext = &variableDescriptorCountAllocInfo,
452 .descriptorPool = descriptorPool,
453 .descriptorSetCount = 1u,
454 .pSetLayouts = &graphicsDescriptorSetLayout,
458 renderer->getObjectCullingComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
459 renderer->getBinningAllocatorComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
460 renderer->getMeshletUnpackingDispatchComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
461 renderer->getMeshletUnpackingComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
462 renderer->getMeshletCullingDispatchComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
463 renderer->getMeshletCullingComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
464 renderer->getDrawPreparationComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
468 renderer->getVSBinningAllocatorComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
469 renderer->getVSInstanceUnpackingComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
470 renderer->getVSPrepareDrawComputePass().createDescriptorSet(context->getVkDevice(), getEyeIndex(), descriptorPool);
471 PLOGI <<
"[VS_INSTANCED] Created descriptor sets for VS instanced drawing passes (eye " << eyeIndex <<
")";
472 }
catch (
const std::runtime_error& e) {
473 PLOGI <<
"[VS_INSTANCED] VS instanced drawing disabled, skipping descriptor sets";
476 updateRendererDescriptorSets();
478 updateComputeObjectCullingDescriptorSets();
479 updateComputeBinningAllocatorDescriptorSets();
480 updateComputeMeshletUnpackingDispatcherDescriptorSets();
481 updateComputeMeshletUnpackingDescriptorSets();
482 updateComputeMeshletCullingDispatcherDescriptorSets();
483 updateComputeMeshletCullingDescriptorSets();
484 updateComputePrepareDrawDescriptorSets();
554 for (
size_t eye = 0; eye < headset->
getEyeCount(); eye++) {
555 if (activeCamera !=
nullptr) {
611 std::vector<VkDescriptorImageInfo> imageInfos(textures.size());
612 for (uint32_t i = 0; i < imageInfos.size(); i++) {
613 imageInfos.at(i).imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
614 imageInfos.at(i).sampler = textures.at(i)->getVkImageSampler();
615 imageInfos.at(i).imageView = textures.at(i)->getVkImageView();
618 VkWriteDescriptorSet write {
619 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
622 .dstArrayElement = firstIndex,
623 .descriptorCount =
static_cast<uint32_t
>(imageInfos.size()),
624 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
625 .pImageInfo = imageInfos.data(),
626 .pBufferInfo =
nullptr,
627 .pTexelBufferView =
nullptr
631 vkUpdateDescriptorSets(
context->getVkDevice(), 1, &write, 0,
nullptr);
635 uint32_t firstIndex) {
638 writeContainer->
imageInfos.resize(textures.size());
639 for (uint32_t i = 0; i < writeContainer->
imageInfos.size(); i++) {
640 writeContainer->
imageInfos.at(i).imageLayout =
641 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
642 writeContainer->
imageInfos.at(i).sampler = textures.at(i)->getVkImageSampler();
643 writeContainer->
imageInfos.at(i).imageView = textures.at(i)->getVkImageView();
646 writeContainer->
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
650 writeContainer->
write.dstArrayElement =
652 writeContainer->
write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
653 writeContainer->
write.descriptorCount =
static_cast<uint32_t
>(
656 writeContainer->
write.pBufferInfo =
nullptr;
657 writeContainer->
write.pTexelBufferView =
nullptr;
671 PLOGI <<
"Called update descriptor sets for textures";
672 vkUpdateDescriptorSets(
context->getVkDevice(),
static_cast<uint32_t
>(writes.size()), writes.data(), 0,
nullptr);
675 delete writeContainer;
704 binnedVisibleMeshletIndexBuffer->create(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
711 meshletCounterBuffer->create(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
717 constexpr uint32_t INITIAL_BUFFER_CAPACITY = 1000;
719 constexpr VkDeviceSize bufferSize = INITIAL_BUFFER_CAPACITY *
sizeof(
PerObjectData);
727 constexpr uint32_t INITIAL_BUFFER_CAPACITY = 1000;
729 constexpr VkDeviceSize bufferSize =
sizeof(
GpuMeshDescription) * INITIAL_BUFFER_CAPACITY;
736 constexpr VkDeviceSize frustumUBOSize =
sizeof(
FrustumPlanes);
743 constexpr VkDeviceSize bufferSize =
MAX_PIPELINES *
sizeof(VkDrawMeshTasksIndirectCommandEXT);
745 indirectDrawBuffer->create(bufferSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
747 std::vector<VkDrawMeshTasksIndirectCommandEXT> cmd(
MAX_PIPELINES, {1,1,1});
807 for (uint32_t eye = 0; eye < 2u; ++eye) {
814 static_cast<float>(eyeResolution.width),
815 static_cast<float>(eyeResolution.height)
888 constexpr VkDeviceSize bufferSize =
sizeof(
Dispatch);
890 dispatcherDispatchBuffer->create(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT );
895 constexpr VkDeviceSize counterBufferSize =
sizeof(uint32_t);
896 constexpr VkDeviceSize dispatchBufferSize =
sizeof(
Dispatch);
899 countDispatcherCounter->create(counterBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
907 constexpr uint32_t INITIAL_BUFFER_CAPACITY = 1000;
915 constexpr VkDeviceSize bufferSize =
sizeof(uint32_t) * 2;
917 pass1CounterBuffer->create(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
939 constexpr uint32_t INITIAL_BUFFER_CAPACITY = 1000;
940 constexpr VkDeviceSize allocationStructSize = 32;
941 constexpr VkDeviceSize allocationsBufferSize = allocationStructSize * INITIAL_BUFFER_CAPACITY;
945 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
946 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
950 constexpr VkDeviceSize pipelineCountersSize =
sizeof(uint32_t) *
MAX_PIPELINES;
953 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
954 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
958 constexpr VkDeviceSize binOffsetsSize =
sizeof(uint32_t) *
MAX_PIPELINES;
961 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
962 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
981 constexpr uint32_t INITIAL_BUFFER_CAPACITY = 1000;
982 constexpr VkDeviceSize failedBufferSize =
sizeof(uint32_t) * INITIAL_BUFFER_CAPACITY;
986 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
987 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
991 constexpr VkDeviceSize counterSize =
sizeof(uint32_t);
994 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
995 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1011 constexpr uint32_t INITIAL_DRAW_CAPACITY = 10000;
1012 constexpr VkDeviceSize drawBufferSize =
sizeof(VkDrawIndexedIndirectCommand) * INITIAL_DRAW_CAPACITY;
1016 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1017 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1021 constexpr VkDeviceSize countBufferSize =
sizeof(uint32_t);
1024 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1025 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1028 PLOGI <<
"[VS_PATH] Created VS indirect draw buffers for frame " <<
eyeIndex;
1043 constexpr uint32_t INITIAL_INSTANCE_CAPACITY = 10000;
1044 constexpr uint32_t MAX_GEOMETRY_TYPES = 256;
1045 constexpr uint32_t MAX_VS_INSTANCES_PER_GEO = 16384;
1049 constexpr VkDeviceSize visibleInstancesSize =
sizeof(uint32_t) * INITIAL_INSTANCE_CAPACITY;
1052 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1053 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1057 constexpr VkDeviceSize countSize =
sizeof(uint32_t);
1060 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1061 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1066 constexpr VkDeviceSize allocationStructSize = 3 *
sizeof(uint32_t);
1067 constexpr VkDeviceSize allocationsBufferSize = allocationStructSize * INITIAL_INSTANCE_CAPACITY;
1070 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1071 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1075 constexpr VkDeviceSize geometryCountersSize =
sizeof(uint32_t) * MAX_GEOMETRY_TYPES;
1078 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1079 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1085 constexpr VkDeviceSize instanceIdsSize =
sizeof(uint32_t) * MAX_GEOMETRY_TYPES * MAX_VS_INSTANCES_PER_GEO;
1088 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1089 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1094 constexpr VkDeviceSize drawCommandsSize =
sizeof(VkDrawIndexedIndirectCommand) * MAX_GEOMETRY_TYPES;
1097 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1098 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1104 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1105 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1108 PLOGI <<
"[VS_PATH_INSTANCED] Created VS instanced drawing buffers for frame " <<
eyeIndex;
1143 constexpr uint32_t INITIAL_CLUSTER_SURVIVOR_CAPACITY = 100000;
1147 constexpr VkDeviceSize survivorsSize =
sizeof(
ClusterSurvivor) * INITIAL_CLUSTER_SURVIVOR_CAPACITY;
1150 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1151 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1155 constexpr VkDeviceSize counterSize =
sizeof(uint32_t);
1158 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
1159 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
1165 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1169 PLOGI <<
"[LOD] Created LOD cluster selection buffers for frame " <<
eyeIndex;
1185 float nearPlane,
float screenWidth,
float screenHeight,
1186 float errorThresholdPixels,
bool ditherEnabled) {
1192 lodConfigData_.screenSize = glm::vec2(screenWidth, screenHeight);
1202 bool anyRecreated =
false;
1203 constexpr VkMemoryPropertyFlags deviceLocal = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1204 constexpr VkBufferUsageFlags storageUsage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1207 const VkDeviceSize perObjectSize = primitiveCount *
sizeof(
PerObjectData);
1227 constexpr VkDeviceSize allocationStructSize = 32;
1228 const uint32_t clusterCount =
renderer->getRenderingDataManager()->getClusterCount();
1229 const VkDeviceSize allocationsSize = (primitiveCount + clusterCount) * allocationStructSize;
1232 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, deviceLocal);
1236 const VkDeviceSize failedBufferSize = primitiveCount *
sizeof(uint32_t);
1239 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, deviceLocal);
1244 const VkDeviceSize vsDrawBufferSize = primitiveCount *
sizeof(VkDrawIndexedIndirectCommand);
1247 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, deviceLocal);
1259 PLOGI <<
"RenderProcess " <<
eyeIndex <<
": Buffers resized for " << primitiveCount <<
" primitives";
1262 return anyRecreated;
1271 if (device == VK_NULL_HANDLE)
return;
1273 for (VkImageView mipView :
mipViews) {
1274 if (mipView != VK_NULL_HANDLE) {
1275 vkDestroyImageView(device, mipView,
nullptr);
1281 vkDestroyImageView(device,
fullView,
nullptr);
1285 if (
image != VK_NULL_HANDLE) {
1286 vkDestroyImage(device,
image,
nullptr);
1287 image = VK_NULL_HANDLE;
1301 PLOGI <<
"Creating Hi-Z pyramid for frame " <<
eyeIndex <<
" with resolution "
1302 << resolution.width <<
"x" << resolution.height;
1307 std::floor(std::log2(std::max(resolution.width, resolution.height)))) + 1;
1309 PLOGI <<
"Hi-Z pyramid will have " <<
hiZPyramid_.mipLevels <<
" mip levels";
1312 VkImageCreateInfo imageCreateInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
1313 imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
1314 imageCreateInfo.extent.width = resolution.width;
1315 imageCreateInfo.extent.height = resolution.height;
1316 imageCreateInfo.extent.depth = 1u;
1317 imageCreateInfo.mipLevels =
hiZPyramid_.mipLevels;
1318 imageCreateInfo.arrayLayers = arrayLayers;
1319 imageCreateInfo.format = VK_FORMAT_R32_SFLOAT;
1320 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1321 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1322 imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT;
1323 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
1324 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1326 PLOG_FN_VK(vkCreateImage(device, &imageCreateInfo,
nullptr, &
hiZPyramid_.image));
1328 "Hi-Z Pyramid Image Frame " + std::to_string(
eyeIndex));
1331 VkMemoryRequirements memRequirements;
1332 vkGetImageMemoryRequirements(device,
hiZPyramid_.image, &memRequirements);
1334 uint32_t memoryTypeIndex = 0u;
1335 VkMemoryRequirements2 memReqs2{VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
1336 memReqs2.memoryRequirements = memRequirements;
1338 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, memoryTypeIndex))
1340 THROW_ERROR(
"Could not find suitable memory type for Hi-Z pyramid");
1343 VkMemoryAllocateInfo allocInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
1344 allocInfo.allocationSize = memRequirements.size;
1345 allocInfo.memoryTypeIndex = memoryTypeIndex;
1347 PLOG_FN_VK(vkAllocateMemory(device, &allocInfo,
nullptr, &
hiZPyramid_.deviceMemory));
1349 "Hi-Z Pyramid Memory Frame " + std::to_string(
eyeIndex));
1354 VkImageViewCreateInfo viewInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
1356 viewInfo.viewType = (arrayLayers == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
1357 viewInfo.format = VK_FORMAT_R32_SFLOAT;
1358 viewInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
1359 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
1360 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1361 viewInfo.subresourceRange.baseMipLevel = 0;
1362 viewInfo.subresourceRange.levelCount =
hiZPyramid_.mipLevels;
1363 viewInfo.subresourceRange.baseArrayLayer = 0;
1364 viewInfo.subresourceRange.layerCount = arrayLayers;
1366 PLOG_FN_VK(vkCreateImageView(device, &viewInfo,
nullptr, &
hiZPyramid_.fullView));
1368 "Hi-Z Pyramid Full View Frame " + std::to_string(
eyeIndex));
1372 for (uint32_t mip = 0; mip <
hiZPyramid_.mipLevels; mip++)
1374 VkImageViewCreateInfo mipViewInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
1376 mipViewInfo.viewType = (arrayLayers == 1u ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY);
1377 mipViewInfo.format = VK_FORMAT_R32_SFLOAT;
1378 mipViewInfo.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
1379 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
1380 mipViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1381 mipViewInfo.subresourceRange.baseMipLevel = mip;
1382 mipViewInfo.subresourceRange.levelCount = 1;
1383 mipViewInfo.subresourceRange.baseArrayLayer = 0;
1384 mipViewInfo.subresourceRange.layerCount = arrayLayers;
1386 PLOG_FN_VK(vkCreateImageView(device, &mipViewInfo,
nullptr, &
hiZPyramid_.mipViews[mip]));
1388 "Hi-Z Pyramid Mip " + std::to_string(mip) +
" View Frame " + std::to_string(
eyeIndex));
1391 PLOGI <<
"Hi-Z pyramid created successfully for frame " <<
eyeIndex;
constexpr uint32_t MAX_PIPELINES
constexpr uint32_t MAX_MESHLETS_PER_BIN
constexpr uint32_t MAX_TEXTURE_COUNT
#define TRACY_ZONE_SCOPED_FUNCTION
#define TRACY_ZONE_SCOPED_NAMED(name)
The application context is the core class which stores the basic openxr and vulkan objects.
A camera component that provides view and projection matrices based on its SceneNode transform....
glm::mat4 getViewMatrix() const
Gets the view matrix computed from the camera's world transform.
The Descriptor set updater is used to create a list of descriptor set writes which are executed with ...
void update(VkDevice device) const
Updates the bindings on a descriptor sets.
DescriptorSetUpdater & addUniformBuffer(uint32_t binding, const VkDescriptorBufferInfo *pBufferInfo)
Adds a uniform buffer (glsl std140 buffer) to the chain of updates to execute.
DescriptorSetUpdater & addStorageBuffer(uint32_t binding, const VkDescriptorBufferInfo *pBufferInfo)
Adds a storage buffer (glsl std430 buffer) to the chain of updates to execute.
DescriptorSetUpdater & addTextureArrayIf(const bool condition, uint32_t binding, std::vector< VkDescriptorImageInfo > *imageInfos)
Adds updates to texture array.
VkSampler getHiZSampler() const
VkExtent2D getEyeResolution(size_t eyeIndex) const
Gets eye resolution in x and y for a specified eye index. 0 is left.
glm::mat4 getViewProjectionMatrix(size_t eyeIndex) const
Gets you a matrix of the multiplied view and projection matrix.
glm::mat4 getEyeProjectionMatrix(size_t eyeIndex) const
Gets the projection matrix for an eye.
uint32_t getEyeCount() const
Gets eye count.
VkCommandBuffer graphicsCommandBuffer
void createCountDispatcherBuffers()
const VulkanStagedBuffer & getLodConfigBuffer() const
VkSemaphore mirrorViewImageReadySemaphore
BS_tracy::tracy_thread_pool< BS_tracy::tp::none > bufferUpdateThreadPool
void processTextureUpload()
std::optional< VulkanBuffer > vsInstanceIdsBuffer_
Stage 2: VSInstanceUnpacking outputs.
void updateComputeVSBinningAllocatorDescriptorSets() const
std::optional< VulkanBuffer > dispatcherDispatchBuffer
const VulkanBuffer & getMeshletCounterBuffer() const
const VulkanBuffer & getCullingFailedBuffer() const
Two-pass occlusion culling buffer getters.
std::optional< VulkanStagedBuffer > meshRenderingInfoBuffer
VkCommandBuffer & getGraphicsCommandBuffer()
void updateComputeVSPrepareDrawDescriptorSets() const
void updateComputeMeshletCullingDescriptorSets() const
std::optional< VulkanStagedBuffer > perObjectDataBuffer
const VulkanBuffer & getVisibleObjectRangesBuffer() const
const VulkanStagedBuffer & getFrustumUBOBuffer() const
bool ensureBufferSizes(uint32_t primitiveCount)
Ensures RenderProcess buffers have sufficient capacity for the given primitive count Dynamically resi...
const VulkanBuffer & getIndirectDrawBuffer() const
std::vector< TextureWriteContainer * > textureWritesToUpload
void updateComputeObjectCullingDescriptorSets(VkImageView previousFrameHiZView=VK_NULL_HANDLE) const
Updates object culling descriptor sets.
const std::unique_ptr< SceneManager > & sceneManager
std::optional< VulkanBuffer > vsGeometryCountersBuffer_
Atomic instance count per geometry type.
std::optional< VulkanBuffer > vsDrawCountBuffer_
Number of draw commands.
void createViewProjectionBuffer()
ApplicationContext * context
const VulkanBuffer & getPipelineCountersBuffer() const
std::optional< VulkanBuffer > allocationsBuffer
Binning allocator stage buffers (Stage 1)
struct EngineCore::RenderProcess::ViewMatrixUniformData staticVertexUniformData
VkSemaphore transferFinishedSemaphore
const VulkanBuffer & getVSInstanceIdsBuffer() const
void updateFrustumUBOData(const Headset *headset)
std::vector< PrimitiveMeshletData > objectMeshletData
void updateEyeViewProjectionMatrices(const Headset *headset)
writes a view projection matrix to an eye
void updateMeshletDataBuffer()
std::vector< PerObjectData > perObjectData
Rendering resource.
void createDispatcherDispatchBuffer()
const VulkanBuffer & getVSDrawCommandsBuffer() const
const VulkanBuffer & getLodClusterSurvivorsBuffer() const
LOD cluster-based selection buffer getters.
VkImageView getHiZPyramidFullView() const
void updateMeshRenderingData()
bool getGraphicsFenceSubmitted() const
VkDescriptorSet graphicsDescriptorSet
void createVSIndirectDrawBuffers()
void createPass1CounterBuffer()
uint32_t getHiZMipLevels() const
std::vector< GpuMeshDescription > unifiedMeshes
VulkanStagedBufferSyncObjects uploadMeshRenderingStagingData()
const VulkanBuffer & getCullingFailedCounterBuffer() const
VkSemaphore getRenderFinishedSemaphore() const
std::optional< VulkanBuffer > vsIndirectDrawCountBuffer_
Legacy: was draw count.
void createHiZPyramid(VkDevice device, VkExtent2D resolution, uint32_t arrayLayers)
const VulkanStagedBuffer & getHiZViewProjectionBuffer() const
VkFence & getGraphicsCompleteFence()
VulkanStagedBufferSyncObjects uploadLodConfigBuffer()
Upload LOD config buffer to GPU.
std::optional< VulkanBuffer > cullingFailedBuffer
Two-pass occlusion culling buffers.
std::optional< VulkanBuffer > vsVisibleCountBuffer_
Number of visible VS path primitives.
void addTexturesToUpload(const std::vector< Texture * > &textures, uint32_t firstIndex)
void uploadNewTextures(const std::vector< Texture * > &textures, uint32_t firstIndex) const
const VulkanBuffer & getVSIndirectDrawCountBuffer() const
bool transferFenceSubmitted
VulkanStagedBuffer & getMeshletToObjectMapBuffer()
const VulkanBuffer & getLodClusterSurvivorCountBuffer() const
void createHiZViewProjectionBuffer()
void createVSInstancedDrawingBuffers()
void createVisibleObjectRangesBuffer()
FrustumPlanes frustumData
Rendering Resource.
RenderProcess(ApplicationContext *context, VkDeviceSize uniformBufferOffsetAlignment, VkCommandPool graphicsCommandPool, VkCommandPool transferCommandPool, VkDescriptorPool descriptorPool, VkDescriptorSetLayout graphicsDescriptorSetLayout, uint32_t eyeIndex, Renderer *renderer, const Engine *engine)
std::optional< VulkanStagedBuffer > objectMeshletDataBuffer
const VulkanBuffer & getAllocationsBuffer() const
Binning allocator stage buffer getters.
void updateLodConfig(const glm::vec3 &cameraPosition, const glm::mat4 &projMatrix, float nearPlane, float screenWidth, float screenHeight, float errorThresholdPixels=1.0f, bool ditherEnabled=true)
Update LOD configuration with camera and screen info Call this once per frame before dispatching prim...
void updateHiZViewProjectionData(const Headset *headset)
Updates Hi-Z view-projection data for occlusion culling Must be called after updateEyeViewProjectionM...
std::optional< VulkanBuffer > vsDrawCommandsBuffer_
Stage 3: VSPrepareDraw outputs.
bool getTransferFenceSubmitted() const
VulkanBuffer & getBinnedVisibleMeshletIndexBuffer()
const VulkanBuffer & getVSInstanceAllocationsBuffer() const
std::optional< VulkanBuffer > vsVisibleInstancesBuffer_
Primitive IDs from culling (uint array)
void setGraphicsFenceSubmitted(bool isSubmitted)
std::optional< VulkanBuffer > binnedVisibleMeshletIndexBuffer
const VulkanBuffer & getPass1CounterBuffer() const
std::optional< VulkanBuffer > pipelineCountersBuffer
Per-pipeline meshlet counters (atomic)
const VulkanBuffer & getVSGeometryCountersBuffer() const
std::optional< VulkanBuffer > pipelineBinOffsetsBuffer
Prefix sum of pipeline counters.
uint64_t lastSeenDataVersion_
VkDescriptorSet getGraphicsDescriptorSet() const
void createBinningAllocatorBuffers()
std::optional< VulkanBuffer > countDispatcherDispatchBuffer
VulkanStagedBufferSyncObjects uploadSSBOStagingBuffer()
std::optional< VulkanStagedBuffer > lodConfigBuffer_
LodConfigUBO for camera/screen info.
void updateSSBO(const Renderer *renderer)
VkCommandBuffer transferCommandBuffer
void createMeshRenderingInfoBuffers()
void createBinnedVisibleMeshletIndexBuffer()
void createCullingFailedBuffers()
VulkanStagedBufferSyncObjects uploadUniformBufferData()
VkFence & getTransferCompleteFence()
const VulkanBuffer & getVSVisibleCountBuffer() const
void createIndirectDrawBuffer()
VkFence graphicsCompleteFence
StaticFragmentUniformData staticFragmentUniformData
const VulkanBuffer & getVSDrawCountBuffer() const
void updateComputeVSInstanceUnpackingDescriptorSets() const
void createMeshletCounterBuffer()
std::optional< VulkanBuffer > vsInstanceAllocationsBuffer_
Stage 1: VSBinningAllocator outputs.
VkCommandBuffer & getTransferCommandBuffer()
HiZViewProjectionData hiZViewProjectionData_
Hi-Z view-projection data for occlusion culling (per-frame to avoid races)
void updateComputeMeshletCullingDispatcherDescriptorSets() const
const VulkanStagedBuffer & getObjectMeshletDataBuffer() const
void createMeshletToObjectMapBuffer()
std::optional< VulkanBuffer > indirectDrawBuffer
void addStagingBufferForCleanup(VulkanBuffer &&stagingBuffer)
std::vector< VulkanBuffer > stagingBuffersForCleanup
void updateComputePrepareDrawDescriptorSets() const
std::optional< VulkanStagedBuffer > hiZViewProjectionBuffer_
void refreshAllDescriptorSets()
Refreshes all descriptor sets after buffer recreation Call this when RenderingDataManager buffers hav...
std::optional< VulkanBuffer > meshletCounterBuffer
void updateFragmentTime(float time)
Sets the time value for time based fragment shader effects.
std::optional< VulkanBuffer > vsIndirectDrawBuffer_
Legacy: was VkDrawIndexedIndirectCommand array.
VulkanStagedBufferSyncObjects uploadFrustumUBO()
void cleanup()
Cleans up all artifacts of the class.
void createPerObjectSSBOBuffer()
std::optional< VulkanBuffer > lodClusterSurvivorsBuffer_
LOD cluster-based selection buffers.
void setTransferFenceSubmitted(bool isSubmitted)
std::optional< VulkanBuffer > cullingFailedCounterBuffer
Atomic counter for failed objects.
const VulkanStagedBuffer & getPerObjectSSBOBuffer() const
LodConfigUBO lodConfigData_
CPU-side LOD config data.
VkSemaphore getMirrorViewImageSemaphore() const
VkFence transferCompleteFence
std::optional< VulkanBuffer > countDispatcherCounter
void updateComputeBinningAllocatorDescriptorSets() const
void updateRendererDescriptorSets()
VkSemaphore renderFinishedSemaphore
std::optional< VulkanStagedBuffer > meshletToObjectMapBuffer
void createFrustumUBOBuffer()
const VulkanBuffer & getPipelineBinOffsetsBuffer() const
std::optional< VulkanStagedBuffer > viewProjectionBuffer
std::optional< VulkanBuffer > pass1CounterBuffer
void cleanupStagingBuffer()
const VulkanStagedBuffer & getMeshRenderingBuffer() const
void syncWithRenderingDataManager(RenderingDataManager *rdm)
Sync descriptor sets with RenderingDataManager if data has changed Compares version numbers and updat...
bool graphicsFenceSubmitted
void createObjectMeshletDataBuffer()
VulkanStagedBuffer & getViewProjectionBuffer()
void updateComputeMeshletUnpackingDescriptorSets() const
const VulkanBuffer & getVSVisibleInstancesBuffer() const
Vertex shader path buffer getters (instanced drawing pipeline)
std::optional< VulkanBuffer > visibleObjectRangesBuffer
void updateComputeMeshletUnpackingDispatcherDescriptorSets() const
std::optional< VulkanStagedBuffer > frustumDataBuffer
VkSemaphore getTransferFinishedSemaphore() const
uint32_t getEyeIndex() const
const VulkanBuffer & getVSIndirectDrawBuffer() const
Legacy VS path buffer getters (backwards compatibility)
std::optional< VulkanBuffer > lodClusterSurvivorCountBuffer_
Atomic counter for LOD cluster survivors.
VulkanStagedBufferSyncObjects uploadHiZViewProjectionUBO()
Uploads Hi-Z view-projection UBO to GPU.
The rendering data manager is supposed to hold all methods to update the contents of the buffers whic...
uint64_t getDataVersion() const
Get the current data version Incremented each time buffers are updated. RenderProcesses use this to k...
RAII wrapper for Vulkan buffer and device memory.
VkBuffer getBuffer() const
static bool findSuitableMemoryType(VkPhysicalDevice physicalDevice, VkMemoryRequirements2 requirements, VkMemoryPropertyFlags properties, uint32_t &out_typeIndex)
static void createFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence, const std::string &name)
static VkResult allocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers, const std::string &name)
static VkResult createSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore, const std::string &name)
static void uploadDataToExistingBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool, VkQueue queue, VkDeviceSize size, const void *dataPtr, VkBuffer targetBuffer)
static void setObjectName(VkDevice device, VulkanObjectType objectHandle, const std::string &name)
static VkResult allocateDescriptorSets(VkDevice device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets, const std::string &name)
static VkDescriptorBufferInfo fullBufferInfo(VkBuffer buffer)
@ MATERIAL_DYNAMIC_TEXTURES
@ MESHLET_TO_OBJECT_MAP_BUFFER
@ MATERIAL_STATIC_LIGHTMAP
@ MATERIAL_DIFFUSE_FLAT_COLOR
@ MESHLET_TRIANGLES_BUFFER
@ BINNED_VISIBLE_MESHLET_INDEX_BUFFER
@ MATERIAL_MOVABLE_DIFFUSE
@ MATERIAL_DIFFUSE_SHADER
@ MESHLET_CULLING_DISPATCH_COUNTER
@ MESHLET_CULLING_DISPATCH_BUFFER
@ MESHLET_CULLING_INDICES
@ MESHLET_CULLING_BINNED_RENDERING
@ MESHLET_CULLING_FRUSTUM_PLANES
@ MESHLET_UNPACKING_DISPATCH_COUNTER
@ MESHLET_UNPACKING_DISPATCH_BUFFER
@ MESHLET_UNPACKING_DISPATCH_LOD_COUNTER
@ UNPACKING_LOD_CLUSTER_SURVIVOR_COUNT
@ UNPACKING_SURVIVOR_COUNT
@ PREPARE_DRAW_MESHLET_COUNTER
@ PREPARE_DRAW_INDIRECT_DRAW
@ BINNING_PIPELINE_COUNTERS
@ BINNING_CLUSTER_LOD_DATA
@ BINNING_PRIMITIVE_MESHLET_DATA
@ BINNING_CULLING_SURVIVORS
@ BINNING_LOD_CLUSTER_SURVIVOR_COUNT
@ BINNING_PRIMITIVE_MESHLET_DATA_LOD
@ BINNING_LOD_CLUSTER_SURVIVORS
@ PRIMITIVE_INSTANCE_CULLING_DATA
@ PRIMITIVE_CULLING_FRUSTUM_PLANES
@ PRIMITIVE_CULLING_FAILED_COUNTER
@ PRIMITIVE_CULLING_FAILED
@ PRIMITIVE_PER_OBJECT_DATA
@ PRIMITIVE_CULLING_COUNTER
@ PRIMITIVE_MESH_GEOMETRY_DATA
@ LOD_CLUSTER_SURVIVOR_COUNT
@ PRIMITIVE_MESH_UNPACKING_DATA
@ PRIMITIVE_SINGLE_MESHLET_GEO
@ PRIMITIVE_VS_INDIRECT_COUNT
@ PRIMITIVE_VS_INDIRECT_DRAW
@ VS_BINNING_VISIBLE_COUNT
@ VS_BINNING_VISIBLE_INSTANCES
@ VS_BINNING_GEOMETRY_COUNTERS
@ VS_BINNING_INSTANCE_CULLING_DATA
@ VS_BINNING_MESH_GEOMETRY_DATA
@ VS_UNPACKING_ALLOCATIONS
@ VS_UNPACKING_VISIBLE_COUNT
@ VS_UNPACKING_INSTANCE_IDS
@ VS_PREPARE_SINGLE_MESHLET_GEO
@ VS_PREPARE_GEOMETRY_COUNTERS
@ VS_PREPARE_INDIRECT_DRAWS
Log category system implementation.
CameraComponent * getActiveCamera()
Gets the currently active camera.
Cluster survivor data passed from culling to binning shaders. Contains the LOD selection result inclu...
Frustum planes for frustum culling in the first compute shader stage.
Describes a mesh on the gpu. Where it is in the memory and how many meshlets it consists of.
View-projection data for Hi-Z occlusion culling Contains matrices and screen info needed to project b...
LOD configuration for GPU shader selection. Updated per-frame with camera and screen information.
Stores all data which is unique to each object.
Data for the primitive culling shader to assemble and pass on to the unpacking shader.
VkDeviceMemory deviceMemory
VkImageView fullView
View of all mip levels for sampling.
void cleanup(VkDevice device)
std::vector< VkImageView > mipViews
Per-mip views for compute writes.
VkWriteDescriptorSet write
std::vector< VkDescriptorImageInfo > imageInfos
Struct for the result buffer of the culling operation. Stores which objects have passed the culling t...