Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
RenderProcess.h
Go to the documentation of this file.
1#pragma once
2
3#include "RenderData.h"
5
6#include <array>
9#include <glm/mat4x4.hpp>
10#include <memory>
11#include <optional>
12#include <vector>
13
14namespace EngineCore
15{
16 class Headset;
18 struct GpuMeshDescription;
19 struct PerObjectData;
20 class GraphicsPipeline;
21 class Renderer;
22 class DataBuffer;
23 class SceneManager;
25
37 class RenderProcess final
38 {
39 public:
46 void updateComputeObjectCullingDescriptorSets(VkImageView previousFrameHiZView = VK_NULL_HANDLE) const;
53
54 // VS instanced drawing pipeline descriptor set updates
58
64
71 bool ensureBufferSizes(uint32_t primitiveCount);
72
80
82
84
85 void updateSSBO( const Renderer * renderer );
87
89
90 void updateFrustumUBOData( const Headset * headset );
91
93
99 void updateHiZViewProjectionData(const Headset* headset);
100
106
109 VkDeviceSize uniformBufferOffsetAlignment,
110 VkCommandPool graphicsCommandPool,
111 VkCommandPool transferCommandPool,
112 VkDescriptorPool descriptorPool,
113 VkDescriptorSetLayout graphicsDescriptorSetLayout,
114 uint32_t eyeIndex,
116 const Engine * engine
117 );
124 void cleanup();
125
134 {
135 std::array<glm::mat4, 2u> viewProjectionMatrices; // 0 = left eye, 1 = right eye
137
146 void updateEyeViewProjectionMatrices( const Headset * headset );
147
156 void updateFragmentTime( float time );
157
158 [[nodiscard]] VkCommandBuffer & getTransferCommandBuffer();
159 [[nodiscard]] VkCommandBuffer & getGraphicsCommandBuffer();
160 [[nodiscard]] VkSemaphore getTransferFinishedSemaphore() const;
161 [[nodiscard]] VkSemaphore getRenderFinishedSemaphore() const;
162 [[nodiscard]] VkDescriptorSet getGraphicsDescriptorSet() const;
163 [[nodiscard]] VkSemaphore getMirrorViewImageSemaphore() const;
164
166 uint32_t getEyeIndex() const;
167
168 void uploadNewTextures( const std::vector<Texture *> & textures, uint32_t firstIndex ) const;
169 // upload fragmented sections
170 void addTexturesToUpload( const std::vector<Texture *> & textures, uint32_t firstIndex );
172
173 void addStagingBufferForCleanup( VulkanBuffer && stagingBuffer );
175
176 private:
177 Renderer * renderer = nullptr;
179
180 uint32_t eyeIndex = 0u; // 0 = left eye, 1 = right eye
181
182 std::vector<VulkanBuffer> stagingBuffersForCleanup;
183
191 {
192 float time;
193 };
194
196#ifdef IS_IN_DEBUG
197 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT = nullptr;
198 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT = nullptr;
199#endif
200
201 const std::unique_ptr<SceneManager> & sceneManager;
202
204 {
205 std::vector<VkDescriptorImageInfo> imageInfos{};
206 VkWriteDescriptorSet write = {};
207 };
208
209 std::vector<TextureWriteContainer *> textureWritesToUpload;
210
211 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
212
213
214 VkDescriptorSet graphicsDescriptorSet = VK_NULL_HANDLE;
215
216 std::vector<PrimitiveMeshletData> objectMeshletData{};
217
218
219 std::optional<VulkanStagedBuffer> viewProjectionBuffer;
220 std::optional<VulkanStagedBuffer> meshletToObjectMapBuffer;
221 std::optional<VulkanStagedBuffer> perObjectDataBuffer;
222 std::optional<VulkanStagedBuffer> objectMeshletDataBuffer;
223 std::optional<VulkanStagedBuffer> frustumDataBuffer;
224 std::optional<VulkanStagedBuffer> meshRenderingInfoBuffer;
225
226 std::optional<VulkanBuffer> binnedVisibleMeshletIndexBuffer;
227 std::optional<VulkanBuffer> meshletCounterBuffer;
228 std::optional<VulkanBuffer> visibleObjectRangesBuffer;
229 std::optional<VulkanBuffer> pass1CounterBuffer;
230 std::optional<VulkanBuffer> countDispatcherCounter;
231 std::optional<VulkanBuffer> countDispatcherDispatchBuffer;
232 std::optional<VulkanBuffer> indirectDrawBuffer;
233
235 std::optional<VulkanBuffer> allocationsBuffer;
236 std::optional<VulkanBuffer> pipelineCountersBuffer;
237 std::optional<VulkanBuffer> pipelineBinOffsetsBuffer;
238
239 std::optional<VulkanBuffer> dispatcherDispatchBuffer;
240
242 std::optional<VulkanBuffer> cullingFailedBuffer;
243 std::optional<VulkanBuffer> cullingFailedCounterBuffer;
244
247 std::optional<VulkanBuffer> vsVisibleInstancesBuffer_;
248 std::optional<VulkanBuffer> vsVisibleCountBuffer_;
249
251 std::optional<VulkanBuffer> vsInstanceAllocationsBuffer_;
252 std::optional<VulkanBuffer> vsGeometryCountersBuffer_;
253
255 std::optional<VulkanBuffer> vsInstanceIdsBuffer_;
256
258 std::optional<VulkanBuffer> vsDrawCommandsBuffer_;
259 std::optional<VulkanBuffer> vsDrawCountBuffer_;
260
261 // Legacy VS path buffers (kept for backwards compatibility during transition)
262 std::optional<VulkanBuffer> vsIndirectDrawBuffer_;
263 std::optional<VulkanBuffer> vsIndirectDrawCountBuffer_;
264
266 std::optional<VulkanBuffer> lodClusterSurvivorsBuffer_;
267 std::optional<VulkanBuffer> lodClusterSurvivorCountBuffer_;
268 std::optional<VulkanStagedBuffer> lodConfigBuffer_;
270
271 std::unordered_map<GraphicsPipeline *, uint32_t> pipelineIndices;
272
280 std::vector<PerObjectData> perObjectData;
281
292
297 std::optional<VulkanStagedBuffer> hiZViewProjectionBuffer_;
298 bool hiZFirstFrame_ = true;
299
300 std::vector<GpuMeshDescription> unifiedMeshes;
301
318 void createVSIndirectDrawBuffers(); // Legacy
319 void createVSInstancedDrawingBuffers(); // New instanced drawing pipeline
320 void createLodBuffers(); // LOD cluster-based selection buffers
321
322 BS_tracy::tracy_thread_pool<BS_tracy::tp::none> bufferUpdateThreadPool;
323
324 public:
326 [[nodiscard]] const VulkanStagedBuffer & getViewProjectionBuffer() const;
327
329 [[nodiscard]] const VulkanStagedBuffer & getMeshletToObjectMapBuffer() const;
330
332 [[nodiscard]] const VulkanBuffer & getBinnedVisibleMeshletIndexBuffer() const;
333
334 [[nodiscard]] const VulkanBuffer & getMeshletCounterBuffer() const;
335
336 [[nodiscard]] const VulkanStagedBuffer & getPerObjectSSBOBuffer() const;
337
338 [[nodiscard]] const VulkanBuffer & getPerObjectSSBO_StagingBuffer() const;
339
340 [[nodiscard]] const VulkanStagedBuffer & getMeshRenderingBuffer() const;
341
342 [[nodiscard]] const VulkanBuffer & getMeshRenderingStagingBuffer() const;
343
344 [[nodiscard]] const VulkanStagedBuffer & getFrustumUBOBuffer() const;
345
346 [[nodiscard]] const VulkanStagedBuffer & getHiZViewProjectionBuffer() const;
347
348 [[nodiscard]] const VulkanBuffer & getIndirectDrawBuffer() const;
349
350 [[nodiscard]] const VulkanBuffer & getVisibleObjectRangesBuffer() const;
351
352 [[nodiscard]] const VulkanBuffer & getPass1CounterBuffer() const;
353
354 [[nodiscard]] const VulkanStagedBuffer & getObjectMeshletDataBuffer() const;
355
357 [[nodiscard]] const VulkanBuffer & getAllocationsBuffer() const;
358 [[nodiscard]] const VulkanBuffer & getPipelineCountersBuffer() const;
359 [[nodiscard]] const VulkanBuffer & getPipelineBinOffsetsBuffer() const;
360
362 [[nodiscard]] const VulkanBuffer & getCullingFailedBuffer() const;
363 [[nodiscard]] const VulkanBuffer & getCullingFailedCounterBuffer() const;
364
366 [[nodiscard]] const VulkanBuffer & getVSVisibleInstancesBuffer() const;
367 [[nodiscard]] const VulkanBuffer & getVSVisibleCountBuffer() const;
368 [[nodiscard]] const VulkanBuffer & getVSInstanceAllocationsBuffer() const;
369 [[nodiscard]] const VulkanBuffer & getVSGeometryCountersBuffer() const;
370 [[nodiscard]] const VulkanBuffer & getVSInstanceIdsBuffer() const;
371 [[nodiscard]] const VulkanBuffer & getVSDrawCommandsBuffer() const;
372 [[nodiscard]] const VulkanBuffer & getVSDrawCountBuffer() const;
373
375 [[nodiscard]] const VulkanBuffer & getVSIndirectDrawBuffer() const;
376 [[nodiscard]] const VulkanBuffer & getVSIndirectDrawCountBuffer() const;
377
379 [[nodiscard]] const VulkanBuffer & getLodClusterSurvivorsBuffer() const;
380 [[nodiscard]] const VulkanBuffer & getLodClusterSurvivorCountBuffer() const;
381 [[nodiscard]] const VulkanStagedBuffer & getLodConfigBuffer() const;
382
394 void updateLodConfig(const glm::vec3& cameraPosition, const glm::mat4& projMatrix,
395 float nearPlane, float screenWidth, float screenHeight,
396 float errorThresholdPixels = 1.0f, bool ditherEnabled = true);
397
403
404 [[nodiscard]] VkFence & getTransferCompleteFence();
405 [[nodiscard]] VkFence & getGraphicsCompleteFence();
406
407 void setTransferFenceSubmitted( bool isSubmitted );
408 void setGraphicsFenceSubmitted( bool isSubmitted );
409
410 bool getTransferFenceSubmitted() const;
411 bool getGraphicsFenceSubmitted() const;
412
413 private:
414 VkCommandBuffer transferCommandBuffer = VK_NULL_HANDLE;
415 VkCommandBuffer graphicsCommandBuffer = VK_NULL_HANDLE;
416
417 VkFence transferCompleteFence = VK_NULL_HANDLE;
418 VkFence graphicsCompleteFence = VK_NULL_HANDLE;
419
420 // Initialized to true because fences are created in SIGNALED state,
421 // so the first frame needs to wait and reset them properly
424
428
429 VkSemaphore renderFinishedSemaphore = VK_NULL_HANDLE;
430 VkSemaphore transferFinishedSemaphore = VK_NULL_HANDLE;
431 VkSemaphore mirrorViewImageReadySemaphore = VK_NULL_HANDLE;
432
433 // ============================================================================
434 // Hi-Z Occlusion Culling resources (per-frame to avoid cross-frame hazards)
435 // ============================================================================
436 struct HiZPyramid {
437 VkImage image = VK_NULL_HANDLE;
438 VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
439 VkImageView fullView = VK_NULL_HANDLE;
440 std::vector<VkImageView> mipViews;
441 uint32_t mipLevels = 0;
442 VkExtent2D extent{};
443
444 void cleanup(VkDevice device);
445 };
447
448 void createHiZPyramid(VkDevice device, VkExtent2D resolution, uint32_t arrayLayers);
449
450 public:
451 // Hi-Z accessors
452 [[nodiscard]] VkImage getHiZPyramidImage() const { return hiZPyramid_.image; }
453 [[nodiscard]] VkImageView getHiZPyramidFullView() const { return hiZPyramid_.fullView; }
454 [[nodiscard]] VkImageView getHiZPyramidMipView(uint32_t mipLevel) const { return hiZPyramid_.mipViews.at(mipLevel); }
455 [[nodiscard]] uint32_t getHiZMipLevels() const { return hiZPyramid_.mipLevels; }
456 [[nodiscard]] VkExtent2D getHiZExtent() const { return hiZPyramid_.extent; }
457 };
458
459} // namespace EngineCore
The application context is the core class which stores the basic openxr and vulkan objects.
VkCommandBuffer graphicsCommandBuffer
const VulkanStagedBuffer & getLodConfigBuffer() const
VkSemaphore mirrorViewImageReadySemaphore
BS_tracy::tracy_thread_pool< BS_tracy::tp::none > bufferUpdateThreadPool
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 & getPerObjectSSBO_StagingBuffer() const
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.
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
std::vector< PerObjectData > perObjectData
Rendering resource.
const VulkanBuffer & getVSDrawCommandsBuffer() const
const VulkanBuffer & getLodClusterSurvivorsBuffer() const
LOD cluster-based selection buffer getters.
VkImageView getHiZPyramidFullView() const
bool getGraphicsFenceSubmitted() const
VkDescriptorSet graphicsDescriptorSet
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
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.
std::unordered_map< GraphicsPipeline *, uint32_t > pipelineIndices
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
VulkanStagedBuffer & getMeshletToObjectMapBuffer()
const VulkanBuffer & getLodClusterSurvivorCountBuffer() const
FrustumPlanes frustumData
Rendering Resource.
VkImageView getHiZPyramidMipView(uint32_t mipLevel) const
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.
VkDescriptorSet getGraphicsDescriptorSet() const
std::optional< VulkanBuffer > countDispatcherDispatchBuffer
VulkanStagedBufferSyncObjects uploadSSBOStagingBuffer()
std::optional< VulkanStagedBuffer > lodConfigBuffer_
LodConfigUBO for camera/screen info.
VkExtent2D getHiZExtent() const
void updateSSBO(const Renderer *renderer)
VkCommandBuffer transferCommandBuffer
VkPhysicalDevice physicalDevice
VulkanStagedBufferSyncObjects uploadUniformBufferData()
const VulkanBuffer & getVSVisibleCountBuffer() const
VkImage getHiZPyramidImage() const
StaticFragmentUniformData staticFragmentUniformData
const VulkanBuffer & getVSDrawCountBuffer() const
void updateComputeVSInstanceUnpackingDescriptorSets() const
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
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.
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
std::optional< VulkanBuffer > countDispatcherCounter
void updateComputeBinningAllocatorDescriptorSets() const
VkSemaphore renderFinishedSemaphore
std::optional< VulkanStagedBuffer > meshletToObjectMapBuffer
const VulkanBuffer & getPipelineBinOffsetsBuffer() const
std::optional< VulkanStagedBuffer > viewProjectionBuffer
std::optional< VulkanBuffer > pass1CounterBuffer
const VulkanBuffer & getMeshRenderingStagingBuffer() const
const VulkanStagedBuffer & getMeshRenderingBuffer() const
void syncWithRenderingDataManager(RenderingDataManager *rdm)
Sync descriptor sets with RenderingDataManager if data has changed Compares version numbers and updat...
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
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 renderer is the main class for rendering. It owns all data which is used any time in any frame....
Definition Renderer.h:72
The rendering data manager is supposed to hold all methods to update the contents of the buffers whic...
Manages game objects within a scene, handling registration, ID allocation, and GPU buffer synchroniza...
RAII wrapper for Vulkan buffer and device memory.
Log category system implementation.
Frustum planes for frustum culling in the first compute shader stage.
Definition RenderData.h:195
Describes a mesh on the gpu. Where it is in the memory and how many meshlets it consists of.
Definition RenderData.h:51
View-projection data for Hi-Z occlusion culling Contains matrices and screen info needed to project b...
Definition RenderData.h:209
LOD configuration for GPU shader selection. Updated per-frame with camera and screen information.
Definition RenderData.h:498
Stores all data which is unique to each object.
Definition RenderData.h:124
VkImageView fullView
View of all mip levels for sampling.
std::vector< VkImageView > mipViews
Per-mip views for compute writes.
Stores the time for time based shader effects.
std::vector< VkDescriptorImageInfo > imageInfos
This struct holds the data for the view projection matrix which will be passed to every rendered obje...
std::array< glm::mat4, 2u > viewProjectionMatrices