Skip to content

Commit 69487d7

Browse files
committed
* remove superfluous code directory. The code can now be found in the attachments directory and only there.
* switch to using VULKAN_HPP_NO_STRUCT_CONSTRUCTORS so we get slightly more verbosity in our example code. * use Vulkan 1.4 modern techniques ** show removal of framebuffer and renderpasses ** show timeline semaphores in the compute example. ** show synch2 practices.
1 parent e379481 commit 69487d7

File tree

88 files changed

+6772
-22095
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+6772
-22095
lines changed

attachments/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

attachments/00_base_code.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class HelloTriangleApplication {
1818
}
1919

2020
private:
21-
GLFWwindow* window;
21+
GLFWwindow* window = nullptr;
2222

2323
void initWindow() {
2424
glfwInit();
@@ -47,7 +47,7 @@ class HelloTriangleApplication {
4747
};
4848

4949
int main() {
50-
HelloTriangleApplication app;
50+
HelloTriangleApplication app{};
5151

5252
try {
5353
app.run();

attachments/01_instance_creation.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class HelloTriangleApplication {
2525
GLFWwindow* window = nullptr;
2626

2727
vk::raii::Context context;
28-
std::unique_ptr<vk::raii::Instance> instance;
28+
vk::raii::Instance instance = nullptr;
2929

3030
void initWindow() {
3131
glfwInit();
@@ -53,11 +53,17 @@ class HelloTriangleApplication {
5353
}
5454

5555
void createInstance() {
56-
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
56+
constexpr vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
57+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
58+
.pEngineName = "No Engine",
59+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
60+
.apiVersion = vk::ApiVersion14 };
5761
uint32_t glfwExtensionCount = 0;
5862
auto glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
59-
vk::InstanceCreateInfo createInfo({}, &appInfo, {}, glfwExtensions);
60-
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
63+
vk::InstanceCreateInfo createInfo{
64+
.pApplicationInfo = &appInfo,
65+
.ppEnabledLayerNames = glfwExtensions};
66+
instance = vk::raii::Instance(context, createInfo);
6167
}
6268
};
6369

attachments/02_validation_layers.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class HelloTriangleApplication {
3838
GLFWwindow* window = nullptr;
3939

4040
vk::raii::Context context;
41-
std::unique_ptr<vk::raii::Instance> instance;
42-
std::unique_ptr<vk::raii::DebugUtilsMessengerEXT> debugMessenger;
41+
vk::raii::Instance instance = nullptr;
42+
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
4343

4444
void initWindow() {
4545
glfwInit();
@@ -72,23 +72,36 @@ class HelloTriangleApplication {
7272
throw std::runtime_error("validation layers requested, but not available!");
7373
}
7474

75-
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
75+
constexpr vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
76+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
77+
.pEngineName = "No Engine",
78+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
79+
.apiVersion = vk::ApiVersion14 };
7680
auto extensions = getRequiredExtensions();
7781
std::vector<char const *> enabledLayers;
7882
if (enableValidationLayers) {
7983
enabledLayers.assign(validationLayers.begin(), validationLayers.end());
8084
}
81-
vk::InstanceCreateInfo createInfo({}, &appInfo, enabledLayers.size(), enabledLayers.data(), extensions.size(), extensions.data());
82-
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
85+
vk::InstanceCreateInfo createInfo{
86+
.pApplicationInfo = &appInfo,
87+
.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size()),
88+
.ppEnabledLayerNames = enabledLayers.data(),
89+
.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
90+
.ppEnabledExtensionNames = extensions.data() };
91+
instance = vk::raii::Instance(context, createInfo);
8392
}
8493

8594
void setupDebugMessenger() {
8695
if (!enableValidationLayers) return;
8796

8897
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
8998
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
90-
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT({}, severityFlags, messageTypeFlags, &debugCallback);
91-
debugMessenger = std::make_unique<vk::raii::DebugUtilsMessengerEXT>( *instance, debugUtilsMessengerCreateInfoEXT );
99+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
100+
.messageSeverity = severityFlags,
101+
.messageType = messageTypeFlags,
102+
.pfnUserCallback = &debugCallback
103+
};
104+
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
92105
}
93106

94107
std::vector<const char*> getRequiredExtensions() {

attachments/03_physical_device_selection.cpp

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,17 @@ class HelloTriangleApplication {
3838
GLFWwindow* window = nullptr;
3939

4040
vk::raii::Context context;
41-
std::unique_ptr<vk::raii::Instance> instance;
42-
std::unique_ptr<vk::raii::DebugUtilsMessengerEXT> debugMessenger;
41+
vk::raii::Instance instance = nullptr;
42+
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
4343

44-
std::unique_ptr<vk::raii::PhysicalDevice> physicalDevice;
44+
vk::raii::PhysicalDevice physicalDevice = nullptr;
45+
46+
std::vector<const char*> deviceExtensions = {
47+
vk::KHRSwapchainExtensionName,
48+
vk::KHRSpirv14ExtensionName,
49+
vk::KHRSynchronization2ExtensionName,
50+
vk::KHRCreateRenderpass2ExtensionName
51+
};
4552

4653
void initWindow() {
4754
glfwInit();
@@ -75,27 +82,66 @@ class HelloTriangleApplication {
7582
throw std::runtime_error("validation layers requested, but not available!");
7683
}
7784

78-
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
85+
constexpr vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
86+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
87+
.pEngineName = "No Engine",
88+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
89+
.apiVersion = vk::ApiVersion14 };
7990
auto extensions = getRequiredExtensions();
8091
std::vector<char const *> enabledLayers;
8192
if (enableValidationLayers) {
8293
enabledLayers.assign(validationLayers.begin(), validationLayers.end());
8394
}
84-
vk::InstanceCreateInfo createInfo({}, &appInfo, enabledLayers.size(), enabledLayers.data(), extensions.size(), extensions.data());
85-
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
95+
vk::InstanceCreateInfo createInfo{
96+
.pApplicationInfo = &appInfo,
97+
.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size()),
98+
.ppEnabledLayerNames = enabledLayers.data(),
99+
.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
100+
.ppEnabledExtensionNames = extensions.data() };
101+
instance = vk::raii::Instance(context, createInfo);
86102
}
87103

88104
void setupDebugMessenger() {
89105
if (!enableValidationLayers) return;
90106

91107
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
92108
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
93-
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT({}, severityFlags, messageTypeFlags, &debugCallback);
94-
debugMessenger = std::make_unique<vk::raii::DebugUtilsMessengerEXT>( *instance, debugUtilsMessengerCreateInfoEXT );
109+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
110+
.messageSeverity = severityFlags,
111+
.messageType = messageTypeFlags,
112+
.pfnUserCallback = &debugCallback
113+
};
114+
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
95115
}
96116

