vblanco20-1 / vkguide-comments

Storage for the comments of vulkan-guide
0 stars 0 forks source link

Vkguide 2 Beta Comments #14

Open utterances-bot opened 8 months ago

utterances-bot commented 8 months ago

- Vulkan Guide

Practical guide to vulkan graphics programming

https://www.vkguide.dev/docs/new_vkguide/chapter_1/vulkan_mainloop/

vblanco20-1 commented 7 months ago

@Fletterio Thats an error that has been reported on some older AMD gpus (Polaris, like a RX 580). Its caused by AMD drivers missing a extension that renderdoc needs to debug buffer-device-address. On those, renderdoc cant create a vulkan 1.3 context and the engine fails. Works well on linux where the drivers do implement this fine, its just a problem with an older AMD card on windows .

oh-facts commented 7 months ago

I completed mesh loading. I tried rendering two monkey heads. One of them closer to the camera and one further away. My depth buffer for individual monkey heads works fine but when I have two monkey heads, the closer one is drawn behind the further one (Both heads have same scale too so I could tell the one that looked smaller should have been behind).

Are there any other considerations I need to account for when depth buffering?

Is there any other info that I should share? Thank you!

vblanco20-1 commented 7 months ago

@oh-facts are you doing 2 separate render-passes? If you are rendering the 2 monkeyheads one after another within the same render pass, depth buffering should work correctly. Try running it through renderdoc to see whats going on.

Latias94 commented 7 months ago

Hello, in the setting up IMGUI chapter, there is no need to call ImGui_ImplVulkan_DestroyFontUploadObjects, and some interface changes (ImGui_ImplVulkan_CreateFontsTexture) for the latest ImGui version. vkDestroyDescriptorPool should be called after ImGui_ImplVulkan_Shutdown. It also lack the implementation of VkRenderingInfo rendering_info(VkExtent2D renderExtent, VkRenderingAttachmentInfo* colorAttachment, VkRenderingAttachmentInfo* depthAttachment); Here is my implementation: https://github.com/Latias94/learn_vkguide/commit/d8f858cfabcd150d4d0271d6102ef93dede20eae . Thanks for your excellent tutorial again!

Latias94 commented 7 months ago

In Mesh Loading chapter, it is better to remind reader to add GLM_FORCE_DEPTH_ZERO_TO_ONE define, if not we can't see the model.

antoinethomaspro commented 7 months ago

I'm at chapter 3 and I think there's a mistake when we set the VkRenderingAttachmentInfo struct of the colorAttachment in draw_geometry(): The layout is VK_IMAGE_LAYOUT_GENERAL. Shouldn't it be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL?

vblanco20-1 commented 7 months ago

@Latias94 that #define is set in the cmake options for glm. That way its added to all includes as its common to have problems with the split defines in one files and others.

Alexmdias commented 7 months ago

I'm going to continue with the tutorial, but I wasn't able to trigger a validation layer error by destroying the Instance before the Device. Not sure what I missed.

