mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-05 18:24:08 +00:00
[host] dxgi: sleep until it's close to time to map
This change adds an average function to time how long it takes the GPU to copy and map the texture, and then uses this average to sleep for 80% of this average lowering CPU usage and potentially decreasing lock contention.
This commit is contained in:

committed by
Geoffrey McRae

parent
7f5f46c448
commit
f02d61d665
@@ -26,6 +26,7 @@
|
||||
#include "common/locking.h"
|
||||
#include "common/event.h"
|
||||
#include "common/dpi.h"
|
||||
#include "common/runningavg.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdatomic.h>
|
||||
@@ -63,6 +64,7 @@ typedef struct Texture
|
||||
volatile enum TextureState state;
|
||||
ID3D11Texture2D * tex;
|
||||
D3D11_MAPPED_SUBRESOURCE map;
|
||||
uint64_t copyTime;
|
||||
}
|
||||
Texture;
|
||||
|
||||
@@ -90,6 +92,9 @@ struct iface
|
||||
atomic_int texReady;
|
||||
bool needsRelease;
|
||||
|
||||
RunningAvg avgMapTime;
|
||||
uint64_t usleepMapTime;
|
||||
|
||||
CaptureGetPointerBuffer getPointerBufferFn;
|
||||
CapturePostPointerBuffer postPointerBufferFn;
|
||||
LGEvent * frameEvent;
|
||||
@@ -185,6 +190,7 @@ static bool dxgi_create(CaptureGetPointerBuffer getPointerBufferFn, CapturePostP
|
||||
this->texture = calloc(sizeof(struct Texture), this->maxTextures);
|
||||
this->getPointerBufferFn = getPointerBufferFn;
|
||||
this->postPointerBufferFn = postPointerBufferFn;
|
||||
this->avgMapTime = runningavg_new(10);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -221,6 +227,9 @@ static bool dxgi_init(void)
|
||||
this->texWIndex = 0;
|
||||
atomic_store(&this->texReady, 0);
|
||||
|
||||
runningavg_reset(this->avgMapTime);
|
||||
this->usleepMapTime = 0;
|
||||
|
||||
lgResetEvent(this->frameEvent);
|
||||
|
||||
status = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&this->factory);
|
||||
@@ -700,6 +709,7 @@ static void dxgi_free(void)
|
||||
|
||||
free(this->texture);
|
||||
|
||||
runningavg_free(&this->avgMapTime);
|
||||
free(this);
|
||||
this = NULL;
|
||||
}
|
||||
@@ -821,6 +831,7 @@ static CaptureResult dxgi_capture(void)
|
||||
if (copyFrame)
|
||||
{
|
||||
// issue the copy from GPU to CPU RAM
|
||||
tex->copyTime = microtime();
|
||||
ID3D11DeviceContext_CopyResource(this->deviceContext,
|
||||
(ID3D11Resource *)tex->tex, (ID3D11Resource *)src);
|
||||
}
|
||||
@@ -935,6 +946,11 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
||||
|
||||
Texture * tex = &this->texture[this->texRIndex];
|
||||
|
||||
// sleep until it's close to time to map
|
||||
const uint64_t delta = microtime() - tex->copyTime;
|
||||
if (delta < this->usleepMapTime)
|
||||
usleep(this->usleepMapTime - delta);
|
||||
|
||||
// try to map the resource, but don't wait for it
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
@@ -958,6 +974,10 @@ static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
|
||||
break;
|
||||
}
|
||||
|
||||
// update the sleep average and sleep for 80% of the average on the next call
|
||||
runningavg_push(this->avgMapTime, microtime() - tex->copyTime);
|
||||
this->usleepMapTime = (uint64_t)(runningavg_calc(this->avgMapTime) * 0.8);
|
||||
|
||||
tex->state = TEXTURE_STATE_MAPPED;
|
||||
|
||||
frame->formatVer = tex->formatVer;
|
||||
|
Reference in New Issue
Block a user