Skip to content

Commit 73eeb37

Browse files
committed
Merge branch 'section/shader-objects' into section/memory-allocation
2 parents 811b904 + 506bbc1 commit 73eeb37

File tree

9 files changed

+229
-44
lines changed

9 files changed

+229
-44
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
name: ci-push
1+
name: ci-pr
22
on:
3-
push:
3+
pull_request:
44
branches-ignore:
55
- staging
6+
workflow_dispatch:
67
jobs:
78
format-check:
89
runs-on: ubuntu-latest
@@ -25,11 +26,11 @@ jobs:
2526
- name: init
2627
run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
2728
- name: configure
28-
run: export CXX=g++-14; cmake -S . --preset=default -B build -DGLFW_BUILD_X11=OFF
29+
run: cmake -S . --preset=ninja-gcc -B build -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14
2930
- name: build debug
30-
run: cmake --build build --config=Debug
31+
run: cmake --build build --config=Debug -- -v
3132
- name: build release
32-
run: cmake --build build --config=Release
33+
run: cmake --build build --config=Release -- -v
3334
- name: test debug
3435
run: cd build && ctest -V -C Debug
3536
- name: test release
@@ -43,9 +44,9 @@ jobs:
4344
- name: configure
4445
run: cmake -S . --preset=ninja-clang -B build -DGLFW_BUILD_X11=OFF
4546
- name: build debug
46-
run: cmake --build build --config=Debug
47+
run: cmake --build build --config=Debug -- -v
4748
- name: build release
48-
run: cmake --build build --config=Release
49+
run: cmake --build build --config=Release -- -v
4950
- name: test debug
5051
run: cd build && ctest -V -C Debug
5152
- name: test release
@@ -57,11 +58,11 @@ jobs:
5758
- name: init
5859
run: uname -m; sudo apt update -yqq && sudo apt install -yqq ninja-build mesa-common-dev libwayland-dev libxkbcommon-dev wayland-protocols extra-cmake-modules
5960
- name: configure
60-
run: export CXX=g++-14; cmake -S . --preset=default -B build -DGLFW_BUILD_X11=OFF
61+
run: cmake -S . --preset=ninja-gcc -B build -DGLFW_BUILD_X11=OFF -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14
6162
- name: build debug
62-
run: cmake --build build --config=Debug
63+
run: cmake --build build --config=Debug -- -v
6364
- name: build release
64-
run: cmake --build build --config=Release
65+
run: cmake --build build --config=Release -- -v
6566
- name: test debug
6667
run: cd build && ctest -V -C Debug
6768
- name: test release
@@ -75,9 +76,9 @@ jobs:
7576
- name: configure
7677
run: cmake -S . --preset=ninja-clang -B build -DGLFW_BUILD_X11=OFF
7778
- name: build debug
78-
run: cmake --build build --config=Debug
79+
run: cmake --build build --config=Debug -- -v
7980
- name: build release
80-
run: cmake --build build --config=Release
81+
run: cmake --build build --config=Release -- -v
8182
- name: test debug
8283
run: cd build && ctest -V -C Debug
8384
- name: test release
@@ -105,9 +106,9 @@ jobs:
105106
- name: configure
106107
run: cmake -S . --preset=ninja-clang -B clang
107108
- name: build debug
108-
run: cmake --build clang --config=Debug
109+
run: cmake --build clang --config=Debug -- -v
109110
- name: build release
110-
run: cmake --build clang --config=Release
111+
run: cmake --build clang --config=Release -- -v
111112
- name: test debug
112113
run: cd clang && ctest -V -C Debug
113114
- name: test release

CMakePresets.json