(my vkengine.cpp : https://github.com/Alexmdias/Vulkan_from_scratch/blob/main/src/vk_engine.cpp)

Latias94 commented 7 months ago

I'm going to continue with the tutorial, but I wasn't able to trigger a validation layer error by destroying the Instance before the Device. Not sure what I missed.

(my vkengine.cpp : https://github.com/Alexmdias/Vulkan_from_scratch/blob/main/src/vk_engine.cpp)

Your code is nothing wrong. The validation error only raise if you call vkDestroyInstance before vkDestroyDevice

Alexmdias commented 7 months ago

Your code is nothing wrong. The validation error only raise if you call vkDestroyInstance before vkDestroyDevice

Yeah I know, when I do that I still don't get an error. Is it supposed to show up on Visual code's debugger or somewhere else?

Latias94 commented 7 months ago

Your code is nothing wrong. The validation error only raise if you call vkDestroyInstance before vkDestroyDevice

Yeah I know, when I do that I still don't get an error. Is it supposed to show up on Visual code's debugger or somewhere else?

- constexpr bool bUseValidationLayers = false;
+ constexpr bool bUseValidationLayers = true;
Alexmdias commented 7 months ago

Your code is nothing wrong. The validation error only raise if you call vkDestroyInstance before vkDestroyDevice

Yeah I know, when I do that I still don't get an error. Is it supposed to show up on Visual code's debugger or somewhere else?

- constexpr bool bUseValidationLayers = false;
+ constexpr bool bUseValidationLayers = true;

I've tried that too. But thank you for the suggestion

oh-facts commented 7 months ago

Hi. So, some meshes that I parse have no index data, only vertices. So for those do I do something like

if(index_count == 0)
{
    vkcmddraw()
}

Or are gltf 2.0 models always indexed?

vblanco20-1 commented 7 months ago

@oh-facts gltf models are allowed to not have index data, but we never found a 3d program that exported models without indices. Its more of a test file type of thing. FastGLTF has an option that creates the 0-1-2-3... index buffer for those meshes.

oh-facts commented 6 months ago

Hi, I have some models that don't use textures. Should I create a separate pipeline and shader for them?

ByAlu commented 6 months ago

hey blanco! in chapter2 "Improving the render loop" at the final draw() function while copying images vkutil::copy_image_to_image(cmd, _drawImage.image, _swapchainImages[swapchainImageIndex], _drawExtent, _swapchainExtent);

because of _swapchainExtent struct members width and height not inited before I got validation error. Fixed it assign them create swapchain function

oh-facts commented 6 months ago

Why aren't we putting material desc sets inside frame data? Do we not want to do the frame overlap thing witht them?

Brettehwarrior commented 6 months ago

New to Vulkan coming from only some OpenGL experience in C; I'm a little confused by the inclusion of SDL under the list of included libraries in the Third party libraries section, because on the starting-point branch there is no SDL included. I did notice it on the starting-point-2, but the guide thus far did not indicate how to set up SDL in any unique way

louisforestier commented 6 months ago

Hi ! I have some strange results in chapter 4 when i add the textures. The monkey face is red and yellow instead of magenta and black. And i have the same error when I use the code in the all-chapters-2 branch. Do you have any idea, why that would happen ?

niemilau commented 6 months ago

The default hardcoded images in Chapter 4 (Textures) did not work for me either. For example, this:

uint32_t black = 0x000000FF;
    _blackImage = create_image((void*)&black, VkExtent3D{ 1, 1, 1 }, VK_FORMAT_R8G8B8A8_UNORM, 
VK_IMAGE_USAGE_SAMPLED_BIT);

resulted in an image that looked like it had the RGBA order flipped. Using an array of uint8_t instead of uint32_t to represent the colors worked.

louisforestier commented 6 months ago

I found the reason and another solution for the problem in chapter 4. The spec says :

VK_FORMAT_R8G8B8A8_UNORM specifies a four-component, 32-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.

This means that black is 0x000000FF on big endian architecture and 0xFF000000 on little endian architecture. Same thing for magenta, 0xFF00FFFF on BE and 0xFFFF00FF on LE.

GummyGun commented 6 months ago

I'm halfway through chapter 3-mesh loading I'm using a language different from c++ so I don't have a way to directly use libraries mainly fastgltf, previously I could see the mesh rendering when sending the identity matrix but after applying my equivalent of the perspective matrix function I can't see the mesh rendering. but when I set near to 1 and far to 10000 i can see the shapes rendering. So anyone has an idea of where is the mistake. Or is there more I need to do get the mesh to render with the perspective matrix. I have validated that my perspective function is returning the exact same matrix as glm

Note that I don't have depth testing activated yet

Jojonobody2 commented 6 months ago
  • Improving the render loop
  1. Suggest how to include VmaAllocator -> "#include "vk_mem_alloc.h"
  2. "We have an AllocatedImage structure that already holds format, size, imageview, and the image itself". We don't as far as I know by the time we reach that chapter. VkTypes hasn't been touched yet(it's also the place where vk_mem_alloc is included).
  3. Typoes:
  • "new draw loop" should be capitalized.
  • "Vulkan has 2 main ways of copying one image to another. you can use VkCmdCopyImage or VkCmdBlitImage CopyImage is faster" needs a dot after VkCmdBlitImage.
  • "//transtion the draw image and the swapchain image into their correct transfer layouts" in the last code piece -> "transition"
  • "The main diference we have in the render loop is that we no longer do the clear on the swapchain image" -> "difference"
  1. I got linking error due to Vma, I guess #define VMA_IMPLEMENTATION is needed. I added it in the main.
  2. You say "In our case, we want TransferSRC because we will have it as a copy source to the swapchain, Storage because thats the “compute shader can write to it” layout, and Color Attachment so that we can use graphics pipelines to draw geometry into it." but in the code snippet "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT" is missing.
  3. So far everything works as intended(flashing blue on screen) but I got a validation error that has to do with how drawImage was created but I'm not sure how to fix it: "Validation Error: [ VUID-vkCmdClearColorImage-image-00002 ] Object 0: handle = 0x1a047dde250, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xcfef35000000000a, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x636f8691 | vkCmdClearColorImage(): image (VkImage 0xcfef35000000000a[]) was created with usage VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT (missing VK_IMAGE_USAGE_TRANSFER_DST_BIT). The Vulkan spec states: image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag (https://vulkan.lunarg.com/doc/view/1.3.268.0/windows/1.3-extensions/vkspec.html#VUID-vkCmdClearColorImage-image-00002)"

I think it's a me problem :/

to fix the vkcmdclearcolor error you have to add the following to your SwapchainCreateInfo: SwapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

or if you use VkBootstrap add the following to your Swapchain builder: .add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT)

monomere commented 6 months ago

I may be wrong, but isn't the deletion queue more of a deletion stack?

RefuX commented 6 months ago

Chapter 4 - Engine Architecture When you introduce the IRenderable class, you reference to sometimes a RenderContext and sometimes a DrawContext.

mlealdefreitas commented 6 months ago

For those of you that got the error use of undefined type VmaAllocation_T in Visual Studio 2022 due to the line

void* data = staging.allocation->GetMappedData();

this is probably because you've implementend VMA in another file (i.e., not in the file in which you're implementing upload_mesh), so the compiler has no idea that VmaAllocation_T has a member function GetMappedData() in the corresponding translation unit.

I'm quite sure accessing member functions of VmaAllocation_T is not recommended. I think the proper way to get the data is by doing

void* data{};
vmaMapMemory(_allocator, staging.allocation, &data);
vmaUnmapMemory(_allocator, staging.allocation);

which, although more verbose, doesn't use the inner structure of the VmaAllocation_T class.

CrunchyBiscuit19 commented 6 months ago

For those who got a weird yellow-red-ish looking checkerboard in the Textures chapter, here's a fix I came up with.

Change the endianness of the colour data in vk_engine.cpp. In C++23 this can be done with std::byteswap.

constexpr uint32_t white = std::byteswap(0xFFFFFFFF);
constexpr uint32_t grey = std::byteswap(0xAAAAAAFF);
constexpr uint32_t black = std::byteswap(0x000000FF);
constexpr uint32_t magenta = std::byteswap(0xFF00FFFF);

Then change the colour blend factors in vk_pipelines.cpp to the following.

_colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
_colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
eqdiag commented 5 months ago

Having an issue with Ch3 ("Setting up the render pipeline"):

So far, I've had no problems drawing everything from the first 2 chapters (compute shader background + imgui on top).

I've finished all the graphics pipeline setup, but I'm just not seeing the triangle drawn. There are no validation error messages.

At this point, I would normally check out what's going on in RenderDoc but it's crashing when I load up the .exe, because I think it only supports Vulkan 1.2 at this point.

Anyone else having this problem?

Hkozacz commented 5 months ago

Hmm, for some reason copying from staging buffer to index buffer didn't worked for me, the indecies were empty and gl_VertexIndex was 0 for me. When i created two separate staging buffers, one for vertex one for index, it worked like a charm, idk if it's just me, or there is some wrong with offset/size calculation when trying to point on indecies part in staging buffer

Fletterio commented 5 months ago

@eqdiag I moved over to Linux after having the same issue with RenderDoc (bigger community of people developing drivers so your GPU is more likely to support the VK extension required by RenderDoc)

CrunchyBiscuit19 commented 5 months ago

In chapter 5 "GLTF Textures", move the empty lambda to the bottom to avoid it getting called before the other lambdas actually used to load the functions.

Also, don't copy-paste the texture-loading code (right after the STB_IMPLEMENTATION part) as the end of loadGltf, replace the previous placeholder texture loading code in "GLTF Scene Nodes".

MinistrUtoky commented 5 months ago

In the uploadMesh(...) function I think the destructors for newSurface.vertexBuffer and newSurface.indexBuffer should be added to _mainDeletionQueue, otherwise they persist in _allocator and won't let it be destroyed, leading to VMA_ASSERT_LEAK and an error when closing the program.

The exact error's console message is: Assertion failed: m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!" and it leads to init_vulkan() with it's vmaDestroyAllocator thing

If you do have the same problem just add the destructors, hope it helps somebody

Hkozacz commented 5 months ago

In textures chapter, values

uint32_t grey = 0xAAAAAAFF;
uint32_t black = 0x000000FF;

are wrong :/ it should be

uint32_t grey = 0x808080;
uint32_t black = 0x000000;

otherwise the names of the colors are not reflected in values

Hkozacz commented 5 months ago

Textures chapter: remember to add destroy_image calls at the end of initDefaultData(...) otherwise vma will be mad that we are leaking memory

alephpt commented 5 months ago

the code shown in the write-up and the code in the repo don't match.

MatsJKUL commented 4 months ago

Problem with instance creation. I didn't really want to use vkinit and just do the initialization myself. By looking at vkinit's source and just manually creating the objects (based on vulkan-tutorial) But the extension for Dynamic rendering: VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME has some dependencies namely: VK_KHR_depth_stencil_resolve and VK_KHR_get_physical_device_properties2. The problem is that my gpu does not support this extension(Or I am managing my search for the extensions wrongly). How would vkinit handle this? I am on a Legion Y540 laptop with a nvidia rtx2060 and integrated intel gpu. Neither of them seem to support the get_physical_device_properties2 extension. (https://www.notebookcheck.net/Lenovo-Legion-Y540-with-RTX-2060-laptop-review-Gaming-laptop-with-good-sound-and-144-Hz-panel.428659.0.html)

MatsJKUL commented 4 months ago

Nevermind I realised that there is a difference between instance extensions and device extensions

Danf96 commented 4 months ago

The starting project contains an older version of the sky compute shader that does not include push constants.

dhdylan commented 4 months ago

Hey there - earlier in the guide I noticed a discrepancy in what is written here and what is in the code I pulled from GitHub. In the guide VulkanEngine has constexpr bool bUseValidationLayers. It is mentioned in the Vulkan Initialization section as being line 10 of vk_engine.cpp but the file (unchanged from how it was pulled from the vk-guide-2-start branch). I thought it may have been a one-off case so I went ahead to the next section and there is indeed an error after I paste in the definition of the init_vulkan function - it uses member bUseValidationLayers which does not exist.

timkruse commented 4 months ago

Using an imGUI version after the 12.02.24 changes the imgui ImGui_ImplVulkan_InitInfo init_info from

init_info.UseDynamicRendering = true;
init_info.ColorAttachmentFormat = _swapchainImageFormat;

to

init_info.PipelineRenderingCreateInfo.sType                   = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
init_info.PipelineRenderingCreateInfo.colorAttachmentCount    = 1;
init_info.PipelineRenderingCreateInfo.pColorAttachmentFormats = &_swapchainImageFormat;

see imgui commit 8901931

Danf96 commented 4 months ago

@Hkozacz how did you set up those destroy image calls? I'm passing them to the deletion queue, but I'm still getting an assertion failure when closing the program.

EDIT: Solved my problem by flushing the deletion queues of each frame before the main deletion queue.

prog0111 commented 4 months ago

I'm at "Improving the render loop" in chapter 2. Everything seems to work, but I really don't understand why only one _drawImage is needed? Shouldn't this be in FrameData so there's one for each frame in flight? I'm trying to understand the synchronization, but it looks like multiple frames could touch it simultaneously. For instance, can't frame 2 start altering _drawImage while frame 1 is still working on it as both frames use a different fence and semaphores?

I'd really appreciate if anyone more experienced could give it a look, or help explain it to me if I'm missing something.

timkruse commented 4 months ago

@prog0111 As soon as the drawImage has finished drawing it is copied to the swapchainImage vkutil::copy_image_to_image(_) and therefore it is ready to get overridden in the next draw()-loop iteration.

prog0111 commented 4 months ago

@prog0111 As soon as the drawImage has finished drawing it is copied to the swapchainImage vkutil::copy_image_to_image(_) and therefore it is ready to get overridden in the next draw()-loop iteration.

Thanks! That got me looking deeper into the transition and copy image functions. I realized the pipeline barrier used during transitions is a 3rd synchronization mechanism that I'd overlooked. I'm assuming this prevents frame 2's command buffer from starting and touching drawImage until frame 1 has finished processing its own commands? I'm still a bit lost on how the barrier there can work between different command buffers, but it's a learning process.

EDIT: After studying further, I believe I understand it now. When command buffers are submitted, they're added to the queue's execution graph. The pipeline barrier adds specific memory dependencies to the order commands can be processed by a queue. While the queue will generally try to do everything in parallel, the dependency on drawImage should force the commands of frame 2 to execute only after frame 1 has finished with it. Therefore there's no potential overlap and no race condition.

DogeSquad commented 4 months ago

I have experienced issues with the two compute pipelines not being properly deleted. I only noticed it in chapter 3 but the problem seems to be coming from "Chapter 2 - Push Constants" at the end of the init_background_pipelines() function:

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

This is my theory and fix for it: mainDeletionQueue references sky and gradient. Those are stack allocated (but stored in backgroundEffects). As the function returns those go out of scope and cant be used by the mainDeletionQueue later on when deleting, vkDestroyPipeline therefore thinks that they are VK_NULL_HANDLEs. To solve this just replace them by the actual references we use:

_mainDeletionQueue.push_function([&]() {
    vkDestroyPipelineLayout(_device, _gradientPipelineLayout, nullptr);
    vkDestroyPipeline(_device, backgroundEffects[0].pipeline, nullptr);
    vkDestroyPipeline(_device, backgroundEffects[1].pipeline, nullptr);
});
uhfrb commented 4 months ago

VMA states that VMA_MEMORY_USAGE_CPU_TO_GPU is deprecated and obsolete, but I've been unable to find out what the preferred method is to achieve this behaviour (or if mapping is supported by default). Do you happen to know?

mlealdefreitas commented 4 months ago

@uhfrb You'll probably want to use VMA_MEMORY_USAGE_AUTO. From the VMA header (vma/vk_mem_alloc.h in your Vulkan include):

Selects best memory type automatically. This flag is recommended for most common use cases.

When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT), you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT in VmaAllocationCreateInfo::flags.

It can be used only with functions that let the library know VkBufferCreateInfo or VkImageCreateInfo, e.g. vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo() and not with generic memory allocation functions.

If you want to allocate memory for staging, you'd use VMA_MEMORY_USAGE_AUTO and set the bits VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT and VMA_ALLOCATION_CREATE_MAPPED_BIT. Check the VMA wiki for a pattern and more info on other usages.

vblanco20-1 commented 3 months ago

Ive updated imgui to latest, changed the backwards colors, and fixed the issue with imgui draw layout. Ill see if i can go on the list fixing other small issues.

nicolasgustafsson commented 3 months ago

It would be nice if the minimum guaranteed push constants size(128 bytes as per the documentation and the legacy guide) was stated in chapter 2, as I'd assume most renderers would use it as a guide.

nicolasgustafsson commented 3 months ago

I would like it if the imgui part was later on (after a triangle ideally); mostly because I'm using a different language where the imgui-vulkan bindings don't come easy(C#) so I have to do things out of order. If I had a triangle up then most of imgui rendering would have been solved so it'd be a lot more feasible to implement.