Giter VIP home page Giter VIP logo

vulkan-guide's Introduction

Vulkan tutorial guide with a hands on, step by step, approach.

vulkan-guide's People

Contributors

alexdmiller avatar cdgiessen avatar clement-pirelli avatar david-digioia avatar hydos avatar jake-pauls avatar k1ngst0m avatar lesleylai avatar martty avatar masterchef365 avatar nixaj avatar patrick-han avatar piras314 avatar pixelcluster avatar samantha-payson avatar tom-leys avatar vblanco20-1 avatar zentros avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vulkan-guide's Issues

Chapter 1 Errata

Just finished going through chapter 1! Great stuff you guys have here, and I'm excited to see the rest.

I did notice just two minor nitpicks within the example code while going through:

Chapter 1 - Setting up renderpass code
init_commands is shown before it is created. Looks like the commands and renderpass sections may have traded places at one point?

Chapter 1 - Setting up Vulkan commands
vkinit::command_pool_create_info should have VkCommandPoolCreateFlags parameter instead of VkCommandPoolResetFlags

Multisampling isn't covered by the tutorial (yet)

After I finished the classic tutorial over at vulkantutorial to learn the basics I started from scratch using your guide. I noticed that you do not cover multisampling (yet). I am aware that with some adjustments one may implement it with the explanation on vulkantutorial but I wanted to ask whether you plan to integrate that yourself as well.

ImGui background window has "End" inside IF (new chapter 2)

End must always be called, even if Begin returns false. So the example in new chapter 2 will abort if you close the example window

ImGui::NewFrame();
		
if (ImGui::Begin("background")) {
	
	ComputeEffect& selected = backgroundEffects[currentBackgroundEffect];

	ImGui::Text("Selected effect: ", selected.name);

	ImGui::SliderInt("Effect Index", &currentBackgroundEffect,0, backgroundEffects.size() - 1);

	ImGui::InputFloat4("data1",(float*)& selected.data.data1);
	ImGui::InputFloat4("data2",(float*)& selected.data.data2);
	ImGui::InputFloat4("data3",(float*)& selected.data.data3);
	ImGui::InputFloat4("data4",(float*)& selected.data.data4);

// --->			ImGui::End();  Remove this
}
ImGui::End();  // Place outside the IF

ImGui::Render();

New Chapter 2, Push Constants and new shaders -- 0xC0000005: Access violation reading location

I was following along the 'new' guide for Vulkan 1.3 with dynamic rendering, and got a runtime error when exiting application, during cleanup() function ( _mainDeletionQueue.flush(); ).

The lambda expression is capturing by reference, but in its body, the variables sky and gradient reference garbage data, as they are not fields of the VulkanEngine class.

void VulkanEngine::init_background_pipelines() {
  // ...
  _mainDeletionQueue.push_function([&]() {
	  vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr);
	  vkDestroyPipeline(_device, sky.pipeline, nullptr);
	  vkDestroyPipeline(_device, gradient.pipeline, nullptr);
  });
}

https://github.com/vblanco20-1/vulkan-guide/blame/4fafdfee151fea55d036c727b3b0b372d1c9239e/docs/new_chapter_2/vulkan_pushconstants.md#L215C2-L215C2

I got it working by replacing the lines responsible for pipeline destruction that were using sky and gradient by reference with a for loop, and also destroying _gradientPipelineLayout last, like this:

  _mainDeletionQueue.push_function([&]() {
	for (auto it = backgroundEffects.rbegin(); it != backgroundEffects.rend(); it++){
		vkDestroyPipeline(_device, it->pipeline, nullptr);
	}
	vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr);
	});

Seems typo in introduction to push constants, sayning "Push constants have a **minimum** size of 128 bytes"?

https://vkguide.dev/docs/chapter-3/push_constants/#new-pipelinelayout

In the paragraph introducing pipelinelayout, there is a sentence

Push constants have a minimum size of 128 bytes, which is enough for common things like a 4x4 matrix and a few extra parameters.

Is this minimum typo, which should be maximum?


EDIT: after some search. I understand that by spec, the minimum size of push constant is required to be 128bytes.

