oceanzhang88 / Vulkan-Rasterizer-Apple-Silicon

A Vulkan renderer running on macOS M1 chip

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A Vulkan Rasterizer

This C++ project is to build a modern rasterization pipeline around the Vulkan graphics API.

About

Modern Vulkan Graphics API is important in many ways. This project uses Vulkan to build a rasterization pipeline on Apple Silicon M1/2 chip. The default rasterization pipeline is Forward light architecture.

The components of this rasterizer incude: projective camera, shader loading and parsing, texture, Vulkan pipeline components: Device, Swap Chain, Command Buffer, Descriptor, Push Constant, loading obj models, multi-point Lighting, alpha blending and more. Meanwhile, you can move the camera around using keyboard keys.

Vulkan Overview

vulkan_pipeline_block_diagram

Command Buffer and Pipelines

GPU Memory and Command Execution A Rasterization Pipeline Data Structure within Command
Screenshot 2023-03-19 at 19 10 51 Screenshot 2023-03-19 at 19 11 04
A General Purpose Compute Pipeline Data Structure within Command A Ray Tracing Pipeline Data Structure within Command (2020 and later)
Screenshot 2023-03-19 at 19 11 25 Screenshot 2023-03-28 at 10 38 32

Commands and Synchronization

Screenshot 2023-03-19 at 19 40 30

Race Conditions

  1. Read-after-Write (R-a-W) – the memory write in one operation starts overwriting the memory that another operation’s read needs to use.
  2. Write-after-Read (W-a-R) – the memory read in one operation hasn’t yet finished before another operation starts overwriting that memory.
  3. Write-after-Write (W-a-W) – two operations start overwriting the same memory and the end result is non-deterministic.

Sync Locks (left sends signal -> right receives signal)

  • Wait Idle Operations (GPU -> CPU sync, CPU waits on queue or device, cleanup work)
  • Fences (GPU -> CPU sync, CPU waits for acquireNextImage, avoid input latency, NVIDIA/AMD low latency mode)
  • Semaphores (queue sync, between queues)
    • Binary Semaphores (queue -> queue sync, GPU only, Swap Chain presentation and drawing)
    • Timeline Semaphores (queue -> queue sync, CPU <-> GPU sync, Physics Engine)
  • Pipeline Barriers (command -> command sync, intra-queue, cmds start in order, finish out of order)
    • Execution Barriers (execution-only dependency, memory disregarded, not commonly used)
    • Memory Barriers (execution and memory dependencies, optimal layout for operation, image wraps texture)
  • Render Pass Subpass Dependencies (subpass memory dependencies, stage+access flags, similar to memory barrier)
  • Events (“split barriers”, CPU -> GPU sync, not sure how to use)

Lighting Architecture

NOTE: Lighting pipeline architecture choice (Forward/Deferred/Tile-based Forward/Tile-based Deferred) is how we orchestrate Vulkan API not a built-in part of Vulkan or any other Graphics APIs.

In deferred lighting architecture, we render objects to G-Buffer first and then render lights reading from G-Buffer. In forward mode, lights and objects are coupled together.

Tile-based Deferred architecture is proposed by Apple:

TBDR

Tile-based Forward architecture is proposed by a paper with a fancy name:

Foward+

Tile based GPU

Tile GPU

Demo

202303120158.1.1.mp4

Requirements

C++ Lib:

  • GLM
  • GLFW

Vulkan SDK:

Build on MacOS

C++17 is needed to compile the project.

./macBuild

Run on MacOS

cd build
./Vulkan-Rasterizer

Keyboard Controls

  • W/A/S/D/E/Q to change the camera positions.

  • Arrow key up/left/right/down to rotate the camera.

Credits

  1. Thanks to the wonderful tutorial by Brendan
  2. Thanks to the Vulkan Docs

About

A Vulkan renderer running on macOS M1 chip


Languages

Language:C++ 89.2%Language:GLSL 8.2%Language:CMake 2.6%Language:Shell 0.1%