#Fwog and co.
1 messages ยท Page 14 of 1
which one?
my buffer and texture abstractions are getting a new coat of polish
I'm fixing a bunch of broken inconsistent things
and naming
actually, what should I call SubImage and SubData while I'm at it
Update/Upload
I think your original ones are good choices
SublimalImage
I just have some gl infection
You could even provide overloads for Update/UploadRectangle perhaps for the x,y,width,height values
or part of?
glTexImage is also a horrible name for a function that allocates an image and maybe uploads data to it
ja im really wondering why the opengl people couldnt come up with something more sofisticuffed
developers are horrible namers
glCreateTextureFromPixels ๐
glCreateTextures is already a thing that does something completely different ๐ฆ
yeah that came much later
they really messed up the API tbh
but glTexImage is there since forever, 1.1 or so
well glTexStorage is new and is still jacked up
there really should have been one glCreateTexture function that makes an object AND allocates memory
glTexImage is especially horrid because you can make mip levels with arbitrary sizes and formats
ja ๐ฆ
now that you mention refuckulating Buffer/Texture i also need to change my bufferisms
i do this atm
_instanceBuffer = _graphicsContext.CreateShaderStorageBuffer<GpuMeshInstance>("SceneInstances");
_instanceBuffer.AllocateStorage(1024 * Marshal.SizeOf<GpuMeshInstance>(), StorageAllocationFlags.Dynamic);
but i should incorporate storage into CSSB already
_instanceBuffer = _graphicsContext.CreateSSBO<T>(Label, elementCount, Flags);
or make the api even more obvious, and have CreateStatic/CreateDynamic
if i ever decide to add mapped buffer i can do CreateMapped too
i also like this one #general message ๐
back when I actually made renderers with more than 1 feature
why not redo with Fwog
too much schtuff on plate ๐ฆ
I'm working on a secret article (which will be public when published) that I need to finish at some point so I don't feel guilty for touching fwog in the meantime
i see i see
๐ผ๐ญ๐พ ๐ฎ๐ธ ๐ฎ๐น ๐ธ๐ช๐จ๐ท๐ช๐นโ ๐ฎ๐ณ ๐ผ๐ญ๐ฆ๐น ๐ผ๐ฆ๐พ ๐ฎ๐ธ ๐ฎ๐น ๐ธ๐ช๐จ๐ท๐ช๐นโ
idk why tbh (I'm not the only one working on it)
but it will be public when done ๐
at amd you mean?
man, I love that gif
this code is now engoodened a little
static auto pixelBuf = Fwog::Buffer(frame.gAlbedo->Extent().width * frame.gAlbedo->Extent().height * 4, Fwog::BufferStorageFlag::MAP_MEMORY);
Fwog::CopyTextureToBuffer({.sourceTexture = *frame.gAlbedo, .targetBuffer = pixelBuf, .extent = frame.gAlbedo->Extent()});
glFinish();
auto pixels = pixelBuf.GetMappedPointer();
memset(pixels, 255, 4 * 1000 * 100);
Fwog::CopyBufferToTexture({.sourceBuffer = pixelBuf, .targetTexture = *frame.gAlbedo, .extent = frame.gAlbedo->Extent()});
the format and type are now INFER_FORMAT and INFER_TYPE by default (matching Vulkan), but you can still do conversions if you want
does UpdateSubImage sound too deranged for you
or maybe someTexture.Update() is descriptive enough
or UpdateImage (which would be consistent with the ClearImage that I already have)
I pick that one ๐
uh oh
do y'all smell burnt toast
i like UpdateImage >>> UpdateSubImage... the latter is subpar ;P
special filter
somehow the special filter works in the other sample that uses it
I accidentally overwrote a matrix (in other words, I found the bug)

msaayy lmao (zoom in to see it)
much ๐ ฑ๏ธeter
these jaggies are visible from space
I'm actually surprised MSAA just worked tbh
just had to make an MS texture, draw to it as usual, then blit it to some other texture for resolve
thought fwog was gonna have some screwed up API usage somehow, but I guess not
oh no msaa is very easy in ogl compared to vk 

that actually reminds me
I need to add a corresponding struct to fwog
otherwise you can't do A2C or other fancy tricks
let me inspect the cap first to make sure I'm not tardo
somethin is definitely fucky
renderdoc be saying there are two
les, yet...
debug feature 
EID 581?
ye
you on AMD?
as god intended
mashallah it must be an nv driver buge
bug = reported
should've kept it secret for that competitive advantage frfr
WONTFIX + opengL + termination for helping a competitor
the code is quite shrimple
there is an MS render target and a non MS texture that I blit to for resolve
then I blit that to the screen to upscale so you can see the big pixels
multishrimple is also something i have to work on, after being skolded yestergestern
MSAA is very simple when your renderer is microscopic
and not naively deferrered?
yeah that makes things double plus unshrimple
for complex forward renderers it's a huge pain, but in a different way
because all full screen effects now need to worry about multisampling
3000 multisample image resolves of Allah
: )
testing my resolve smh
Lol
just do your fullscreen effects after your resolve
OIT with MLAB gave me the most pain because I thought I could resolve it without sample rate shading but that's just what I ended up doing
luckily nsight doesn't work on my card otherwise I'd see how awful that actually is
I guess some fullscreen stuff will have aliasing if you do it after MSAA resolve
so you have to be careful
I just learned that you can set a bunch of framebuffer parameters for when you render with no attachments
I wonder when you might want to draw with no attachments at all, let alone care about how many samples, layers, etc. are "drawn" to
no attachment is transform feedback
voxelization would be one case where you draw without attachments but still care about width, height and samples
ah
transform feedback alone doesn't care about those
guess I need to add these flags then
I see
is that why they implement the UB depth spinlock atomic thing (besides needing 64 bit atomics)
idk what I'm even saying
I guess both the sw and rw rasterizer need the funky 64 bit atomic
btw, in vulkan with dynamic rendering, how do you set the "framebuffer size" if there are no attachments? is it just VkRenderingInfo::renderArea?
vkCmdSetFramebufferWidth
sadly no such thing
maybe stuff like OIT? it at least cares about the depth buffer tho so not truly 0 attachment
but pretty much anything where you want to rasturbate but imageLoad/Store instead of writing out to attachments?
btw, what's the point of A2C when you can just make your own sample mask ๐ธ
and you don't even get control over the pattern that's used
i think A2C predates mask access in the shader
i c
twatter bread with a2c impls
what is the purpose of alpha to one
GL_SAMPLE_ALPHA_TO_ONE
If enabled, each sample alpha value is replaced by the maximum representable alpha value.
if you have both a2c and blending
hmm, if you're using a2c with, for example, foliage, would you normally want alpha to one enabled?
otherwise the alpha would be "applied" twice
right, i am not sure why you wouldn't turn blending off though, or why you'd want no-a21 when a2c is on
true ๐ธ
ebic a2c dither pattern
ye
first of all, how dare you
but second of all, it only supports multishrimple to 8 on vulkan
my guess if it actually does support larger counts on ogl, it is emulated
did you check?
ye, it claims to support up to 32
les on gl ๐ธ
is this the hacked multisampling transparency
alpha to coverage
what I wonder is how it behaves when one 50% opaque object moves in front or behind another 50% opaque object
it sure is a problem with just dithered transparency
because samples are aligned in screen space
so you need to shift them somehow based on depth or something, yet also make sure to avoid flickering
you only see the front object
because the shrimple masks align
you fix it by using hashed alpha testing
except the paper does some fancy stuff to make the pattern stable, but not move with the screen
I mean stochastic transparency was a thing too
the paper mentions it too
so obvious direction to take with that
actually wondering which is an earlier paper this or stochastic transparency
I thought you mean mentions not ST but stochastic a2c
the stochastic transparency paper mentioned in this paper is from 2010 ๐ธ
but ig proper word would have been "covers" instead of "mentions"
covered in a soft blankie
fake
different publication maybe
perhaps
btw there seem to be two versions of the paper
yours has 12 pages, but mine has 8
btw what I find funny is how many papers have ideas that you can explain in few sentences but papers are massive
and some of them esp in context of rasterization are proposed as new things but they inevitably come from ray tracing
or in concepts which are basic in ray tracing context
so most of them would be things people who started out with rt would be able to come up on their own accord
stochastic publication: publish 16 different versions of your paper with randomly discarded pages
but then ray tracing papers are concepts from physics, and maths used there is basic maths used for physics solvers
the difference is that they have different notation lmao
physics notation is killing me inside every time I look at any papers on physics
not that I read papers on physics often if at all, the thing about stuff coming from physics to rt was pointed out by @analog fiber , however I've seen before an instance of that in woodcock tracking paper
can you link said paper
๐ชต ๐ ๐ ๐ ?
๐พ๐ช
it's from rt gems 1 or 2 probably
damn I should have posted the entire link as flag emojis
wasted opportunity
@long robin some people of the interwebs claim that when you go above 8 it switches to SSAA
pretty hilarious tho
it breaks code that actually observes samples
like a2c
why?
well its no longer msaa
but it still has samples?
supersampling, yeah
so why would it not have samples
i don't mean it the signal processing way
i mean in the api way
you saw above Jaker's videos
you can no longer discard individual samples because it is not MSAA
it discards individual samples though, it's just different pattern from what I can see
it discards entire fragments, and fragments are single sample
by transitivity fragment->sample
so it discards samples
you are really high on this definition train atm
I still don't understand what you are talking about
i can see that
API wise there is difference between an MSAA image and SSAA image
if your code depends on observing those differences, it will break when you go to 16 or 32 samples on nvogl
thats it
what is the difference though?
for example modifying the coverage mask
if your image is not MSAA, and just supersampled, you can't modify the coverage mask
by the way how did jaker even set more than 8 samples
by the power of opengl
its advertised
or you are looking at sample locations (in SSAA the sample is always at the center of the fragment)
ok so basically no dithering but overall a2c still functions
because the mask can't hold more than 8 bits
wait that doesn't make sense
how would you discard the samples
ok I see so nvidia implements more than 8 samples by doubling fragments
for 16 and 32 samples
and leaves the 8 bit mask
for each
so the pattern should remain the same but there is additional step that downsamples all excess fragments
but it doesn't remain the same
actually yes it does not
I wonder if I should only expose 8 samples in fwog then ๐ธ
@heavy cipher do you have any idea about the truthiness of this statement: #opengl message
I guess the "implicitly" means something something bus snooping
And explicitly is glFlushMappedBufferRange
downloaded resharper c++ and it's interesting
it taught me about std::views::values for when you want to iterate over all the values in a map
#include <ranges> though 
not doing that just to make one line of code look slightly nicer ๐
so much noise
Free-monadic meta-transformers would make this a one liner smhmh
it's just big brain opengl design to make glTextureX for each texture type
my complaint was about all the resharper hints and suggestions 
yeh I'm just casually hatin' on gl
resharper found a critical missing destructor already
nvm it wasn't critical or even necessary ๐ธ (except maybe to prevent UB lel)
rate my UB
struct A { ~A() {} };
struct B : A {};
int main()
{
A* bp = new B;
delete bp;
}
btw, I really hate this inheritance I have
class TypedBuffer : public Buffer
class TextureView : public Texture
I used inheritance so I could copy the interface in the case of TextureView and so functions could accept both types while only specifying a const reference to Texture or Buffer in the signature
Stupid question, what's the UB here, non-virtual dtor?
yeah, so B doesn't get destroyed
but it has no members itself, so maybe that case isn't UB
Anyways what would you do instead?
I was thinking that I could make some reference thingy that can be implicitly constructed from Texture and TextureView, and make the functions take that as a param
Composition instead of inheritance is nice but then you can't pass them around as the base
Aah
Like a wrapper that accepts either?
yeah, then it just copies the gl handle and the createinfo struct
Sounds good ye
seems maybe less yucky than being forced to add virtual destructors
which is what I currently have
but then I'll be forced to copy the interfaces to the derived types ๐ธ
I'm gonna sound like an orThODoX C++ guy but, inheritance in C++ not very good, it's too easy to mess up and so brittle
You could uh
Make a macro
in my case, it (inheritance) is simply not the 100% correct solution
but it feels close to what I want
DECLARE_BUFFER_ACCESSORS(Bababuffer)
I'm half kidding, tbh
It can be fine in some cases, depends how involved the interface is
yeah
Darn
the use case I imagine is when you have a counter + array
Right
basically { unbounded array + anything else } can't be represented by my typed buffer
tbh i dont mind the big switch block
Eh sometimes a bit of copy paste is fine
The complaint was about the resharper squiggles
i know ๐ but i had to read past all that other complaining of you ๐
Hehehe well I was just makin a silly jok
Free-monadic meta-transformers don't exist, though free monads exist and monadic transformers exist
anyways, buffer views were something I've been wanting to add
indeed
I could probably make some cursed template abomination to express all kinds of SSBOs
e.g.,
auto buffer = Fwog::TypedBuffer<uint32_t, Fwog::UnboundedArray<Bababooey>>(69);
idk how the uploading interface would look though
same as Texture's Update perchance, BufferView's Update knows the offset already, so no ned to pass that in
I mean to make this specific thing work
buffer.UpdateFirstThingy(someUint32);
buffer.UpdateSecondThingy(someArrayOfBababooeys);
buffer is just one thing, how can it know about first or second or fird
since unbounded arrays have to be the last member of an SSBO, you could logically partition the buffer as {struct of first members, unbounded array member }
oh its some c++ery
it wouldn't be super magical though. I'll show an ex
le
i was thinking, that Buffer is just a memory range of size size. and buffer views describe what type and range in buffer
similar to gltf bufferview and accessor nonsense
// shader
struct AABB { ... };
readonly buffer FOO
{
uint counter;
float someData;
AABB boxes[];
};
// host
struct FooData
{
uint32_t counter;
float someData;
};
struct AABB { ... };
std::vector aabbs = ...
auto buffer = Fwog::TypedBuffer<FooData, AABB>(aabbs.size());
...
buffer.UpdateArray(aabbs.data(), aabbs.size());
the buffer view type would be syntactic sugar for buffer + offset + length, and would be used in interfaces, but not as a thing the user manipulates
hmmmm
one for the "struct type" (everything before the array), and one for the unbounded array type
i am probably just too stupid to understand that
remember, unbounded arrays always have to be last in SSBOs
i didnt know that, but now i do, in glsl terms
and they are the sole thing fucking with my current impl (which accepts one template param)
ok i understand now, i just never staff more than Foo foos[] into a ssbo before ๐
the thing I showed is how you can have type safety for these without resorting to an untyped buffer
BufferView is a complete different topic here
then I can eliminate untyped buffers
hmm would be cool if your c++ code would generate the glsl counterpart for it
ok also differen topic
hehe
having to update structs in two places indeed sucks
but it's not the end of the world
it looks funny
having such a system would mean Fwog would interact with shaders and the filesystem
std::vector aabbs = ...
auto buffer = Fwog::TypedBuffer<FooData, AABB>(aabbs.size());
...
buffer.UpdateArray(aabbs.data(), aabbs.size());
yeah, it's PoC syntax ๐
like how would you as a consumer of fwog know when to call what
i know ๐
would it mayhaps make sense to have some reflection analyze the glsl part and yell at you when arrays are not the last fields in the struct
and you just fill the data on host side as usual
reflection makes it way harder
just to syntax check
I'd prefer if the user just input the types themselves ๐
fair
but you're asking to check on bind, I presume
honestly probably not too hard to do that
weellllllll
I forgor that reflecting C++ types is stupid hard
you could reflect the size of the struct types easily I guess
i just mean shader reflection by whatever means (builtin glism is kinda fucky for blocks tho) maybe some sort of regex
hmm
its a good question ๐
the whole buffer thing
hmm
@long robin how are you going to proceed right now?

