mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +00:00
[host] dxgi: fix d3d12 backend resource leak
The handle is only needed so we can open the resource, once we have it we can close the handle. We then cache the shared resource for future reuse if possible.
This commit is contained in:
parent
0510d06c4b
commit
2206752b66
@ -44,25 +44,25 @@ struct D3D12Texture
|
|||||||
HANDLE event;
|
HANDLE event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SharedCache
|
||||||
|
{
|
||||||
|
ID3D11Texture2D * tex;
|
||||||
|
ID3D12Resource ** d12src;
|
||||||
|
};
|
||||||
|
|
||||||
struct D3D12Backend
|
struct D3D12Backend
|
||||||
{
|
{
|
||||||
float copySleep;
|
float copySleep;
|
||||||
ID3D12Device ** device;
|
ID3D12Device ** device;
|
||||||
ID3D12CommandQueue ** commandQueue;
|
ID3D12CommandQueue ** commandQueue;
|
||||||
ID3D12Resource ** src;
|
|
||||||
struct D3D12Texture * texture;
|
struct D3D12Texture * texture;
|
||||||
UINT64 fenceValue;
|
UINT64 fenceValue;
|
||||||
ID3D12Fence ** fence;
|
ID3D12Fence ** fence;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
|
|
||||||
// shared handle cache
|
// shared handle cache
|
||||||
struct
|
struct SharedCache sharedCache[10];
|
||||||
{
|
int sharedCacheCount;
|
||||||
ID3D11Texture2D * tex;
|
|
||||||
HANDLE handle;
|
|
||||||
}
|
|
||||||
handleCache[10];
|
|
||||||
int handleCacheCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct DXGIInterface * dxgi = NULL;
|
static struct DXGIInterface * dxgi = NULL;
|
||||||
@ -283,8 +283,7 @@ static bool d3d12_create(struct DXGIInterface * intf)
|
|||||||
dxgi->texture[i].impl = this->texture + i;
|
dxgi->texture[i].impl = this->texture + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
comRef_newGlobal(&this->src);
|
// dxgi->useAcquireLock = false;
|
||||||
dxgi->useAcquireLock = false;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -310,9 +309,6 @@ static void d3d12_free(void)
|
|||||||
if (this->event)
|
if (this->event)
|
||||||
CloseHandle(this->event);
|
CloseHandle(this->event);
|
||||||
|
|
||||||
for(int i = 0; i < this->handleCacheCount; ++i)
|
|
||||||
CloseHandle(this->handleCache[i].handle);
|
|
||||||
|
|
||||||
free(this);
|
free(this);
|
||||||
this = NULL;
|
this = NULL;
|
||||||
}
|
}
|
||||||
@ -324,25 +320,24 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
struct D3D12Texture * tex = parent->impl;
|
struct D3D12Texture * tex = parent->impl;
|
||||||
bool fail = true;
|
bool fail = true;
|
||||||
comRef_defineLocal(IDXGIResource1, res1);
|
comRef_defineLocal(IDXGIResource1, res1);
|
||||||
|
ID3D12Resource * d12src = NULL;
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
if (this->copySleep > 0)
|
if (this->copySleep > 0)
|
||||||
nsleep((uint64_t)(this->copySleep * 1000000));
|
nsleep((uint64_t)(this->copySleep * 1000000));
|
||||||
|
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
if (this->sharedCacheCount > -1)
|
||||||
|
|
||||||
if (this->handleCacheCount > -1)
|
|
||||||
{
|
{
|
||||||
// see if there is a cached handle already available for this texture
|
// see if there is a cached handle already available for this texture
|
||||||
for(int i = 0; i < this->handleCacheCount; ++i)
|
for(int i = 0; i < this->sharedCacheCount; ++i)
|
||||||
if (this->handleCache[i].tex == src)
|
if (this->sharedCache[i].tex == src)
|
||||||
{
|
{
|
||||||
handle = this->handleCache[i].handle;
|
d12src = *this->sharedCache[i].d12src;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (!d12src)
|
||||||
{
|
{
|
||||||
status = ID3D11Texture2D_QueryInterface(src,
|
status = ID3D11Texture2D_QueryInterface(src,
|
||||||
&IID_IDXGIResource1, (void **)res1);
|
&IID_IDXGIResource1, (void **)res1);
|
||||||
@ -353,47 +348,48 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE handle;
|
||||||
status = IDXGIResource1_CreateSharedHandle(*res1,
|
status = IDXGIResource1_CreateSharedHandle(*res1,
|
||||||
NULL, DXGI_SHARED_RESOURCE_READ, NULL, &handle);
|
NULL, DXGI_SHARED_RESOURCE_READ, NULL, &handle);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
||||||
fail = true;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the handle for later use
|
status = ID3D12Device_OpenSharedHandle(*this->device,
|
||||||
if (this->handleCacheCount < ARRAY_LENGTH(this->handleCache))
|
handle, &IID_ID3D12Resource, (void **)&d12src);
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
this->handleCache[this->handleCacheCount].tex = src;
|
DEBUG_WINERROR("Failed to open the shared handle for texture", status);
|
||||||
this->handleCache[this->handleCacheCount].handle = handle;
|
goto cleanup;
|
||||||
++this->handleCacheCount;
|
}
|
||||||
|
|
||||||
|
// store the texture for later use
|
||||||
|
if (this->sharedCacheCount < ARRAY_LENGTH(this->sharedCache))
|
||||||
|
{
|
||||||
|
struct SharedCache *cache = &this->sharedCache[this->sharedCacheCount++];
|
||||||
|
cache->tex = src;
|
||||||
|
*comRef_newGlobal(&cache->d12src) = (IUnknown *)d12src;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// too many handles to cache, disable the cache entirely
|
// too many handles to cache, disable the cache entirely
|
||||||
for(int i = 0; i < this->handleCacheCount; ++i)
|
for(int i = 0; i < this->sharedCacheCount; ++i)
|
||||||
CloseHandle(this->handleCache[i].handle);
|
{
|
||||||
this->handleCacheCount = -1;
|
struct SharedCache *cache = &this->sharedCache[this->sharedCacheCount++];
|
||||||
|
comRef_release(cache->d12src);
|
||||||
|
}
|
||||||
|
this->sharedCacheCount = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ID3D12Device_OpenSharedHandle(*this->device,
|
|
||||||
handle, &IID_ID3D12Resource, (void **)this->src);
|
|
||||||
|
|
||||||
if (this->handleCacheCount == -1)
|
|
||||||
CloseHandle(handle);
|
|
||||||
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
|
||||||
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLoc =
|
D3D12_TEXTURE_COPY_LOCATION srcLoc =
|
||||||
{
|
{
|
||||||
.pResource = *this->src,
|
.pResource = d12src,
|
||||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
.SubresourceIndex = 0
|
.SubresourceIndex = 0
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user