Closed 0xC0000054 closed 3 years ago
From what I've seen, WARP uses its own thread pool -- or at least, I've never seen those threads being used for any other work. That thread pool appears to use a simple queue for work items, rather than a queue-of-work-queues that would permit round-robin scheduling. So if some task queues up a ton of work, and then another task queues up some small work, the latter just has to wait around for the first to finish.
You can recreate a similar kind of UI-thread stalling in PDN by doing something like this:
It takes awhile for all of the tiles to render. You will probably see UI elements -- the grab handles on the canvas, as well as general UI fps and status bar updates -- not working very well. The UI thread is using WARP, as are all the background threads which are being completely flooded with work from the bicubic rendering code.
So, I'm not sure this can be avoided unless you're heck-bent on hoisting this code into a separate process, which would then finally have a separate work queue that won't compete with the main processes's UI thread. We seem to be approaching a critical mass of need for this type of infrastructure.
I think we just have to deal with the fact that if you're running w/o hardware acceleration, performance just isn't going to be optimal.
I'm grasping at straws here, but maybe IDXGIDevice::SetGPUThreadPriority()
would help? https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgidevice-setgputhreadpriority . You'd set the priority ... lower? It's not clear whether lower values give higher priority, or the reverse. I also don't know if WARP pays attention to this.
ID3D11Device
can be QI'd for a pointer to its IDXGIDevice
implementation.
I think we just have to deal with the fact that if you're running w/o hardware acceleration, performance just isn't going to be optimal.
I agree. Thanks for the detailed explanation.
So, I'm not sure this can be avoided unless you're heck-bent on hoisting this code into a separate process, which would then finally have a separate work queue that won't compete with the main processes's UI thread. We seem to be approaching a critical mass of need for this type of infrastructure.
Running FileType plugins (and the shell open and save dialogs) in a separate process makes sense. It could also simplify cancellation support for FileType plugins, the OS would free any native resources when the process exits.
Closing this issue.
When encoding larger images with the WARP DirectCompute device the Paint.NET UI stops responding when the progress reaches a certain point. WARP batches its rendering calls, and after it starts rendering the SaveConfigDialog will freeze if you try to interact with it.
Edit: The UI freeze occurs regardless of whether
D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
is set, so I am not sure what could be causing it.I observed the SaveConfigDialog being marked as not responding in task manager when using a 4096x4096 pixel blank canvas. On a 1024x1024 pixel blank canvas the SaveConfigDialog does not fully paint until the image has been compressed, it is not blocked long enough on my system to show up as not responding in task manager.
Screenshots with a blank 4096x4096 pixel canvas
![UI not responding](https://user-images.githubusercontent.com/26996983/95667966-94eca200-0b2a-11eb-8c08-f6d1c67194cf.png) ![PDN task manager](https://user-images.githubusercontent.com/26996983/95667957-7ab2c400-0b2a-11eb-9f29-aa6d61364c11.png)Paint.NET diagnostics:
Unfortunately, the DirectXTex CPU encoder for BC7 is extremely slow so it is not a viable alternative when compressing large images.
cc @rickbrew