Skip to content

README Erfan's Tasks #834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Feb 11, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 47 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,19 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu odio gravida,

# Features

### 🧩 The Nabla Core Profile
### 🧩 **The Nabla Core Profile**

Nabla exposes [a curated set of Vulkan extensions and features](https://github.com/Devsh-Graphics-Programming/Nabla/blob/master/src/nbl/video/vulkan/profiles/NablaCore.json) compatible across the GPUs we aim to support on Windows, Linux, (coming soon MacOS, iOS as well as Android)

Vulkan evolves fast—just when you think you've figured out [sync](), you realize there's [sync2](). Keeping up with new extensions, best practices, and hardware quirks is exhausting.
Instead of digging through [gpuinfo.org](gpuinfo.org) or [Vulkan specs](), Nabla gives you a well-thought-out set of extensions—so you can focus on what you want to achieve, not get lost in extreme details.
Instead of digging through [gpuinfo.org](gpuinfo.org) or [Vulkan specs](), Nabla gives you a well-thought-out set of extensions—so you can focus on what you want to achieve, not get stuck in an eternal loop of:
- mastering a feature
- finding out about a new feature
- assesing whether obsoletes or just adds the one you've just mastered
- working if the feature is ubiquitous on the devices you target
- rewriting what you've just polished

### 🧩 Physical Device Selection and Filteration
### 🧩 **Physical Device Selection and Filteration**

Nabla allows you to select the best GPU for your compute or graphics workload.

Expand All @@ -118,11 +123,11 @@ void filterDevices(core::set<video::IPhysicalDevice*>& physicalDevices)
}
```

### 🧩 SPIR-V and Vulkan as First-Class Citizens
### 🧩 **SPIR-V and Vulkan as First-Class Citizens**

Nabla treats **SPIR-V** and **Vulkan** as the preferred, reference standard—everything else is built around them, with all other backends adapting to them.

### 🧩 Integration of Renderdoc
### 🧩 **Integration of Renderdoc**

Built-in support for capturing frames and debugging with [Renderdoc](https://renderdoc.org/).
This is how one debugs headless or async GPU workloads that are not directly involved in producing a swapchain frame to be captured by Renderdoc.
Expand All @@ -138,7 +143,7 @@ queue->submit({&submitInfo,1});
m_api->endCapture(); // End Renderdoc Capture
```

### 🧩 Nabla Event Handler: Seamless GPU-CPU Synchronization
### 🧩 **Nabla Event Handler: Seamless GPU-CPU Synchronization**

Nabla Event Handler's extensive usage of [Timeline Semaphores](https://www.khronos.org/blog/vulkan-timeline-semaphores) enables CPU Callbacks on GPU conditions.

