#Vkguide 2 thread

1 messages ยท Page 3 of 1

hallow berry
#

"Old VkGuide"

#

next to "VkGuide"

kind ferry
#

i dont think i can do that without breaking the hyperlinks

#

not sure

hallow berry
#

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

kind ferry
#

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

hallow berry
#

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

ancient portal
#

Another way is to do URL redirection

kind ferry
#

good attempt

hallow berry
#

url redirection might require access to the webserver

#

hmm i thought vkguide.dev was an url pointing to github.io ๐Ÿ™‚

kind ferry
#

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

kind ferry
#

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

ancient portal
#

So the menu is autogenerated by url structure and there is no way to change that?

kind ferry
#

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

kind ferry
#

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

kind ferry
#

ok ive updated the site with a bunch of legacy warnings and legacy vkguide chapter and so on

#

how do you think its now?

hallow berry
#

๐Ÿ‘๏ธ ๐Ÿ‘ƒ ๐Ÿ‘๏ธ

#

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

kind ferry
#

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

hallow berry
#

ah

#

then perhaps the dear imgui in Extra is not needed anymore

kind ferry
#

i leave it there because its still a useful stand-alone article

hallow berry
#

man i cant read

#

and links out there point to it perhaps

kind ferry
#

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

hallow berry
#

hehe

kind ferry
#

janky ass code

hallow berry
#

i clicked through from the top (from inside the articles)

#

and noticed that the legacy chapters open up too in the menu

kind ferry
#

nah thats just jank code on the generator

#

it compares the stuff by name

hallow berry
#

fook

#

did i tell you that i can reference code in files in mkdocs too?

kind ferry
#

seems to be because the chapter name is the same

#

0: initial setup

hallow berry
#

yeah

kind ferry
#

on both

hallow berry
#

if you use the new_ prefix for the main articles, perhaps use it for all subarticles too

#

links are also all the same

kind ferry
#

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

hallow berry
#

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

kind ferry
#

wtf its on all chapters

#

more jank this is supposed o be setup correctly

hallow berry
#

hihi

kind ferry
#

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

hallow berry
#

๐Ÿ‡ผ ๐Ÿ‡น๐Ÿ‡ซ

#

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

kind ferry
#

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

hallow berry
kind ferry
#

ive modified the layout system

hallow berry
#

let me check

kind ferry
#

now you set the comment chapter in page properties

#

and it embeds them in the correct place

#

currently running ghpages refresh

hallow berry
#

let me know when its done

kind ferry
#

jekyll is going full retard

#

that one works

hallow berry
#

ill look

kind ferry
#

the styling engine is essentially creating the exact same string so why is it not working

hallow berry
kind ferry
#

wait what if im colliding on the name

hallow berry
#

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

kind ferry
#

the old links are all being kept

#

it would just point to the legacy one

hallow berry
#

that means all old links can be prefixed ... ah ok

kind ferry
#

ok fuck this im embedding the html

#

lets see now

hallow berry
#

toc is below comments still

#

Building project looks somewhat correct for some reason

#

i also explicitly disabled cache, just in case

kind ferry
#

fixed

#

gonna implement it across the tutorial

hallow berry
#

while at it

#

can you make a little more space between the Next chapter links and the comments section

#

like a <p>

kind ferry
#

done, but for the chapters with children

#

now everything has the new comments

hallow berry
#

space looks good though : >

#

seems to be just that one, others seem to work

kind ferry
#

parser broke FUCK

hallow berry
#

yep but works

#

i went through all chapters and articles in the main quest

#

next links work there

#

its only in building_project

kind ferry
#

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

hallow berry
#

lol

#

you should just use a framework which does all that nonsense already

kind ferry
#

no

hallow berry
#

against NIH? ๐Ÿ˜„

kind ferry
#

the parser is like 300 locs

#

and it has the features i need to build the tutorial

hallow berry
#

exactly

#

like what features?

#

reading code from underlying source files?

kind ferry
#

copypasting tags from source code and setting up a few macros

hallow berry
#

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

kind ferry
#

that kinda sucks as it uses lines

#

i use text tags

hallow berry
#

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

kind ferry
#

thats kinda how mine works

#

i dont support nesting

#

but i havent needed it

hallow berry
#

ah it feels like we spokea bout that already some time ago now that i see that snippet again

kind ferry
#

ye

#

im still using the same system

#

just fixing some bugs/etc