97117
void pickPhysicalDevice() {
98-
physicalDevice = std::make_unique<vk::raii::PhysicalDevice>(vk::raii::PhysicalDevices( *instance ).front());
118+
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
119+
const auto devIter = std::ranges::find_if(devices,
120+
[&](auto const & device) {
121+
auto queueFamilies = device.getQueueFamilyProperties();
122+
bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
123+
const auto qfpIter = std::ranges::find_if(queueFamilies,
124+
[]( vk::QueueFamilyProperties const & qfp )
125+
{
126+
return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
127+
} );
128+
isSuitable = isSuitable && ( qfpIter != queueFamilies.end() );
129+
auto extensions = device.enumerateDeviceExtensionProperties( );
130+
bool found = true;
131+
for (auto const & extension : deviceExtensions) {
132+
auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;});
133+
found = found && extensionIter != extensions.end();
134+
}
135+
isSuitable = isSuitable && found;
136+
printf("\n");
137+
if (isSuitable) {
138+
physicalDevice = device;
139+
}
140+
return isSuitable;
141+
});
142+
if (devIter == devices.end()) {
143+
throw std::runtime_error("failed to find a suitable GPU!");
144+
}
99145
}
100146

101147
std::vector<const char*> getRequiredExtensions() {

attachments/04_logical_device.cpp

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,20 @@ class HelloTriangleApplication {
3838
GLFWwindow* window = nullptr;
3939

4040
vk::raii::Context context;
41-
std::unique_ptr<vk::raii::Instance> instance;
42-
std::unique_ptr<vk::raii::DebugUtilsMessengerEXT> debugMessenger;
41+
vk::raii::Instance instance = nullptr;
42+
vk::raii::DebugUtilsMessengerEXT debugMessenger = nullptr;
4343

44-
std::unique_ptr<vk::raii::PhysicalDevice> physicalDevice;
45-
std::unique_ptr<vk::raii::Device> device;
44+
vk::raii::PhysicalDevice physicalDevice = nullptr;
45+
vk::raii::Device device = nullptr;
4646

47-
std::unique_ptr<vk::raii::Queue> graphicsQueue;
47+
vk::raii::Queue graphicsQueue = nullptr;
48+
49+
std::vector<const char*> deviceExtensions = {
50+
vk::KHRSwapchainExtensionName,
51+
vk::KHRSpirv14ExtensionName,
52+
vk::KHRSynchronization2ExtensionName,
53+
vk::KHRCreateRenderpass2ExtensionName
54+
};
4855

4956
void initWindow() {
5057
glfwInit();
@@ -79,48 +86,95 @@ class HelloTriangleApplication {
7986
throw std::runtime_error("validation layers requested, but not available!");
8087
}
8188

82-
constexpr auto appInfo = vk::ApplicationInfo("Hello Triangle", 1, "No Engine", 1, vk::ApiVersion14);
89+
constexpr vk::ApplicationInfo appInfo{ .pApplicationName = "Hello Triangle",
90+
.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ),
91+
.pEngineName = "No Engine",
92+
.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ),
93+
.apiVersion = vk::ApiVersion14 };
8394
auto extensions = getRequiredExtensions();
8495
std::vector<char const *> enabledLayers;
8596
if (enableValidationLayers) {
8697
enabledLayers.assign(validationLayers.begin(), validationLayers.end());
8798
}
88-
vk::InstanceCreateInfo createInfo({}, &appInfo, enabledLayers.size(), enabledLayers.data(), extensions.size(), extensions.data());
89-
instance = std::make_unique<vk::raii::Instance>(context, createInfo);
99+
vk::InstanceCreateInfo createInfo{
100+
.pApplicationInfo = &appInfo,
101+
.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size()),
102+
.ppEnabledLayerNames = enabledLayers.data(),
103+
.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
104+
.ppEnabledExtensionNames = extensions.data() };
105+
instance = vk::raii::Instance(context, createInfo);
90106
}
91107

