- Use Title Case for all labels, and add hyphens where relevant.
- Mention Roughness in SSR Filter's label name, as it's only enabled
when the SSR roughness quality is not set to Disabled.
Metal Support contributed by Migeran (https://migeran.com) and Stuart Carnie.
Co-authored-by: Stuart Carnie <stuart.carnie@gmail.com>
Co-authored-by: Gergely Kis <gergely.kis@migeran.com>
And anything that uses luminance.
The class Luminance in luminance.cpp is in charge of averaging the
luminance of all pixels.
It performs multiple passes until it reaches a 1x1 texture containing
the total average. This is standard luminance averaging on GPU.
Then the "result" of this frame and the "prev_frame_result" are averaged
together at a certain speed to mimic eye adaptation.
Then this avarege becomes the "source" for the next frame. This is done
here:
```cpp
SWAP(p_luminance_buffers->current,
p_luminance_buffers->reduce.write[p_luminance_buffers->reduce.size() -
1]);
```
So far pretty normal stuff.
**The problem is: prev_frame_result IS UNINITIALIZED**. Therefore it's
possible for prev_frame_result to contain garbage values like -5+e15
which causes the screen to stay black for a minute until eye adaptation
catches up.
Windows will always force allocations to be reset to 0, but Linux does
not do that.
However Windows just delays the bug; because it's possible for VMA to
reuse a block.
You can repro this bug by downloading Bistro, creating a camera,
selecting a default scene; and then launching Bistro.
Everything will work fine.
Until you decide to resize the window. It takes a few tries on Godot,
but eventually the screen becomes black.
If you wait around a minute, the screen will "unblack" itself back to
normal.
Even if it's not stuck in black after resize, you may notice that every
resize is inconsistent in how the eye adaptation catches up (i.e.
sometimes it flashes to white, sometimes it does not).
If you can't repro the bug, you need to try harder by doing arbitrary
resizes until it triggers.
Also, I advise to try this on Linux; since Windows' sanitization of
memory gets in the way.
There's probably multiple tickets already filled around issues that were
rooted in luminance calculations starting from uninitialized memory.
This PR sets a default value of 0, which causes the screen to always
flash white after resize. Setting a different value like 0.1 makes the
flash effect weaker. Setting it to a high value like 5.0 makes the
screen flash from dark instead.
This bug can be backported to 4.3. I don't know if it can be backported
to earlier; as the render graph makes sure the texture_clear() calls
gets issued in the right place; whereas in <= 4.2 it might be
problematic depending on when Luminance::LuminanceBuffers::configure is
being called.
PR #100062 introduced BUFFER_USAGE_DEVICE_ADDRESS_BIT.
However it did so by adding a boolean to uniform_buffer_create(), called
"bool p_enable_device_address".
This makes maintaining backwards compatibility harder because I am
working on another feature that would require introducing yet another
bit flag.
This would save us the need to add fallback routines when the feature I
am working on makes it to Godot 4.5.
Even if my feature doesn't make it to 4.5 either, this PR makes the
routine more future-proof.
This PR also moves STORAGE_BUFFER_USAGE_DEVICE_ADDRESS into
BUFFER_CREATION_DEVICE_ADDRESS_BIT, since it's an option available to
both storage and uniforms.
This PR also moves the boolean use_as_storage into
BUFFER_CREATION_AS_STORAGE.
- Buffers changing their usage are no longer treated as write usage unless the API requires it.
- Draw lists are not treated as being dependent on each other if their regions do not intersect despite both being write commands.
- Particles were tweaked to use different unused buffers to reduce dependencies.
Before this change, using FSR2 resulted in the following error when the
effect was destroyed:
ERROR: Attempted to free invalid ID: 662734928609453
at: _free_internal (servers/rendering/rendering_device.cpp:4957)
This happened because ACCUMULATE and ACCUMULATE_SHARPEN passes shared
the same shader_version object but had different pipeline IDs. When
version_free was called for ACCUMULATE pass, it destroyed pipelines
created from that version, including the pipeline for the
ACCUMULATE_SHARPEN pass.
Using a unique version could work around this problem, but it's easier
to rely on version_free destroying the created pipelines through the
dependency mechanism.