hallow berry
#

ok then ignore what i said, and i need to get some gingko pills or so to help my brain

kind ferry
#

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

hallow berry
#

heh

low minnow
#

chapter 5 vkloader.cpp still uses std::cerr instead of fmt::print

kind ferry
#

ill fix

low minnow
#

already done

#

see pr

kind ferry
#

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

low minnow
#

ive pushed a few other things

civic mantle
#

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

hallow berry
#

there should be custom dll copy cmake isms in there already

civic mantle
#

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.

low minnow
#

no the if I check is the one that gives exactly the information about this

hallow berry
#

uh i totally didnt notice that thomas is writing too, i thought its all sean xD

low minnow
#
civic mantle
#

$<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

low minnow
#

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

civic mantle
#

I know I see that now, I'm trying to see if there is a better way

low minnow
#

so it will error while building

civic mantle
#
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:exe> $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>

Apparently this could work around it

lapis isle
#

why not do something like

if (NOT ("$<TARGET_RUNTIME_DLLS:exe>" STREQUAL ""))
  # copy the DLLs
endif()
civic mantle
#

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

low minnow
#

no idea

#

i just found that post on the cmake forums and decided it looked good

kind ferry
#

whats the error you get when compiling on mac?

civic mantle
#

(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.

kind ferry
#

does the code even run on mac? being 1.3

civic mantle
#

does it build on linux? The copy command probably fails in the exact same way. "didn't specify destination" or some error like that.

low minnow
#

but I think this would be the same error on Linux

kind ferry
#

does it actually error

low minnow
#

because cmake -E copy with the runtime dlls fail when there are no runtime dlls

#

so the build fails

kind ferry
#

target_runtime_dlls would be empty so no copy command

low minnow
#

no the copy command triggers build failure

kind ferry
#

hmm

#

i guess the if(win) is the best approach

low minnow
#

shall I change it or remove that commit

civic mantle
#

doesn't error out for me on linux

low minnow
#

with the if or without?

civic mantle
#

just on all-chapters branch - so no if statement

low minnow
#

hmm

#

so then if(WIN32) wouldnt work because there are runtime dlls it needs to copy on linux?

civic mantle
#

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)

kind ferry
#

@civic mantle all-chapters-2

#

the other is for older vkguide

#

sorry

#

all-chapters-1.3-wip

civic mantle
#

so wait, which is the 'this is the vkguide 2.0 all-chapters' branch?

low minnow
#

1.3-wip

kind ferry
#

one sec ill upload all-chapters-2 to be clearer and easier to find

#

up it is

low minnow
#

should I re-target the PR?

kind ferry
#

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

kind ferry
#

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?

lapis isle
#

what chapter do you go over descriptors in

kind ferry
#

they are used and started in the 2 Vulkan Shaders articles in chapter 2

lapis isle
#

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"

kind ferry
#

i have some bigger paragraphs of explanation i can copypasta from the older one

#

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

lapis isle
#

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)

lapis isle
# lapis isle

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

kind ferry
#

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

lapis isle
#

or alternatively, shorten the section on pipeline layout, cut out any details about descriptor sets

#

and leave that all to later

kind ferry
#

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

lapis isle
#

maybe just bringing the diagram to the shader theory chapter is enough

#

and doing a short discussion on it

lapis isle
kind ferry
#

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

kind ferry
#

ive updated that article a bit

#

moved some of the wording from the older descriptor article into it

#

but small amount

lapis isle
#

I like it a lot

#

I think it makes everything fit together more

kind ferry
#

is there a KTX lib/header to read them?

kind ferry
#

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

outer sigil
#

did anyone with no experience tried to go thru this guide? looks good so I might try ๐Ÿ˜„

lapis isle
kind ferry
#

you kinda got mistaken by the naming there

lapis isle
#

lmao rip

#

this is the one

hallow berry
#

using libktx is just ~10loc

kind ferry
#

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

hallow berry
#

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);
low minnow
#

@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

kind ferry
#

do you have release tag?

#

also its embedded as code in the project. no submodules

low minnow
#

yes v0.6.1 is the last

lusty hound
#

so uh how followable is vkguide without vkb? gotten through half of the first chapter of vulkan-tutorial

lapis isle
#

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

lusty hound
#

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

hallow berry
#

vkguide covers the initialization part

#

by using vbkootstrap

kind ferry
#

bootstrap is used to find queue, create device, and create swapchain

#