Expand All @@ -149,11 +154,11 @@ You can enqueue callbacks that trigger upon submission completion (workload fini
memory_pool->deallocate(&offset,&size,nextSubmit.getFutureScratchSemaphore());
```

### 🧩 GPU Object Lifecycle Tracking
### 🧩 **GPU Object Lifecycle Tracking**

Nabla uses [reference counting]() to track the lifecycle of GPU objects. Descriptor sets and command buffers are responsible for maintaining reference counts on the resources (e.g., buffers, textures) they use. The queue itself also tracks command buffers, ensuring that objects remain alive as long as they are pending execution. This system guarantees the correct order of deletion and makes it difficult for GPU objects to go out of scope and be destroyed before the GPU has finished using them.

### 🧩 HLSL2021 Standard Template Library
### 🧩 **HLSL2021 Standard Template Library**

- 🔄 Reusable: Unified single-source C++/HLSL libraries eliminate code duplication with reimplementation of STL's `type_traits`, `limits`, `functional`, `tgmath`, etc.

Expand All @@ -169,14 +174,18 @@ Nabla uses [reference counting]() to track the lifecycle of GPU objects. Descrip
- [Vulkanised 2024: Beyond SPIR-V: Single Source C++ and Shader Programming](https://www.youtube.com/watch?v=JCJ35dlZJb4)
- [Vulkanised 2023: HLSL202x like its C++, building an `std::` like Library]()

### 🧩 Full Embrace of [Buffer Device Address]() and [Descriptor Indexing]()
### 🧩 **Full Embrace of [Buffer Device Address]() and [Descriptor Indexing]()**

By utilizing Buffer Device Addresses (BDAs), Nabla enables more direct access to memory through 64-bit GPU virtual addresses. Synergized with Descriptor Indexing, this approach enhances flexibility by enabling more dynamic, scalable resource binding without relying on traditional descriptor sets.

### 🧩 Minimally Invasive Design
### 🧩 **Minimally Invasive Design**

No Singletons, No Main Thread—Nabla allows multiple instances of every object (including Vulkan devices) without assuming a main thread or thread-local contexts. Thread-agnostic by design, it avoids global state and explicitly passes contexts for easy multithreading.

Nabla's minimally invasive and flexible design with api handle acquisitions and multi-window support make it ideal for custom rendering setups and low-level GPU programming without unnecessary constraints such as assuming a main thread or a single window.

Even Win32 windowing is wrapped for use across multiple threads, breaking traditional single-thread limitations.

This allows simpler porting of legacy OpenGL and DirectX applications.

<p align="center">
Expand All @@ -186,22 +195,22 @@ This allows simpler porting of legacy OpenGL and DirectX applications.
</details>
</p>

### 🧩 Designed for Interoperation
### 🧩 **Designed for Interoperation**
Nabla is built with interoperation in mind, supporting memory export and import between different compute and graphics APIs.

### 🧩 TODO: Cancellable Future based Async I/O
```
somewhere here you can add "No Singletons, No Main Thread"
### 🧩 **Cancellable Future based Async I/O**

Basically you can have as many instances of every object as you please (VK device), there's no assumption of a main thread or threadwise contexts.
File I/O is fully asynchronous, using nbl::system::future_t, a cancellable MPSC circular buffer-based future implementation.

Not thread safe, but thread agnostic, we avoid global state, we pass contexts around explicitly to allow for easy multithreading (e.g. no mutable state in factory classes).
Requests start in a PENDING state and can be invalidated before execution if needed. This enables efficient async file reads and GPU memory writes, ensuring non-blocking execution:

Can also mentioned that we managed to wrap Win32 windowing in a way that lets you use it from multiple threads.
```cpp
ISystem::future_t<size_t> bytesActuallyWritten;
file->read(bytesActuallyWritten, gpuMemory->getMappedPointer(), offsetInFile, 2*1024*1024*1024);
while (!bytesActuallyWritten.ready()) { /* Do other work */ }
```


### 🧩 Data Transfer Utilities
### 🧩 **Data Transfer Utilities**
Nabla's [Utilities](https://github.com/Devsh-Graphics-Programming/Nabla/blob/master/include/nbl/video/utilities/IUtilities.h) streamlines the process of pushing/pulling arbitrary-sized buffers and images with fixed staging memory to/from the GPU, ensuring seamless data transfers.
The system automatically handles submission when buffer memory overflows, while [promoting unsupported formats](https://github.com/Devsh-Graphics-Programming/Nabla/tree/dac9855ab4a98d764130e41a69abdc605a91092c/include/nbl/asset/format) during upload to handle color format conversions.
By leveraging device-specific properties, the system respects alignment limits and ensures deterministic behavior. The user only provides initial submission info through [SIntendedSubmitInfo](), and the utility manages subsequent submissions automatically.
Expand All @@ -211,16 +220,27 @@ By leveraging device-specific properties, the system respects alignment limits a
- 📚 Our Blog post: [Uploading Textures to GPU - The Good Way](https://erfan-ahmadi.github.io/blog/Nabla/imageupload)


### 🧩 TODO: Virtual File System (archive mounting, our alternative to #embed, everything is referenced by absolute - path)
### 🧩 **Virtual File System**

Nabla provides a [**unified Virtual File System**]() (`system::ISystem`) that supports **mounting archives and folders** under different virtual paths. This enables access to both external and embedded assets while preserving **original relative paths**.

For embedding, we provide an alternative to C++23's #embed, which allows embedding files directly into compiled binaries. Instead of relying on compiler support, we use **Python + CMake** to generate what we call **built-in resource archives**—packing files (e.g., images, shaders, `.obj`, `.mtl`, `.dds`) into DLLs as **memory-mapped `system::IFile` objects** ensuring that dependent assets (e.g., models and their textures) **retain their correct relative paths** even when embedded.

The embedding process:
1. **At build time**, Python reads an input path table (generated by CMake).
2. It serializes files into **constexpr arrays** with metadata (key + timestamps).
3. The output **C++ source + header** define a **built-in resource library**, linked into Nabla or examples.

This approach keeps assets self-contained, making file access efficient while maintaining asset dependencies.

### 🧩 Asset System
### 🧩 **Asset System**
The asset system in Nabla maintains a 1:1 mapping between CPU and GPU representations, where every CPU asset has a direct GPU counterpart.
The system also allows for coordination between loaders—for instance, the OBJ loader can trigger the MTL loader, and the MTL loader in turn invokes image loaders, ensuring smooth asset dependency management.

### 🧩 Asset Converter (CPU to GPU)
### 🧩 **Asset Converter (CPU to GPU)**
The Asset Converter transforms CPU objects (`asset::IAsset`) into GPU objects (`video::IBackendObject`) while eliminating duplicates with Merkle Trees. Instead of relying on pointer comparisons, it hashes asset contents to detect and reuse identical GPU objects.

### 🧩 Unit-Tested BxDFs for Physically Based Rendering
### 🧩 **Unit-Tested BxDFs for Physically Based Rendering**
A statically polymorphic library for defining Bidirectional Scattering Distribution Functions (BxDFs) in HLSL and C++. Each BxDF is rigorously unit-tested in C++ as well as HLSL. This is part of Nabla’s HLSL-C++ compatible library.

Part of our [BxDF Unit Test](https://github.com/Devsh-Graphics-Programming/Nabla-Examples-and-Tests/blob/d7f7a87fa08a56a16cd1bcc7d4d9fd48fc8c278c/66_HLSLBxDFTests/main.cpp#L93):
Expand All @@ -242,14 +262,14 @@ TestJacobian<bxdf::transmission::SGGXDielectricBxDF<sample_t, iso_cache, aniso_c
TestJacobian<bxdf::transmission::SGGXDielectricBxDF<sample_t, iso_cache, aniso_cache, spectral_t>,true>::run(initparams, cb);
```

### 🔧 In Progress: Property Pools (GPU Entity Component System)
### 🔧 **In Progress: Property Pools (GPU Entity Component System)**
*Property Pools* group related properties together in a Structure Of Arrays (SoA) manner, allowing efficient, cache-friendly access to data on the GPU. The system enables transferring properties (Components) between the CPU and GPU, with the `PropertyPoolHandler` managing scattered updates with a special compute shader. Handles are assigned for each object and remain constant as data is added or removed.

### 🧩 SPIR-V Introspection and Layout Creation
### 🧩 **SPIR-V Introspection and Layout Creation**

SPIR-V introspection in Nabla eliminates most of the boilerplate code required to set up descriptor and pipeline layouts, simplifying resource binding to shaders.

### 🧩 Nabla Extensions
### 🧩 **Nabla Extensions**
- [ImGui integration](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/ext/ImGui) – `MultiDrawIndirect` based and draws in as little as a single drawcall.
- [Fast Fourier Transform Extension](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/ext/FFT) – for image processing and all kind of frequncy-domain fun.
- [Workgroup Prefix Sum](https://github.com/Devsh-Graphics-Programming/Nabla/tree/master/include/nbl/builtin/hlsl/workgroup) – Efficient parallel prefix sum computation.
Expand All @@ -261,7 +281,7 @@ SPIR-V introspection in Nabla eliminates most of the boilerplate code required t
- [WIP] OptiX interoperability for ray tracing.
- [WIP] Global Scan – High-speed parallel scanning across large datasets.

### 🚀 Coming Soon
### 🚀 **Coming Soon**
- Full CUDA interoperability support.
- Scene Loaders
- GPU-Driven Scene Graph
Expand Down