92108
void setupDebugMessenger() {
93109
if (!enableValidationLayers) return;
94110

95111
vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError );
96112
vk::DebugUtilsMessageTypeFlagsEXT messageTypeFlags( vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation );
97-
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT({}, severityFlags, messageTypeFlags, &debugCallback);
98-
debugMessenger = std::make_unique<vk::raii::DebugUtilsMessengerEXT>( *instance, debugUtilsMessengerCreateInfoEXT );
113+
vk::DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfoEXT{
114+
.messageSeverity = severityFlags,
115+
.messageType = messageTypeFlags,
116+
.pfnUserCallback = &debugCallback
117+
};
118+
debugMessenger = instance.createDebugUtilsMessengerEXT(debugUtilsMessengerCreateInfoEXT);
99119
}
100120

101121
void pickPhysicalDevice() {
102-
physicalDevice = std::make_unique<vk::raii::PhysicalDevice>(vk::raii::PhysicalDevices( *instance ).front());
122+
std::vector<vk::raii::PhysicalDevice> devices = instance.enumeratePhysicalDevices();
123+
const auto devIter = std::ranges::find_if(devices,
124+
[&](auto const & device) {
125+
auto queueFamilies = device.getQueueFamilyProperties();
126+
bool isSuitable = device.getProperties().apiVersion >= VK_API_VERSION_1_3;
127+
const auto qfpIter = std::ranges::find_if(queueFamilies,
128+
[]( vk::QueueFamilyProperties const & qfp )
129+
{
130+
return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0);
131+
} );
132+
isSuitable = isSuitable && ( qfpIter != queueFamilies.end() );
133+
auto extensions = device.enumerateDeviceExtensionProperties( );
134+
bool found = true;
135+
for (auto const & extension : deviceExtensions) {
136+
auto extensionIter = std::ranges::find_if(extensions, [extension](auto const & ext) {return strcmp(ext.extensionName, extension) == 0;});
137+
found = found && extensionIter != extensions.end();
138+
}
139+
isSuitable = isSuitable && found;
140+
printf("\n");
141+
if (isSuitable) {
142+
physicalDevice = device;
143+
}
144+
return isSuitable;
145+
});
146+
if (devIter == devices.end()) {
147+
throw std::runtime_error("failed to find a suitable GPU!");
148+
}
103149
}
104150

