mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 21:47:23 +00:00
[host] dxgi: use CopySubresourceRegion when possible
This commit adds damage tracking to the DXGI textures, and only copies the damaged areas to the textures with ID3D11DeviceContext::CopySubresourceRegion. The sleep logic in waitFrame makes it difficult for this to reduce the latency, but removing it shows significant improvements (6-7 ms to ~3 ms) when a tiny portion of the screen is damaged, while showing no difference on full screen damage.
This commit is contained in:
parent
7e982a6658
commit
9bded74543
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#include "dxgi_extra.h"
|
#include "dxgi_extra.h"
|
||||||
|
|
||||||
#define LOCKED(x) INTERLOCKED_SECTION(this->deviceContextLock, x)
|
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
|
||||||
|
|
||||||
enum TextureState
|
enum TextureState
|
||||||
{
|
{
|
||||||
@ -56,8 +56,10 @@ typedef struct Texture
|
|||||||
ID3D11Texture2D * tex;
|
ID3D11Texture2D * tex;
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
uint64_t copyTime;
|
uint64_t copyTime;
|
||||||
uint8_t damageRectsCount;
|
uint32_t damageRectsCount;
|
||||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
|
int32_t texDamageCount;
|
||||||
|
FrameDamageRect texDamageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||||
}
|
}
|
||||||
Texture;
|
Texture;
|
||||||
|
|
||||||
@ -556,6 +558,7 @@ static bool dxgi_init(void)
|
|||||||
|
|
||||||
for (int i = 0; i < this->maxTextures; ++i)
|
for (int i = 0; i < this->maxTextures; ++i)
|
||||||
{
|
{
|
||||||
|
this->texture[i].texDamageCount = -1;
|
||||||
status = ID3D11Device_CreateTexture2D(this->device, &texDesc, NULL, &this->texture[i].tex);
|
status = ID3D11Device_CreateTexture2D(this->device, &texDesc, NULL, &this->texture[i].tex);
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
@ -859,10 +862,36 @@ static CaptureResult dxgi_capture(void)
|
|||||||
{
|
{
|
||||||
computeFrameDamage(tex);
|
computeFrameDamage(tex);
|
||||||
|
|
||||||
|
if (tex->texDamageCount < 0 || tex->damageRectsCount == 0 ||
|
||||||
|
tex->texDamageCount + tex->damageRectsCount > KVMFR_MAX_DAMAGE_RECTS)
|
||||||
|
tex->texDamageCount = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(tex->texDamageRects + tex->texDamageCount, tex->damageRects,
|
||||||
|
tex->damageRectsCount * sizeof(FrameDamageRect));
|
||||||
|
tex->texDamageCount += tex->damageRectsCount;
|
||||||
|
tex->texDamageCount = rectsMergeOverlapping(tex->texDamageRects, tex->texDamageCount);
|
||||||
|
}
|
||||||
|
|
||||||
// issue the copy from GPU to CPU RAM
|
// issue the copy from GPU to CPU RAM
|
||||||
tex->copyTime = microtime();
|
tex->copyTime = microtime();
|
||||||
|
if (tex->texDamageCount < 0)
|
||||||
ID3D11DeviceContext_CopyResource(this->deviceContext,
|
ID3D11DeviceContext_CopyResource(this->deviceContext,
|
||||||
(ID3D11Resource *)tex->tex, (ID3D11Resource *)src);
|
(ID3D11Resource *)tex->tex, (ID3D11Resource *)src);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < tex->texDamageCount; ++i)
|
||||||
|
{
|
||||||
|
FrameDamageRect * rect = tex->texDamageRects + i;
|
||||||
|
D3D11_BOX box = {
|
||||||
|
.left = rect->x, .top = rect->y, .front = 0, .back = 1,
|
||||||
|
.right = rect->x + rect->width, .bottom = rect->y + rect->height,
|
||||||
|
};
|
||||||
|
ID3D11DeviceContext_CopySubresourceRegion(this->deviceContext,
|
||||||
|
(ID3D11Resource *)tex->tex, 0, rect->x, rect->y, 0,
|
||||||
|
(ID3D11Resource *)src, 0, &box);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copyPointer)
|
if (copyPointer)
|
||||||
@ -879,6 +908,22 @@ static CaptureResult dxgi_capture(void)
|
|||||||
{
|
{
|
||||||
ID3D11Texture2D_Release(src);
|
ID3D11Texture2D_Release(src);
|
||||||
|
|
||||||
|
for (int i = 0; i < this->maxTextures; ++i)
|
||||||
|
{
|
||||||
|
Texture * t = this->texture + i;
|
||||||
|
if (i == this->texWIndex)
|
||||||
|
t->texDamageCount = 0;
|
||||||
|
else if (tex->damageRectsCount > 0 && t->texDamageCount >= 0 &&
|
||||||
|
t->texDamageCount + tex->damageRectsCount <= KVMFR_MAX_DAMAGE_RECTS)
|
||||||
|
{
|
||||||
|
memcpy(t->texDamageRects + t->texDamageCount, tex->damageRects,
|
||||||
|
tex->damageRectsCount * sizeof(FrameDamageRect));
|
||||||
|
t->texDamageCount += tex->damageRectsCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t->texDamageCount = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// set the state, and signal
|
// set the state, and signal
|
||||||
tex->state = TEXTURE_STATE_PENDING_MAP;
|
tex->state = TEXTURE_STATE_PENDING_MAP;
|
||||||
tex->formatVer = this->formatVer;
|
tex->formatVer = this->formatVer;
|
||||||
|
Loading…
Reference in New Issue
Block a user