Incorrect statement on line 32 of master/docs/chapter-4/descriptors.md

On the specified line, the tutorial states that enabling the VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag when creating a descriptor pool disallows freeing individual descriptor sets, however, according to the spec, this flag enables this functionality instead of disallowing it
image
image

Incorrect sync in vkQueuePresent

The semaphore passed to vkQueuePresent should be per-image-index not per-frame-index.

The semaphore passed to vkQueuePresent can't be submitted for signalling again until it's retired. As there's no signal semaphore/fence parameter to vkQueuePresent, the only way to know it's retired is if vkAcquireNextImage returns the same imageIndex (and has fully completed, i.e. it has signaled the semaphore/fence passed to it).

The current setup (per-frame) works if presentation engines return images in order (and the swapchain has the same or more images than frames-in-flight), but this is not contractually guaranteed and out-of-order acquires is explicitly allowed by the spec. A 3 image swapchain could for example hand out images in the order 012121212121212 etc., and the semaphore used for the first present call would be rendered unusable.

Cannot compile asset-baker

Hi!
The last week I tried to compile the asset-baker, but I can't make it work.
It can't find stb_image and nvtt, but I don't know why. I installed both via vcpkg in many different versions, tried release builds, static builds etc. None worked.

I get many many errors like these:

D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_load_from_memory
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_load
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_load_16_from_memory
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_image_free
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_is_16_bit_from_memory
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_write_png_to_func
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_write_bmp_to_func
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol stbi_write_jpg_to_func
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\asset_main.cpp.obj : error LNK2001: unresolved external symbol "bool __cdecl tinyobj::LoadObj(struct tinyobj::attrib_t *,class std::vector<struct tinyobj::shape_t,class std::allocator<struct tinyobj::shape_t> > *,class std::vector<struct tinyobj::_material_t,class std::allocator<struct tinyobj::_material_t> > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,char const *,char const *,bool,bool)" (?LoadObj@tinyobj@@YA_NPEAUattrib_t@1@PEAV?$vector@Ushape_t@tinyobj@@V?$allocator@Ushape_t@tinyobj@@@std@@@std@@PEAV?$vector@U_material_t@tinyobj@@V?$allocator@U_material_t@tinyobj@@@std@@@4@PEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@4@3PEBD4_N5@Z)
D:\Code\cpp\vulkan-guide\out\build\x64-Debug (default)\nvtt.lib(CompressionOptions.obj) : error LNK2001: unresolved external symbol "int __cdecl nvAbort(char const *,char const *,int,char const *,char const *,...)" (?nvAbort@@YAHPEBD0H00ZZ)

... and many more nvtt.lib unresolved external symbol errors.

I don't know what I'm doing wrong. Here is my repo: https://github.com/itmuckel/vulkan-guide

[GLTF Loading]

In case anyone else gets stuck on this, with newer versions of fastgltf (I am using 7.0.0), the functions you pass to fastgltf::visitor, the signatures seem to have changed slightly, causing ... odd behavior. Specifically, the branch that takes a fastgltf::sources::Vector& should be const fastgltf::sources::Array&. Probably an update to fastgltf since the time of writing. According to their docs, sources::Vector is only used for writing out gltf files, and reading should always use sources::Array. Also don't forget to mark it as a const reference or else it will still match, but the bytes will be filled with junk, and you'll bang your head for 3 days reevaluating your entire asset loading system. Or maybe that was just me.

Chapter 4 - "Setting up descriptor sets" Error

The last block of code in "Setting up camera buffers", before "Descriptor sets: shader"