thats the first few chapters of tutorial

lusty hound
#

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?

hallow berry
#

yes

#

idk about rust, im sure it has if you look

civic mantle
lusty hound
civic mantle
#

๐Ÿ˜›

kind ferry
#

@lusty hound definitely. once yoy get to hello triangle, you have all you need

lusty hound
#

okokok thank you

kind ferry
#

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

lusty hound
#

How necessary is going through the compute chapter of the tutorial is...? I know it's dumb KEKW but given I gotten to Hello, Triangle it does feel like taking a lot of steps back

hallow berry
#

go through it

#

dont be that lazy copy pasta guy

kind ferry
#

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

drifting maple
#

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

kind ferry
#

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

drifting maple
#

descriptor buffer can't come any sooner

kind ferry
#

does renderdoc already support them?

crimson timber
#

i dont like that you upload the whole thing every frame. That partly negates the whole point of bindless

kind ferry
#

its perfectly fine, i have some sort of texture manager, and it reallocs every frame. Of course, could always cache it between frames

crimson timber
#

why do you not simply update only changing slots inside the array

kind ferry
#

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

crimson timber
#

why waste 0.2ms

kind ferry
#

because its a tutorial and doing proper caching complicates things

crimson timber
#

hmm

kind ferry
#

and 0.2 cost to enable bindless textures is.. perfectly fine

#

this would be done exactly once through this texture manager object thingy

crimson timber
#

im sceptical that this is simpler

kind ferry
#

keep in mind if you are doing texture streaming you would be modifying it almost every frame

#

resizes not that often, but updates sure

crimson timber
#

it doesnt matter

#

simply send the slot to be reused on destruction

#

they have the same lifetime

#

the slot and the resource

kind ferry
#

yeye, im thinking of having the texture manager be some sort of slotmap with stable indexing

#

so it keeps holes and reuses them

crimson timber
#

yes

#

but why copy every frame then

drifting maple
#

to be fair, since potrick showed me the shader resource tableโ„ข๏ธ (a stupid simple free list allocator of descriptors KEKW), I agree that any other method of managing descriptor sets feels weird

kind ferry
#

๐Ÿค”

#

i can see your point

#

so just init the descriptor array as fucking-huge

#

and then do the individual writes to it?

drifting maple
#

ye

crimson timber
#

yea babyy

kind ferry
#

i would still need 2 due to frames on flight

drifting maple
#

no

crimson timber
#

no

drifting maple
#

you can update unused slots and defer destruction of existing resources

kind ferry
#

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?

drifting maple
#

I like separate, they just make more sense, but perhaps combined samplers are better for beginners

kind ferry
#

combined sampler has the bonus that it maps directly to what i already have

crimson timber
#

i cant answer that i only use separate

kind ferry
#

but i remember the hardware vendors didnt like it much

drifting maple
#

NV still recommends combined

crimson timber
#

but only nv

drifting maple
#

(for some reason)

crimson timber
#

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

kind ferry
#

combined it is then

#

i find it much easier to think about

crimson timber
#

meh

#

imo combined is a complication

#

thats how i do it (if you care ๐Ÿ’…). Should have everything desceiptor related inside

lapis isle
#

yeah I use separate, also I am currently trashing my current implementation because it sucks in several ways:

  1. relies on robustness ext for null descriptors
  2. has frames-in-flight descriptor sets and writing logic built around that
  3. is built on top of DescriptorAllocator abstractions instead of just owning its own precisely sized descriptor pool
  4. has shit for storage buffer indexing (now useless since I use BDA)
#
  1. 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

lusty hound
#

uh I'm having trouble understanding wtf PoolSizeRatio is doing

#

why would we need a ratio larger than 1...?

kind ferry
#

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

lusty hound
#

ohhh

#

alright

#

thank you

hallow berry
#

@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

hallow berry
#

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

hallow berry
#

all fields in FrameData are not initialized : (

kind ferry
#

but they are ๐Ÿค” i manually went through the entire tutorial copypasting the code snippets as it worked

#

might be shown a bit later

hallow berry
#

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

kind ferry
#

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

hallow berry
#

thats what im doing too : )

#

just removed all vk bits from my main branch, and follow vguide2

kind ferry
#

what do you mean with in the docs

hallow berry
#

in the guide, sorry

#

and please dont do int a,b,c; ๐Ÿ˜ฆ

kind ferry
#

