Commit graph

37 commits

Author SHA1 Message Date
Ben Rog-Wilhelm
e5ab5acd95 Rename RDD::MemoryBarrier to avoid conflicts with the Windows headers. 2025-09-10 05:19:36 -05:00
Dario
5a30a7e7cd Add shader baker to project exporter.
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>
2025-05-27 12:45:27 -03:00
Sander
6ae50cad17 RenderingDevice: introduce parameter 'mipmaps' for texture_create_from_extension() 2025-05-07 15:15:55 +03:00
Thaddeus Crews
c0e695d5e8
Merge pull request #100944 from Nazarwadim/LocalVector_use_1.5x_growth_factor
Use 1.5x growth factor for LocalVector
2025-04-21 08:24:22 -05:00
Thaddeus Crews
0d267e7b1e
Core: Add dedicated BitField template 2025-04-11 11:53:26 -05:00
Rémi Verschelde
408d07109b
Merge pull request #99551 from DarioSamo/fragment-density-map
Implement Fragment density map support.
2025-03-28 14:31:19 +01:00
Dario
76d709be74 Implement support for fragment density maps.
Co-Authored-By: Bastiaan Olij <mux213@gmail.com>
2025-03-24 11:50:04 -05:00
Thaddeus Crews
324512e11c
Style: Replace header guards with #pragma once 2025-03-07 17:33:47 -06:00
thimenesup
3d92f406b2 Implement Buffer Device Address for Rendering Device Vulkan and DirectX12 2025-01-13 22:43:29 -08:00
Nazarii
6609caf76e Use 1.5x growth factor for LocalVector 2025-01-10 15:57:54 +02:00
Stuart Carnie
11dc4f2e5e Metal: Add MetalFX upscaling support
Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro>
2025-01-06 06:03:18 -07:00
Thaddeus Crews
e06d83860d
Style: Enforce AllowShortFunctionsOnASingleLine 2025-01-02 10:09:41 -06:00
Yufeng Ying
e88e30c273 Remove unused headers in servers.
Co-authored-by: bruvzg <7645683+bruvzg@users.noreply.github.com>
2024-12-20 18:51:01 +08:00
Matias N. Goldberg
c77cbf096b Improvements from TheForge (see description)
The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.

This is the most "risky" PR so far because the previous ones have been
miscellaneous stuff aimed at either [improve
debugging](https://github.com/godotengine/godot/pull/90993) (e.g. device
lost), [improve Android
experience](https://github.com/godotengine/godot/pull/96439) (add Swappy
for better Frame Pacing + Pre-Transformed Swapchains for slightly better
performance), or harmless [ASTC
improvements](https://github.com/godotengine/godot/pull/96045) (better
performance by simply toggling a feature when available).

However this PR contains larger modifications aimed at improving
performance or reducing memory fragmentation. With greater
modifications, come greater risks of bugs or breakage.

Changes introduced by this PR:

TBDR GPUs (e.g. most of Android + iOS + M1 Apple) support rendering to
Render Targets that are not backed by actual GPU memory (everything
stays in cache). This works as long as load action isn't `LOAD`, and
store action must be `DONT_CARE`. This saves VRAM (it also makes
painfully obvious when a mistake introduces a performance regression).
Of particular usefulness is when doing MSAA and keeping the raw MSAA
content is not necessary.

Some GPUs get faster when the sampler settings are hard-coded into the
GLSL shaders (instead of being dynamically bound at runtime). This
required changes to the GLSL shaders, PSO creation routines, Descriptor
creation routines, and Descriptor binding routines.

 - `bool immutable_samplers_enabled = true`

Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.

Immutable samplers requires that the samplers stay... immutable, hence
this boolean is useful if the promise gets broken. We might want to turn
this into a `GLOBAL_DEF` setting.

Instead of creating dozen/hundreds/thousands of `VkDescriptorSet` every
frame that need to be freed individually when they are no longer needed,
they all get freed at once by resetting the whole pool. Once the whole
pool is no longer in use by the GPU, it gets reset and its memory
recycled. Descriptor sets that are created to be kept around for longer
or forever (i.e. not created and freed within the same frame) **must
not** use linear pools. There may be more than one pool per frame. How
many pools per frame Godot ends up with depends on its capacity, and
that is controlled by
`rendering/rendering_device/vulkan/max_descriptors_per_pool`.

