graphics: take stream captures off the game's present thread to avoid game perf hit (#889)
## Link to GitHub Issue or related Pull Request, if one exists #0 ## Description of change Capturing a frame for the API stream made the game wait for `GetRenderTargetData` in the middle of its present, roughly 1270us per frame at 1080p. A 120Hz cab visibly lost frames for as long as a viewer was connected. The present thread now only issues a `StretchRect` into a render target we own, which is queued rather than waited on, and a pool thread does the readback and the pixel conversion. That takes the present thread cost to 1-4us. Each snapshot is read on the request after the one that took it, so the blit and its transfer have a full frame to land and the read does not stall on the GPU either, at the cost of one frame of stream latency. Only streaming takes this path, and only on a device created with `D3DCREATE_MULTITHREADED`. Screenshots, `capture.get_jpg` and the `THREAD_BAN` models keep the existing inline readback unchanged. Also raises the x264 encoder from `i_threads = 1` to 4, which was holding a 1080p60 stream to 41fps and making a keyframe cost 12.7ms against 6.6ms for an ordinary frame. Capped rather than automatic because this encodes on the same machine it is capturing. ## Testing tested against iidx33, which was the most sensitive to frame drops
This commit is contained in:
@@ -634,6 +634,9 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::Reset(
|
||||
overlay::OVERLAY->reset_invalidate();
|
||||
}
|
||||
|
||||
// Reset refuses to run while any default pool resource is outstanding
|
||||
d3d9_readback::discard_snapshot_targets(pReal);
|
||||
|
||||
HRESULT res = pReal->Reset(pPresentationParameters);
|
||||
|
||||
// recreate overlay
|
||||
@@ -2321,6 +2324,9 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::ResetEx(
|
||||
overlay::OVERLAY->reset_invalidate();
|
||||
}
|
||||
|
||||
// ResetEx refuses to run while any default pool resource is outstanding
|
||||
d3d9_readback::discard_snapshot_targets(pReal);
|
||||
|
||||
HRESULT res = static_cast<IDirect3DDevice9Ex *>(pReal)->ResetEx(
|
||||
gfdm_parameters.presentation_parameters,
|
||||
gfdm_parameters.fullscreen_display_modes);
|
||||
|
||||
Reference in New Issue
Block a user