but that stuff is initialized right after when it builds the init_sync_structures

hallow berry
#

c++ good practice should apply here too

#

tutorial or not

#

noobs copy paste stuff blindly

kind ferry
#

nope

#

its a tutorial it needs to be almost codegolfed

hallow berry
#

noooooooooooooooo

kind ferry
#

there is no need to waste space on initializers when the code is already hardcoded to init it

hallow berry
#

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

kind ferry
#

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

hallow berry
#

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

round jungle
hallow berry
#

and picture adding *

round jungle
#

Well the * goes on the variable not the data type, but I can see how noobs can be confused

hallow berry
#

* goes on the type not on the variable

hallow berry
#

but anyway : )

#

we have #bikeshed-๐Ÿ˜‡ for those kind of things

#

there is enough bad and unreadable code out there already

round jungle
#

okay just need a yes or no, don't want to #bikeshed-๐Ÿ˜‡, am I wrong on code-style or how pointer declaration works

hallow berry
#

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

hallow berry
#

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

kind ferry
#

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

hallow berry
#

the deletionqueue.flush on the framedata is also kaputt... or im too stupid to read

kind ferry
#

not really? its actually used later for allocating per-frame uniforms

hallow berry
#

you are flusing it in Draw() after vkWaitForFences

#

but there is no code yet which recreates those

#

in new renderloop

kind ferry
#

what do you mean re-create

hallow berry
#

when you flush the deletion queue it invokes vkDestroyXXX

kind ferry
#

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

hallow berry
#

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

kind ferry
#

its for stuff like more draw image, descriptor pools, pipelines, etc

hallow berry
#

yeah

#

that makes sense now

kind ferry
#

to stop adding everything into the cleanup() function

hallow berry
#

well

#

vk is verbose

#

i dont mind having a 50loc cleanup function ๐Ÿ˜„

kind ferry
#

issue is that it would mean the entire tutorial keeps coming back to the cleanup function

#

deletion queue and push is just waaaaaaay easier

hallow berry
#

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

kind ferry
#

every engine ever will need to create and destroy stuff dynamically perframe

hallow berry
#

and that has no impact?

#

compared to just update an ubo with camera data for instance

kind ferry
#

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

lapis isle
#

btw what made you opt to have fences instead of timeline semaphores after all

kind ferry
#

cant use timeline on swapchin

#

would need to explain 2 types and use only 1 (the old)

lusty hound
#

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 bleakekw

kind ferry
#

its barely used

lusty hound
#

okok thank you

lusty hound
#

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?

fringe berry
lusty hound
#

AHHHH WAIT YEAH

#

Image transitions

#

Thank you

#

So the rasterzzer waits until the draw image transitions from general to color attachment i guess?

fringe berry
#

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

lusty hound
#

Huhh okay okay

junior sinew
#

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

kind ferry
#

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

hallow berry
#

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

junior sinew
#

also "let's"

lusty hound
#

It gets brought way too casually then slides into implementation

kind ferry
#

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

junior sinew
#

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_GPU is deprecated btw. You should use VMA_MEMORY_USAGE_AUTO_PREFER_HOST and then add VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT to VmaAllocationCreateInfo::flags

kind ferry
#

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

kind ferry
#

i understand that new workflow, but i kinda dont like it with the PC target the tutorial has

low minnow
junior sinew
#

maybe put a disclaimer if you're going to tell newbies to use deprecated functionality

kind ferry
#

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

low minnow
#

you explicitly using VMA 2 in vkguide sources?

junior sinew
#

vma 2?

low minnow
#

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

junior sinew
#

I see

low minnow
#

oh wait no it couldn't use vma 2 as that didn't support bda

#

and iirc vkguide 2 heavily uses that?

kind ferry
#

vkguide was using the vma from 2020

#

vkguide 2 was created with that version too

#

i just later went and updated to latest

low minnow
#

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

kind ferry
#

thats why everything is vendored-in

#

but good point, i should add the versions of the stuff to the guide

kind ferry
#

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 ๐Ÿค”

lapis isle
#

what's the status on renderdoc support for descriptor buffers? last I heard there wasn't any

crimson timber
#

i dont see how they help at all for bindless

#

also no renderdoc big nono

kind ferry
#

didnt it add them last version?

crimson timber
#

i only know of mesh shader s beegin added

drifting maple
#

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

sage orbit
#
~/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)

bleakekw thonk

#

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?

kind ferry
#

