Skip to content
This repository was archived by the owner on Aug 2, 2025. It is now read-only.

Commit 24e063a

Browse files
committed
Update tutorial to be compatible with Daxa master
1 parent 3d940c5 commit 24e063a

File tree

7 files changed

+376
-161
lines changed

7 files changed

+376
-161
lines changed

docs/01_Installing_dependencies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This page will explain how to install all the necessary tools to compile the Dax
66

77
### Visual Studio
88

9-
In this tutorial, we will be using Clang as our compiler. Clang relies on the Microsoft STL, which we can get most easily by installing [Visual Studio](https://visualstudio.microsoft.com/de/vs/community/) and selecting the C++ desktop development component during installation
9+
In this tutorial, ~~we will be using Clang as our compiler~~ (EDIT: For now, there are some issues with Clang on Windows, so ). Clang relies on the Microsoft STL, which we can get most easily by installing [Visual Studio](https://visualstudio.microsoft.com/de/vs/community/) and selecting the C++ desktop development component during installation
1010

1111
### Clang & Ninja
1212

docs/03_Getting_started/00_Creating_a_window.md

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@ The first thing when developing a graphics application is to open a blank window
44

55
## Creating a header file
66

7-
In this tutorial, we will create a new header file `window.hpp` that is responsible for interfacing and abstracting the windowing library of our choice GLFW.
7+
In this tutorial, we will create a new header file `src/window.hpp` that is responsible for interfacing and abstracting the windowing library of our choice GLFW.
88

99
```cpp
1010
#pragma once
1111

12-
struct Window{
12+
struct AppWindow{
1313
};
1414
```
1515

1616
Next, we need to include the libraries. Since we need the native window handle later, we also need the native GLFW headers. Since those libraries are platform dependant though, we need some extra preprocessor magic.
1717

1818
```cpp
1919
#include <daxa/daxa.hpp>
20+
// For things like `u32`. Not necessary of course.
2021
using namespace daxa::types;
2122

2223
#include <GLFW/glfw3.h>
@@ -43,7 +44,7 @@ bool swapchain_out_of_date = false;
4344
We can now create a constructor and a destructor for the window.
4445

4546
```cpp
46-
explicit Window(char const * window_name, u32 sx = 800, u32 sy = 600) : width{sx}, height{sy} {
47+
explicit AppWindow(char const * window_name, u32 sx = 800, u32 sy = 600) : width{sx}, height{sy} {
4748
// Initialize GLFW
4849
glfwInit();
4950

@@ -59,19 +60,16 @@ explicit Window(char const * window_name, u32 sx = 800, u32 sy = 600) : width{sx
5960
// Set the user pointer to this window
6061
glfwSetWindowUserPointer(glfw_window_ptr, this);
6162

62-
// Enable vsync (To limit the framerate to the refresh rate of the monitor)
63-
glfwSwapInterval(1);
64-
6563
// When the window is resized, update the width and height and mark the swapchain as out of date
66-
glfwSetWindowContentScaleCallback(glfw_window_ptr, [](GLFWwindow* window, float xscale, float yscale){
67-
auto* win = static_cast<Window*>(glfwGetWindowUserPointer(window));
68-
win->width = static_cast<u32>(xscale);
69-
win->height = static_cast<u32>(yscale);
64+
glfwSetWindowSizeCallback(glfw_window_ptr, [](GLFWwindow *window, int size_x, int size_y) {
65+
auto* win = static_cast<AppWindow*>(glfwGetWindowUserPointer(window));
66+
win->width = static_cast<u32>(size_x);
67+
win->height = static_cast<u32>(size_y);
7068
win->swapchain_out_of_date = true;
7169
});
7270
}
7371

74-
~Window() {
72+
~AppWindow() {
7573
glfwDestroyWindow(glfw_window_ptr);
7674
glfwTerminate();
7775
}
@@ -145,18 +143,10 @@ We can now go ahead and open our window for the first time. We therefore need to
145143
```cpp
146144
#include "window.hpp"
147145
148-
#include <iostream>
149-
150-
#include <daxa/daxa.hpp>
151-
#include <daxa/utils/pipeline_manager.hpp>
152-
#include <daxa/utils/task_graph.hpp>
153-
154-
using namespace daxa::types;
155-
156146
int main(int argc, char const *argv[])
157147
{
158148
// Create a window
159-
auto window = Window("Learn Daxa", 860, 640);
149+
auto window = AppWindow("Learn Daxa", 860, 640);
160150
161151
// Daxa code goes here...
162152

docs/03_Getting_started/02_Choosing_a_device.md

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,10 @@
22

33
A PC can have multiple graphics cards. Unlike OpenGL, you need to manually select which GPU you want to use to perform calculations. Since each GPU is different Daxa provides a simple system to select the GPU best suited for your application. You can choose the considered parameters yourself and change how they are weighed against each other.
44

5-
Below is a sample code to select a GPU based on location & VRAM.
5+
Below is sample code that selects the first device provided by the Vulkan driver (so long as it supports all of Daxa's required features). This means that if the user sets a device override in an application such as NVIDIA control panel, said device will be selected.
66

77
```cpp
8-
daxa::Device device = instance.create_device({
9-
.selector = [](daxa::DeviceProperties const & device_props) -> daxa::i32
10-
{
11-
daxa::i32 score = 0;
12-
switch (device_props.device_type)
13-
{
14-
case daxa::DeviceType::DISCRETE_GPU: score += 10000; break;
15-
case daxa::DeviceType::VIRTUAL_GPU: score += 1000; break;
16-
case daxa::DeviceType::INTEGRATED_GPU: score += 100; break;
17-
default: break;
18-
}
19-
score += static_cast<daxa::i32>(device_props.limits.max_memory_allocation_count / 100000);
20-
return score;
21-
},
22-
.name = "my device",
23-
});
8+
daxa::Device device = instance.create_device_2(instance.choose_device({}, {}));
249
```
2510

26-
The struct daxa::DeviceProperties has many fields indicating different GPU attributes, such as Vulkan version, device type, ray tracing capabilities, ... ([Code reference](https://github.com/Ipotrick/Daxa/blob/master/include/daxa/device.hpp#L188))
11+
Usually, this is the desired behavior. If you want more control over device selection, see how this is done in [The device creation sample in the Daxa repository](https://github.com/Ipotrick/Daxa/blob/master/tests/2_daxa_api/2_device/main.cpp)

docs/03_Getting_started/03_Creating_a_swapchain.md

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,18 @@ daxa::Swapchain swapchain = device.create_swapchain({
2929
});
3030
```
3131

32-
In the sample code, the native window handle can be obtained by the `Window#get_native_handle` and `Window#get_native_platform`
32+
In the sample code, the native window handle can be obtained by 2 of the helper-functions we created `AppWindow::get_native_handle()` and `AppWindow::get_native_platform()`
3333

3434
### daxa::PresentMode
3535

36-
This defines how the rendered images are supplied to your screen. `daxa::PresentMode::MAILBOX` is the recommended default option for most use cases.
36+
This defines how the rendered images are supplied to your screen. `daxa::PresentMode::FIFO` is the recommended default option for most use cases.
3737

3838
| mode | meaning |
3939
| --- | --- |
4040
| daxa::PresentMode::IMMEDIATE | Images submitted by your application are transferred to the screen right away, which may result in tearing |
4141
| daxa::PresentMode::FIFO | The swapchain is a queue where the display takes an image from the front of the queue when the display is refreshed and the program inserts rendered images at the back of the queue. If the queue is full then the program has to wait. This is most similar to vertical sync as found in modern games. The moment that the display is refreshed is known as "vertical blank". |
4242
| daxa::PresentMode::FIFO_RELAXED | This mode only differs from the previous one if the application is late and the queue was empty at the last vertical blank. Instead of waiting for the next vertical blank, the image is transferred right away when it finally arrives. This may result in visible tearing. |
43-
| daxa::PresentMode::MAILBOX | This is another variation of the second mode. Instead of blocking the application when the queue is full, the images that are already queued are simply replaced with the newer ones. This mode can be used to render frames as fast as possible while still avoiding tearing, resulting in fewer latency issues than standard vertical sync. This is commonly known as "triple buffering", although the existence of three buffers alone does not necessarily mean that the framerate is unlocked. |
44-
45-
### daxa::Format
46-
47-
This defines the color space for the swapchain images. (`R8G8B8A8_UINT` is the default 256-bit RGBA color space most displays use).
43+
| daxa::PresentMode::MAILBOX | This is another variation of the second mode. Instead of blocking the application when the queue is full, the images that are already queued are simply replaced with the newer ones. This mode can be used to render frames as fast as possible while still avoiding tearing, resulting in fewer latency issues than standard vertical sync. This is commonly known as "triple buffering", although the existence of three buffers alone does not necessarily mean that the framerate is unlocked. Although this may be desirable, it has limited support on AMD devices |
4844

4945
## Swapchain usage
5046

@@ -61,59 +57,19 @@ If all swapchain images are used in queued submissions to the GPU, the present c
6157
```cpp
6258
#include "window.hpp"
6359

64-
#include <iostream>
65-
66-
#include <daxa/daxa.hpp>
67-
#include <daxa/utils/pipeline_manager.hpp>
68-
#include <daxa/utils/task_graph.hpp>
69-
70-
using namespace daxa::types;
71-
7260
int main(int argc, char const *argv[])
7361
{
7462
// Create a window
75-
auto window = Window("Learn Daxa", 860, 640);
63+
auto window = AppWindow("Learn Daxa", 860, 640);
7664

7765
daxa::Instance instance = daxa::create_instance({});
7866

79-
daxa::Device device = instance.create_device({
80-
.selector = [](daxa::DeviceProperties const &device_props) -> i32
81-
{
82-
i32 score = 0;
83-
switch (device_props.device_type)
84-
{
85-
case daxa::DeviceType::DISCRETE_GPU:
86-
score += 10000;
87-
break;
88-
case daxa::DeviceType::VIRTUAL_GPU:
89-
score += 1000;
90-
break;
91-
case daxa::DeviceType::INTEGRATED_GPU:
92-
score += 100;
93-
break;
94-
default:
95-
break;
96-
}
97-
score += static_cast<i32>(device_props.limits.max_memory_allocation_count / 100000);
98-
return score;
99-
},
100-
.name = "my device",
101-
});
67+
daxa::Device device = instance.create_device_2(instance.choose_device({}, {}));
10268

10369
daxa::Swapchain swapchain = device.create_swapchain({
10470
.native_window = window.get_native_handle(),
10571
.native_window_platform = window.get_native_platform(),
106-
.surface_format_selector = [](daxa::Format format)
107-
{
108-
switch (format)
109-
{
110-
case daxa::Format::R8G8B8A8_UINT:
111-
return 100;
112-
default:
113-
return daxa::default_format_score(format);
114-
}
115-
},
116-
.present_mode = daxa::PresentMode::MAILBOX,
72+
.present_mode = daxa::PresentMode::FIFO,
11773
.image_usage = daxa::ImageUsageFlagBits::TRANSFER_DST,
11874
.name = "my swapchain",
11975
});

docs/03_Getting_started/04_Push_constants.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The Vulkan spec defines Push Constants as:
55
66
## Implementation
77

8-
To use push constants in our demo project, we need to create a new file: `shader/shared.inl` which will be a shared file between our main program and our shader file. Since Glsl is more or less a superset of basic C, we can use some code snippets in both languages.
8+
To use push constants in our demo project, we need to create a new file: `src/shader/shared.inl` which will be a shared file between our main program and our shader file. Since Glsl is more or less a superset of basic C, we can use some code snippets in both languages.
99

1010
Since this document is treated as a header file in our C++ code, we can simply insert `#pragma once` at the top to make sure it's only included once. We also need to include the Daxa (Shader) API directly beneath it: `#include <daxa/daxa.inl>`.
1111

0 commit comments

Comments
 (0)