ah, that was for a thingie used for vertex attributes, where those strange formats don't make sense
what do you think about spamming const everywhere
+1
maybe another day
to please the const correct gods
did you know resharper allows you to apply file/project/solution wide
I only care about const correctness for parameter passing and classes
ye
I'm scared to do anything more than file-wide because I don't know if it will correctly detect my project
hehe
you can press ctrl+t multiple times
that "search everywhere" should change accordingly
ah
๐ค
unconventional ๐
this is kinda annoying
the whole point of optional::value() is that it is checked, and will throw if empty
I'm aware of that fact, which is why I'm calling it
it wants me to write if (foo.has_value()) {} else {}
disabling the warning means it won't warn for the actually unchecked case of *foo or foo->thing (which are UB if foo is empty)
all of these warnings seem completely unhelpful
yeah but how well does this linter know what's actually unchecked?
idk, I already disabled this one
i dont think these warnings are unreasonable
I disabled a bunch already
most are just telling you to follow modernester c++ practices
there are over 1000 checks. I think it's okay if I disable a few dozen
I disabled a bunch of arithmetic conversion checks because I don't want to write a billion casts just to mix size_t and int on the same line
I bite the bullet and do those, but its not like it actually makes your code any safer/more correct
you can still overflow/index OOB
well some of them do
like the ones that tell you to cast to a wider type before doing maf
but I Know What I'm Doingโข๏ธ, so I can """safely""" disable the checks
btw, the unmarked fallthrough check found a pretty bad bug
which made clearing the swapchain also invalidate it
about to do the topics from logl i never touched but with fwog
mfw
lol wat
I am so dumb that I cannot comprehend this after reading it like 3 times
spec people must be extra autistic
i wonder if jaker asked a colleague about multishrimple and that is the response
i think it's just that they don't support multisampled textures with a sample count of 1, you have to use ordinary textures
makes sense since the sampler types are different and stuffs so it's probably different paths in hw
It's from the bug report I made