/bin/Release/engine.exe

sage orbit
#

Yeah, that's VS only...

#

Ninja, Make etc. will build in ./bin/chapter_2 etc.

kind ferry
#

not really sure how to solve unless it does some kind of path searching at startup

sage orbit
#

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

kind ferry
#

no

#

because then i would also need to move the assets folder

sage orbit
#

Oh, assets use "../../" too bleakekw

#

Well, you can symlink this directory to be present in bin

kind ferry
#

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

lapis isle
#

yeah you can get it with a generator expression, I don't see why symlinks are too bad though

kind ferry
#

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

sage orbit
#
//< init_data
testMeshes = loadGltfMeshes(this,"..\\..\\assets\\basicmesh.glb").value();

froge_bleak

#

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

kind ferry
#

just fix that, its basically only in a couple places

#

hapens on windows too if one runs the cmake directly on VS

sage orbit
#
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 KEKW

#

There are probably 1000s of better ways to fix this, but I won't bother, heh

lapis isle
#
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

sage orbit
#

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)
kind ferry
#

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

kind ferry
#

but until i advance more with chapter 6, ill write a extra-chapter about how to set bindless textures as the basics are simple

kind ferry
#

anyway if you want to see how it works the WIP c6 code is up and has bindless

#

need to play with it more

sage orbit
#

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)

kind ferry
#

i had it before

#

but removed it for a reason

#

dont really remember exactly why

sage orbit
#

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)
kind ferry
#

a lot of the cleanuo code is emitted, no need to worry

sage orbit
#

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)

kind ferry
#

its mostly failung in intermediate steps

#

almost all of those are fixed at the end of each chapter

sage orbit
#

Iโ€™ll see how next chapters look for me. But the end result of ch2 has like 10 validation errors ๐Ÿ˜…

sage orbit
sage orbit
#

ImGui chapter will need some modifications since people really love breaking stuff in its Vulkan backend.

  1. immediate_submit is now not needed - font texture is loaded automatically
  2. Need to pass VkPipelineRenderingCreateInfo to ImGui_ImplVulkan_InitInfo
  3. vkDestroyDescriptorPool on ImGui's pool should be called after ImGui_ImplVulkan_Shutdown, otherwise you get validation errors

Here's my commit where I added Dear ImGui successfully ๐Ÿ˜„
https://github.com/eliasdaler/edbr/commit/0c4cbdcf9fee7c922acc78e2c985c88dbe94d8cc

sage orbit
#

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();
low minnow
#

I only added a VkFormat for the color attachment in the original dynamic rendering pr

civic mantle
sage orbit
#

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

junior sinew
#

also it's way easier to complain on discord than to go through the process of making a pr

#

which is what you said kekkedsadge

sage orbit
#

GPU driven chapter update when? ๐Ÿ˜…
(And how different will it be from the old one?)

fringe berry
#

TIL vkguide really hates intel (found the issue when talking with vblanco)

lusty hound
#

why do we not call it a deletion stack ๐Ÿค“

fringe berry
#

stack would imply last-in-first-out

lusty hound
#

oh wait im dumb LMAO thanks

ancient portal
#

The code is FIFOLIFO though

fringe berry
#

yes, FIFO is correct; LIFO is not

ancient portal
fringe berry
#

...ah wait you're right. I guess stack could make sense ๐Ÿค”

lusty hound
#

AHHHH

#

okay i thought i was going insane

low minnow
#

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

sturdy ivy
#