105151
void createLogicalDevice() {
106152
// find the index of the first queue family that supports graphics
107-
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice->getQueueFamilyProperties();
153+
std::vector<vk::QueueFamilyProperties> queueFamilyProperties = physicalDevice.getQueueFamilyProperties();
108154

109-
// get the first index into queueFamiliyProperties which supports graphics
110-
auto graphicsQueueFamilyProperty =
111-
std::find_if( queueFamilyProperties.begin(),
112-
queueFamilyProperties.end(),
113-
[]( vk::QueueFamilyProperties const & qfp ) { return qfp.queueFlags & vk::QueueFlagBits::eGraphics; } );
155+
// get the first index into queueFamilyProperties which supports graphics
156+
auto graphicsQueueFamilyProperty = std::ranges::find_if( queueFamilyProperties, []( auto const & qfp )
157+
{ return (qfp.queueFlags & vk::QueueFlagBits::eGraphics) != static_cast<vk::QueueFlags>(0); } );
114158

115159
auto graphicsIndex = static_cast<uint32_t>( std::distance( queueFamilyProperties.begin(), graphicsQueueFamilyProperty ) );
116160

161+
// query for Vulkan 1.3 features
162+
auto features = physicalDevice.getFeatures2();
163+
vk::PhysicalDeviceVulkan13Features vulkan13Features;
164+
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT extendedDynamicStateFeatures;
165+
vulkan13Features.dynamicRendering = vk::True;
166+
extendedDynamicStateFeatures.extendedDynamicState = vk::True;
167+
vulkan13Features.pNext = &extendedDynamicStateFeatures;
168+
features.pNext = &vulkan13Features;
117169
// create a Device
118170
float queuePriority = 0.0f;
119-
vk::DeviceQueueCreateInfo deviceQueueCreateInfo( {}, graphicsIndex, 1, &queuePriority );
120-
vk::DeviceCreateInfo deviceCreateInfo( {}, deviceQueueCreateInfo );
171+
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
172+
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
173+
deviceCreateInfo.enabledExtensionCount = deviceExtensions.size();
174+
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
121175

122-
device = std::make_unique<vk::raii::Device>( *physicalDevice, deviceCreateInfo );
123-
graphicsQueue = std::make_unique<vk::raii::Queue>( *device, graphicsIndex, 0 );
176+
device = vk::raii::Device( physicalDevice, deviceCreateInfo );
177+
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );
124178
}
125179

126180
std::vector<const char*> getRequiredExtensions() {

0 commit comments

Comments
 (0)