godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.1k stars 21.15k forks source link

`RenderingDevice` cannot release texture resource when window is minimized #98044

Open hippogyz opened 2 days ago

hippogyz commented 2 days ago

Tested versions

4.3.stable.mono

System information

Godot v4.3.stable.mono - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4070 (NVIDIA; 31.0.15.3161) - AMD Ryzen 9 7900X 12-Core Processor (24 Threads)

Issue description

When the game window is minimized, the texture created by RenderingDevice.create_texture() won't be freed by calling RenderingDevice.free_rid().

image when the game window is not minimized

image when the game window is minimized after a while

BTW, the Memory inspected by Editor Debugger grows much slower than inspected by Windows Task Manager, when this bug is triggered. image not minimized image minimized after a while

Steps to reproduce

extends Node2D

var rd : RenderingDevice;
var texture : RID;

func _ready() -> void:
    rd = RenderingServer.get_rendering_device()

func _process(delta: float) -> void:
    #RenderingServer.call_on_render_thread(create_texture);
    create_texture()

func create_texture() -> void:
    if texture.is_valid():
        rd.free_rid(texture)

    var format = RDTextureFormat.new()
    format.width = 1024
    format.height = 1024
    format.depth = 1
    format.format = RenderingDevice.DATA_FORMAT_R8G8B8A8_UNORM
    format.array_layers = 1
    format.mipmaps = 1
    format.usage_bits = RenderingDevice.TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice.TEXTURE_USAGE_CAN_UPDATE_BIT | RenderingDevice.TEXTURE_USAGE_STORAGE_BIT

    texture = rd.texture_create(format, RDTextureView.new(), [])
  1. This script will create a texture pre frame and release the texture created last frame.
  2. Attach it to a node and run the scene.
  3. Minimize the game window (not editor). (just hide this window below other windows won't trigger this bug)

Minimal reproduction project (MRP)

See 'Steps to reproduce'

hippogyz commented 2 days ago

Maybe related with #90030 and #90017.

Similar situation is also found when a NoiseTexture Resource is modified every frame by a script (I know it is not recommended). In my understanding, the NoiseTexture will create a new texture when the parameter is modified. So this bug might be triggered when the window is minimized.

hippogyz commented 2 days ago

A workaround should be checking if the game window is minimized before creating resources from RenderingDevice.

Such as:

if Engine.get_main_loop().root.mode == Window.MODE_MINIMIZED:
   return
# ... original code
clayjohn commented 2 days ago

Do the resources get freed once the window is no longer minimized?

hippogyz commented 2 days ago

Do the resources get freed once the window is no longer minimized?

Probably NO, it seems only part of them will be freed.

In my project, I find this bug in a compute shader which creates a texture each frame. In this case, the memory leak is more obvious than the example code above.

The memory leak of the example code above is too severe, so I cannot observe the same behavior before my compute's memory used up :(

image This is observed in my compute shader case, I just reopen the window three times which corresponds to the three sudden decline.