Skip to content

Rendering engine architecture #1

@ASVIEST

Description

@ASVIEST

It heavily inspired by guide on https://www.howtovulkan.com

Vulkan is a headache, but it can be eased with extensions:

  • Dynamic rendering (no more VkRenderPass and VkFramebuffer). It makes vulkan rendering much simpler at cost of tiled gpu's which mostly for mobile etc. So tiled gpu's fuck you. But with VK_KHR_dynamic_rendering_local_read can also work without overhead for tiled gpu if it will needed.
  • Descriptor indexing (aka bindless descriptors)
  • Synchronization2
  • Buffer device address
  • Unified image layouts (allows always use VK_IMAGE_LAYOUT_GENERAL)
  • [Maybe] Push descriptors

The rendering engine should use a render graph generated at compile time via nim macros. This way, there should be no performance overhead compared to manual control of render pass inputs and outputs. At the same time it significantly reduces the complexity of working with the renderer.

render pass API pseudo code:

pass "scene":
  produce "sceneColor"
  clear [1.0, 0.0, 0.0, 1.0]
  record cmd:
    # do some drawing

pass "final":
  consume "sceneColor"
  output Swapchain
  shader[fragment] fancyPostProcessEffectSpirv

Textures: simply use bindless texture array. Yes, texture atlases are no longer necessary nowadays since bindless descriptor sets exist. Each texture is a VkImage, and image views are stored in a bindless descriptor set. The original purpose of texture atlases was to reduce draw call counts. Bindless descriptors can achieve this in a single draw call via instanced rendering with vertex or storage buffer. Moreover, it slightly simplifies the shaders. In fact, this enables drawing in a single draw call and allows for easy addition of new textures in real-time without significant overhead, which is quite useful for modding or procedural texture generation. Interestingly, this also simplifies the creation of textures with different sizes.

Memory management is a huge pain, so it's necessary to either create bindings for a library like Vulkan Memory Allocator or build a custom simple GPU allocator (the implementation at https://github.com/Traverse-Research/gpu-allocator is worth looking into).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions