mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-11-04 06:31:54 +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:
		@@ -40,7 +40,7 @@
 | 
			
		||||
 | 
			
		||||
#include "dxgi_extra.h"
 | 
			
		||||
 | 
			
		||||
#define LOCKED(x) INTERLOCKED_SECTION(this->deviceContextLock, x)
 | 
			
		||||
#define LOCKED(...) INTERLOCKED_SECTION(this->deviceContextLock, __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
enum TextureState
 | 
			
		||||
{
 | 
			
		||||
@@ -56,8 +56,10 @@ typedef struct Texture
 | 
			
		||||
  ID3D11Texture2D          * tex;
 | 
			
		||||
  D3D11_MAPPED_SUBRESOURCE   map;
 | 
			
		||||
  uint64_t                   copyTime;
 | 
			
		||||
  uint8_t                    damageRectsCount;
 | 
			
		||||
  uint32_t                   damageRectsCount;
 | 
			
		||||
  FrameDamageRect            damageRects[KVMFR_MAX_DAMAGE_RECTS];
 | 
			
		||||
  int32_t                    texDamageCount;
 | 
			
		||||
  FrameDamageRect            texDamageRects[KVMFR_MAX_DAMAGE_RECTS];
 | 
			
		||||
}
 | 
			
		||||
Texture;
 | 
			
		||||
 | 
			
		||||
@@ -556,6 +558,7 @@ static bool dxgi_init(void)
 | 
			
		||||
 | 
			
		||||
  for (int i = 0; i < this->maxTextures; ++i)
 | 
			
		||||
  {
 | 
			
		||||
    this->texture[i].texDamageCount = -1;
 | 
			
		||||
    status = ID3D11Device_CreateTexture2D(this->device, &texDesc, NULL, &this->texture[i].tex);
 | 
			
		||||
    if (FAILED(status))
 | 
			
		||||
    {
 | 
			
		||||
@@ -859,10 +862,36 @@ static CaptureResult dxgi_capture(void)
 | 
			
		||||
      {
 | 
			
		||||
        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
 | 
			
		||||
        tex->copyTime = microtime();
 | 
			
		||||
        ID3D11DeviceContext_CopyResource(this->deviceContext,
 | 
			
		||||
          (ID3D11Resource *)tex->tex, (ID3D11Resource *)src);
 | 
			
		||||
        if (tex->texDamageCount < 0)
 | 
			
		||||
          ID3D11DeviceContext_CopyResource(this->deviceContext,
 | 
			
		||||
            (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)
 | 
			
		||||
@@ -879,6 +908,22 @@ static CaptureResult dxgi_capture(void)
 | 
			
		||||
    {
 | 
			
		||||
      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
 | 
			
		||||
      tex->state     = TEXTURE_STATE_PENDING_MAP;
 | 
			
		||||
      tex->formatVer = this->formatVer;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user