EDIT: Docs and minor bug fixed
This commit is contained in:
23
docs/ASSETS.md
Normal file
23
docs/ASSETS.md
Normal file
@@ -0,0 +1,23 @@
|
||||
**Assets & Paths**
|
||||
|
||||
- Default locations
|
||||
- `assets/` for models/textures and `shaders/` for GLSL live at the repo root.
|
||||
- The engine auto‑detects these folders by walking up from the working directory.
|
||||
|
||||
- Override root via environment
|
||||
- Set `VKG_ASSET_ROOT` to a directory containing `assets/` and/or `shaders/`.
|
||||
- Example: `VKG_ASSET_ROOT=/home/user/vulkan-engine ./bin/vulkan_engine`
|
||||
|
||||
- API
|
||||
- Use `AssetLocator` through `EngineContext::getAssets()` helpers:
|
||||
- `shaderPath("name.spv")` resolves a shader.
|
||||
- `assetPath("relative/or/absolute")` resolves runtime assets.
|
||||
- `modelPath("some.glb")` is an alias for `assetPath`.
|
||||
|
||||
- Sample content
|
||||
- The engine loads `assets/police_office.glb` by default in `VulkanEngine::init()`.
|
||||
- Ensure this file (and any textures it references) exists under your asset root, or adjust the path used by the sample scene.
|
||||
|
||||
- Materials & sRGB
|
||||
- See `docs/asset_manager.md` for mesh/material creation and sRGB/UNORM handling.
|
||||
|
||||
38
docs/BUILD.md
Normal file
38
docs/BUILD.md
Normal file
@@ -0,0 +1,38 @@
|
||||
**Build & Environment**
|
||||
|
||||
- Prerequisites
|
||||
- Vulkan SDK installed and `VULKAN_SDK` set.
|
||||
- A C++20 compiler and CMake ≥ 3.8.
|
||||
- GPU drivers with Vulkan 1.2+.
|
||||
|
||||
- Configure
|
||||
- `cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug`
|
||||
- Re-run configure after toolchain or dependency changes.
|
||||
|
||||
- Build (single-config)
|
||||
- `cmake --build build --target vulkan_engine`
|
||||
|
||||
- Build (multi-config, e.g., MSVC)
|
||||
- `cmake --build build --config Release`
|
||||
|
||||
- Run
|
||||
- `./bin/vulkan_engine` (Linux/macOS)
|
||||
- `bin/vulkan_engine.exe` (Windows)
|
||||
|
||||
- Shaders
|
||||
- CMake compiles GLSL via `glslangValidator` to SPIR‑V targeting Vulkan 1.2:
|
||||
- Files under `shaders/*.vert|*.frag|*.comp` are rebuilt on `cmake --build`.
|
||||
- Windows helper: `./compile_shaders.ps1` uses `glslc` with `--target-env=vulkan1.3` and supports additional stages (mesh/task/ray tracing).
|
||||
- Ensure `glslangValidator`/`glslc` is on `PATH`. See `docs/SHADERS.md`.
|
||||
|
||||
- Windows SDK note
|
||||
- `CMakeLists.txt` includes a default SDK path for Windows `1.3.296.0`:
|
||||
- Update the path or set `VULKAN_SDK` accordingly if your version differs.
|
||||
|
||||
- Third‑party deps
|
||||
- Vendored under `third_party/` and brought in via CMake. Do not edit headers directly; update through targets.
|
||||
|
||||
- Validation Layers
|
||||
- Enabled in Debug (`kUseValidationLayers = true` in `src/core/config.h`).
|
||||
- Disable by building Release or toggling the flag during local experimentation.
|
||||
|
||||
34
docs/FrameResources.md
Normal file
34
docs/FrameResources.md
Normal file
@@ -0,0 +1,34 @@
|
||||
## Frame Resources: Per-Frame Command, Sync, and Transient Descriptors
|
||||
|
||||
Per-frame struct that owns the command buffer, semaphores/fence, a transient descriptor allocator, and a small deletion queue. Frames are indexed by `FRAME_OVERLAP` (currently 2) and rotated by `_frameNumber` in `VulkanEngine`.
|
||||
|
||||
- File: `src/core/frame_resources.h/.cpp`
|
||||
|
||||
### Responsibilities
|
||||
- Command recording: `_mainCommandBuffer` allocated from a per-frame `_commandPool` with RESET flag.
|
||||
- Synchronization: `_swapchainSemaphore` (image acquired), `_renderSemaphore` (render finished), `_renderFence` (CPU wait per frame).
|
||||
- Transient descriptors: `_frameDescriptors` is a `DescriptorAllocatorGrowable` cleared every frame via `clear_pools()`.
|
||||
- Lifetime: `_deletionQueue` holds lambdas for transient GPU objects created during the frame (buffers/images) and is flushed at the start of the next frame.
|
||||
|
||||
### Frame Flow (engine side)
|
||||
- Start of frame:
|
||||
- Wait on `_renderFence` (previous GPU work for this frame index), flush `_deletionQueue`, and clear `_frameDescriptors` pools.
|
||||
- Acquire swapchain image signaling `_swapchainSemaphore`.
|
||||
- Reset `_renderFence` and `_mainCommandBuffer`; begin recording.
|
||||
- Publish `currentFrame` pointer and `drawExtent` on `EngineContext`.
|
||||
- Graph build and execute:
|
||||
- Render Graph is cleared and rebuilt; `ResourceManager::register_upload_pass(...)` is added first if there are pending uploads.
|
||||
- Passes record using the published `currentFrame` to allocate transient descriptor sets and to enqueue per-frame cleanups.
|
||||
- Submit and present:
|
||||
- Submit `cmd` with wait on `_swapchainSemaphore` and signal `_renderSemaphore`, fence `_renderFence`.
|
||||
- Present waits on `_renderSemaphore`.
|
||||
|
||||
### Do/Don’t
|
||||
- Do use `currentFrame->_frameDescriptors` for descriptor sets that live only for this frame.
|
||||
- Do push transient resource destruction into `currentFrame->_deletionQueue`.
|
||||
- Don’t stash per-frame descriptor sets across frames — they are reset on `clear_pools()`.
|
||||
|
||||
### Extending
|
||||
- If a pass needs additional short-lived command buffers, allocate them from `_commandPool` and reset per frame.
|
||||
- If you add frames-in-flight, update `FRAME_OVERLAP` and verify fences/semaphores and swapchain image acquisition logic.
|
||||
|
||||
21
docs/RUNTIME.md
Normal file
21
docs/RUNTIME.md
Normal file
@@ -0,0 +1,21 @@
|
||||
**Runtime Controls & Debug UI**
|
||||
|
||||
- Camera
|
||||
- Move: `W/A/S/D`
|
||||
- Look: hold Right Mouse Button
|
||||
- Mouse wheel: adjust movement speed
|
||||
- Ctrl + wheel: adjust FOV (30°..110°)
|
||||
|
||||
- Windows (ImGui)
|
||||
- Background: choose compute background effect and `Render Scale`.
|
||||
- Stats: frame/draw/update timings, triangle and draw counts.
|
||||
- GPU/Resources: per‑frame allocations and render‑graph resource view.
|
||||
- Pipelines: list graphics pipelines and hot‑reload changed shaders.
|
||||
- Targets: swapchain/draw extent/format info.
|
||||
- PostFX: tonemap operator (Reinhard/ACES) and exposure.
|
||||
- Scene: counts of opaque/transparent draws.
|
||||
|
||||
- Shadow Modes
|
||||
- Cascaded shadow mapping (CSM) is the default; cascades are created per‑frame via the render graph.
|
||||
- If ray tracing extensions and device support are present, ray‑traced shadows can be enabled via `_context->shadowSettings.mode` (see `src/core/config.h` and usage in `LightingPass`).
|
||||
|
||||
42
docs/RayTracing.md
Normal file
42
docs/RayTracing.md
Normal file
@@ -0,0 +1,42 @@
|
||||
## Ray Tracing Manager: BLAS Cache and Per-Frame TLAS
|
||||
|
||||
Optional subsystem that enables hybrid or full ray traced shadows via Ray Query. It builds and caches BLAS per mesh and rebuilds a TLAS from the current `DrawContext` when enabled.
|
||||
|
||||
- Files: `src/core/vk_raytracing.h/.cpp`
|
||||
|
||||
### Device Feature & Extension Enablement
|
||||
- Feature detection happens in `DeviceManager::init_vulkan()` and sets:
|
||||
- `VK_KHR_acceleration_structure`, `VK_KHR_ray_query`, and `VK_KHR_deferred_host_operations` (if supported).
|
||||
- Device features are appended via `DeviceBuilder.add_pNext(...)`.
|
||||
- `DescriptorManager::gpuSceneDataLayout()` adds a TLAS binding at `(set=0, binding=1)` when AS is supported.
|
||||
|
||||
### BLAS Build & Cache
|
||||
- `AccelStructureHandle getOrBuildBLAS(const std::shared_ptr<MeshAsset>& mesh)`:
|
||||
- One GAS per `MeshAsset`, keyed by vertex buffer `VkBuffer`.
|
||||
- Populated with one triangle geometry per `GeoSurface`.
|
||||
- Built with `VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR` and device-local storage + scratch.
|
||||
- Cached in `_blasByVB` for reuse across frames.
|
||||
- Called from `AssetManager::createMesh(...)` and from GLTF loader after mesh upload.
|
||||
|
||||
### TLAS Rebuild Per Frame
|
||||
- `VkAccelerationStructureKHR buildTLASFromDrawContext(const DrawContext& dc)`:
|
||||
- Iterates `dc.OpaqueSurfaces` and creates one instance per render object.
|
||||
- Looks up BLAS by `RenderObject::vertexBuffer`; if missing, instance is skipped.
|
||||
- Uploads instances to a CPU→GPU buffer with device address.
|
||||
- Builds TLAS with `immediate_submit` and stores device address for Ray Query.
|
||||
|
||||
### Renderer Integration
|
||||
- In `VulkanEngine::draw()` before building passes:
|
||||
- If RT mode is enabled (`shadowSettings.mode != 0`) and manager exists, TLAS is rebuilt from the latest draw context.
|
||||
- Lighting pass binds the TLAS at `set=0,binding=1` when available.
|
||||
|
||||
### Modes & UI
|
||||
- Mode 0: Shadow maps only (CSM).
|
||||
- Mode 1: Hybrid — selected cascades assisted by Ray Query (configurable bitmask).
|
||||
- Mode 2: Ray Query only (no shadow maps).
|
||||
|
||||
### Notes & Caveats
|
||||
- BLAS cache key is the vertex buffer handle; if you rebuild meshes in-place, BLAS must be invalidated.
|
||||
- CPU→GPU memory is used for the TLAS instance buffer to simplify updates. On some platforms, you may prefer staging + device-local.
|
||||
- The RT path requires Vulkan 1.2+ with Ray Query and Acceleration Structure features available.
|
||||
|
||||
@@ -70,6 +70,8 @@ addPass(std::move(myPass));
|
||||
- Background (compute): Declares `ComputeWrite(drawImage)` and dispatches a selected effect instance.
|
||||
- Geometry (G-Buffer): Declares 3 color attachments and `DepthAttachment`, plus buffer reads for shared index/vertex buffers.
|
||||
- Lighting (deferred): Reads G‑Buffer as sampled images and writes to `drawImage`.
|
||||
- Shadows: Cascaded shadow maps render to per-frame transient depth images (four cascades). If Ray Query is enabled,
|
||||
the lighting pass additionally samples TLAS to evaluate shadow visibility according to the selected mode.
|
||||
- Transparent (forward): Writes to `drawImage` with depth test against `depthImage` after lighting.
|
||||
- ImGui: Inserted just before present to draw on the swapchain image.
|
||||
|
||||
|
||||
@@ -47,3 +47,7 @@ Central allocator and uploader built on VMA. Provides creation helpers, an immed
|
||||
- For tooling and one‑off setup, use `immediate_submit(lambda)` to avoid per‑frame queuing.
|
||||
- When creating transient images/buffers used only inside a pass, prefer the Render Graph’s `create_*` so destruction is automatic at frame end.
|
||||
|
||||
### Known Issue (transition after mip generation)
|
||||
|
||||
- In the Render Graph upload pass, the mipmap path should leave the image in `VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL` after `vkutil::generate_mipmaps(...)`. If you see an extra transition back to `TRANSFER_DST_OPTIMAL` after mip generation, remove it. The helper already transitions to the final sampled layout.
|
||||
|
||||
|
||||
25
docs/SHADERS.md
Normal file
25
docs/SHADERS.md
Normal file
@@ -0,0 +1,25 @@
|
||||
**Shaders & Hot Reload**
|
||||
|
||||
- Locations
|
||||
- Sources live under `shaders/` and are compiled to `.spv` next to the sources.
|
||||
|
||||
- Build integration
|
||||
- CMake invokes `glslangValidator -V` for `*.vert`, `*.frag`, `*.comp` targeting Vulkan 1.2.
|
||||
- Windows PowerShell helper `compile_shaders.ps1` uses `glslc` targeting Vulkan 1.3 and supports additional stages:
|
||||
- `.mesh` (`-fshader-stage=mesh`), `.task`, and ray tracing stages (`.rgen`, `.rmiss`, `.rchit`, `.rahit`, `.rint`, `.rcall`).
|
||||
- Keep `glslangValidator`/`glslc` on `PATH` and ensure your Vulkan SDK is installed.
|
||||
|
||||
- Hot reload
|
||||
- `PipelineManager::hotReloadChanged()` watches `.spv` modification times.
|
||||
- Pipelines rebind the next frame when a shader file timestamp changes.
|
||||
- ImGui → Pipelines window provides a manual “Reload Changed” button and lists currently registered pipelines.
|
||||
|
||||
- Conventions
|
||||
- Name SPIR‑V files with full extension, e.g. `fullscreen.vert.spv`, `deferred_lighting.frag.spv`.
|
||||
- Use `EngineContext::getAssets()->shaderPath("<name>.spv")` when registering pipelines.
|
||||
- Use sRGB formats for albedo textures and UNORM for PBR control textures (see `docs/asset_manager.md`).
|
||||
|
||||
- Adding a pipeline (graphics)
|
||||
- Fill `GraphicsPipelineCreateInfo` with shader paths, descriptor set layouts, optional push constants, and a `configure(PipelineBuilder&)` callback to set topology, raster, depth/blend, and attachment formats.
|
||||
- Register with `PipelineManager::createGraphicsPipeline(name, info)`. Retrieve via `getGraphics` or `getMaterialPipeline`.
|
||||
|
||||
26
docs/TROUBLESHOOTING.md
Normal file
26
docs/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,26 @@
|
||||
**Troubleshooting**
|
||||
|
||||
- Shader compiler not found
|
||||
- Ensure `glslangValidator` (and/or `glslc` on Windows) is on `PATH`.
|
||||
- Re‑open your terminal after installing the Vulkan SDK.
|
||||
|
||||
- Windows SDK version mismatch
|
||||
- `CMakeLists.txt` references `C:/VulkanSDK/1.3.296.0` by default.
|
||||
- Update the path or set `VULKAN_SDK` to your installed version.
|
||||
|
||||
- Validation errors on startup
|
||||
- Update GPU drivers and Vulkan SDK.
|
||||
- Try running a Release build to confirm if the issue is validation‑only.
|
||||
|
||||
- Black screen or out‑of‑date swapchain
|
||||
- Resize the window once to force a swapchain rebuild.
|
||||
- Check the ImGui “Targets” window for swapchain/draw formats and extent.
|
||||
|
||||
- No models rendering
|
||||
- Verify `assets/police_office.glb` exists (see `docs/ASSETS.md`).
|
||||
- Open the “Scene” window to confirm draw counts > 0.
|
||||
|
||||
- Shader changes not visible
|
||||
- Confirm the `.spv` file changed (timestamp) and click “Reload Changed” in the Pipelines window.
|
||||
- Ensure you are editing the correct files referenced by `shaderPath()`.
|
||||
|
||||
Reference in New Issue
Block a user