Skip to content

Commit aef0b4a

Browse files
committed
Refactor Vulkan tutorial for RAII and modern Vulkan practices
Updated code and documentation to align with modern Vulkan best practices: - Adopted RAII wrappers for better resource management and type safety. - Introduced structured initialization for clarity and consistency. - Improved tutorial content with grammatical fixes, terminology updates, and modernization of examples. - Rephrased sections for better readability and alignment with Vulkan 1.3+ features.
1 parent dd53e8f commit aef0b4a

23 files changed

+113
-111
lines changed

attachments/05_window_surface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class HelloTriangleApplication {
173173
// first check if the graphicsIndex is good enough
174174
auto presentIndex = physicalDevice.getSurfaceSupportKHR( graphicsIndex, *surface )
175175
? graphicsIndex
176-
: static_cast<uint32_t>( queueFamilyProperties.size() );
176+
: ~0 );
177177
if ( presentIndex == queueFamilyProperties.size() )
178178
{
179179
// the graphicsIndex doesn't support present -> look for another family index that supports both

attachments/06_swap_chain_creation.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,7 @@ class HelloTriangleApplication {
260260
}
261261

262262
static vk::PresentModeKHR chooseSwapPresentMode(const std::vector<vk::PresentModeKHR>& availablePresentModes) {
263-
for (const auto& availablePresentMode : availablePresentModes) {
264-
if (availablePresentMode == vk::PresentModeKHR::eMailbox) {
265-
return availablePresentMode;
266-
}
267-
}
268-
return vk::PresentModeKHR::eFifo;
263+
return std::ranges::contains( presentModes, vk::PresentModeKHR::eMailbox ) ? vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo;
269264
}
270265

271266
vk::Extent2D chooseSwapExtent(const vk::SurfaceCapabilitiesKHR& capabilities) {

attachments/07_image_views.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,13 @@ class HelloTriangleApplication {
227227
// create a Device
228228
float queuePriority = 0.0f;
229229
vk::DeviceQueueCreateInfo deviceQueueCreateInfo { .queueFamilyIndex = graphicsIndex, .queueCount = 1, .pQueuePriorities = &queuePriority };
230-
vk::DeviceCreateInfo deviceCreateInfo{ .pNext = &features, .queueCreateInfoCount = 1, .pQueueCreateInfos = &deviceQueueCreateInfo };
231-
deviceCreateInfo.enabledExtensionCount = deviceExtensions.size();
232-
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
230+
vk::DeviceCreateInfo deviceCreateInfo{
231+
.pNext = &features,
232+
.queueCreateInfoCount = 1,
233+
.pQueueCreateInfos = &deviceQueueCreateInfo
234+
.enabledExtensionCount = deviceExtensions.size();
235+
.ppEnabledExtensionNames = deviceExtensions.data();
236+
};
233237

234238
device = vk::raii::Device( physicalDevice, deviceCreateInfo );
235239
graphicsQueue = vk::raii::Queue( device, graphicsIndex, 0 );

attachments/21_index_buffer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ class HelloTriangleApplication {
507507
commandBuffers[currentFrame].setViewport(0, vk::Viewport(0.0f, 0.0f, static_cast<float>(swapChainExtent.width), static_cast<float>(swapChainExtent.height), 0.0f, 1.0f));
508508
commandBuffers[currentFrame].setScissor( 0, vk::Rect2D( vk::Offset2D( 0, 0 ), swapChainExtent ) );
509509
commandBuffers[currentFrame].bindVertexBuffers(0, *vertexBuffer, {0});
510-
commandBuffers[currentFrame].bindIndexBuffer( *indexBuffer, 0, vk::IndexType::eUint16 );
510+
commandBuffers[currentFrame].bindIndexBuffer( *indexBuffer, 0, vk::IndexTypeValue<decltype(indices)::value_type>::value );
511511
commandBuffers[currentFrame].drawIndexed(indices.size(), 1, 0, 0, 0);
512512
commandBuffers[currentFrame].endRendering();
513513
// After rendering, transition the swapchain image to PRESENT_SRC
@@ -698,4 +698,4 @@ int main() {
698698
}
699699

700700
return EXIT_SUCCESS;
701-
}
701+
}

attachments/24_texture_image.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ class HelloTriangleApplication {
444444
void createTextureImage() {
445445
int texWidth, texHeight, texChannels;
446446
stbi_uc* pixels = stbi_load("textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
447-
VkDeviceSize imageSize = texWidth * texHeight * 4;
447+
vk::DeviceSize imageSize = texWidth * texHeight * 4;
448448

449449
if (!pixels) {
450450
throw std::runtime_error("failed to load texture image!");

attachments/25_sampler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ class HelloTriangleApplication {
448448
void createTextureImage() {
449449
int texWidth, texHeight, texChannels;
450450
stbi_uc* pixels = stbi_load("textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
451-
VkDeviceSize imageSize = texWidth * texHeight * 4;
451+
vk::DeviceSize imageSize = texWidth * texHeight * 4;
452452

453453
if (!pixels) {
454454
throw std::runtime_error("failed to load texture image!");

attachments/26_shader_textures.slang

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@ ConstantBuffer<UniformBuffer> ubo;
1414
struct VSOutput
1515
{
1616
float4 pos : SV_Position;
17-
float3 fragColor;
1817
float2 fragTexCoord;
1918
};
2019

2120
[shader("vertex")]
2221
VSOutput vertMain(VSInput input) {
2322
VSOutput output;
2423
output.pos = mul(ubo.proj, mul(ubo.view, mul(ubo.model, float4(input.inPosition, 0.0, 1.0))));
25-
output.fragColor = input.inColor;
2624
output.fragTexCoord = input.inTexCoord;
2725
return output;
2826
}

attachments/27_depth_buffering.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -512,18 +512,16 @@ class HelloTriangleApplication {
512512
}
513513

514514
vk::Format findSupportedFormat(const std::vector<vk::Format>& candidates, vk::ImageTiling tiling, vk::FormatFeatureFlags features) {
515-
for (const auto format : candidates) {
516-
vk::FormatProperties props = physicalDevice.getFormatProperties(format);
517-
518-
if (tiling == vk::ImageTiling::eLinear && (props.linearTilingFeatures & features) == features) {
519-
return format;
520-
}
521-
if (tiling == vk::ImageTiling::eOptimal && (props.optimalTilingFeatures & features) == features) {
522-
return format;
523-
}
515+
auto formatIt = std::ranges::find_if(candidates, [&physicalDevice, &tiling, &features](auto const format){
516+
vk::FormatProperties props = physicalDevice->getFormatProperties(format);
517+
return (((tiling == vk::ImageTiling::eLinear) && ((props.linearTilingFeatures & features) == features)) ||
518+
((tiling == vk::ImageTiling::eOptimal) && ((props.optimalTilingFeatures & features) == features)));
519+
});
520+
if ( formatIt == candidates.end())
521+
{
522+
throw std::runtime_error("failed to find supported format!");
524523
}
525-
526-
throw std::runtime_error("failed to find supported format!");
524+
return *formatIt;
527525
}
528526

529527
vk::Format findDepthFormat() {
@@ -1000,7 +998,8 @@ class HelloTriangleApplication {
1000998
}
1001999

10021000
static vk::Format chooseSwapSurfaceFormat(const std::vector<vk::SurfaceFormatKHR>& availableFormats) {
1003-
return (availableFormats[0].format == vk::Format::eUndefined) ? vk::Format::eB8G8R8A8Unorm : availableFormats[0].format;
1001+
auto formatIt = std::ranges::find(availableFormats, vk::SurfaceFormatKHR(vk::Format::eB8G8R8A8Srgb, vk::ColorSpaceKHR::eSrgbNonlinear));
1002+
return (formatIt != availableFormats.end() ? *formatIt : availableFormats[0];
10041003
}
10051004

10061005
static vk::PresentModeKHR chooseSwapPresentMode(const std::vector<vk::PresentModeKHR>& availablePresentModes) {

attachments/31_compute_shader.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,6 @@ class ComputeShaderApplication {
410410
vk::raii::ShaderModule fragShaderModule = createShaderModule(readFile("shaders/frag.spv"));
411411
vk::raii::ShaderModule shaderModule = createShaderModule(readFile("shaders/slang.spv"));
412412

413-
// vk::PipelineShaderStageCreateInfo vertShaderStageInfo({}, vk::ShaderStageFlagBits::eVertex, vertShaderModule, "main");
414-
// vk::PipelineShaderStageCreateInfo fragShaderStageInfo({}, vk::ShaderStageFlagBits::eFragment, fragShaderModule, "main");
415413
vk::PipelineShaderStageCreateInfo vertShaderStageInfo{ .stage = vk::ShaderStageFlagBits::eVertex, .module = shaderModule, .pName = "vertMain" };
416414
vk::PipelineShaderStageCreateInfo fragShaderStageInfo{ .stage = vk::ShaderStageFlagBits::eFragment, .module = shaderModule, .pName = "fragMain" };
417415
vk::PipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};

en/00_Introduction.adoc

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
== Attribution
66

7-
The Khronos Vulkan^®^ Tutorial is based on the "link:https://vulkan-tutorial .com/[Vulkan Tutorial]" by Alexander Overvoorde licensed under
7+
The Khronos Vulkan^®^ Tutorial is based on the "link:https://vulkan-tutorial.com/[Vulkan Tutorial]" by Alexander Overvoorde licensed under
88
link:https://creativecommons.org/licenses/by-sa/4.0/[CC BY-SA 4.0].
99

1010
== About
1111

1212
This tutorial will teach you the basics of using the
1313
https://www.khronos.org/vulkan/[Vulkan] graphics and compute API.
14-
Vulkan is a new API by the https://www.khronos.org/[Khronos group] (known
15-
for OpenGL) that provides a much better abstraction of modern graphics cards.
14+
Vulkan is an API by the https://www.khronos.org/[Khronos group] that
15+
provides a much better abstraction of modern graphics cards.
1616
This new interface allows you to better describe what your application
1717
intends to do, which can lead to better performance and less surprising
1818
driver behavior compared to existing APIs like
@@ -82,10 +82,6 @@ different linear algebra library, and you will be on your own in terms of
8282
code structuring.
8383
We will use C{pp} features like classes and RAII to organize logic and
8484
resource lifetimes.
85-
There are also two alternative versions of this tutorial available for Rust
86-
developers:
87-
https://github.com/bwasty/vulkan-tutorial-rs[Vulkano based],
88-
https://kylemayes.github.io/vulkanalia[Vulkanalia based].
8985

9086
To make it easier to learn to work with Vulkan, we'll be using the newer
9187
https://github.com/KhronosGroup/Vulkan-Hpp[Vulkan-Hpp] bindings that
@@ -133,8 +129,6 @@ certain Vulkan feature.
133129
That means that the site is also useful as a reference.
134130
All the Vulkan functions and types are linked to the specification, so you
135131
can click them to learn more.
136-
Vulkan is a very new API, so there may be some shortcomings in the
137-
specification itself.
138132
You are encouraged to submit feedback to https://github
139133
.com/KhronosGroup/Vulkan-Docs[this Khronos repository].
140134

0 commit comments

Comments
 (0)