- **Possible improvement for later:** It should be possible for Godot
to adapt to how many descriptors per pool are needed on a per-key basis
(i.e. grow their capacity like `std::vector` does) after rendering a few
frames; which would be better than the current solution of having a
single global value for all pools (`max_descriptors_per_pool`) that the
user needs to tweak.

 - `bool linear_descriptor_pools_enabled = true`

Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.
Setting it to false is required when workarounding driver bugs (e.g.
Adreno 730).

A ridiculous optimization. Ridiculous because the original code
should've done this in the first place. Previously Godot was doing the
following:

  1. Create a command buffer **pool**. One per frame.
  2. Create multiple command buffers from the pool in point 1.
3. Call `vkBeginCommandBuffer` on the cmd buffer in point 2. This
resets the cmd buffer because Godot requests the
`VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT` flag.
  4. Add commands to the cmd buffers from point 2.
  5. Submit those commands.
6. On frame N + 2, recycle the buffer pool and cmd buffers from pt 1 &
2, and repeat from step 3.

The problem here is that step 3 resets each command buffer individually.
Initially Godot used to have 1 cmd buffer per pool, thus the impact is
very low.

But not anymore (specially with Adreno workarounds to force splitting
compute dispatches into a new cmd buffer, more on this later). However
Godot keeps around a very low amount of command buffers per frame.

The recommended method is to reset the whole pool, to reset all cmd
buffers at once. Hence the new steps would be:

  1. Create a command buffer **pool**. One per frame.
  2. Create multiple command buffers from the pool in point 1.
3. Call `vkBeginCommandBuffer` on the cmd buffer in point 2, which is
already reset/empty (see step 6).
  4. Add commands to the cmd buffers from point 2.
  5. Submit those commands.
6. On frame N + 2, recycle the buffer pool and cmd buffers from pt 1 &
2, call `vkResetCommandPool` and repeat from step 3.

**Possible issues:** @dariosamo added `transfer_worker` which creates a
command buffer pool:

```cpp
transfer_worker->command_pool =
driver->command_pool_create(transfer_queue_family,
RDD::COMMAND_BUFFER_TYPE_PRIMARY);
```

As expected, validation was complaining that command buffers were being
reused without being reset (that's good, we now know Validation Layers
will warn us of wrong use).
I fixed it by adding:

```cpp
void RenderingDevice::_wait_for_transfer_worker(TransferWorker
*p_transfer_worker) {
	driver->fence_wait(p_transfer_worker->command_fence);
	driver->command_pool_reset(p_transfer_worker->command_pool); //
! New line !
```

**Secondary cmd buffers are subject to the same issue but I didn't alter
them. I talked this with Dario and he is aware of this.**
Secondary cmd buffers are currently disabled due to other issues (it's
disabled on master).

 - `bool RenderingDeviceCommons::command_pool_reset_enabled`

Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.

There's no other reason for this boolean. Possibly once it becomes well
tested, the boolean could be removed entirely.

Adds `command_bind_render_uniform_sets` and
`add_draw_list_bind_uniform_sets` (+ compute variants).

It performs the same as `add_draw_list_bind_uniform_set` (notice
singular vs plural), but on multiple consecutive uniform sets, thus
reducing graph and draw call overhead.

 - `bool descriptor_set_batching = true;`

Setting it to false enforces the old behavior. Useful for debugging bugs
and regressions.

There's no other reason for this boolean. Possibly once it becomes well
tested, the boolean could be removed entirely.

Godot currently does the following:

 1. Fill the entire cmd buffer with commands.
 2. `submit()`
    - Wait with a semaphore for the swapchain.
- Trigger a semaphore to indicate when we're done (so the swapchain
can submit).
 3. `present()`

The optimization opportunity here is that 95% of Godot's rendering is
done offscreen.
Then a fullscreen pass copies everything to the swapchain. Godot doesn't
practically render directly to the swapchain.

The problem with this is that the GPU has to wait for the swapchain to
be released **to start anything**, when we could start *much earlier*.
Only the final blit pass must wait for the swapchain.

TheForge changed it to the following (more complicated, I'm simplifying
the idea):

 1. Fill the entire cmd buffer with commands.
 2. In `screen_prepare_for_drawing` do `submit()`
    - There are no semaphore waits for the swapchain.
    - Trigger a semaphore to indicate when we're done.