#1019779751600205955 message
it's funny seeing the genesis of some ancient code in there
and some things like "there only needs to be a flag for clearing buffers" which is shrimply wrong
@long robin hey wanna make a probe based GI sample with my assistance
idk I can't write actual code it's too time consuming
if you could make cubemap capture code I could try to fill in the shader code though in free time
basically if I had a template to work with I could cook something
what kind of probe based GI
half life style but with rough reflections
would it be something scuffed where the probes are just cubemaps
well yes one radiance map and one irradiance map for diffuse
like source
irradiance map could be way smaller in resolution
it'd basically be one bounce of GI unless we bake it multiple times
rough reflections could be made from stochastic sampling at runtime
a few samples from radiance map mip based on roughness value
you could bake multiple times, what gives?
my motivation
if you don't wanna then fine
the baking would take only a few seconds max though even multiple times
well, if there are 1000 probes, then that would be at least a few seconds for one iteration
because it's a big number
especially if you can interpolate between them
big numbers cool
muh leakage
could do something like DDGI's variance shadow map per probe though
no leakage if placed right
do you mean manual placement
because I don't wanna do that
I'd rather have something that just naturally reduces leakage (like DDGI)
ok then implement ray tracing mr picky eater
well I don't need tray racing to be inspired by one part of DDGI
which is the VSM thingy to reduce leeking
how would that reduce leaking though
at some point the scuffed rasterized probes could be replaced by ray traced probes
instead of naively interpolating between all 8 neighbor probes, you do a chebychev test to see if each probe is actually visible
so there is still leaking, but less than shrimple trilinear interpolation
(each probe would store its own VSM for this test in addition to radiance and/or irradiance)
I gotta push a bunch of MSAA stuff before I work on anything else
!remindme 5 hours install this thingy https://marketplace.visualstudio.com/items?itemName=Sedenion.VSDoxyHighlighter
Alright Jaker, I'll remind you about install this thingy https://marketplace.visualstudio.com/items?itemName=Sedenion.VSDoxyHighlighter in 5 hours. ID: 56989283
I wonder how to make resharper not spam me with this shit every time I launch vs
btw deleting all the build files fixed this
looking through FSR 2 requirements and I found this nice extension
https://registry.khronos.org/OpenGL/extensions/EXT/EXT_shader_image_load_formatted.txt
FSR 2 also requires samplerless texture functions, which should be easy enough to get around (just bind a dummy sampler and continue using texelFetch)
set = # will be an easy fix too
I'm not sure where to start when it comes to actually making a GL backend though. I guess I can just transform the Vulkan backend
I'll can try integrating it with the gltf viewer I guess. one more feature can't hurt
argh I don't think stb_include handles transitive includes ๐ฆ
actually I may be wrong
hell yeah I'm wrong
Hype
I'll need to do some minor translation of all the .glsl shaders here
I'm going to copy them and change the extension, but I'm not sure to what (since glsl is already taken)
I'm thinking about .glsl2 ๐
or maybe .openglglsl lol
Holy jesus
This is going to be one tedious thing
we'll see how far I get
I predict that translating the shaders will be relatively easy
the hard(er) part will be making a fresh backend
the vk one is "only" 2000 lines long, so I have some confidence that I can make a much shorter one in gl
resource creation, descriptor management, etc. are a lot shrimpler in GL
glCreateBuffers, alright done, glNamedBufferSubData boom, stuffed with data, glBindBufferBase done
I imagine in vulkan it's like: "to create a buffer, you first have to invent a parallel Universe in which said buffer exists"
there are so many steps to do the equivalent things in vk that I can't even remember
creating a buffer alone requires like 3 function calls
vkCreateBuffer, vkGetBufferMemoryRequirements, and vkBindBufferMemory
to upload data, you need to make a staging buffer with the host visible flag, map it (vkMapMemory), memcpy your data to the pointer, unmap (vkUnmapMemory), then copy the buffer (vkCmdCopyBuffer), which requires an active command buffer
then (if you're using a simple staging buffer scheme) you put the temporary buffer in a zombie list because you can't just delete schtuff right away (unless you wait for the GPU to finish using it)
Ah yes, just the """simple""" scheme
I imagine the complex scheme requires inventing a new protocol alongside PCIe to communicate with the GPU?
now that we have a buffer, we can finally copy its descriptor to a descriptor set and bind that bad boy before dispatching
which is ignoring the fact that creating a descriptor set requires a descriptor pool and is another thing that isn't magically sync'd by the driver (so you may need to make multiple)
gl drivers are quite magical indeed
Is it GL that's weird because it doesn't require any of this stuff or do GPU actually need to perform all this..?
I mean I probably already know the answer, if it wasn't necessary they wouldn't have made it like this...
keep in mind vulkan is still an abstraction over the GPU
Well yeah, I'm surprised Vulkan doesn't require you to write your own Warp scheduler 
heh
It doesn't... right?
no, it does not ๐
Thank god
vulkan removes some significant fake stuff that gl has, like implicit sync
if you make a resource in vulkan, you only make one copy of it
you're responsible for making sure the CPU and GPU have overlapping work
if you want to write some data to a (e.g., uniform) buffer from the CPU, you have two real options
- wait for the GPU to finish using that buffer first (big stall!)
- have a second copy of the buffer that the CPU writes to while the GPU is reading

descriptor sets are another resource that the CPU needs to write to frequently, so they need the same double buffering treatment
and when you delete a resource in vulkan, it gets deleted "immediately", so you need to make sure it's not being used by the GPU first
Yeah, GL isn't that bad after all, GL_NEAREST disabling mips ain't a big deal
unlike gl, where the driver will be like "okay bud" and keep using the resource until all references to it are gone on both the CPU and GPU
Big thank you to all driver teams working on GL 
now you hopefully have an idea why low-effort gl apps will run better than low-effort vk apps, because you're basically offloading all the optimization work to the driver in gl
Yeah I always see deccer going "Vulkan will be slower, at first, than GL", now I know
it's even worse when you're porting a gl app to vulkan
because you get used to glisms like changing pipeline state randomly and on the fly, creating and destroying resources willy nilly, etc.
which require some effort to do performantly in vk (basically reimplementing the heroics that driver engineers have implemented already in their gl driver)
"some"?
at least 1
We are using the -ln(1 - x) scale right?
it seems more likely to not have to do these heroics if you're making an engine from scratch though
and you can take into account the limitations (more like difficulties) of the API you're using
I wanted to read the vulkan-tutorial.com thing a few days ago, just to get a few things you fellas talk about, before going for occlusion culling, but I then compare the word count of that with the word count of learnopengl and I was scared away
vkguide.dev is better anyways
vulkan-tutorial teaches you how to render a simple model, but the code is not very reusable
vkguide uses vkb to abstract some annoying stuff (instance creation and device selection) and vma to abstract some other annoying stuff (memory management), and has a better renderer architecture
the stuff that gets abstracted away in vkguide is ultimately unimportant boilerplate, plus vma is widely used in the industry so you might as well learn it
I see, I have a feeling I'll follow both, just because I think that's how much time it's going to take me to digest the stuff I'm reading
Rehearsing while digesting shouldn't be too bad (I hope)
yeah I did both, but that's only because I ignorantly thought I'd learn better from vulkan-tutorial
in reality, you'll need to read a million blog posts in addition to those tutorials to get a good grasp
you should be good on the basics of graphics stuff at this point
which means just learning the weird vulkan stuff
There is still a lot I don't know, derivatives are magic
I used dFdxFine for calculating recevier depth plane bias, except I have no idea how the hell this works
Do derivatives just mean "rate of change" in this context, how do you measure that though?
finite difference
Yeah but how?
If I write in the shader dFdx(some_random_float_idk), how does the GPU know what to do with it?
??? - ??? Fill in the gaps 
gpu executes fragments in 2x2 quads
evaluated in blocks
subtracts values from each other
gets the difference
you want derivative of x, then shader will get you the derivative of x by subtracting from x es of neighbouring pixels in the block
Hmm, so each thread in the GPU knows about the values of all x in the 2x2 block it's shading?
if I had to guess it reverses the operands but idk
so instead of f(x+a)-f(x) you get f(x)-f(x-a) or something
yeah and also some of those can be helper invocations, which run the shader but don't execute any writes
and just remove push_constants ๐ ez
it's kind of funny how updating VS doesn't do this
Absolutely hilarious even
going 2 need to tell this one at open mic night
what's the deal with visual studio? [slap bass]
oof I just realized that I need to manually add a bunch of defines to the shader sources since I won't be using a spirv compiler
unless...
I suppose I can give spirv in opengl another shot
luckily you be using gl46 ๐
I'm debating whether to use fwog for the backend ๐
I don't think it will be too helpful, since it's just a bunch of compute shaders
hmm okay I convinced myself
having no standard opengl header sucks
eh I guess I can just vendor glad........... again
you should get that cough checked out
does C have default function parameters 
i only find variadic nonsense and other hacks
i suppose thats where esotheric languages like zig and nim try to shine ๐
hmm
I ask because this code in the FSR 2 source uses default params in what is supposedly a C header
No C doesn't have default parameters but you can have C linkage on any C++ function
hmm, so I guess the point is slightly better ABI compatibility?
otherwise they shouldn't bother with the extern "C" block
because it's ultimately a C++ header since it uses that one feature lol
I think it's an oversight tbh
Probably, it could also mean easier loading from DLLs (or porting FFX to other languages)
tru
Without, you know, writing dlsym("__ZZAFIYaa@@SD350951ffxGetTexture@@520faygtZZ_s__gteoi")
I wonder how other languages' FFI thingies interact with C++ headers though
C++ name mangling was a mistake
or I guess you just write your own function prototypes when you write bindings
Yeah
are you sure all C++ functions can have C linkage though ๐ค
what about overloaded functions
You technically can't do that, but compilers usually have an extern "C++" that's supposed to deal with stuff like that
I am not entirely sure how it works though
huh
It's all implementation defined
With namespaces it's even funnier, cursed stuff like:
namespace A { extern "C" void f(); }
namespace B { extern "C" void f(); }
Both declarations of f() refer to the same function 
this convo reminds me of some cursed thing you can do with extern "C", kinda like this
class Joe
{
void secret()
{
printf("boo!\n");
}
};
extern "C"
{
void secret(Joe*);
}
int main()
{
Joe j;
secret(&j);
}
(except this code doesn't actually link because I didn't predict how Joe::secret would get mangled)
You can just do this
extern "C" {
void Joe::secret() {
printf("boo!\n");
}
}```
yeah but my goal is to hack into a private member of a class
hmm how do I make compiler explorer show mangled identifiers
found it
its tru๐ฑ๐พ cursed
here's what I managed to produce
https://godbolt.org/z/eazxnrMWP
removing the spurious call to j.secret makes it not link, I guess because the symbol gets removed
Disable LTO 
smh gcc can't see that _ZN3Joe6secretEv(&j); is obviously referring to Joe::secret
didn't work ๐ฆ
Damn, compiler is too smart
google tells me that the flags for disabling lto don't work
I'll try clang
let's go 
https://godbolt.org/z/6M5xrxodG
ah, now you can make secret private and it still works ๐ฅฐ
epic
All inputs that are provided at Render Resolution, except for motion vectors, should be rendered with jitter. Motion vectors should not have jitter applied, unless the FX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION flag is present.
how are you supposed to efficiently render motion vectors without jitter, if everything else in the gbuffer is jittered
I'm not sure when you wouldn't use that flag
use an unjittered view matrix when computing the previous/current positions i guess?
hmm
/// Helper macro to do safe free on a pointer.
#define FFX_SAFE_FREE(x) \
if (x) \
free(x)
void free( void *ptr);
If ptr is a null pointer, the function does nothing.
Classic
I'm a bit conchfused here, does glslang automatically make permutations of a shader if you pass defines in curly braces like this?
set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_GL_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF={0,1})
the "docs" are lacking
-D<name[=def]> | --define-macro <name[=def]> | --D <name[=def]>
define a pre-processor macro
here is the full snippet of cmake where this appears
# combine base and permutation args
if (${PASS_SHADER_FILENAME} STREQUAL "ffx_fsr2_compute_luminance_pyramid_pass")
# skip 16-bit permutations for the compute luminance pyramid pass
set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_GL_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF=0)
else()
set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_GL_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF={0,1})
endif()
I have my work cut out for me 
le sigh, I wish opengl glsl had separate samplers
hopefully none of these textures are sampled in more than one way
fortunately, it looks like only one sampler is used
mfw Intel is the only vendor who supports GL_KHR_shader_subgroup_quad in OpenGL ๐
time to get an actually good GPU I guess
oh shid, the shaders actually compiled in gl mode ๐ณ
wtf (there are 48 of these alone)
are you porting fsr2 to opengl
perhap
cool beans
i can use it with both nvidia and amd. I think they dont report it as a standalone extension because you are supposed to check that yourself by doing bitwise and on GetIntegerv(GL_SUBGROUP_SUPPORTED_FEATURES_KHR)
oh, huh
I didn't know that was a thing
I see it is part of KHR_shader_subgroup
unfortunately, glslang can't compile shaders with that extension unless the env is spirv1.3
I'm not sure if opengl can consume that
I'll try later I guess
sweet, now it seems like I really have the cmake and shaders working
now I can write code in an actual IDE and compile it to see if schtuff works
sounds promising
Lovely
Tbh, the backend seems rather straightforward to implement
I just need to fill in the interface functions
And using the vk backend as a starting point makes it a lot easier
thank god we did the exercise of writing a modern-gl-almost-vk-looking thing already ๐
this is syntax for the custom FFX shader compiler tool, it turns out
directx is a scourge on humanity
I love how everything is either a UAV or SRV, yet both can refer to textures and buffers 
Ultra Accessible Value, Sometimes Relevant Value
I love seeing // bind uavs and // bind srvs in vulkan code. it really helps me understand what is happening
developed on dx first then ported to vk?
perchance
or dx speak is shrimpler
eh
: >
dxisms are present throughout the public API
maybe you can hunt down the amd peeps who wrote this
and interlocute them why everything is soaked in dxisms
you could ask for a friend ๐
I figure it's because everything in the industry is dx
almost
it feels like vulkan is barely past the threshold for most big companies to care about it ๐ฆ
I blame inertia from dx being better than opengl for a long time
valve is pushing vk
i do remember a very brief discussion about opengl and 3dfx on the school yard decades ago
how opengl sucked over glide when the voodoo cards were killing it
vk = valve krafics
I wonder if fsr2 uses any ubos from last frame
the vk backend has this fancy ring buffer that they use for acquiring ubo ranges
is d3d11 worth learning or just go straight to d3d12 regarding this context
no point in learning d3d11 if you already know opengl tbh
(same with d3d12 and vulkan tbqh :^))
idk, d3d12 is weird and doesn't feel as well-planned as vulkan
d3d12 has some significant warts
seems like it inherits a lot of dumb stuff from d3d11 (and its own "special" stuff like sync)
oh okay. I'll stick to just OpenGL and WebGL then.
rate my type safety
namespace GL
{
struct Texture { GLuint id; };
struct Buffer { GLuint id; };
struct Sampler { GLuint id; };
}
I feel very safe now
I'm trying to make this ugly thing less ugly
// store for resources and resourceViews
struct Resource
{
#ifdef _DEBUG
char resourceName[64] = {};
#endif
VkImage imageResource;
VkImageAspectFlags aspectFlags;
VkBuffer bufferResource;
FfxResourceDescription resourceDescription;
FfxResourceStates state;
VkImageView allMipsImageView;
VkImageView singleMipImageViews[FSR2_MAX_IMAGE_VIEWS];
};
(btw, FSR2 uses C++11, so no std::variant)
that char array shivers me timbers
It's my fault
I wanted FSR2 on OpenGL and Jaker went: "sure I needed an excuse to work on it anyways"
So now I am in debt with Jaker for the rest of my life (please don't sell me)
he will be exchanged for 2 silk bundles alhamdullah
progress is slow, but those areas that aren't packed with red stripes are what I've completed so far
Can you do this at work since itโs kinda related or would that not fly
I could, at least in theory
let's just say that it's unlikely that you'll ever see an official GL backend
yep 
I love how there are tons of checks for null pointers here, where the function does nothing if the pointer is null
maybe to keep nullcheck linter things calm
it would be smarter to just terminate or smth instead of continuing in a clearly broken state
or throw some error to let the user know at least
instead of just silently being broken lol
obvious null checks might also improve awareness of possible nullisms
not everyone is an elitec++ist
the real solution is not being nullable in the first place smh
are C# objects nullable
it reminds me of when I was learning C and would write things like this
void vec2_add(const vec2* a, const vec2* b, vec2* c)
{
if (!a || !b || !c) return;
... // implement logic
}

we have all written bad code
too bad my oldest code only exists locally on a dead laptop
silently failing sucks
objects are reference types, so yeah, but with a compiler flag enabled, the compiler will be in your face
alright at least you can disable it at compile time
i know java has @NonNull or something but thats just a hint iirc
I could imagine C++ having such a thing, but it's just used as a contract (i.e., it's another source of UB)
ye JetBrains provided those hints too over a long time, CanBeNull/NotNull to aid analysers, and notify the user
nullable is an actual compiler ism
another win for kotlin over java
kotlin is nice indeed
kotlin is actually super nice to work with
thats what java should have been
it would at least help your static analyzer hopefully catch the UB though
using the dereference operator in general makes the non-null assumption, so you'd have just as much UB
I love me some ub though
Foo foo;
...
foo?.Method(); // method will not run when foo is null
UB is nice, it helps keep you on the ground
living on the edge
dodging ub makes me alive
Also objects are not nullable by default, only Foo? would be nullable
objects are nullable by default
oh i thought we were talking about kotlin
right
C# nullability is v v v v nice
its also a little pain in the rear
only annoying part about it is value types imo
when you make valuetypes nullable then its the same pos and negative thing
I remember in high school arguing with someone using unity that bool? was dumb for a tri-state value lol
me done for now
I still need a program to actually hook this up to when I'm done
mayhaps I can use @dapper gorge's as a lab rat
Fwog goes FSR2.x, stay tuned
or I can finally add motion vectors to 03_gltf_viewer and use that
I shall be the first user in the world of OpenGL FSR2
stay tuned here
https://github.com/JuanDiegoMontoya/FidelityFX-FSR2
I haven't pushed anything yet
but soonโข๏ธ
man made horrors upscaled beyond comprehension
is there a way to search VS keybindings by key
I accidentally resolved a keybind conflict with some dumb resharper functionality and I can't find the option to rectify it
(the shortcut I fucked was alt+down arrow to move a line down)
fuckit, reset all keybinds and it works fine now
i think so yes
in the keymap dialog should be a textbox above the list of all actions/keyassignments
btw I'm about 50% done with the gl backend now
oi that was kwik
Big hype
I mostly deleted a bunch of vulkan code which made the errors go away 
it's nice not having to create descriptor pools, descriptor sets, pipeline layouts, or search for memory heaps with specific properties
deccer if jaker succedes with making a fsr 2 gl backend you know your job
make it work with C#
pls
fortunately it has a very shrimple C interface
hmm is it very difficult to make C# bindings for a library with a C interface? mayhaps you could do it yourself
i doubt its very hard
hehe maybe it's better for you to learn than make deccer do monkey labor
ok sir
I found this thingy of deccer's. It might be helpful for learning how to do this
https://github.com/deccer/EngineKit.Native.Glfw
if it's a shared library then it's super easy, just got to annotate functions with DllImport
same with structs, just copy paste c ones and stick a layout attribute on the top
don't you also have to marshall the inputs from C# properly
tbf the only time I tried exposing C to "C#" was trying to make bindings for powershell and that was basically playing on challenge mode
its super shrimple
i do be using function pointers
a newer way to interop with c
almost 0/no performance loss
how do you make variadic function bindings lol
id go to the c person and beat them up first
Valid
mayhaps you have to make a binding for each set of argument types
c# has some options for marshalling things
otherwise there could be a way via C++/CLI bridge
Foo(params int[] parameters) is much cooler
Foo(23, 4, 5, 3, 5);
hmm, it needs to accept any set of types (primitive and aggregate) though
object[] instead of int[] then
actually idk if varadics work with aggregate types
well you can't pass arrays since they just decay to pointers
was just saying how "variadics" manifest in c#
ah
sorry for sizzling in some conchfusion
np
smh va_start can only take one argument starting in C23
otherwise you're forced to pass some useless extra param to it
all this stuff boils down to shrimple pointerisms anyway
yeah
though variadics are kinda wacky
since the way they work in C is by putting a list of arguments on the stack, then iterating over them with the weird va_ macros
yeah
I guess they're not that weird when I put it that way lol
though they still suck because it requires the user to somehow indicate how many args there are and the type of each, and to follow some careful contract (or get UB)
i never liked that , ... syntax
id rather have a hint like params $DataType[] parameterName
or perhaps template<typename... Ts> hehe
same shit ๐
inshallah the backend is "done"
missing a bunch of optimizations like fp16 and subgroup ops, but theoretically (barring all the bugs that are certainly hiding here) this will work if you plug it into a renderer
but does it
no clue tbqh
I'll try cramming it in my gltf viewer with no motion vectors
but first, lemme commit + push
@dapper gorge ^
it's probably super broken, so don't get your hopes up too much
Haha, love the pedantic backend renaming :p
- message(STATUS " This framework supports DX12 and VULKAN, you need to invoke cmake in one of these ways:")
+ message(STATUS " This framework supports DX12, Vulkan, and OpenGL. You need to invoke CMake in one of these ways:")
We shall try this
maybe it's not ideal to get a 1.5 gb repo with fetchcontent
actually I might be 
there is a fat sponza model in a submodule methinks
yeah, cauldron-media is 2.5 gb ๐
๐ญ๐ฒ somehow the fsr2 project is ignoring the options I set when I fetch
Let me know when you won't make me download 3GB of data 
it's still trying to build the vulkan target with this
option(GFX_API_DX12 "" OFF)
option(GFX_API_VK "" OFF)
option(GFX_API_GL "" ON)
option(FFX_FSR2_API_DX12 "" OFF)
option(FFX_FSR2_API_VK "" OFF)
option(FFX_FSR2_API_GL "" ON)
FetchContent_Declare(
fsr2
GIT_REPOSITORY https://github.com/JuanDiegoMontoya/FidelityFX-FSR2.git
GIT_TAG 3d0f3287f241daec7da336f77b36a8aac81abd82
GIT_SUBMODULES ""
)
FetchContent_MakeAvailable(fsr2)
GIT_SUBMODULES "" should theoretically make it not do that
but it seems like cmake 3.16 and older doesn't respect that
https://gitlab.kitware.com/cmake/cmake/-/issues/20579
smh I just told you that GFX_API_VK is OFF 
if(GFX_API_VK)
find_package(Vulkan REQUIRED)
add_subdirectory(src/VK)
endif()
okay, it at least doesn't error anymore
nvm, linker error now 
hmm, I wonder if the issue is that there are two glad.c in the project
probably dies because the symbols are the same or smth
--allow-multiple-definition
I just need the glad header tbh

The linker will toss a coin to decide which to use every time
For a spicier experience
I just need prototypes and gl constants for stuff like this
I'll try simply not compiling glad.c in fsr
I forgor how to make a target with only an include directory though
add_library INTERFACE?
ah yes, I have done this before
https://github.com/JuanDiegoMontoya/LD52/blob/main/external/CMakeLists.txt#L76
rip, same error
LINK : fatal error LNK1104: cannot open file 'ffx_fsr2_api_.lib'
wait no that's different
well, hardcoded the target name and now it be running
target_link_libraries(03_gltf_viewer PRIVATE glfw lib_glad fwog glm lib_imgui ffx_fsr2_api_x64)
was previously ffx_fsr2_api_${FSR2_PLATFORM_NAME}, but I guess the variable wasn't visible
Why not make your own platform deciderโข๏ธ
well I wanted to use the one in fsr lol
I wonder why the variable isn't available ๐ค
idk, it's probably private or some shit
have you been sanding your sailboat lately
oh fancy new line number link thing
rapa nui
I think interface is correct for header-only libs, the "cannot open file '*.lib'" is usually just when you supply a bad target name
yeah
I fixed that thing already
I want to include these now
#include "../ffx_fsr2.h"
#include "ffx_fsr2_gl.h"
this sucks
#include "../fsr2-src/src/ffx-fsr2-api/ffx_fsr2.h"
#include "../fsr2-src/src/ffx-fsr2-api/gl/ffx_fsr2_gl.h"
(also fsr2-src is only there if you use fetchcontent)
doesn't FetchContent populate some info variables about what you fetched
like can't you get fsr2_SOURCE_DIR or whatever
and build an interface around that
perchance
I added ${fsr2_SOURCE_DIR} to my target's include dirs, but it still isn't clear where the headers are
and the cmake docs are not clear on what foo_SOURCE_DIR is supposed to be populated with exactly
is "default value" just nothing lmao
and there's basically nothing else
I think stuff like volk_FOUND and volk_INCLUDE_DIR only come from the find_package method
cmake's completely disjoint package finding methods strike again
how useful 
oddly, I'm already "successfully" using ${tinygltf_SOURCE_DIR} in some other targets
maybe it's not actually doing anything lol
I think tinygltf is header only so that might be why
man I hate cm*ke
don't wanna
I dun like fetchcontent because if I clear the cache I have to fetch all my shit again
because it doesn't make web requests every time
I'm like the guy with the pickaxe about to strike diamonds

I just need 1 line of cmake to make this work (probably)
bruh
only if you get frozen for the next 5 years and wait for them to write cmake 4
where does it say override
yeah so I think you'll have to slap your own paths together using base_dir
well I wasn't lookin at dat
what i mean that it isn't VOLK_SOURCE_DIR it is FETCHCONTENT_SOURCE_DIR_VOLK
well, neither are expected to be populated with a meaningful value so its all the same
wot