Lines changed: 144 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,131 @@
11
{
2-
"version": 2,
2+
"version": 5,
33
"cmakeMinimumRequired": {
44
"major": 3,
5-
"minor": 20,
5+
"minor": 24,
66
"patch": 0
77
},
88
"configurePresets": [
99
{
1010
"name": "default",
11-
"description": "Build configuration using Ninja Multi-config",
11+
"displayName": "Default Config",
12+
"description": "Base configuration using Ninja Multi-config",
1213
"generator": "Ninja Multi-Config",
1314
"binaryDir": "${sourceDir}/out/default",
1415
"cacheVariables": {
1516
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
1617
}
1718
},
1819
{
19-
"name": "ninja-clang",
20-
"description": "Build configuration using Ninja Multi-config / clang",
20+
"name": "base-gcc",
21+
"hidden": true,
22+
"inherits": "default",
23+
"cacheVariables": {
24+
"CMAKE_C_COMPILER": "gcc",
25+
"CMAKE_CXX_COMPILER": "g++"
26+
}
27+
},
28+
{
29+
"name": "base-clang",
30+
"hidden": true,
2131
"inherits": "default",
22-
"binaryDir": "${sourceDir}/out/clang",
2332
"cacheVariables": {
2433
"CMAKE_C_COMPILER": "clang",
2534
"CMAKE_CXX_COMPILER": "clang++"
2635
}
2736
},
37+
{
38+
"name": "base-msvc",
39+
"hidden": true,
40+
"inherits": "default",
41+
"cacheVariables": {
42+
"CMAKE_C_COMPILER": "cl",
43+
"CMAKE_CXX_COMPILER": "cl"
44+
}
45+
},
46+
{
47+
"name": "ninja-gcc",
48+
"displayName": "Ninja GCC",
49+
"description": "Build configuration using Ninja Multi-config / GCC",
50+
"inherits": "base-gcc",
51+
"binaryDir": "${sourceDir}/out/gcc",
52+
"cacheVariables": {
53+
"CMAKE_CXX_FLAGS_DEBUG_INIT": "-Wall -Wextra -Wpedantic -Werror=return-type",
54+
"CMAKE_CXX_FLAGS_INIT": "-Wall -Wextra -Wpedantic -Werror"
55+
}
56+
},
57+
{
58+
"name": "ninja-clang",
59+
"displayName": "Ninja Clang",
60+
"description": "Build configuration using Ninja Multi-config / Clang",
61+
"inherits": "base-clang",
62+
"binaryDir": "${sourceDir}/out/clang",
63+
"cacheVariables": {
64+
"CMAKE_CXX_FLAGS_DEBUG_INIT": "-Wall -Wextra -Wpedantic -Werror=return-type",
65+
"CMAKE_CXX_FLAGS_INIT": "-Wall -Wextra -Wpedantic -Werror"
66+
}
67+
},
68+
{
69+
"name": "ninja-msvc",
70+
"displayName": "Ninja MSVC",
71+
"description": "Build configuration using Ninja Multi-config / MSVC",
72+
"inherits": "base-msvc",
73+
"binaryDir": "${sourceDir}/out/msvc",
74+
"cacheVariables": {
75+
"CMAKE_CXX_FLAGS_INIT": "/WX"
76+
}
77+
},
2878
{
2979
"name": "ninja-ubsan",
80+
"displayName": "Ninja UBSan",
3081
"description": "UBSan build configuration using Ninja Multi-config",
3182
"inherits": "default",
3283
"binaryDir": "${sourceDir}/out/ubsan",
3384
"cacheVariables": {
34-
"CMAKE_C_FLAGS": "-fsanitize=undefined",
35-
"CMAKE_CXX_FLAGS": "-fsanitize=undefined"
85+
"CMAKE_CXX_FLAGS_DEBUG_INIT": "-fsanitize=undefined -Wall -Wextra -Wpedantic -Werror=return-type",
86+
"CMAKE_CXX_FLAGS_INIT": "-fsanitize=undefined -Wall -Wextra -Wpedantic -Werror"
3687
}
3788
},
3889
{
3990
"name": "ninja-asan",
91+
"displayName": "Ninja ASan",
4092
"description": "ASan build configuration using Ninja Multi-config",
4193
"inherits": "default",
4294
"binaryDir": "${sourceDir}/out/asan",
4395
"cacheVariables": {
44-
"CMAKE_C_FLAGS": "-fsanitize=address",
45-
"CMAKE_CXX_FLAGS": "-fsanitize=address"
96+
"CMAKE_CXX_FLAGS_DEBUG_INIT": "-fsanitize=address -Wall -Wextra -Wpedantic -Werror=return-type",
97+
"CMAKE_CXX_FLAGS_INIT": "-fsanitize=address -Wall -Wextra -Wpedantic -Werror"
98+
}
99+
},
100+
{
101+
"name": "ninja-msvc-asan",
102+
"displayName": "Ninja MSVC ASan",
103+
"description": "ASan build configuration using Ninja Multi-config",
104+
"inherits": "base-msvc",
105+
"binaryDir": "${sourceDir}/out/asan",
106+
"cacheVariables": {
107+
"CMAKE_CXX_FLAGS_INIT": "-fsanitize=address"
46108
}
47109
},
48110
{
49111
"name": "ninja-tsan",
112+
"displayName": "Ninja TSan",
50113
"description": "TSan build configuration using Ninja Multi-config",
51114
"inherits": "default",
52115
"binaryDir": "${sourceDir}/out/tsan",
53116
"cacheVariables": {
54-
"CMAKE_C_FLAGS": "-fsanitize=thread",
55-
"CMAKE_CXX_FLAGS": "-fsanitize=thread"
117+
"CMAKE_CXX_FLAGS_INIT": "-fsanitize=thread -Wall -Wextra -Wpedantic -Werror=return-type"
56118
}
57119
},
58120
{
59121
"name": "vs22",
122+
"displayName": "Visual Studio 2022",
60123
"description": "Build configuration using Visual Studio 17 (2022)",
61124
"generator": "Visual Studio 17 2022",
62125
"binaryDir": "${sourceDir}/out/vs",
126+
"cacheVariables": {
127+
"CMAKE_CXX_FLAGS_INIT": "/WX"
128+
},
63129
"architecture": {
64130
"value": "x64",
65131
"strategy": "external"
@@ -82,6 +148,36 @@
82148
"configurePreset": "default",
83149
"configuration": "RelWithDebInfo"
84150
},
151+
{
152+
"name": "GCC Debug",
153+
"configurePreset": "ninja-gcc",
154+
"configuration": "Debug"
155+
},
156+
{
157+
"name": "GCC RelWithDebInfo",
158+
"configurePreset": "ninja-gcc",
159+
"configuration": "RelWithDebInfo"
160+
},
161+
{
162+
"name": "Clang Debug",
163+
"configurePreset": "ninja-clang",
164+
"configuration": "Debug"
165+
},
166+
{
167+
"name": "Clang RelWithDebInfo",
168+
"configurePreset": "ninja-clang",
169+
"configuration": "RelWithDebInfo"
170+
},
171+
{
172+
"name": "MSVC Debug",
173+
"configurePreset": "ninja-msvc",
174+
"configuration": "Debug"
175+
},
176+
{
177+
"name": "MSVC Release",
178+
"configurePreset": "ninja-msvc",
179+
"configuration": "Release"
180+
},
85181
{
86182
"name": "UBSan Debug",
87183
"configurePreset": "ninja-ubsan",
@@ -107,6 +203,42 @@
107203
"configuration": "RelWithDebInfo",
108204
"inheritConfigureEnvironment": true
109205
},
206+
{
207+
"name": "GCC Debug",
208+
"configurePreset": "ninja-gcc",
209+
"configuration": "Debug",
210+
"inheritConfigureEnvironment": true
211+
},
212+
{
213+
"name": "GCC RelWithDebInfo",
214+
"configurePreset": "ninja-gcc",
215+
"configuration": "RelWithDebInfo",
216+
"inheritConfigureEnvironment": true
217+
},
218+
{
219+
"name": "Clang Debug",
220+
"configurePreset": "ninja-clang",
221+
"configuration": "Debug",
222+
"inheritConfigureEnvironment": true
223+
},
224+
{
225+
"name": "Clang RelWithDebInfo",
226+
"configurePreset": "ninja-clang",
227+
"configuration": "RelWithDebInfo",
228+
"inheritConfigureEnvironment": true
229+
},
230+
{
231+
"name": "MSVC Debug",
232+
"configurePreset": "ninja-msvc",
233+
"configuration": "Debug",
234+
"inheritConfigureEnvironment": true
235+
},
236+
{
237+
"name": "MSVC Release",
238+
"configurePreset": "ninja-msvc",
239+
"configuration": "Release",
240+
"inheritConfigureEnvironment": true
241+
},
110242
{
111243
"name": "UBSan Debug",
112244
"configurePreset": "ninja-ubsan",

guide/src/rendering/render_sync.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ Add a private `struct RenderSync` to `App`:
1717
struct RenderSync {
1818
// signaled when Swapchain image has been acquired.
1919
vk::UniqueSemaphore draw{};
20-
// signaled when image is ready to be presented.
21-
vk::UniqueSemaphore present{};
2220
// signaled with present Semaphore, waited on before next render.
2321
vk::UniqueFence drawn{};
2422
// used to record rendering commands.
@@ -68,7 +66,6 @@ void App::create_render_sync() {
6866
std::views::zip(m_render_sync, command_buffers)) {
6967
sync.command_buffer = command_buffer;
7068
sync.draw = m_device->createSemaphoreUnique({});
71-
sync.present = m_device->createSemaphoreUnique({});
7269
sync.drawn = m_device->createFenceUnique(fence_create_info_v);
7370
}
7471
}

guide/src/rendering/swapchain_loop.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ Additionally, the number of swapchain images can vary, whereas the engine should
1919

2020
## Virtual Frames
2121

22-
All the dynamic resources used during the rendering of a frame comprise a virtual frame. The application has a fixed number of virtual frames which it cycles through on each render pass. For synchronization, each frame will be associated with a [`vk::Fence`](https://registry.khronos.org/vulkan/specs/latest/man/html/VkFence.html) which will be waited on before rendering to it again. It will also have a pair of [`vk::Semaphore`](https://registry.khronos.org/vulkan/specs/latest/man/html/VkSemaphore.html)s to synchronize the acquire, render, and present calls on the GPU (we don't need to wait for them on the CPU side / in C++). For recording commands, there will be a [`vk::CommandBuffer`](https://docs.vulkan.org/spec/latest/chapters/cmdbuffers.html) per virtual frame, where all rendering commands for that frame (including layout transitions) will be recorded.
22+
All the dynamic resources used during the rendering of a frame comprise a virtual frame. The application has a fixed number of virtual frames which it cycles through on each render pass. For synchronization, each frame will be associated with a [`vk::Fence`](https://registry.khronos.org/vulkan/specs/latest/man/html/VkFence.html) which will be waited on before rendering to it again. It will also have a [`vk::Semaphore`](https://registry.khronos.org/vulkan/specs/latest/man/html/VkSemaphore.html) to synchronize the acquire and render calls on the GPU (we don't need to wait for them in the code). For recording commands, there will be a [`vk::CommandBuffer`](https://docs.vulkan.org/spec/latest/chapters/cmdbuffers.html) per virtual frame, where all rendering commands for that frame (including layout transitions) will be recorded.
23+
24+
Presentation will require a semaphore for synchronization too, but since the swapchain loop waits on the _drawn_ fence, which will be pre-signaled for each virtual frame on first use, present semaphores cannot be part of the virtual frame. It is possible to acquire another image and submit commands with a present semaphore that has not been signaled yet - this is invalid. Thus, these semaphores will be tied to the swapchain images (associated with their indices), and recreated with it.
2325

2426
## Image Layouts
2527

guide/src/rendering/swapchain_update.md

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
11
# Swapchain Update
22

3+
Add a vector of semaphores and populate them in `recreate()`:
4+
5+
```cpp
6+
void create_present_semaphores();
7+
8+
// ...
9+
// signaled when image is ready to be presented.
10+
std::vector<vk::UniqueSemaphore> m_present_semaphores{};
11+
12+
// ...
13+
auto Swapchain::recreate(glm::ivec2 size) -> bool {
14+
// ...
15+
populate_images();
16+
create_image_views();
17+
// recreate present semaphores as the image count might have changed.
18+
create_present_semaphores();
19+
// ...
20+
}
21+
22+
void Swapchain::create_present_semaphores() {
23+
m_present_semaphores.clear();
24+
m_present_semaphores.resize(m_images.size());
25+
for (auto& semaphore : m_present_semaphores) {
26+
semaphore = m_device.createSemaphoreUnique({});
27+
}
28+
}
29+
```
30+
31+
Add a function to get the present semaphore corresponding to the acquired image, this will be signaled by render command submission:
32+
33+
```cpp
34+
auto Swapchain::get_present_semaphore() const -> vk::Semaphore {
35+
return *m_present_semaphores.at(m_image_index.value());
36+
}
37+
```
38+
339
Swapchain acquire/present operations can have various results. We constrain ourselves to the following:
440

541
- `eSuccess`: all good
@@ -59,13 +95,15 @@ auto Swapchain::acquire_next_image(vk::Semaphore const to_signal)
5995
Similarly, present:
6096
6197
```cpp
62-
auto Swapchain::present(vk::Queue const queue, vk::Semaphore const to_wait)
98+
auto Swapchain::present(vk::Queue const queue)
6399
-> bool {
64100
auto const image_index = static_cast<std::uint32_t>(m_image_index.value());
101+
auto const wait_semaphore =
102+
*m_present_semaphores.at(static_cast<std::size_t>(image_index));
65103
auto present_info = vk::PresentInfoKHR{};
66104
present_info.setSwapchains(*m_swapchain)
67105
.setImageIndices(image_index)
68-
.setWaitSemaphores(to_wait);
106+
.setWaitSemaphores(wait_semaphore);
69107
// avoid VulkanHPP ErrorOutOfDateKHR exceptions by using alternate API.
70108
auto const result = queue.presentKHR(&present_info);
71109
m_image_index.reset();

0 commit comments

Comments
 (0)