3. Fill a new cmd buffer that only does the final blit to the
swapchain.
 4. `submit()`
    - Wait with a semaphore for the submit() from step 2.
- Wait with a semaphore for the swapchain (so the swapchain can
submit).
- Trigger a semaphore to indicate when we're done (so the swapchain
can submit).
 5. `present()`

Dario discovered this problem independently while working on a different
platform.

**However TheForge's solution had to be rewritten from scratch:** The
complexity to achieve the solution was high and quite difficult to
maintain with the way Godot works now (after Übershaders PR).
But on the other hand, re-implementing the solution became much simpler
because Dario already had to do something similar: To fix an Adreno 730
driver bug, he had to implement splitting command buffers. **This is
exactly what we need!**. Thus it was re-written using this existing
functionality for a new purpose.

To achieve this, I added a new argument, `bool p_split_cmd_buffer`, to
`RenderingDeviceGraph::add_draw_list_begin`, which is only set to true
by `RenderingDevice::draw_list_begin_for_screen`.

The graph will split the draw list into its own command buffer.

 - `bool split_swapchain_into_its_own_cmd_buffer = true;`

Setting it to false enforces the old behavior. This might be necessary
for consoles which follow an alternate solution to the same problem.
If not, then we should consider removing it.

PR #90993 added `shader_destroy_modules()` but it was not actually in
use.

This PR adds several places where `shader_destroy_modules()` is called
after initialization to free up memory of SPIR-V structures that are no
longer needed.
2024-12-09 11:49:28 -03:00
Thaddeus Crews
3cff32a92d
Merge pull request #98910 from darksylinc/matias-id_arm32
Force `RDD::id` to be always `uint64_t`
2024-11-10 12:12:53 -06:00
Matias N. Goldberg
e69a0c7d60 Force RID::id to be always uint64_t
On Vulkan, some handles are meant to always be u64, even on 32-bit
architectures such as arm32.

Fixes #98654
2024-11-06 20:03:56 -03:00
Thaddeus Crews
2b49543478
Merge pull request #98709 from darksylinc/matias-upsidedown-splash
Fix splash screen upside down on Android
2024-11-04 21:52:01 -06:00
Dario
5216ef5f9c Add dependency detection improvements to the render graph.
- 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.
2024-11-01 09:46:52 -03:00
Matias N. Goldberg
b9a2f108fc Fix splash screen upside down on Android
Fixes an issue introduced in #96439 (see
https://github.com/godotengine/godot/pull/96439#issuecomment-2447288702)

Godot was relying on Java's
activity.getWindowManager().getDefaultDisplay().getRotation(); to apply
pre-rotation but this is wrong.

First, getRotation() may temporarily return a different value from the
correct one; which is what was causing the splash screen to be upside
down. It would return -90 instead of 90 for the first rendered frame.

But unfortunately, the splash screen is just one frame rendered for a
very long time, so the error lingered for a long time for everyone to
see.

Second, to determine what rotation to use, we should be looking at what
Vulkan told us, which is the value we pass to
VkSurfaceTransformFlagBitsKHR::preTransform.

