turanszkij / WickedEngine

3D engine with modern graphics
https://wickedengine.net
MIT License
5.45k stars 568 forks source link

Incomprehensible work of wi::jobsystem. #825

Open Geniok opened 1 month ago

Geniok commented 1 month ago

When checking whether engine initialization has completed, the IsInitializeFinished() check is used, which is based on the wi::jobsystem::IsBusy check.

For me, when initializing the engine, the message [wi::initializer] Wicked Engine Initialized appears before the actual initialization is completed. This can be seen in the CPU load graph in debug mode in Visual Studio. At the time the [wi::initializer] Wicked Engine Initialized message is displayed, the load is still quite high and is approximately 70-80%.

To test this, I slightly modified the code for the wi::jobsystem::IsBusy function.

bool IsBusy(const context& ctx) {
   // Whenever the context label is greater than zero, it means that there is
   // still work that needs to be done return ctx.counter.load() > 0;
   auto cnt = ctx.counter.load();
   wi::backlog::post("IsBusy: " + std::to_string(cnt));
   return (cnt > 0);
}

Example console output: . . . IsBusy: 0 (!!!) IsBusy: 0 (!!!) IsBusy: 1 IsBusy: 1 IsBusy: 0 (!!!) IsBusy: 1 IsBusy: 1 IsBusy: 1 wi::renderer Initialized (2340 ms) IsBusy: 1 IsBusy: 0

[wi::initializer] Wicked Engine Initialized (2402 ms) Thread 0x48c4 exited with code 0 (0x0). IsBusy: 0 Executed startup file: D:/Work/Projects/WickedEngine/Editor/startup.lua IsBusy: 0 IsBusy: 0 IsBusy: 1 (!!!) IsBusy: 0 IsBusy: 3 (!!!)

Created envprobe depth buffer for request Resolution = 64 64 6 Sample Count = 1 Mip Levels = 1 Format = D16_UNORM Memory = 48.0 KB

Created envprobe render target for request Resolution = 64 64 6 Sample Count = 1 Mip Levels = 3 Format = R11G11B10_FLOAT Memory = 126.0 KB

Created envprobe filtering target for request Resolution = 64 64 6 Sample Count = 1 Mip Levels = 3 Format = R11G11B10_FLOAT Memory = 126.0 KB

IsBusy: 3 (!!!) IsBusy: 3 IsBusy: 3 IsBusy: 3 . . . IsBusy: 1 IsBusy: 1 IsBusy: 1 BlockCompress created a new raw block texture to fit request: BC6H_UF16 (64, 64) Format = R32G32B32A32_UINT Resolution = 64 * 64 Array Size = 6 Memory = 384.0 KB

IsBusy: 1 wi::gui Initialized (0 ms)

turanszkij commented 1 month ago

when initializing the engine, the message [wi::initializer] Wicked Engine Initialized appears before the actual initialization is completed

How are you verifying that engine hasn't yet initialized when message is printed? If it's just the CPU load graph in Visual Studio, that's not enough because after initialization the CPU load can still remain high for some things like creating shader cache or loading application specific contents.

If you just print stuff from jobsystem::IsBusy(), that's called from a lot of other places, not just from the initializer, so I don't see the point in doing that.

Geniok commented 1 month ago

Using the editor as an example. After the message “[wi::initializer] Wicked Engine Initialized” is displayed, the window remains black and empty for another 10-15 seconds. Which overall looks very strange and illogical. It turns out that the engine has already been initialized, the initialization screen is no longer displayed, but the editor still does not display anything and is not ready for work, just a black window.

In this case, there is no way to know that the engine is actually fully initialized.

turanszkij commented 1 month ago

This is probably due to shader caching time, which is not included in the initialization screen as it goes asynchronously, it should take a couple seconds on the first run, and it should be immediate after that. However on some older GPU like Intel this can be slow.

Geniok commented 1 month ago

I have a built-in Intel 630 graphics card installed on my computer. Perhaps because of this, initialization of the application takes 30-40 seconds. In this case, a black screen instead of a splash screen is displayed for approximately 20-25 seconds. At the same time, the CPU is busy with asynchronous tasks for about 60-80 seconds and is loaded by 70-80%. Is it possible to somehow find out that the initialization is complete, so that the initial screen can be turned off after complete initialization? The IsInitializeFinished() condition is not actually such a condition.

Geniok commented 1 month ago

Let me also add that if the application is closed before the load is removed from the CPU, it crashes.