o3de / o3de

Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations.
https://o3de.org
Other
7.62k stars 2.18k forks source link

Resizing viewport may result in slow rendering (GPU memory is used up?) #16532

Open ohmaya opened 1 year ago

ohmaya commented 1 year ago

Maybe the original author of the feature can easily get the point.

Also becomes slow once captured using NSight Graphics.

Thanks.

moudgils commented 1 year ago

This ticket needs more details.

djfos commented 1 year ago

Have the same issue. When the GPU memory runs out, resizing viewport leads fps drop from 60 to 10. But the weird thing is that restarting editor could not fix this problem. I have to restart my computer. My GPU: RTX3080 10GB.

ohmaya commented 1 year ago

Needs virtual texturing.

ohmaya commented 1 year ago

Finally, I have a good Nsight Graphics capture with 120 FPS and Forward pass of 1.56 ms.

After resizing, the FPS is 15 and Forward pass is 18.14 ms.

ohmaya commented 1 year ago

DX12::ImagePool::InitImageInternal (committed resource) that is called on resizing:

            /**
             * Super simple implementation. Just creates a committed resource for the image. No
             * real pooling happening at the moment. Other approaches might involve creating dedicated
             * heaps and then placing resources onto those heaps. This will allow us to control residency
             * at the heap level.
             */

See slide deck "Practical DirectX 12 - Programming Model and Hardware Capabilities" by Gareth Thomas & Alex Dunn:

Would expect the pool pre-allocates Placed resource (always lives in Dedicated GPU Memory) of enough size.

moudgils commented 1 year ago

When you resize the window the only resource that will be impacted is transient resources as the render target of your transient attachments is changing. So in this case we would want to take a look at TransientAttachmentPool. Every frame we calculate how much transient memory is needed and sub-allocate as well as alias it as needed. A significant fps drop usually indicates a memory cliff where we are now using system memory instead of dedicated gpu memory. What are the exact repro steps? Maybe we can try it out locally, as well as which backend is impacted (dx12 or Vk?

For streaming texture we use tiled resource support so DX12::ImagePool is very rarely used and its only for specific set of resources which should be a minority. For the most part for images we should be using StreamingImagePool or Transient Pool

ohmaya commented 1 year ago

The only member function that looks relevant in DX12::TransientAttachmentPool is ActivateImage(), which is called every frame even without resizing.

But, it is clear that "DX12::ImagePool::InitImageInternal (committed resource) that is called on resizing". The ImageInitRequest has a resolution after resizing. The callstack contains RPI:AttachmentImage and RHI:ImagePool.

ohmaya commented 1 year ago

Or, .assetinfo sidecar file can reduce loaded texture size individually? If there is a global setting to do this, like Unreal's Texture LOD Bias configued for each platform, a quick test can be done.

moudgils commented 1 year ago

For streaming textures there is a way to reduce the streaming image pool and it will automatically stream out higher LODs as needed. Tagging @VickyAtAZ who can provide steps on how to modify this number.

tarboss commented 11 months ago

it can go even worse: it freezes for seconds - but the 23.05 release version has not that issues - tested with latest night build.

ohmaya commented 11 months ago

it can go even worse: it freezes for seconds - but the 23.05 release version has not that issues - tested with latest night build.

O3DE.Editor.2023-09-02.10-04-50_b1000k.mp4

This scene does not seem to contain many textures.

ohmaya commented 6 months ago

https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Libraries/D3DX12Residency/readme.md#what-happens-if-i-dont-manage-memory-using-this-library-or-otherwise Without this library or any other sort of memory management, there is a real and significant GPU performance hit when your app uses more memory than is available. This is most noticeable on low memory (1GB/2GB) boards but can easily happen on 4GB cards as well (e.g. 4k, ultra settings, etc). The OS's Video Memory Manager (VidMM) will do its absolute best to ensure your application can always make forward progress but any contingencies that VidMM has to use to keep your app running often come with a performance hit. It is critical that applications manage their memory instead of relying on VidMM to make general case decisions which will invariably be non-optimal.