(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.

sage orbit
#

See this KEKW
#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

sturdy ivy
low minnow
#

VK_CHECK(vkCreateSampler(_device, &createInfo, 0, &_depthSampler));
ahhhh who uses 0 instead of nullptr (this is in the compute based culling chapter)

fringe berry
#

absolute heresy

kind ferry
#

probably copypasted from somewhere lol

tawdry sable
#

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

tawdry sable
junior sinew
#

Might be less effort to just open a PR with typo fixes because there are a lot

lusty hound
#

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

kind ferry
#

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

lusty hound
#

alright alright thank you blanco

lusty hound
#

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?

kind ferry
#

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

kind ferry
#

i now realized vkguide blending is 100% wrong

#

i have source and destination in reverse rip

lusty hound
#

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?

fringe berry
kind ferry
#

ye but only uses additive and additive hqppens to work anyway

#

the one that is megafucked is alphablend

fringe berry
#

yeah it was an interesting problem to figure out 'cause it almost looked like a reverse depth test

lusty hound
#

so uh

#

which ones have their dst and src mixed around?

lusty hound
#

ahhhh

#

so additive works as normal

fringe berry
#

ye

lusty hound
fringe berry
#

that definitely looks like a layout problem

lusty hound
#

hmm ill look more into it

lusty hound
fringe berry
#

image layout

#

it's either a bad layout or some kind of sync issue

lusty hound
#

could it also be some stupid descriptor binding issue

kind ferry
#

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

lusty hound
#

oh

kind ferry
#

this should be the correct one

lusty hound
#

huh so turned out that pixel bug was literally because of that KEKW

#

although the monkey isn't transparent hmmm

lusty hound
#

LET SGOOOO

#

not exactly sure why removing the draw background step would've caused all this sync issue however

kind ferry
#

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

fringe berry
#

ah yeah that'd do it, so you were color blending with undefined

lusty hound
#

AHHH

#

that makes sense

low minnow
#

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 is std::stack, which would be exactly what you want.

kind ferry
#

std vector does a full reallocate when it grows

#

deque doesnt

low minnow
#

does it use a linked list underneath?

#

how does that work

kind ferry
#

its a linked list of memory blocks

#

each block can store up to N items (impl defined, and that N is pretty low)

low minnow
#

well interesting

kind ferry
#

this dude has a repo of the first chapter of vkguide on jai

#

no vkbootstrap so he grabbed the init code from vulkan-tut

lusty hound
#

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

low minnow
#

with glm that's correct, no

lusty hound
#

AHH glam has it different

#

alright that makes sense now

drifting maple
#

d3d brained smh

kind ferry
#

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

fringe berry
#

Asset management has always been a thorn in my side. Loading and unloading dynamically at runtime.

kind ferry
#

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

kind ferry
#

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

twilit siren
#

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

kind ferry
#

that one is dumb af lmao

twilit siren
#

Why

kind ferry
#

i just have a RenderMeshComponent, which holds model matrix + pointer to Mesh (on the gltf object)

twilit siren
#

Oh i see

kind ferry
#

the renderer loops though those and calls mesh->draw(matrix)

twilit siren
#

Yeah thatโ€™s what I had too

kind ferry
#

the different object types all end up refreshing the RenderMeshComponent from their logic

twilit siren
#

Next time I want a separation

#

I want more separation between rendering and game systems

kind ferry
#

why, its not that tricky

#

your game systems eventually just store RenderMeshComponent somehow

twilit siren
#

It got really messy

kind ferry
#

why?

twilit siren
#

It just felt like the wrong abstraction to me, I didnโ€™t run into any trouble with it

kind ferry
#

my renderer basically only cares about that render-mesh-comp

#

(dont have lights yet, but they would work in the same fashion)

jaunty halo
#

interesting website bug, on chrome ios I can't open the menu (but on safari I can)

weak ravine
#

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

twilit siren
#

The guide provides an email for feedback iirc but people have left it here also

kind ferry
#

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

lapis isle
#

yeah seems interesting, frame breakdown blogs are always cool

kind ferry
#

i also could use the space to kinda quickly demonstrate how one does a perf analysis

kind ferry
kind ferry
#

@lapis isle what do you think? looking for some feedback before i put it into social media

lapis isle
#

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

kind ferry
#

no barriers

#

renderdoc shows the barriers as separate compute passes

lapis isle
#

huh

#

explain why a FST/FSQ would require more bandwidth than compute

kind ferry
#

its about the layer part

#

a fullscreen quad is fine, 5 of them in a row isnt

lapis isle
#

oh I think that should be in a separate sentence then

kind ferry
#

might reword it a bit then

lapis isle
#

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?

kind ferry
#

that goes a bit clearer at the end

#

where i comment on the perf of things

tidal timber
#

small typo in "An stimate"

kind ferry
#

fixed both things

#

i need more people to check it out and comment, what do you think @crimson timber (shameless ping) and @lilac oak

lilac oak
fringe berry
#

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

kind ferry
#

you mean the jrpg?

#

there is a demo its pretty cool game

fringe berry
#

ye

clever adder
#

oh yeah is the article public now?

kind ferry
#

been for a couple days

#

wonder if graphics weekly will pick it up because the tweet i did got zero following

kind ferry
#

should have baited much harder

kind ferry
#

not on the weekly graphics thingy

kind ferry
#

seems like this kinda confirms tthat you need to be retweeted enough times to get there

#

reddit/others isnt enough

lapis isle
#

have you tried submitting it directly to him

kind ferry
#

how?

lapis isle
#

idk he's probably got a contact on his site

#

doxed

narrow plover
#

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

kind ferry
#

in what way

twilit siren
#

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

narrow plover
# kind ferry in what way

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

kind ferry
#

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

narrow plover
# kind ferry 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

kind ferry
#

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

narrow plover
#

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

kind ferry
#

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

narrow plover
#

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

narrow plover
#

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 *

twilit siren
#

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

narrow plover
narrow plover
#

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

#

it was all because i used a newer version of fastgltf. lesson learned.

low minnow
#

ah yeah Array vs Vector

#

I changed this in version 0.8 iirc

narrow plover
#

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

kind ferry
#

its not normal

#

first time i ever see this happening

narrow plover
#

it was happening with the provided structure.glb, and a few others i tested

kind ferry
#

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

narrow plover
#

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

narrow plover
#

i misspoke

kind ferry
#

alphablendmodetest has no names it seems

#

it only has the uri for loading from the jpeg path

narrow plover
#

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?

kind ferry
#

adding the ID into the name works fine i think

#

it doesnt even really have to be a map

low minnow
#

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:

  1. Assign images a unique name
  2. Use another criteria to differentiate, like for example indices or a content hash
narrow plover
low minnow
#

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

narrow plover
#

thank you for your contributions to vkguide, and thanks for fastgltf

kind ferry
#

@low minnow you mean the fastgltf fixes pr from a year ago?

low minnow
#

ye its still open

#

idk if they have been addressed or not

kind ferry
#

i think i fixed a couple

narrow plover
#

@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?

kind ferry
#

both

#

here allows discussing it a bit

narrow plover
#

what is the purpose of

struct GLTFMaterial
{
    MaterialInstance data;
};```
in ``vk_loader.h``

why wouldn't I just use ``MaterialInstance`` directly?
kind ferry
#

placeholder to then have more stuff later, particularly for different passes of that same material

narrow plover
#

ah makes sense, ill label it as such.

#

any plans for MSAA in the next version?

kind ferry
#

msaa is just kinda trivial to add

#

if anything it would just be a short extra chapter

twilit siren
kind ferry
#

hell yeah

twilit siren
#

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

pulsar egret
#

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.

twilit siren
kind ferry
#

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

twilit siren
#

yes I put my own name on my licenses

low minnow
#

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);
                    });
              }
            }
kind ferry
#

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

kind ferry
#

next one will be about framegraphs and gbuffers

civic mantle
#

@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.

kind ferry
#

@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

civic mantle
#

sounds good.
I'll add in the "dump reasons why it failed" to the snippets as there is no point otherwise

kind ferry
#

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+

lilac oak
#

WASSUP

kind ferry
#

the correct BRDF math

#

i remember you mentioned learnopengl was dogshit

lilac oak
#

mmmm

kind ferry
#

maybe i could go with the Filament ones, but afaik those are also fairly approximate

lilac oak
#

son

#

knock yourself the fuck out

kind ferry
#

given im making a new chapter i want to use high end formulas or whatever is the best ones to use atm

lilac oak
#

I just merged this BxDF shit

#

all correct

#

all unit tested

kind ferry
#

i was thinking maybe grab the khronos PBR material standard, with the multilyaer fuckery

kind ferry
#

and try to get that to work math-wise

lilac oak
#

for non-RT rendering you just want my BxDF's eval() method

kind ferry
#

do you happen to know good materials/models/etc i can use for validation ?

lilac oak
#

if you want to PT or generate IBL (preintegrated envmap for every reflection vector) you can use generate and quotient_and_pdf

kind ferry
#

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

lilac oak
#

pseudocode how you'd do IBL with my BxDF lib

#

C++20 concepts in shaders go BRRR

kind ferry
#

interesting

#

maybe i should also do the chapter on slang

lilac oak
#

organise your shit

lilac oak
#

like my weird concepts are just Slang Interfaces

lilac oak
#

ah you mean the culling

kind ferry
#

ye, just for progression

lilac oak
#

tbf I don't like lights with limited ranges

kind ferry
#

pass array of lights to the shader and go

#

neither do i

#

lights must always have a range limit, its nonsense if they dont

lilac oak
#

nope ๐Ÿ˜›