This commit removes the now-unnecessary
screen_get_internal_current_rotation() function (which was introduced by
#96439) and now saves the preTransform value in the swapchain.
2024-10-31 16:52:26 -03:00
Clay John
748f4079e3
Merge pull request #96439 from darksylinc/matias-TheForge-pr03-rebased
Add Swappy & Pre-Transformed Swapchain
2024-10-29 12:34:40 -07:00
Matias N. Goldberg
aaa0e2fddf Add Swappy & Pre-Transformed Swapchain
- Adds Swappy for Android for stable frame pacing
- Implements pre-transformed Swapchain so that Godot's compositor is in
charge of rotating the screen instead of Android's compositor
(performance optimization for phones that don't have HW rotator)

============================

The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.

Changes from original PR:

- Removed "display/window/frame_pacing/android/target_frame_rate" option
to use Engine::get_max_fps instead.
- Target framerate can be changed at runtime using Engine::set_max_fps.
- Swappy is enabled by default.
- Added documentation.
- enable_auto_swap setting is replaced with swappy_mode.
2024-10-28 18:55:37 -03:00
Dario
8c3e46b13b Move transitions of textures initialized by transfer workers to the main graphics queue.
Also adds a new possible texture layout and API trait to support a particular behavior in D3D12 where only the COMMON layout is supported in copy queues. Fixes #98158.
2024-10-18 09:15:25 -03:00
Dario
e2c6daf7ef Implement asynchronous transfer queues, thread guards on RenderingDevice. Add ubershaders and rework pipeline caches for Forward+ and Mobile.
- Implements asynchronous transfer queues from PR #87590.
- Adds ubershaders that can run with specialization constants specified as push constants.
- Pipelines with specialization constants can compile in the background.
- Added monitoring for pipeline compilations.
- Materials and shaders can now be created asynchronously on background threads.
- Meshes that are loaded on background threads can also compile pipelines as part of the loading process.
2024-10-02 15:11:58 -03:00
Matias N. Goldberg
364f916f3f
Add debug utilities for Vulkan
Features:
- Debug-only tracking of objects by type. See
get_driver_allocs_by_object_type et al.
 - Debug-only Breadcrumb info for debugging GPU crashes and device lost
 - Performance report per frame from get_perf_report
- Some VMA calls had to be modified in order to insert the necessary
memory callbacks

Functionality marked as "debug-only" is only available in debug or dev
builds.

Misc fixes:
 - Early break optimization in RenderingDevice::uniform_set_create

============================

The work was performed by collaboration of TheForge and Google. I am
merely splitting it up into smaller PRs and cleaning it up.
2024-08-21 23:48:08 +02:00
Stuart Carnie
2d0165574d
Add Metal support for macOS (arm64) and iOS 2024-08-20 12:11:06 +02:00
Rémi Verschelde
f2796fa06d
Merge pull request #91769 from DarioSamo/d3d12_enhanced_barriers
Add support for enhanced barriers in D3D12.
2024-05-31 14:15:49 +02:00
bruvzg
628c81d2d9
[DisplayServer] Add method to check if window transparency is supported and enabled. 2024-05-23 15:23:18 +03:00
Dario
adabd14d08 Add support for enhanced barriers in D3D12.
Enables support for enhanced barriers if available.

Gets rid of the implementation of [CROSS_FAMILY_FALLBACK] in the D3D12 driver. The logic has been reimplemented at a higher level in RenderingDevice itself.

This fallback is only used if the RenderingDeviceDriver reports the API traits and the capability of sharing texture formats correctly. Aliases created in this way can only be used for sampling: never for writing. In most cases, the formats that do not support sharing do not support unordered access/storage writes in the first place.
2024-05-20 13:04:44 -03:00
jsjtxietian
5a5453bcf2 Fixes RenderingDevice::get_driver_resource will crash or give incorrect result with certain resources 2024-04-08 12:31:22 +08:00
Thaddeus Crews
9903e6779b
Enforce template syntax typename over class 2024-03-07 22:39:09 -06:00
Rémi Verschelde
cfe344f12f
Merge pull request #87872 from RandomShaper/d3d12_tex_mem_is_life
Direct3D 12: Enhance management of texture data life cycle
2024-02-27 16:36:59 +01:00
Pedro J. Estébanez
d47021ac6c Direct3D 12: Enhance management of texture data life cycle 2024-02-27 15:45:19 +01:00
Dario
ee2d8f68ba Merge execute and present commands for RenderingDeviceDriver. 2024-02-19 13:09:03 -03:00
Dario
73eff10c76 Finish splitting functionality of the Vulkan and D3D12 backends into RenderingDeviceDriver. 2024-02-12 10:02:18 -03:00
Dario
cc4d39b0c1 Acyclic Command Graph for RenderingDevice.
Adds a new system to automatically reorder commands, perform layout transitions and insert synchronization barriers based on the commands issued to RenderingDevice.
2024-01-08 14:54:56 -03:00
jsjtxietian
5d361a9e39 Fix msvc 14.1 complains about "atempting to reference a deleted function"
in RenderPassClearValue
2023-12-25 18:52:06 +08:00
Pedro J. Estébanez
12a519bae2 Split RenderingDevice into API-agnostic and RenderingDeviceDriver parts
Credit and thanks to @bruzvg for multiple build fixes, update of 3rd-party items and MinGW support.

Co-authored-by: bruvzg <7645683+bruvzg@users.noreply.github.com>
2023-12-20 19:18:08 +01:00