#Vkguide 2 thread
1 messages ยท Page 3 of 1
ah
i forgot about that
well ๐
keep all the links
they dont have to appear anywhere on the site, but people can navigate to them, and when you open an old link
you will just put a gif showing some cool fitting meme and a link to vkguide2 home
like indiana jones finding the holy grail or something
also a little text explaining that the old stuff is now history and that you worked on v2
im partially serious and partially jk
so what im thinking is to have the 2 versions under their own tag, vkguid 1 and 2. Then remove the "chapter" sections
no more than 1 level of nesting
alternatively just replace the chapters and tag the older ones as (OLD) 0. initial setup
can you reshuffle the menu items without breaking links?
so that the new stuff appears as if its vkg1
and the old one gets an entry like Vkguide 2 now, in that screensho
Another way is to do URL redirection
url redirection might require access to the webserver
hmm i thought vkguide.dev was an url pointing to github.io ๐
it kinda is
its hosted through github
but it uses custom domain
im not retarded enough to have an important site on a github.io without its own domain
its fixed
it sucks :/
also i need to update the introduction text to comment that you should go with the older version if you cant run the 1.3 stuff
So the menu is autogenerated by url structure and there is no way to change that?
kinda
its autogenerated from folder structure of the files
i can actually fix the URL of a given file
but it seems having 2 levels is a bit wonky
probably a code issue with the system
i can stuff the (OLD) part into essentially how it worked with the vkguide 2 beta where its embedded into another chapter and it is double nested for the articles
ok it seems i can fix the navigation
by setting up grand-parent links correctly
damn jekyll is straight up stupid
you need to set the grand-parent links manually
it cant figure out parent of a parent by itself
ok ive updated the site with a bunch of legacy warnings and legacy vkguide chapter and so on
how do you think its now?
๐๏ธ ๐ ๐๏ธ
looks much better now
is it possible however, to rename "new_" to something "v2" perhaps"
because when next vulkan thing comes out, and warrants a renewal. you got old, new and then new new? ๐
and one more thing but thats just me...
when you open each chapter you get this nice indented list of topics
is it possible to avoid word wrap in 4)
that Textures and Engine Architecture kind of ruins the main level
or is it possible to indent "Architecture" to be on the same level as the rest of the words
also also, dear imgui and multi threading from Extra chapter should be part of the main tutorial
the latter perhaps even combined with texture or model loading or a successor of it
dear imgui is part of the tutorial
chapter 3
sorry chapter 2
it does imgui before drawing hello-triangle
multithreading isnt
because its just not needed, and that article is more of an overview, not a tutorial
yes
i have not renamed any hyperlinked thing, its all on the same place
just some of the extra chapters (and the first gpu driven rendering) mention that its for vkguide 1
janky ass code
i clicked through from the top (from inside the articles)
and noticed that the legacy chapters open up too in the menu
yeah
on both
if you use the new_ prefix for the main articles, perhaps use it for all subarticles too
links are also all the same
pushed a fix to the 0: initial setup issue
@hallow berry nah i dont mind having the links be like that on the articles
the individual articles arent using the permanent URL that fixes it
so they come from folder
is it just me or does ctrl+f5 not work in ff anymore
the fix you pushed, also pushed the next links underneath the comment section
hihi
ah i see why
its been like that forever
the comment system is plugged in with a macro but the codegen generates the child articles below the normal content as a footer
๐ผ ๐น๐ซ
ok i probably spoke to soon, i have no idea how weird it would be if i integrated that comment chat thing into my thing
but all that logic there looks weird
i can probably do some hackery to force it down
i can also just not use the automated footer thing
and write it manually
which works fine too
what do you think of forcing the child list to be on top?
its an easy fix there and makes sense, gonnat ry it
insanely jank
gonna check in jekyll docs if i can automate the comment thing as a page property
and embed them in the correct place
oh thats actually pretty easy
im ok with that
ive modified the layout system
let me check
now you set the comment chapter in page properties
and it embeds them in the correct place
currently running ghpages refresh
let me know when its done
ill look
the styling engine is essentially creating the exact same string so why is it not working
wait what if im colliding on the name
hmm i have another idea...
lets assume someone clicked on an old link... chapter 3 memory transfer
would it work if, when you opened it now, that it simply opens a new page, with a hint that chapter 3 memory transfer has now moved to legacy/3/memorytransfer
that means all old links can be prefixed ... ah ok
toc is below comments still
Building project looks somewhat correct for some reason
i also explicitly disabled cache, just in case
while at it
can you make a little more space between the Next chapter links and the comments section
like a <p>
parser broke FUCK
yep but works
i went through all chapters and articles in the main quest
next links work there
its only in building_project
ye its because it is the absolute last line and i had a by-one error
cpp kinda sucks at parsing
i should flip this parser and codegen system into rust
no
against NIH? ๐
copypasting tags from source code and setting up a few macros
mkdocs has this syntax
```cmake title="lib/CMakeLists.txt"
--8<-- "lib/CMakeLists.txt:3:5"
```
cmake for the code hilighter.... title for the caption of the box... that 8< thing is the include trigger thingy... and then the path with :startlinenumber:linecount
all the code schnippets are made with this thing
it sucks, when you modify code, then you have to update the lines ofc
and i wouldnt use it to docs my actual engine project because of that
ah it feels like we spokea bout that already some time ago now that i see that snippet again
ok then ignore what i said, and i need to get some gingko pills or so to help my brain
in some cases in the code i use macros to have 2 versions of a given function so i can tag it in different ways for tutorial stages
not all the code in the guide is from tags, a few is copypasted manually or edited
heh
chapter 5 vkloader.cpp still uses std::cerr instead of fmt::print
ill fix
i see so just error function and the generate indices flag
the cmake things im not sure
but ill pick those small thingies in the loader
ive pushed a few other things
The cmake things are to only copy runtime dlls on platforms where that makes sense - i'm not sure if the logic used to decide when to do that is 'the best' but it makes sense. Linux & macOS have rpaths in their linker making the need to copy dlls unnecessary
there should be custom dll copy cmake isms in there already
I mean that the cmake code to copy dll's is modified by the PR sean made so that it only happens on platforms where it makes sense - but i'm not 100% that the logic for 'which platforms need it' is the best. Except, I don't want to investigate cmake internals nor work through what the logic does exactly.
no the if I check is the one that gives exactly the information about this
uh i totally didnt notice that thomas is writing too, i thought its all sean xD
It looks like youโre trying to add a pre-compiled shared library. I suggest you use the IMPORTED keyword instead of INTERFACE. For example: add_library(Foo SHARED IMPORTED) set_target_properties(Foo PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/bin/libfoo.dll" IMPORTED_IMPLIB "${CMAKE_CURRENT_SOURCE_DIR}/lib/libfoo.lib"/${CM...
$<TARGET_RUNTIME_DLLS:chapter_0>
From the docs:
On non-DLL platforms, this expression always evaluates to an empty string.
https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#genex:TARGET_RUNTIME_DLLS
The generator expression is empty when there isn't anything to copy. Relying on the suffix used is weird and may break in situations where the compiler is on a platform where copying is required (windows) but is producing linux style binaries (like mingw). Ask me know I know about mingw shenanigans
yes but that is a generator expression so I can't use it in an if
and if that command is run that will be an empty string and then cmake -E copy will fail because theres no source specified
I know I see that now, I'm trying to see if there is a better way
so it will error while building
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:exe> $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>
Apparently this could work around it
In the meantime, here's my workaround: COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:exe> $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>. This also copies the target to its own directory. This is wasteful and silly but makes sure that if the *DLLS is an empty string it's still a valid command.
why not do something like
if (NOT ("$<TARGET_RUNTIME_DLLS:exe>" STREQUAL ""))
# copy the DLLs
endif()
cmake
generator expressions run at 'configure time' which is after all the if statements are processed.
(in a nutshell, its more complicated than that)
@low minnow Why not just use if( WIN32)? For the most part, this project is simple usage and knowing what the hell CMAKE_IMPORT_LIBRARY_SUFFIX means is a big ask over what WIN32 means
whats the error you get when compiling on mac?
(this is why bad cmake self propagates - enough of it is written online that people find examples that do work but because it is an arcane incantation rather than sensible language the actually bad code is intermingled with just fine code)
Not trying to cast shade, I too reach for online examples and samples since there is way to much to learn to wrangle cmake.
does the code even run on mac? being 1.3
does it build on linux? The copy command probably fails in the exact same way. "didn't specify destination" or some error like that.
no as I mentioned in the PR
but I think this would be the same error on Linux
does it actually error
because cmake -E copy with the runtime dlls fail when there are no runtime dlls
so the build fails
target_runtime_dlls would be empty so no copy command
no the copy command triggers build failure
shall I change it or remove that commit
doesn't error out for me on linux
with the if or without?
just on all-chapters branch - so no if statement
hmm
so then if(WIN32) wouldnt work because there are runtime dlls it needs to copy on linux?
ignore me, the all-chapters doesn't do the dll copying
Yep, linux build fails with error due to copying (and some bad code things that I think the PR fixes as well)
ninja -C build
ninja: Entering directory `build'
[376/393] Linking CXX executable /home/cdgiessen/personal/temp-vulkan-guide-vblanco/bin/chapter_0
FAILED: /home/cdgiessen/personal/temp-vulkan-guide-vblanco/bin/chapter_0
...
CMake Error: cmake version 3.27.4
Usage: /usr/bin/cmake -E <command> [arguments...]
Available commands:
Yeah so if if(CMAKE_IMPORT_LIBRARY_SUFFIX) was replaced with if(WIN32) I believe it'll do all the things we want and be a bit clearer about why.
Its not like this project is dealing with cross compilation, mingw, or any other weird build setup (unlike the Vulkan-Loader grrrrr)
@civic mantle all-chapters-2
the other is for older vkguide
sorry
all-chapters-1.3-wip
ok ill change it
so wait, which is the 'this is the vkguide 2.0 all-chapters' branch?
1.3-wip
should I re-target the PR?
i wont directly merge it anyway
need to do things like re-run codegen scripts and so on
so dont bother ill manually add it
there is one part of vkguide 2 im not 100% sure with, which is the descriptors
they are under-explained compared to vkguide 1
of course there is just a lot less need for them
better abstractions and later it will just go bindless
but what do you think?
what chapter do you go over descriptors in
https://vkguide.dev/docs/new_chapter_4/descriptor_abstractions/
I found this chapter but I can't find the part of chapter 2 you mention
they are used and started in the 2 Vulkan Shaders articles in chapter 2
this is like the minimum of info, and the - Code section seems to jump right into the descriptor pool implementation
I would want at least a small Descriptors subheader rather than just saying "In vulkan, shader IO is handled through descriptor sets"
i have some bigger paragraphs of explanation i can copypasta from the older one
https://vkguide.dev/docs/chapter-4/descriptors/ the one here
but i kinda worry its just a really huge wall of text to throw to people chapter 2. on vkguide 1 this was on chapter 4
yeah it's kinda tough to mitigate the frontloading of vulkan
but you're just doing stuff in a different order (which I prefer btw)
my concern is that this is the main place to put the "theory" section, esp. since you have a separate section for the code
but I guess it's hard to describe what descriptors are when you don't let the user create buffers and images yet
ye
i could copy that article and put it after the first compute shader draw
to kinda explain in detail what it does
or try to embd those paragraphs while building the abstractions
currently they do have parts of those but.. more
i think the one to add is probably the diagram and the first paragraph of the descriptor set mental model
or alternatively, shorten the section on pipeline layout, cut out any details about descriptor sets
and leave that all to later
thats kinda critical tho
ill think of it
i think doing the descriptor sets with the small abstractions from the start make them so much clearer
everyone gets ultra confused with them
but if you have these builders and its like 'yeh, build layout, use layout to create descriptor set, write it' its much clearer
maybe just bringing the diagram to the shader theory chapter is enough
and doing a short discussion on it
I'm actually liking this idea a lot now that I reread it
i could also copy the entire chapter before the second part of descriptor stuff
which is later in the tutorial
where the allocator v2 (this time it reallocs pools) and descriptor-writer is implemented
ive updated that article a bit
moved some of the wording from the older descriptor article into it
but small amount
is there a KTX lib/header to read them?
im thinking to use it to load the filtered cubemaps from that gltf environments repo
acts as both fancy hdr image loading and mipmapped loading
did anyone with no experience tried to go thru this guide? looks good so I might try ๐
https://github.com/libktx/ktx
yeah there's khronos' official one
using libktx is just ~10loc
oh so it can also bake textures to ktx
with mipmap gen and everything
and with a direct upload-to-vulkan in the lib ๐ค
pretty hax thats awesome
ive only fiddled with loading ktx2
more or less
tex = ktx2_loadfrommemory(imagebytesfromgltf)
if ktx2_encodingrequired(tex)
{
ktx2_reencodeit(tex);
}
uploadtogl/vk(vulkanformattoglformat(tex.format), tex.data);
ktx2_free(tex);
@kind ferry you might want to consider switching to a static commit for fastgltf in vkguide
im about to change a bunch of breaking things
yes v0.6.1 is the last
so uh how followable is vkguide without vkb? gotten through half of the first chapter of vulkan-tutorial
vulkan-tutorial will cover the missing gap of figuring out how to initialize vulkan
but honestly that's just your own time you're wasting, vulkan initialization is not interesting
i see i'll probably switch over to it then since it's getting pretty hard ot follow vulkan-tutorial when i effectively gutted it out and replaced with dynamic rendering and sync2
bootstrap is used to find queue, create device, and create swapchain
thats the first few chapters of tutorial
hmmhm well im doing this in rust and there isn't a vkb equivalent for now, but i gotten through the initalization of vulkan-tutorial so i think i should be fine for the rest of vkguide, no?
sounds like someone should poke me enough into writing a rust version of vkb...
boy oh boy do i have a great idea for you
๐
@lusty hound definitely. once yoy get to hello triangle, you have all you need
okokok thank you
there is also a dude who did vkguide on Ig
zig
and had to implement the start. you can copy what he did
its one of the top posts in zig reddit from last month
How necessary is going through the compute chapter of the tutorial is...? I know it's dumb
but given I gotten to Hello, Triangle it does feel like taking a lot of steps back
gonna add a page on descriptor indexing for current end of chapter 5. it will probably be moved around later, but for now a lot of people really want it to be explained
for descriptor indexing, do you use combined sampler-image? or separated
with current style where im using the combined ones, its a simpler code change to do that, but obviously if a texture is accessed in 2 ways it would take 2 slots. On the other hand i doubt thats going to be a common case
I think combined image shrimplers are good for starting out but they pose serious usability problems
wanna switch out a sampler for a texture, well you gotta call vkUpdateDescriptorSets
maybe change LOD bias, another call to vkUpdateDescriptorSets
im going to write the descriptor array every frame
once
im thinking of putting it on its own descriptor set so that i have this generic "all textures" set
to use across the entire engine
on novuscore we do that and its fine, i think it costs like 0.something ms to update, which is a fine per-frame cost to pay
descriptor buffer can't come any sooner
does renderdoc already support them?
yes
i dont like that you upload the whole thing every frame. That partly negates the whole point of bindless
its perfectly fine, i have some sort of texture manager, and it reallocs every frame. Of course, could always cache it between frames
why do you not simply update only changing slots inside the array
we do that in novuscore and 0 issues, as long as its really once per frame
couse i remember it was like 0.2 or something ms
why waste 0.2ms
because its a tutorial and doing proper caching complicates things
hmm
and 0.2 cost to enable bindless textures is.. perfectly fine
this would be done exactly once through this texture manager object thingy
im sceptical that this is simpler
keep in mind if you are doing texture streaming you would be modifying it almost every frame
resizes not that often, but updates sure
it doesnt matter
simply send the slot to be reused on destruction
they have the same lifetime
the slot and the resource
yeye, im thinking of having the texture manager be some sort of slotmap with stable indexing
so it keeps holes and reuses them
to be fair, since potrick showed me the shader resource tableโข๏ธ (a stupid simple free list allocator of descriptors
), I agree that any other method of managing descriptor sets feels weird
๐ค
i can see your point
so just init the descriptor array as fucking-huge
and then do the individual writes to it?
ye
yea babyy
i would still need 2 due to frames on flight
no
no
you can update unused slots and defer destruction of existing resources
oh
was thinking it wouldnt be allowed to modify that descriptor array while its used
ok that makes sense
what about the question of combined sampler vs separate?
I like separate, they just make more sense, but perhaps combined samplers are better for beginners
combined sampler has the bonus that it maps directly to what i already have
i cant answer that i only use separate
but i remember the hardware vendors didnt like it much
NV still recommends combined
but only nv
(for some reason)
they can pack a texture and sampler pointer into one 32bit int
and use that for sampling directly
so a combined sampler for them is just that already packed for use
meh
imo combined is a complication
thats how i do it (if you care ๐ ). Should have everything desceiptor related inside
yeah I use separate, also I am currently trashing my current implementation because it sucks in several ways:
- relies on robustness ext for null descriptors
- has frames-in-flight descriptor sets and writing logic built around that
- is built on top of DescriptorAllocator abstractions instead of just owning its own precisely sized descriptor pool
- has shit for storage buffer indexing (now useless since I use BDA)
- is the most relevant point for vkguide imo because I built my descriptor indexing on top of the abstractions I got from vkguide without really thinking about whether it made sense
but all 4 are real mistakes I made from just going off on my own, so they might be worth covering
uh I'm having trouble understanding wtf PoolSizeRatio is doing
why would we need a ratio larger than 1...?
its for the case where 1 set will have multiple descriptors
imagine a layout where its 4 images
1 set has 4 images
so thats a ratio 4 on COMBINED_IMAGE_SAMPLER
@kind ferry are you resetting the comments? you mentioned you would, somewhere
now that vkguide2 is the default
there are also some unsigned int vs uint32_t inconsistencies, also only noticed that now
init_commands ... for (int i = 0; i < FRAME_OVERLAP... i should also be uint32_t, since FRAME_OVERLAP is a unsigned int ... warnings suck
in Draw Loop
this sentence doesnt seem to fit
The timeout of the WaitFences call is of 1 second. Itโs using nanoseconds for the wait time. If you call the function with 0 as the timeout, you can use it to know if the GPU is still executing the command or not.
no beginner will understand what that means, and you also dont explain it any further
Id remove it
Or pick it up in some appendix again where "you can use it to know if gpu is still executing ...or not" is explained ideally with an example usecase
get_current_frame() is not defined anywhere
i know its just a return _frames[_frameNumber % FRAME_OVERLAP]; but still
im also not a fan of naming commandBuffer cmd, cmd sounds like just command
i assume its for the sake of keeping the code visible in that little code box... although other code boxes are not wrapping any code either
anyway thats just me nitpicking
This is optional, but we might get a small speedup from our command encoding if we can tell the drivers that this buffer will only be submitted and executed once. We are only doing 1 submit per frame before the command buffer is reset, so this is perfectly good for us.
``` this should probably be picked up later again as well
where you have to deal with other scenarios... ill just leave it here, maybe this will be handled further down the road : )
This means we are going to need a way to transition images as part of a command buffer instead of using a renderpass, so we are going to add it as a function on vk_images.h
``` casually thrown in "instead of using a renderpass"
that probably needs to be explained further
typo: We will be doing a pipeline barrier, using the syncronization 2 feature/extension which synchronization
all fields in FrameData are not initialized : (
but they are ๐ค i manually went through the entire tutorial copypasting the code snippets as it worked
might be shown a bit later
im also stumbling over that waitfence 1s timeout thing again, i dont remember what i did in the old version, my vkguide1 code also just showes 1s
that code is unchanged from vkguide 1
a lot of the first chapter is copypasta-d
where it goes different is on chapter 2 forward where its an almost total rewrite
thats what im doing too : )
just removed all vk bits from my main branch, and follow vguide2
not in the docs
what do you mean with in the docs
but that stuff is initialized right after when it builds the init_sync_structures
c++ good practice should apply here too
tutorial or not
noobs copy paste stuff blindly
noooooooooooooooo
there is no need to waste space on initializers when the code is already hardcoded to init it
not cool
noobs will forget to call InitializeXXX
and then those objects have random values instead of 0, pointing them right at "you forgot to call InitializeXXX"
also again these underscores, which indicate private visibilitlity, when they are not really?
anyway
feels like im talking to a block of wood or so
the underscores will be fixed
they were supposed to be for private stuff but stuff changed midway wich is a bit strange
btw regarding the beta comments, they will get nuked probably next week
i have a bit more nitpickingisms
in the improving renderloop chapter
creating all the infos for the drawimage
you call those a little weirdly.. rimg_xxxx
why not drawImageCreateInfo and drawImageAllocatorInfo and drawImageViewCreateInfo
since they create things for he drawImage : )
perhaps it was meant to be called renderImage hence rimg... but idk
What's wrong with that style of code?
error prone
and picture adding *
Well the * goes on the variable not the data type, but I can see how noobs can be confused
* goes on the type not on the variable
you are so wrong
but anyway : )
we have #bikeshed-๐ for those kind of things
there is enough bad and unreadable code out there already
okay just need a yes or no, don't want to #bikeshed-๐, am I wrong on code-style or how pointer declaration works
theres 3 styles, or 3 types of people
1) type* var;
2) type * var;
3) type *var;
imho 1) is the one and only true way of declaring a pointer type
more foggy stuff imho
in New draw loop
Vulkan has 2 main ways of copying one image to another. you can use VkCmdCopyImage or VkCmdBlitImage. CopyImage is faster, but its much more restricted, for example the resolution on both images must match. Meanwhile, blit image lets you copy images of different formats and different sizes into one another. You have a source rectangle and a target rectangle, and the system copies it into its position. Those two functions are useful when setting up the engine, but later its best to ignore them and write your own version that can do extra logic on a fullscreen fragment shader.
the comment about "but later its best to ignore them and write your own version that can do extra logic on a fullscreen fragment shader" feels out of place
what does that mean? or how is THAT particular thing implemented... perhaps yet again another appendix
hmm more stuff.
you added a deletion queue into FrameData, and just mention where to call it, but you never push anything into it anywhere
just a tiny sentence saying that we should push into it, whenever we create something. Idk perhaps you can put it in one of those /!\ ATTENTION /!\ boxes so that people dont read over it
the deletion queue stuff is for later
its mostly because i implement the deletion queue so might as well also add it to framedata early
you are right with the copyimage paragraph there, could use some rewording
how to implement that thing is something i will do on chapter 6. the compute shader that copies to swapchain is the one that will do exposure/tonemapping
the deletionqueue.flush on the framedata is also kaputt... or im too stupid to read
not really? its actually used later for allocating per-frame uniforms
you are flusing it in Draw() after vkWaitForFences
but there is no code yet which recreates those
in new renderloop
what do you mean re-create
when you flush the deletion queue it invokes vkDestroyXXX
ye
but the frame fences arent put into the per-frame destruction queue
the only thing that is added to the per-frame destruction queue is some camera uniform buffer later
ah i think that one sentence tricked me then
With the deletion queue set, now whenever we create new vulkan objects we can just add them into the queue.
``` this one, i spotted it after rereading this and the section before
and assumed i forgot something
ok, im just too dumb to read properly
its for stuff like more draw image, descriptor pools, pipelines, etc
to stop adding everything into the cleanup() function
issue is that it would mean the entire tutorial keeps coming back to the cleanup function
deletion queue and push is just waaaaaaay easier
deletionQueue makes sense
i guess the per frame stuff to be created/deleted is something i need to wrap my head around still
it feels wrong to create and destroy stuff - per frame - same for opengl where you can do that s well and its fine
every engine ever will need to create and destroy stuff dynamically perframe
and that has no impact?
compared to just update an ubo with camera data for instance
of course it has an impact, but its much easier to code
and the impact is like a microsecond or two so its not like it matters
btw what made you opt to have fences instead of timeline semaphores after all
Uh how devastating would it be if I skipped the dear imgui part?
Rn egui or imgui-rs integration is either non existent or requires me to rewrite the entire tutorial 
its barely used
okok thank you
Hey uh question. When we run draw_background and draw_triangle, how do we ensure the correct order of drawing occurred?
As I;m just confused how we ensured the triangle draws overtop the draw image produced by compute
iirc vkSubmit only ensures order of submission but never order of completion?
The layout transition in between the two ensures that all writes done by the compute shader must be done before the fragment shader can do any writes
AHHHH WAIT YEAH
Image transitions
Thank you
So the rasterzzer waits until the draw image transitions from general to color attachment i guess?
well because vkguide has it simplified, everything waits until the image transition is done. even the vertex shader won't run until the transition is done
if you set it up optimally, the vertex shader, the rasterizer, and even the fragment shader can run while the transition happens; they just can't write to the image until the compute is done
Huhh okay okay
https://vkguide.dev/docs/new_chapter_1/vulkan_mainloop_code/
VkSemaphoreSubmitInfo vkinit::semaphore_submit_info(VkPipelineStageFlags2 stageMask, VkSemaphore semaphore)
{
VkSemaphoreSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO;
submitInfo.pNext = nullptr;
submitInfo.semaphore = semaphore;
submitInfo.stageMask = stageMask;
submitInfo.deviceIndex = 0;
submitInfo.value = 1;
return submitInfo;
}
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSemaphoreSubmitInfo.html
value is either the value used to signal semaphore or the value waited on by semaphore, if semaphore is a timeline semaphore. Otherwise it is ignored.
why is value being set? it doesn't look like you are using timeline semaphores
1 seems incorrect to use even if you were using them
hm i actually dont know why its 1 there
the inits have been copypasted for a very long time so i dunno when that got added
hmm
vkg2 half way in still feels like vkg1
hmm
why is dynamic rendering not mentioned in the navigation thing
its casually sprinkled into the imgui chapter
this deserves its own major chapter
another typo:
in the imgui chapter, first sub chapter "Immediate GPU commands" above the 2nd code box
we need to create those syncronization structures for immediate submit, so lets go into init_commands() function and hook the command part. typo in synchronization
also "let's"
Yeah it does 
It gets brought way too casually then slides into implementation
it then gets implemented again in the rendering chapter
there also isnt much to explain, its kinda beyond trivial. The hard part is getting the images on their correct layouts for drawing, but beggining a renderpass is a very simple thing of just grabbing some render targets and doing begin rendering
renderpasses used to have their whole long explanation due to al they had to do
https://vkguide.dev/docs/new_chapter_4/textures/
We start by allocating a staging buffer with enough space for the pixel data, on the CPU_TO_GPU memory type.
VMA_MEMORY_USAGE_CPU_TO_GPUis deprecated btw. You should useVMA_MEMORY_USAGE_AUTO_PREFER_HOSTand then addVMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BITorVMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BITtoVmaAllocationCreateInfo::flags
its more complicated, i prefer using the older vma then
its not like vma will stop working
the lib barely updates over the years and its basically done
i understand that new workflow, but i kinda dont like it with the PC target the tutorial has
theyโre still marked as deprecated
maybe put a disclaimer if you're going to tell newbies to use deprecated functionality
good point
vma on vkguide codebase is embedded so it wont auto-update
if users want to then update it to latest for some reason then they will see the deprecation stuff
you explicitly using VMA 2 in vkguide sources?
vma 2?
yeah
current version is 3
which introduced all of that automatic usage stuff with CPU_TO_GPU and whatnot
so I asked if vkguide still uses vma 2
I see
oh wait no it couldn't use vma 2 as that didn't support bda
and iirc vkguide 2 heavily uses that?
vkguide was using the vma from 2020
vkguide 2 was created with that version too
i just later went and updated to latest
question about fastgltf
the current code in the repository won't compile anymore if anyone uses main or the latest release
or at least clarify which version the guide uses
thats why everything is vendored-in
but good point, i should add the versions of the stuff to the guide
what if i use descriptor buffers for the bindless stuff?
im tinkering with them and seems the api is better for bindless usage as its much clearer. you allocate a region of memory to store N texture descriptors and go
do you think it would make sense? and whats the current support for them? does all hw that does bindless on pc also do descriptor buffer?
tho im not sure if one can combine a descriptor set and the buffer ๐ค
what's the status on renderdoc support for descriptor buffers? last I heard there wasn't any
didnt it add them last version?
i only know of mesh shader s beegin added
it added shader debugging with BDA
(finally)
but no descriptor buffer in sight
to be honest idk if it's really that useful
but it's certainly easier
~/work/repos_to_check/vulkan-guide/bin$ ./chapter_2
Error when building the compute shader
Error when building the compute shader
[ERROR: Validation]
Validation Error: [ VUID-VkPipelineShaderStageCreateInfo-module-parameter ] Object 0: handle = 0x55876070e2f0, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xfd71dc70 | vkCreateComputePipelines(): pCreateInfos[0].stage.module Invalid VkShaderModule Object 0x7ffccf08e830. The Vulkan spec states: If module is not VK_NULL_HANDLE, module must be a valid VkShaderModule handle (https://vulkan.lunarg.com/doc/view/1.3.275.0/linux/1.3-extensions/vkspec.html#VUID-VkPipelineShaderStageCreateInfo-module-parameter)
Segmentation fault (core dumped)

Oh, it tries to load shader from ../../shaders, but the executable is in ./bin, so it should search for it in ../shaders - where do executables get built on Windows?
/bin/Release/engine.exe
not really sure how to solve unless it does some kind of path searching at startup
I'll try some stuff
What if you did this?
make_directory("${PROJECT_SOURCE_DIR}/bin/shaders")
foreach(GLSL ${GLSL_SOURCE_FILES})
message(STATUS "BUILDING SHADER")
get_filename_component(FILE_NAME ${GLSL} NAME)
set(SPIRV "${PROJECT_SOURCE_DIR}/bin/shaders/${FILE_NAME}.spv")
...
And then in shaders instead of using "../../shaders", you just use "shaders"
(For VS it would need to be a bit more complex, though, to put it to "<Config>/shaders" instead)
Basically you'll get this structure
Oh, assets use "../../" too 
Well, you can symlink this directory to be present in bin
lmao no
i think the best solution would be to have it autodetected at build time in a define
or alternatively, have it auto-search
so from .exe location, check up level until it finds both /bin and /assets
yeah you can get it with a generator expression, I don't see why symlinks are too bad though
platform support
and are megajank overall
plus they wouldnt be relative
so if you copy the folder and put it somewhere else it would break
which is about the biggest nono you can do on a game engine of this sort
//< init_data
testMeshes = loadGltfMeshes(this,"..\\..\\assets\\basicmesh.glb").value();

Idk if you want to support Linux or not. If not, I'm not going to bother and will fork temporarily to make it build, but won't PR the changes
just fix that, its basically only in a couple places
hapens on windows too if one runs the cmake directly on VS
if (WIN32)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
else ()
make_directory("${PROJECT_SOURCE_DIR}/bin/linux")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin/linux")
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin/linux")
endif ()
Now ../../<dir> works 
There are probably 1000s of better ways to fix this, but I won't bother, heh
target_compile_definitions(vkguide PRIVATE VKGUIDE_RESOURCE_PATH=$<PATH:GET_RELATIVE_PART,$<TARGET_FILE_DIR:vkguide>>)
I think this works
assuming you can nest generator expressions like this
Also had to do this (chapter 2):
VkPhysicalDeviceVulkan12Features features12{};
features12.bufferDeviceAddress = true;
And I'm still getting some validation errors, might try to fix later
E.g. (chapter 2,3 on destruction)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyPipeline-pipeline-parameter ] Object 0: handle = 0x5635dfa212a0, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0xaeb3d1a6 | vkDestroyPipeline(): pipeline Invalid VkPipeline Object 0x8d2b9306125bd000. The Vulkan spec states: If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle (https://vulkan.lunarg.com/doc/view/1.3.275.0/linux/1.3-extensions/vkspec.html#VUID-vkDestroyPipeline-pipeline-parameter)
chapter 5 with the refactors needed for texture cache and bindless becomes a huge mess to mantain :/
chapter 6 it is then
gonna make the code i have now into chapter 6 and clean up chapter 5 a bit
i think ill put the bindless texture stuff + some refactoring of the codebase as chapter 6 start parts
an important one is to optimize the vertex format and fix a few things so that the fancy brickadia maps and big stuff like bistro can be loaded without any issue
but until i advance more with chapter 6, ill write a extra-chapter about how to set bindless textures as the basics are simple
anyway if you want to see how it works the WIP c6 code is up and has bindless
need to play with it more
By the way, if you do add_dependencies(chapter_2 Shaders) (and the same for all the chapters), you'll get automatic shader compilation when the glsl file changes (no need to run Shaders target manually every time)
Finished this: https://vkguide.dev/docs/new_chapter_2/vulkan_shader_code/
Getting validation errors (or I missed something - but I don't see where you free up this stuff and I'm getting the same when I compile code from the repo):
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0x9fde6b0000000014, type = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT; | MessageID = 0x4872eaa0 | vkCreateDevice(): OBJ ERROR : For VkDevice 0x55a0f266aec0[], VkDescriptorSetLayout 0x9fde6b0000000014[] 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.3.275.0/linux/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0xdd3a8a0000000015, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0x4872eaa0 | vkCreateDevice(): OBJ ERROR : For VkDevice 0x55a0f266aec0[], VkDescriptorSet 0xdd3a8a0000000015[] 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.3.275.0/linux/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
[ERROR: Validation]
Validation Error: [ VUID-vkDestroyDevice-device-05137 ] Object 0: handle = 0xd175b40000000013, type = VK_OBJECT_TYPE_DESCRIPTOR_POOL; | MessageID = 0x4872eaa0 | vkCreateDevice(): OBJ ERROR : For VkDevice 0x55a0f266aec0[], VkDescriptorPool 0xd175b40000000013[] 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.3.275.0/linux/1.3-extensions/vkspec.html#VUID-vkDestroyDevice-device-05137)
a lot of the cleanuo code is emitted, no need to worry
Well, you do it for everything else, so why not do it for all the objects? ๐
(Will train beginners to do all the cleanup needed and have 0 validation errors all the time)
its mostly failung in intermediate steps
almost all of those are fixed at the end of each chapter
Iโll see how next chapters look for me. But the end result of ch2 has like 10 validation errors ๐
Also apparently in C++20, implicit capture of this via [=] is deprecated, this thing passed:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0806r2.html
For now the compilers only issue a warning, but it's a bit annoying.
ImGui chapter will need some modifications since people really love breaking stuff in its Vulkan backend.
immediate_submitis now not needed - font texture is loaded automatically- Need to pass
VkPipelineRenderingCreateInfotoImGui_ImplVulkan_InitInfo vkDestroyDescriptorPoolon ImGui's pool should be called afterImGui_ImplVulkan_Shutdown, otherwise you get validation errors
Here's my commit where I added Dear ImGui successfully ๐
https://github.com/eliasdaler/edbr/commit/0c4cbdcf9fee7c922acc78e2c985c88dbe94d8cc
Also minor, but maybe using ColorEdit would be more easy to play around with, it's just this:
auto glmToArr = [](const glm::vec4& v) { return std::array<float, 4>{v.x, v.y, v.z, v.w}; };
auto arrToGLM = [](const std::array<float, 4>& v) { return glm::vec4{v[0], v[1], v[2], v[3]}; };
ImGui::Begin("Gradient");
auto from = glmToArr(gradientConstants.data1);
if (ImGui::ColorEdit3("From", from.data())) {
gradientConstants.data1 = arrToGLM(from);
}
auto to = glmToArr(gradientConstants.data2);
if (ImGui::ColorEdit3("To", to.data())) {
gradientConstants.data2 = arrToGLM(to);
}
ImGui::End();
yeah they had to add the VkPipelineRenderingCreateInfo because of stencil and depth formats iirc
I only added a VkFormat for the color attachment in the original dynamic rendering pr
ima be that guy to say that the best way to get things fixed (when they have an obvious mistake) is to make a PR.
Cause otherwise its a lot of work for the maintainer to go through the issues listed and understand/validate them.
Iโm throwing some of these things in so that vblanco can say if theyโre worth fixing or not. I can fix it all, but donโt want to waste my time if PR is then rejected
also it's way easier to complain on discord than to go through the process of making a pr
which is what you said 
GPU driven chapter update when? ๐
(And how different will it be from the old one?)
TIL vkguide really hates intel (found the issue when talking with vblanco)
hey stupid question
https://vkguide.dev/docs/new_chapter_2/vulkan_new_rendering/#deletion-queue
why do we not call it a deletion stack ๐ค
stack would imply last-in-first-out
oh wait im dumb LMAO thanks
The code is FIFOLIFO though
yes, FIFO is correct; LIFO is not
Sorry. I wrote it wrong. The code call callback in reverse order. And IMO that's The desirable behavior (just like C++ destructors)
...ah wait you're right. I guess stack could make sense ๐ค
yeah a stack is LIFO or FILO whatever you call it
it's just because the first thing that gets created gets destroyed last
I guess if you only look at it at the end when it gets destructed its a queue of objects waiting to be destructured
but that's just terminology
(please let me know if that's relevant, or should be moved to 'questions')
Hello, there is an issue that has been driving me crazy for a lot of time, and decided to solve, but I am having a hard time. At some point during Chapter 3 > Mesh Loading, you start getting a memory allocation error upon exiting the application:
Assertion failed: m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!", file C:\Users\Evripidis\Desktop\vkguide\vulkan-renderer\third_party\vma\vk_mem_alloc.h, line 11847
However, at this point, it's easily solved by pushing the deletions of the buffers after loading:
testMeshes = loadGltfMeshes(this, "..\\..\\assets\\basicmesh.glb").value();
_mainDeletionQueue.push_function([&]() {
for (auto& t : testMeshes) {
destroy_buffer(t->meshBuffers.vertexBuffer);
destroy_buffer(t->meshBuffers.indexBuffer);
}
});
Later on with the more complex scene, you get this thing again. Apparently the clearAll(); inside the LoadedGLTF deconstructor either doesn't do the job, or is called at a bad timing.
Has anyone encountered and / or solved this, and would like to share their wisdom? I tried a lot to tackle it as practice, but it starts to get annoying.
See this 
#1167091099446288444 message
I'd recommend making some sort of global "mesh cache" which just goes through all the loaded meshes and removes them.
I don't use deletion queues in my engine anywhere
I meaaaan, this particular cleanup code is not emitted 
Ok, so change logic is the way. But I was also wondering if someone solved that, following the guide itself, out of curiosity.
VK_CHECK(vkCreateSampler(_device, &createInfo, 0, &_depthSampler));
ahhhh who uses 0 instead of nullptr (this is in the compute based culling chapter)
absolute heresy
probably copypasted from somewhere lol
is the project layout and libraries sections supposed to still list Tiny Obj Loader or is it outdated?
yeah its completely mismatched with the building project section
https://vkguide.dev/docs/new_chapter_5/gltf_nodes/
In the third paragraph, weren't is spelled as "werent" and simplicity is spelled as "simpicity"
Might be less effort to just open a PR with typo fixes because there are a lot
It's really not the end of the world, but does vkguide just stop providing vkinit function bodies?
seems like after chapter 3 there aren't function bodies
yeh because they are kind of pointless to keep posting when you can look at the provided vkinit file
at the start its more important because their members have to be explained more
alright alright thank you blanco
Yo sorry if this has been answered in vkguide, but why do we not use the in built vertex input and instead opt into handling that ourselves?
because there is no point of dealing with vertex input logic any more
since the nvidia 1000 series and for a while on AMD vertex input and just accessing vertices from ssbo works about the same
and in vkguide 2 we do buffer device adress for the ssbos so it makes even more sense to just remove vertex input as a concept completely
i now realized vkguide blending is 100% wrong
i have source and destination in reverse rip

thanks i was about to start that section
Oh yeah for windowing resizing, wouldn't you also wanna resize your depth image if you're also resizing the draw image as well?
I saw a user in the vulkan discord with that problem a couple days ago and I forgot to mention, rip
ye but only uses additive and additive hqppens to work anyway
the one that is megafucked is alphablend
yeah it was an interesting problem to figure out 'cause it almost looked like a reverse depth test
https://vkguide.dev/docs/new_chapter_3/blending/ see enable_blending_alphablend
ye

that definitely looks like a layout problem
hmm ill look more into it
wait do you mean layout like image layout or pipeline layout 
could it also be some stupid descriptor binding issue
yeah so the issue with the blending
is that SRC refers to the current pixel in the shader
and dst is the render target
i had them flipped
so yeah all of those DST_alpha need to be SRC_Alpha
oh
huh so turned out that pixel bug was literally because of that 
although the monkey isn't transparent hmmm
LET SGOOOO
not exactly sure why removing the draw background step would've caused all this sync issue however
because the draw background step is a clear
without the background step its probably loading uninitialized memory or similar
try changing the renderpass to be LOAD_OP_CLEAR
ah yeah that'd do it, so you were color blending with undefined
quick question, why does the DeletionQueue use a std::deque?
We will be using that deque as a First In Last Out queue, so that when we flush the deletion queue, it first destroys the objects that were added into it last.
you can do the same with a std::vector. In fact, the LIFO container from the std isstd::stack, which would be exactly what you want.
its a linked list of memory blocks
each block can store up to N items (impl defined, and that N is pretty low)
well interesting
this dude has a repo of the first chapter of vkguide on jai
no vkbootstrap so he grabbed the init code from vulkan-tut
uh quick question
So when we multiply view and projection matrices
did you get the order wrong?
sceneData.viewproj = sceneData.proj * sceneData.view;
Fairly certain it is view * proj and not the other way around
with glm that's correct, no
d3d brained smh
planning on writing an "extra" article on my experience going from vkguide codebase into more of a game framework (adding logic/physics/etc). any things you think i should mention?
no real code, more of a writeup
Asset management has always been a thorn in my side. Loading and unloading dynamically at runtime.
then it wont help you
because i just hardcode load the gltfs at startup
and i have multiple stuff on each gltf so then i just draw what i need from them
plan is to talk about how to hook a "game loop" into the engine class (through callbacks), pointing to the fix-your-timestep article. Then how to use the gltf loader to render game objects, and how to hook an ecs
also how to move the renderer into deferred with postfx
I am curious how your game object data in your ecs is read by your rendering engine
Like if your ecs entity moves in world space how does that position component data make it so it updates where it is drawn
that one is dumb af lmao
Why
i just have a RenderMeshComponent, which holds model matrix + pointer to Mesh (on the gltf object)
Oh i see
the renderer loops though those and calls mesh->draw(matrix)
Yeah thatโs what I had too
the different object types all end up refreshing the RenderMeshComponent from their logic
Next time I want a separation
I want more separation between rendering and game systems
why, its not that tricky
your game systems eventually just store RenderMeshComponent somehow
It got really messy
why?
It just felt like the wrong abstraction to me, I didnโt run into any trouble with it
my renderer basically only cares about that render-mesh-comp
(dont have lights yet, but they would work in the same fashion)
interesting website bug, on chrome ios I can't open the menu (but on safari I can)
no mention to function rebuild_swapchain is in vkguide website, but I see it in chapter 2's source: https://github.com/vblanco20-1/vulkan-guide/blob/all-chapters-2/chapter-2/vk_engine.cpp#L330
and I see that it is used here in draw https://github.com/vblanco20-1/vulkan-guide/blob/all-chapters-2/chapter-2/vk_engine.cpp#L182
that is similar to the chapter 3's resize code. so I guess this is some sort of leftover? not sure this is right channel for the feedback, saw this thread while using discord search about this. anyway, fyi
The guide provides an email for feedback iirc but people have left it here also
mentioning it here couse relevant, but im going to write an article on the sheer crimes metafor:refantasio does on its renderer
as sort of a combo of render pipeline article + perf article
i was thinking of adding it to vkguide but im not sure about it, what do you think?
its kinda relevant to vkguide audience given the nature of the article
yeah seems interesting, frame breakdown blogs are always cool
i also could use the space to kinda quickly demonstrate how one does a perf analysis
Practical guide to vulkan graphics programming
@lapis isle what do you think? looking for some feedback before i put it into social media
still reading through, minus the obvious stuff like fixing the hyperlinks I think it's alright so far
also this date confused me lol
did you ever look at this with barriers on? the first thing I'd ask is what the data dependencies look like
oh I think that should be in a separate sentence then
might reword it a bit then
cuz I am still wondering what that has to do with compute vs not compute
since it seems like it's not compute that would've helped, but merging the kernels into 1 shader?
small typo in "An stimate"
fixed both things
i need more people to check it out and comment, what do you think @crimson timber (shameless ping) and @lilac oak
unfortunately I cannot offer proofreading service until Vulkanised 2025
so yesterday you post a blog about the graphics behind the game and today my language learning servers post about the game
I think the universe wants me to look at whatever this game is
ye
oh yeah is the article public now?
been for a couple days
wonder if graphics weekly will pick it up because the tweet i did got zero following
Baffled with the performance of Metaphor: ReFantazio, i went to profile it on #steamdeck and analyze its performance and techniques to see whats going on with Renderdoc and Radeon Profiler. Wrote about it on https://t.co/6YUMQXDkRG #gamedev #vulkan
should have baited much harder
not on the weekly graphics thingy
seems like this kinda confirms tthat you need to be retweeted enough times to get there
reddit/others isnt enough
have you tried submitting it directly to him
how?
Hey, I'm kind of new to this. If I had a suggestion/question about a bug I encountered (and sort of fixed?) would I post it in here or would I use GitHub Issues
in what way
I read through vkguide quite a bit
I like the use of fmt and the guide for sending up imgui with dynamic rendering
I'm going to do those things
I think how I'll build my renderer is to go through the very outdated vulkan tutorial, do it, get it to work, and then replace the render pass with dynamic rendering, then once that works, replace the code to use shader objects and after that works replace the code with the descriptor indexing extension to get bindless
while at each stage looking at how vkguide does it
I'm also using SDL and vma as vkguide
it's like a blend
oh and I like the window resize part of vkguide
the reason for using the outdated vulkan tutorial instead of vkguide as the template though is to avoid the engine abstraction at the start
idk
I just need to start rendering things
I'm following the tutorial, im at chapter 5.3 (GLTF Scene Nodes and Textures). When I attempt to load structure.glb, my program produces a black screen, and crashes.
The model is being loaded but MeshNode::Draw is failing. It works when I modify it, but I don't think I'm supposed to do this...
void MeshNode::draw(const glm::mat4& top_matrix, DrawContext& ctx)
{
// START OF MODIFICATION: When I add this, most models load
// without it, only a few models will load.
if (mesh.get() == nullptr)
{
return;
}
// END OF MODIFICATION
glm::mat4 node_matrix = top_matrix * world_transform;
for (auto& s : mesh->surfaces)
{
RenderObject def;
def.index_count = s.count;
def.first_index = s.start_index;
def.index_buffer = mesh->mesh_buffers.index_buffer.buffer;
def.material = &s.material->data;
def.bounds = s.bounds;
def.transform = node_matrix;
def.vertex_buffer_address = mesh->mesh_buffers.vertex_buffer_address;
if (s.material->data.pass_type == MaterialPass::Transparent)
{
ctx.transparent_surfaces.push_back(def);
}
else
{
ctx.opaque_surfaces.push_back(def);
}
}
// recurse down
Node::draw(top_matrix, ctx);
}
I suspect its an issue with my load_gltf method, which i mostly copied from the tutorial
that makes little sense, might be a problem with the gltf loading
because a mesh node is only created when there is a mesh
so a meshnode missing a mesh means something went wrong on the loadgltf function
i had to make some changes to it because im using a newer version of fastgltf.
for instance
fastgltf::GltfDataBuffer data;
data.loadFromFile(filePath);
fastgltf::Asset gltf;
std::filesystem::path path = filePath;
auto type = fastgltf::determineGltfFileType(&data);
was changed to
auto data = fastgltf::GltfDataBuffer::FromPath(file_path);
if (data.get_if() == nullptr)
{
fmt::println("Failed to load glTF: {}", file_path);
return {};
}
fastgltf::Asset gltf;
std::filesystem::path path = file_path;
auto type = fastgltf::determineGltfFileType(data.get());
i think this is relevant to the issue but i could be totally wrong. sorry if im not understanding the problem
its later
when you create the meshnode itself
you must give it a mesh, if it doesnt have a mesh then you should be creating a Node, not a MeshNode
Thank you so much, you were exactly right!
Now it works! I just need to figure out why the texture loading isnt working now, and then ill be done (think something is wrong with my std::visit...)
gltf failed to load texture tile_tech_panels_color_albedo
gltf failed to load texture trim_misc_1_albedo
gltf failed to load texture tile_rivet_panels_albedo
gltf failed to load texture set_asphalt_albedo
gltf failed to load texture tile_anti_slip_albedo
gltf failed to load texture tile_steel_albedo
gltf failed to load texture tile_painted_gun_metal_albedo
gltf failed to load texture trim_misc_2_albedo
gltf failed to load texture tile_tech_panels_albedo
gltf failed to load texture floor_grate_wholes_albedo
gltf failed to load texture column_normal
gltf failed to load texture column_albedo
gltf failed to load texture tile_metal_pillars_albedo
gltf failed to load texture light_shafts
i set a breakpoint but it is never reached
check the paths and which of the visits is triggered
the gltf might do something like relative paths that you need to change
i use embedded textures as they work better almost always
im just using the provided structure.glb
and as for the visits, im using Visual Studio's breakpoints and they dont seem to trigger? I might be placing them wrong
looks like [&](fastgltf::sources::BufferView& view) is triggered...
i wonder if it has anything to do with me doing
reinterpret_cast<const unsigned char*>(vector.bytes.data())```
(same thing happens when i do)
```cpp
(unsigned char*)vector.bytes.data()```
because i wanted to change from std::byte * to a stbi_uc *
follow the guide and once you get it working change stuff
then you don't blame the guide, but know it's something with your own code
i have the models all loaded im just trying to figure out whats wrong with my implementation of load_image()
im not trying to blame the guide, sorry if it came off that way
oooh im so close. i know its the inner visit for BufferView that messes up. now i need to figure out why buffer.data isnt of type fastgltf::sources::Vector. time to consult the docs once again
I THINK I GOT IT WORKING. All thanks to matt328's issue https://github.com/vblanco20-1/vulkan-guide/issues/100
it was all because i used a newer version of fastgltf. lesson learned.
I just ran into an issue where an image was being loaded, but not added to the images map in LoadedGLTF.
I loaded two images with identical names (both ""). Because of this, they cannot co-exist in the map.
Original code:
for (fastgltf::Image& image : gltf.images)
{
std::optional<AllocatedImage> img = load_image(engine, gltf, image);
if (img.has_value())
{
images.push_back(*img);
file.images[image.name.c_str()] = *img; // image names used as keys
}
else
{
// use checkerboard texture in case of failure
images.push_back(engine->_error_checkerboard_image);
std::cout << "gltf failed to load texture " << image.name << std::endl;
}
}
Because of this, the clear_all() method could not delete all the loaded images via the map, and VMA would then complain:
UNFREED ALLOCATION; Offset: 4194304; Size: 4194304; UserData: 0000000000000000; Name: vma_empty; Type: IMAGE_OPTIMAL; Usage: 7
UNFREED ALLOCATION; Offset: 0; Size: 4194304; UserData: 0000000000000000; Name: vma_empty; Type: IMAGE_OPTIMAL; Usage: 7```
I created a workaround by adding a counter to the loop, so every image would have a unique name:
```CPP
int ic = 0; // image counter
for (fastgltf::Image& image : gltf.images)
{
std::optional<AllocatedImage> img = load_image(engine, gltf, image);
if (img.has_value())
{
images.push_back(*img);
file.images[(image.name + (char)ic).c_str()] = *img;
}
else
{
// use checkerboard texture in case of failure
images.push_back(engine->_error_checkerboard_image);
std::cout << "gltf failed to load texture " << image.name << std::endl;
}
ic++;
}```
Did I miss something in the tutorial? Or is it normal for some GLB images to be nameless? This doesn't happen for all GLBs
it was happening with the provided structure.glb, and a few others i tested
like generally the images will have their path/etc as name
๐ค
did something change then
i dont remember having any vma issues on the code when i made it
its really weird, it seems to only happen for GLBs with at least 1 transparent texture
but im not certain
actually hold on
i think the structure.glb is ok, but some of the ones i downloaded from Khronos' repo cause the issue
dont worry about your structure.glb or structure_mat.glb, they're ok
i misspoke
I was having the issue with DragonAttenuation.glb and AlphaBlendModeTest.glb https://github.com/KhronosGroup/glTF-Sample-Models/tree/main/2.0
and a sponza.glb I downloaded from elsewhere.
The counter seems to fix my issues but I wonder why the names are blank...
alphablendmodetest has no names it seems
it only has the uri for loading from the jpeg path
so if i wanted to load it, and properly add its textures to the images map, what should i do?
the counter works but the names are just 0,1,2,3,...
is it the responsibility of the author of the GLB/glTF file?
adding the ID into the name works fine i think
it doesnt even really have to be a map
The counter seems to fix my issues but I wonder why the names are blank
Simple, the glTF didn't specify any names
names are not something you should rely on at all
this code is bad in vkguide as well as in your app
so either you:
- Assign images a unique name
- Use another criteria to differentiate, like for example indices or a content hash
thank you very much for the advice. im going to stick with the number counter for now, but later on ill probably just use a different data structure
just to quote the spec here:
Whereas indices are used for internal glTF references, optional names are used for application-specific uses such as display. Any top-level glTF object MAY have a name string property for this purpose. These property values are not guaranteed to be unique as they are intended to contain values created when the asset was authored.
this should probably also be fixed in vkguide
which reminds me that I already have a PR open that fixes a few issues
thank you for your contributions to vkguide, and thanks for fastgltf
@low minnow you mean the fastgltf fixes pr from a year ago?
i think i fixed a couple
@kind ferry I've completed chapter 5 recently and I just want to say: thank you for creating and maintaining Vkguide. It was relatively straight-forward and very informative. You saved me so much time!
If I wanted to contribute to the future versions of the guide (e.g. helping with grammar, bugfixes, etc.), would it be best to make a issue on GitHub, or should it be mentioned here?
what is the purpose of
struct GLTFMaterial
{
MaterialInstance data;
};```
in ``vk_loader.h``
why wouldn't I just use ``MaterialInstance`` directly?
placeholder to then have more stuff later, particularly for different passes of that same material
I got to the monke
hell yeah
so I am using shader objects instead of pipelines, I think what I'll just do though is write something similar to the vkguide pipeline builder but instead of it building a pipeline it just basically records a bunch of commands into the command buffer
Was going over https://vkguide.dev/docs/new_chapter_1/vulkan_mainloop_code/, and I found this line a bit strange, not sure if a typo or a joke that is going over my head (cuz its related to multi gpu I think?):
command_buffer_submit_info only needs the command buffer handle. We dont need anthing else, and we can leave the deviceMask at 0 as we are not it.
https://github.com/vblanco20-1/vulkan-guide/blob/master/LICENSE.txt#L3 <--- is this who I should put as the copyright owner in my own License file, I am not sure if that is correct
thats because im using a open source theme
the MIT license there is from the theme, not the website
tho its a bit unclear i def should update that part
yes I put my own name on my licenses
this is a bug within the vkguide code because it unconditionally loads vertex colors as glm::vec4 which is plainly wrong
// load vertex colors
auto colors = p.findAttribute("COLOR_0");
if (colors != p.attributes.end()) {
fastgltf::iterateAccessorWithIndex<glm::vec4>(gltf, gltf.accessors[(*colors).second],
[&](glm::vec4 v, size_t index) {
vertices[initial_vtx + index].color = v;
});
}
this should be used instead:
// load vertex colors
auto colors = p.findAttribute("COLOR_0");
if (colors != p.attributes.end()) {
if (colors->second.type == AccessorType::Vec4) {
fastgltf::iterateAccessorWithIndex<glm::vec4>(gltf, gltf.accessors[(*colors).second],
[&](glm::vec4 v, size_t index) {
vertices[initial_vtx + index].color = v;
});
} else if (colors->second.type == AccessorType::Vec3) {
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, gltf.accessors[(*colors).second],
[&](glm::vec3 v, size_t index) {
vertices[initial_vtx + index].color = glm::vec4(v, 1.f);
});
}
}
blender used vec4s so i just never tested it
i kinda explain in the guide that its meant to work with gltfs from blender and just barely
i cant really use the space to fix all the stuff that is hardcoded/wrong in the loader part
https://vkguide.dev/docs/ascendant/ascendant_geometry/ The article on the geometry pipeline of project ascendant is up. Not fully sold on how it ended but oh well
Practical guide to vulkan graphics programming
next one will be about framegraphs and gbuffers
@kind ferry Dunno if you saw it, but I added a nifty feature to vk-bootstrap that lets you query why physical device creation failed, EG it'll generate a list of failed conditions like missing extensions & features. https://github.com/charles-lunarg/vk-bootstrap/pull/404
I'm more than happy to add it to the guide as a PR for ya, just wanting to give you a heads up.
@civic mantle its a common issue people have, so if you can PR the change, then ill merge
you need to edit the source text on the new_guide folder, because the folder at /docs/ is codegen-d to insert the code snippets
you might need to hook the snippets too
sounds good.
I'll add in the "dump reasons why it failed" to the snippets as there is no point otherwise
Resurrecting this thing, im going to begin writing chapter 6, which is going to be PBR + lighting shaders
recomended test scenes? i have the gltf spaceship thingy from godot but its not very well configured in regards to shaders
also, do you know whats the best way of doing PBR formulas. @lilac oak i think knew about it. Im going to be doing forward+
WASSUP
wdym PBR formulas ?
mmmm
maybe i could go with the Filament ones, but afaik those are also fairly approximate
given im making a new chapter i want to use high end formulas or whatever is the best ones to use atm
i was thinking maybe grab the khronos PBR material standard, with the multilyaer fuckery
and try to get that to work math-wise
for non-RT rendering you just want my BxDF's eval() method
do you happen to know good materials/models/etc i can use for validation ?
if you want to PT or generate IBL (preintegrated envmap for every reflection vector) you can use generate and quotient_and_pdf
im also thinking making this depth prepass-d forwardplus with msaa
so in a way, the chapter would be like
first part, fix material system and implement the better PBR models
next, implement bruteforce based pointlights and spotlights
then, implementing clustered rendering. I was thinking cluster so it affects transparent objects and i can build clusters from cpu for simplicity
and that would be the chapter
interaction.V = IBL_dir;
for (uint i=0; i<SampleCount; i++)
{
float2 xi = scramble(lowDiscrepancySequence(i),IBL_uv);
L = bxdf.sample(xi);
IBLcolor += (bxdf.quotient_and_pdf(L).value-IBLColor)/float(i+1); // online average
}
pseudocode how you'd do IBL with my BxDF lib
C++20 concepts in shaders go BRRR
you can rewrite this to Slang I think
like my weird concepts are just Slang Interfaces
bruteforce pointlights and spotlights aren't really bruteforce
ah you mean the culling
ye, just for progression
tbf I don't like lights with limited ranges
pass array of lights to the shader and go
neither do i
lights must always have a range limit, its nonsense if they dont
nope ๐