Commit graph

201 commits

Author SHA1 Message Date
kleonc
2bb6ad5cdf Fix debug CanvasItem redraw rects in RD renderer 2025-02-18 23:49:43 +01:00
Stuart Carnie
90b2d4b844 2D: Fix free of invalid ID 2025-02-11 08:17:29 +11:00
Stuart Carnie
0a9cd5ede9 2D: Fix clip children and rendering artefacts
Fixes both GLES3 and RendererRD implementations

Closes #102147
2025-01-30 07:19:47 +11:00
Stuart Carnie
2510fefebd 2D: Fix rendering artefacts when using BackBufferCopy.
Fixes both GLES3 and RendererRD implementations
2025-01-25 10:22:07 +11:00
Stuart Carnie
663917449b 2D: Fix CanvasTexture rendering when updating channels 2025-01-24 07:01:37 +11:00
Aarni Koskela
f134769506 Fix various typos
* Add TODO notes for typos that should be fixed for 5.0

Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
2025-01-08 14:47:42 +02:00
Rémi Verschelde
f7d6924afb
Merge pull request #100677 from clayjohn/light2d-cull
Properly transform light rect and occluder rect to perform Light2D culling in canvas space
2024-12-22 00:10:12 +01:00
clayjohn
30801af298 Properly transform light rect and occluder rect to perform light2d culling in canvas space 2024-12-20 16:58:02 -07: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
Thaddeus Crews
d3e5b62ea2
Merge pull request #99230 from paddy-exe/instance_uniforms_compatability_renderer
Implement 2D instance uniforms
2024-12-19 19:59:37 -06:00
clayjohn
793d065f8b Avoid allocating instance buffer for PointLight2D shadows when there are no instances.
Also avoid the render loop if there are no occluders. We still have to open the render pass to do a clear though.
2024-12-19 09:45:51 -08:00
kobewi
ceefc0d38a Implement 2D instance shader parameters
Co-authored-by: kobewi <kobewi4e@gmail.com>
Co-authored-by: yesfish <huwpascoe@users.noreply.github.com>
Co-authored-by: Álex Román Núñez <eirexe123@gmail.com>
2024-12-17 23:59:16 +01:00
clayjohn
7c61252dd7 Optimize PointLight2D shadow rendering by reducing draw calls and RD state changes.
This dramatically reduces the CPU time spent on rendering shadows for PointLight2Ds
2024-12-17 07:41:09 -08:00
Thaddeus Crews
66dea152b5
Merge pull request #99257 from darksylinc/matias-TheForge-pr04-excluded-ubo+render_opt
Improvements from TheForge
2024-12-10 14:15:55 -06:00
Thaddeus Crews
5f5f86bff0
Merge pull request #100128 from clayjohn/rd-shader-spam
Avoid error spam when shaders fail to compile by freeing shader_data version when compilation fails
2024-12-09 14:33:16 -06:00
Thaddeus Crews
75a425f1d3
Merge pull request #99995 from clayjohn/RD-batch-ptrw
Optimize batch uniform set creation by caching ptrw when creating batch uniform
2024-12-09 14:33:14 -06:00
clayjohn
fce34f22a2 Avoid error spam when shaders fail to compile by freeing shader_data version when compilation fails 2024-12-09 10:51:57 -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
clayjohn
0dfbf4a5df Optimize batch uniform set creation by caching ptrw when creating batch uniform 2024-12-03 17:16:44 -08:00
CrazyRoka
d9ef826c54
Optimize RenderForwardClustered::_setup_render_pass_uniform_set by reducing Vector allocations during push_back operations 2024-12-02 15:03:50 +01:00
Dario
1c6aad660f Fix incorrect clear color flag on canvas renderer. 2024-11-27 20:01:23 -03:00
Dario
6d5ac8f7ef Resolve load and store ops automatically for render passes for discardable textures. 2024-11-25 11:27:48 -03:00
clayjohn
2b68c63a88 Mask out shadows on CanvasItems that don't have a matching item_shadow_mask
This restores the behavior from 3.x
2024-11-21 22:15:54 -08:00
Thaddeus Crews
2b02143d35
Merge pull request #98307 from clayjohn/Light2D-shadow-projection
Precompute projection matrices when rendering 2D shadows
2024-11-10 12:12:14 -06:00
Stuart Carnie
0d1d945727
2D: Fix various issues and minor performance optimisations 2024-10-30 08:36:45 +11:00
clayjohn
62516df757 Precompute projection matrices when rendering 2D shadows 2024-10-18 11:55:00 -07:00
DarioSamo
fa1aacb455 Configure MSAA properly in canvas renderer's pipelines. 2024-10-04 10:45:59 -03:00
clayjohn
65f3df5923 Properly utilize surface information when creating pipelines and vertex arrays in canvas renderer 2024-10-03 16:27:14 -07: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
clayjohn
4d635b7a3a Combine texture and instance data into one uniform set in the 2D renderer
Co-authored-by: Stuart Carnie <stuart.carnie@gmail.com>
2024-09-27 11:05:46 -07:00
Stuart Carnie
e826ab9ba9
[2D,Metal]: Fix subpixel blending; fix inconsistent blend state in Metal 2024-09-20 15:16:31 +10:00
Stuart Carnie
5b5dc00c52
2D: Remove redundant assignment 2024-09-17 06:32:49 +10:00
Stuart Carnie
c113e5b143
2D: Fix use-after-free in batch rendering
Closes #96960
Fixes regression of #95574 using fix from #95666
2024-09-14 07:50:39 +10:00
Stuart Carnie
a657ea42f1
2D: Add batching to RendererCanvasRenderRD 2024-09-12 05:26:06 +10:00
Rémi Verschelde
568589c9d8
Merge pull request #90993 from darksylinc/matias-TheForge
Add debug utilities for Vulkan
2024-08-22 00:38:22 +02: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
Aaron Franke
7db24a9ad5
Simplify and fix Rect2/AABB get_support function 2024-08-19 23:55:31 -07:00
kleonc
1bd8372813 Fix Parallax2D repeats being not relative to its transform 2024-08-19 11:43:16 +02:00
Feiyue Zhang
6f30df4b6a
Linearize color if HDR 2D is on 2024-07-24 09:49:50 +02:00
bruvzg
4790e12f66
Fix LCD font AA modulation in RendererRD. 2024-07-08 11:17:31 +03:00
cosparks
6d0dca76c0 Fixes SDF Collision Enable/Disable
- sets LightOccluderInstance field when sdf collision is updated
- adds check for light occluder sdf_collision field in 2d renderers
2024-04-22 20:27:56 -07:00
Ricardo Buring
2ed2ccc2d8 Fixed Timestep Interpolation (2D)
Adds fixed timestep interpolation to the rendering server (2D only).
Switchable on and off with a project setting (default is off).

Co-authored-by: lawnjelly <lawnjelly@gmail.com>
2024-03-23 12:28:36 +01:00
markdibarry
a62870956a Add new Parallax2D node 2024-03-03 15:46:40 -05:00
Rémi Verschelde
4a30fe5e7c
Merge pull request #86564 from Giwayume/feature/canvas-item-shader-custom-data
Support CUSTOM shader attributes in 2D
2024-02-08 10:53:24 +01:00
jsjtxietian
2004ad1ac5 Clean up outdated USE_LIGHT_SHADER_CODE usage 2024-01-24 12:30:27 +08:00
Giwayume
bb83c4adec Add custom shader attributes to Canvas Item Shaders 2024-01-23 14:36:39 -05:00
Dario
80eacf1b7a Fix incorrect mapping of initial action as clear region continue to clear. 2024-01-09 22:03:21 -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
Rémi Verschelde
342531597b
Merge pull request #85811 from clayjohn/2D-render-info
Implement render info counters for the 2D renderer
2023-12-12 10:41:06 +01:00
clayjohn
528b4a3283 Implement render info counters for the 2D renderer
This provides information for the debug monitors
2023-12-06 14:39:33 -07:00