void VulkanEngine::init_descriptors()
{
	for (int i = 0; i < FRAME_OVERLAP; i++)
	{
		_frames[i].cameraBuffer = create_buffer(sizeof(GPUCameraData), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
	}

	// add buffers to deletion queues
	for (int i = 0; i < FRAME_OVERLAP; i++)
	{
		vmaDestroyBuffer(_allocator,_frames[i].cameraBuffer._buffer, _frames[i].cameraBuffer._allocation);
	}
}

Shouldn't it be,

void VulkanEngine::init_descriptors()
{
	for (uint8_t i = 0; i < FRAME_OVERLAP; ++i)
	{
		_frames[i].cameraBuffer = create_buffer(sizeof(GPUCameraData), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
	}

	// Add buffers to the deletion queue
	for (uint8_t i = 0; i < FRAME_OVERLAP; ++i)
	{
		_mainDeletionQueue.push_function([=]() {
                	vmaDestroyBuffer(_allocator, _frames[i].cameraBuffer._buffer, _frames[i].cameraBuffer._allocation); 
		});
	}
}

because we're pushing the VMA destructors onto the deletion queue?

Chapter 4 validation errors

There are tons of validations errors related to command buffer being in use when quitting the application.

[ERROR: General]
/usr/lib/i386-linux-gnu/libvulkan_radeon.so: wrong ELF class: ELFCLASS32
[ERROR: General]
/usr/lib/i386-linux-gnu/libvulkan_intel.so: wrong ELF class: ELFCLASS32
The gpu has a minimum buffer alignement of 256
WARN: Material file [ monkey_smooth.mtl ] not found in a path :
Failed to load material file(s). Use default material.
material [ 'None' ] not found in .mtl

[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x1f000000001f, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkBuffer 0x1f000000001f[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x1e000000001e, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkBuffer 0x1e000000001e[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x220000000022, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkBuffer 0x220000000022[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x230000000023, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkBuffer 0x230000000023[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x1c000000001c, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkBuffer 0x1c000000001c[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0xb000000000b, type = VK_OBJECT_TYPE_DEVICE_MEMORY; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkDeviceMemory 0xb000000000b[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-00378 ] Object 0: handle = 0x55f937376068, type = VK_OBJECT_TYPE_DEVICE; Object 1: handle = 0x1d000000001d, type = VK_OBJECT_TYPE_DEVICE_MEMORY; | MessageID = 0x71500fba | OBJ ERROR : For VkDevice 0x55f937376068[], VkDeviceMemory 0x1d000000001d[] has not been destroyed. The Vulkan spec states: All child objects created on device must have been destroyed prior to destroying device (https://vulkan.lunarg.com/doc/view/1.2.162.0/linux/1.2-extensions/vkspec.html#VUID-vkDestroyDevice-device-00378)
VulkanEngine: /media/Programs/Programming/C++/VulkanEngine/Engine/Source/Vulkan/../third-party/Vma/vk_mem_alloc.h:12318: void VmaDeviceMemoryBlock::Destroy(VmaAllocator): Assertion `m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!"' failed.
Aborted (core dumped)

Also there should be probably a mention, how to cleanup descriptor sets .
Added this to the end of init_descriptors function
_mainDeletionQueue.push_function([=]() { vkDestroyDescriptorSetLayout(_device, _globalSetLayout, nullptr); vkDestroyDescriptorSetLayout(_device, _objectSetLayout, nullptr); vkDestroyDescriptorPool(_device, _descriptorPool, nullptr); });

Optional chapter that explains how to initialize that Vulkan boilerplate the “manual” way

The introduction section said that

Vk Bootstrap Abstracts a big amount of boilerplate that Vulkan has when setting up. Most of that code is written once and never touched again, so we will skip most of it using this library. This library simplifies instance creation, swapchain creation, and extension loading. It will be removed from the project eventually in an optional chapter that explains how to initialize that Vulkan boilerplate the “manual” way.

I now want to remove vk-bootstrap library, and I'm wondering where can I find such an "optional chapter" concerning initializing the Vulkan boilerplate the manual way?

BTW, a great tutorial!

Textures are using the wrong format

Color textures are (usually) in the sRGB colorspace, and should be loaded as such, into an image/imageview with a format of VK_FORMAT_R8G8B8A8_SRGB, otherwise the sampled value is incorrect.

init_default_data (chapter 3) does not destroy rectangle's buffers

This code is missing from the end of init_default_data defined in Chapter 3 and so the buffers live to program end and cause a VMA assert

    _mainDeletionQueue.push_function([=]() {
        destroy_buffer(rectangle.indexBuffer);
        destroy_buffer(rectangle.vertexBuffer);
    });

After you load the GLTB meshes, this also requires adding

 _mainDeletionQueue.push_function([=]() {
     for(auto asset: testMeshes)
     {
         destroy_buffer(asset->meshBuffers.indexBuffer);
         destroy_buffer(asset->meshBuffers.vertexBuffer);
     }
 });

Out of date ImGui API

Hi,

Due to the ImGui API being out of date, when one adds the demo window to the engine, lots and lots of validation errors are output. This is easily overcome by pulling the newest version of imgui and adapting the CMake file accordingly. But I thought I should say something here about it.

Cleanup Synchronization Structures

Hi! Great tutorial!
I just finished chapter 1 and got errors that

  1. the synchronization structures were still in use.
  2. the synchronization structures weren't destructed.

I'd suggest to add this cleanup code at the end of chapter 1:

vkDeviceWaitIdle(_device);

vkDestroySemaphore(_device, _renderSemaphore, nullptr);
vkDestroySemaphore(_device, _presentSemaphore, nullptr);
vkDestroyFence(_device, _renderFence, nullptr);

Other than that great, thank you for putting this together!

Backwards Colors

The second section of chapter 4 titled "Textures" has a part where it creates some basic textures procedurally. The colors are written in the reverse byte order that they should be, causing the "black" to show up as red, the "grey" to show up as pink, and the "magenta" to show up as yellow.

SPV files are not built

When I reconfigure CMAKE, I see in logs that it tries to build spv files:

[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/colored_triangle.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/colored_triangle.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/colored_triangle_mesh.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/default_lit.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/funky_triangle.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/gradient.comp
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/gradient_color.comp
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/mesh.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/mesh.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/sky.comp
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/tex_image.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/textured_lit.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/tri_mesh.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/tri_mesh_descriptors.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/tri_mesh_pushconstants.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/tri_mesh_ssbo.vert
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/triangle.frag
[cmake] -- BUILDING SHADER
[cmake] -- C:/Users/***/Documents/GitHub/vulkan-guide/shaders/triangle.vert

However, no spv file is added to shaders folder. Does anyone else have same problem? I am working on Windows 11 and trying all-chapters or all-chapters-1.3-wip branches. Vulkan SDK is installed as rest of c++ code is compiled normally. Any help would be appreciated.

Typo

In new_chapter_1 in vulkan_mainloop.md under the section Image Layouts in the second paragraph there is the word "scren." I believe this is supposed to be "screen." it is the second to last word in the second paragraph.

Not trying to be a stickler. this typo is very small and insignificant.

Mac OS

Has anyone tried running this code on Mac OS? It works fine up until switching from vertices hard coded in the shader to vertex buffers. After this change, I don't get any validation warnings or errors, just nothing is rendered on the screen. It's really hard to debug on Mac, and of course it works just fine on Windows. Compiling with clang on both platforms if that matters.

I'm unable to get the chapter 3 code to run as-is on Mac OS, I get tons of linker errors coming from SDL. My own code that isn't working has some some minor differences from the code in this repo, mainly using vcpkg instead of vendoring everything.

I also have other examples of vertex buffers working on Mac OS, just there are a lot of differences, eg not using vkbootstrap or vulkan-memory-allocator.

I think the only way to debug vulkan on Mac OS is to install Xcode, but I can't for the life of me seem to free up enough disk space to allow Xcode to install.

Why did you drop the reflection based descriptor builder ?

Hi,
First, i want to thank you for this great guide, it helps me lot.
I am currently trying to implement the missing bits in my engine to get to the GPU driven rendering part, mostly shader and material abstraction.
I wanted to ask why you went from the reflection based descriptor builder to the one described in the extra chapter.
I thought the reflection based one would be easier to work with but I don't have the full picture about that.

cannot open Sponza.pfb

hello,i generator assert_export by baker.exe&assert forder, then make extra.exe run,it has errors : object->material is nullptr,why and how to make it run sucess。

Where to ask questions regarding implementation details?

Hi,

Thanks for the guide. I have a question regarding how the depth culling logic works and do not know where to ask.

visible = visible && depthSphere >= depth;

The current logic seems to only draw objects that are closer to the camera than other objects drawn the previous frame. The article mentions "one frame of latency" but never explains how this resolves the following question. Suppose that an object very close to the camera is drawn on frame N, but disappears the next frame. Its depth values seem to always persist in the depth attachment, even after it is removed. How is this artifact resolved?

zeux's depth culling technique uses some crafty logic to address this, that I have yet to locate something similar in this project:
https://github.com/zeux/niagara/blob/2fe8f9dd6477be4cad0df26a6e3162ac5593ce42/src/niagara.cpp#L1086-L1099

I'm working on building the engine locally to step through with RenderDoc but there's quite a few (undocumented) steps involved.

Thanks,
Jesse

Inconsistencies I found

(mainly making the issue to document them before I can get a chance to fix them)

Multi-chapter comments:

  • Stop mapping and unmapping. Just map it at the start and leave it be.
  • Maybe 'diffing' would be a lot cleaner about when/where you need stuff to change. (not sure how to implement that in markdown)

Chapter 2 - Cleanup and deletion queue
fence_create_info and semaphore_create_info are used but never introduced.

Chapter 3 - Scene Management:
References monkey.obj but no such file exists in the assets folder, monkey_smooth.obj is used in the OBJ chapter
Code in question

_monkeyMesh.load_from_obj("../../assets/monkey.obj");`

Chapter 4 - Setting up descriptor sets:
GPUCameraData has projection as a member, but later is used as proj.

GPUCameraData camData;
camData.proj = projection;
camData.view = view;
camData.viewproj = projection * view;

The cleanup code is missing from the tutorial. The all-chapters branch has the correct code, its just missing in the tutorial.
The full code would need to be broken up as each of these item are introduced.

Chapter 4 - Dynamic Descriptor Sets
VkBootstrap already queries the VkPhysicalDeviceProperties and stores it in the vkb::Device struct. Can just pull it out of there instead of querying it again. Not a big difference, but hey, use whats available I say.
```c
    _gpuProperties = vkbDevice.physical_device.properties;

In the previous section, we created VkDescriptorSetLayoutCreateInfo setInfo = {}; but in this section its VkDescriptorSetLayoutCreateInfo setinfo = {}; (lowercase info). Makes for subtle but obnoxious errors.

The names used here probably should change more, it feels wrong to keep calling it 'colorMeshShader' everywhere instead of default_lit which is the new name.

if (!load_shader_module("../../shaders/default_lit.frag.spv", &colorMeshShader))
{
	std::cout << "Error when building the colored mesh shader" << std::endl;
}

Missing a ellipsis for code that exists between two changes

VkDescriptorBufferInfo sceneInfo;
sceneInfo.buffer = _sceneParameterBuffer._buffer;
sceneInfo.offset = 0;
sceneInfo.range = sizeof(GPUSceneData);

...

VkWriteDescriptorSet sceneWrite = vkinit::write_descriptor_buffer(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, _frames[i].globalDescriptor, &sceneInfo, 1);

The text/code has VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER in the layout binding instead of UNIFORM_BUFFER_DYNAMIC

    // binding for scene data at 1
    VkDescriptorSetLayoutBinding sceneBind = vkinit::descriptorset_layout_binding(
        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 1);

Got this validation error message - not sure if its bogus or not.

Validation Error: [ VUID-VkShaderModuleCreateInfo-pCode-01091 ] Object 0: handle = 0x23610f91908, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xa7bb8db6 | vkCreateShaderModule(): The SPIR-V Capability (DrawParameters) was declared, but none of the requirements were met to use it. The Vulkan spec states: If pCode declares any of the capabilities listed in the SPIR-V Environment appendix, one of the corresponding requirements must be satisfied (https://vulkan.lunarg.com/doc/view/1.2.189.2/windows/1.2-extensions/vkspec.html#VUID-VkShaderModuleCreateInfo-pCode-01091)

Chapter 4 - Storage Buffers:
Need ellipsis and missing semicolon on GPUObjectData

struct FrameData {
	AllocatedBuffer objectBuffer;
};

struct GPUObjectData{
	glm::mat4 modelMatrix;
}

A lot of refactoring goes on when looking at Chapter 4's source code. Seems that its much leaner, but none of that is mentioned in the text. Removing stuff that is no longer needed would be kind.

Chapter 5 - Memory Transfers:

Neither command_buffer_begin_info nor submit_info were defined before it was used.

Unclear where the upload_mesh code should go, above or below existing. Looks like it should just replace it entirely, clearer instructions would be good.

Make sure you call load_images before setup_scene in the init function
Just show the change, and its init_scene, not setup_scene

Chapter 5 - Drawing Images:
Didn't mention needing to add #include <glm/vec2.hpp> in vk_mesh.h

Typo - should be _meshPipelineLayout, not meshPipLayout

    create_material(texPipeline, meshPipLayout, "texturedmesh");

Ack - this is because a new variable was introduced. This whole part of the tutorial needs to be looked over with a fine tooth comb.
Okay I may have jumped the gun, looking at the source code a bit too early. Still, its a bit messy and hard to follow what changes go where.

Again, missing cleanup for new descriptor layouts.

Compile Error in vk_mem_alloc.h with VS2019

I downloaded the all-chapters branch configured the project with CMake for VS2019 and then set chapter 3 as startup project.
When trying
to compile I get a bunch of errors in vk_mem_alloc.h

image

draw_geometry (new chapter 3) attaches to wrong image format

In Chapter 3 Draw geometry begins with the following code (attaching using VK_IMAGE_LAYOUT_GENERAL):

void VulkanEngine::draw_geometry(VkCommandBuffer cmd)
{
	//begin a render pass  connected to our draw image
	VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_GENERAL);

However we just transitioned to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. Surely that's the argument required to attachment_info.

vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

draw_geometry(cmd);

Code for the GPU-driven chapter and how to build it

Hi there! I'm currently studying GPU-driven rendering for educational purposes, and I was looking through the GPU-driven chapter of vkguide, and wanted to study the source code - however, it doesn't seem that it is available in this repository?

Engine crashed when window gets minimized

Engine crashes when I minimize the window.

The crash can be avoided by skipping VulkanEngine::draw() if window is minimized.

For example by adding this in the first line:

if (SDL_GetWindowFlags(_window) & SDL_WINDOW_MINIMIZED)
	return;

Extra parameter in vkb::SwapchainBuilder

Chapter 1, "Vulkan Initialization Code", under "Setting up the swapchain" includes the following line of example code:

vkb::SwapchainBuilder swapchainBuilder{_chosenGPU,_device,_surface,_graphicsQueueFamily };

_graphicsQueueFamily has not been created at this point, nor can I see any constructor for vkb::SwapchainBuilder that takes a queue family as a parameter.

Setting up ImGui section of chapter 2

I was having an issue with ImGui looking all glitched out. What fixed it for me was noticing and changing the image layout in the draw_imgui method.

In the chapter and the code on github the for chapter 2, the draw_imgui() is as follows:

void VulkanEngine::draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView)
{
VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(targetImageView, nullptr, VK_IMAGE_LAYOUT_GENERAL);
VkRenderingInfo renderInfo = vkinit::rendering_info(_swapchainExtent, &colorAttachment, nullptr);

vkCmdBeginRendering(cmd, &renderInfo);

ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);

vkCmdEndRendering(cmd);

}

but the target image we send in is not set as VK_IMAGE_LAYOUT_GENERAL but as VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL (see snippet from draw function)

// set swapchain image layout to Attachment Optimal so we can draw it
vkutil::transition_image(cmd, _swapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

//draw imgui into the swapchain image
draw_imgui(cmd, _swapchainImageViews[swapchainImageIndex]);

So the actual draw_imgui method should be as follows

void VulkanEngine::draw_imgui(VkCommandBuffer cmd, VkImageView targetImageView) {
VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(targetImageView, nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
VkRenderingInfo renderInfo = vkinit::rendering_info(_swapchainExtent, &colorAttachment, nullptr);

vkCmdBeginRendering(cmd, &renderInfo);

ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);

vkCmdEndRendering(cmd);

}

Chapter 2 Errata

Chapter 2 - Setting up Triangle shaders - Loading the shaders on initialization

  • VkShaderModule objects aren't being passed as pointers into load_shader_module

Chapter 2 - Toggling shaders - Multiple Pipelines

  • All shaders are using the colored_triangle files

Memory leak

Hi,
branch: engine

I commented this code:

ZoneScopedNC("Flag Objects", tracy::Color::Blue);
//test flagging some objects for changes

//int N_changes = 1000;
//for (int i = 0; i < N_changes; i++)
//{
//	int rng = rand() % _renderScene.renderables.size();
//
//	Handle<RenderObject> h;
//	h.handle = rng;
//	_renderScene.update_object(h);
//}

and when I run the app, after like 3 minutes the memory grows to ~3GB

Don't map & unmap memory every frame.

This is actually not necessary, especially for the buffers you are updating every frame. It is not cheap to map/unmap, best to map at the start and leave it until shutdown.

Trying to compile Engine branch but get errors

third-party/imgui/imgui_impl_sdl.cpp:50:10: fatal error: SDL.h: No such file or directory
   50 | #include <SDL.h>
      |          ^~~~~~~
compilation terminated.
make[2]: *** [third-party/CMakeFiles/imgui.dir/build.make:160: third-party/CMakeFiles/imgui.dir/imgui/imgui_impl_sdl.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:392: third-party/CMakeFiles/imgui.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Calculation of the flash value using abs, instead of std::abs or fabs.

float flash = abs(sin(_frameNumber / 120.f));
This line is causing a problem when running the code from the "Mainloop Code" chapter. The abs function outside the std-namespace casts the parameter to an int, which leads to flash always being zero, making the screen always appear black. I suggest replacing it with std::abs or `fabs. This StackOverflow answer explains why that makes a difference: https://stackoverflow.com/a/3118188.

No CSS on Safari

I noticed recently that vkguide.dev has no CSS styles on macOS Safari. Looking at the page source I think it's caused by these two lines in the HEAD element:

<link rel="stylesheet" href="//www.vkguide.dev/assets/css/just-the-docs.css">
<link rel="shortcut icon" href="//www.vkguide.dev/favicon.ico" type="image/x-icon">

Using the developer tools and changing them to be relative fixes the site styling for me:

<link rel="stylesheet" href="assets/css/just-the-docs.css">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

Maybe the URL here should be vkguide.net?

[CVar system] Memory leak inside the code example + typo inside the article

Hi !

First, thx a lot for all your articles and code examples they are really useful. I'm integrating a CVar system based on your example inside my own engine and I think I found a trivial memory leak inside the example code here:

https://github.com/vblanco20-1/vulkan-guide/blob/engine/extra-engine/cvars.cpp

Line 49 you are doing a dynamic allocation for the CVarStorage array but you never delete this array inside the code. Adding:

~CVarArray()
{
	delete[] cvars;
	cvars = nullptr;
}

Right after the constructor should fix the issue if ever you want to fix it.

Also inside the article:

//checkbox CVAR
AutoCVar_Int CVAR_TestCheckbox("test.checkbox", "just a checkbox", 0, CVarFlags::EditCheckbox);

//int CVAR
AutoCVar_Int CVAR_TestInt("test.int", "just a configurable int", 42);

//float CVAR
AutoCVar_Int CVAR_TestFloat("test.float", "just a configurable float", 13.37);

//string CVAR
AutoCVar_String CVAR_TestString("test.string", "just a configurable string", "just a configurable string");

There is a small typo for the float CVar example. It Should use AutoCVar_Float instead of AutoCVar_Int (it won't compile anyway as the last argument is a double and not an int). Again it's trivial if ever you want to fix it.

Thx again for all the resources.

engine branch code error

in engine branch, file "vk_shader.cpp " line 330.
I think the code in if condition should be "if( b.dstSet != a.dstSet)"

Compile Error in vk_mem_alloc.h with VS2019

image
Build failed in chapter3. I try to switch head file order like:#36, but it does't work.

my build environment: visual studio 2019, CMake 3.15.0 rc3, windows 10 SDK(10.0.19041.0)
thanks for any help

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.