mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 06:47:19 +00:00
dxgi: cache shared handles instead of re-creating them
This will cache up to 10 handles, in practice I have never seen DXGI return anything but the same resource each time but we allow for more anyway should MS change something in the future. Should the cache get over filled it is disabled entirely and we revert to the original behaviour.
This commit is contained in:
parent
04ae9217e8
commit
cff64ee7d3
@ -26,6 +26,7 @@
|
|||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "common/windebug.h"
|
#include "common/windebug.h"
|
||||||
|
#include "common/array.h"
|
||||||
#include "ods_capture.h"
|
#include "ods_capture.h"
|
||||||
|
|
||||||
#define ALIGN_TO(value, align) (((value) + (align) - 1) & -(align))
|
#define ALIGN_TO(value, align) (((value) + (align) - 1) & -(align))
|
||||||
@ -52,6 +53,15 @@ struct D3D12Backend
|
|||||||
UINT64 fenceValue;
|
UINT64 fenceValue;
|
||||||
ID3D12Fence * fence;
|
ID3D12Fence * fence;
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
|
|
||||||
|
// shared handle cache
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ID3D11Texture2D * tex;
|
||||||
|
HANDLE handle;
|
||||||
|
}
|
||||||
|
handleCache[10];
|
||||||
|
int handleCacheCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct DXGIInterface * dxgi = NULL;
|
static struct DXGIInterface * dxgi = NULL;
|
||||||
@ -289,6 +299,9 @@ static void d3d12_free(void)
|
|||||||
if (this->src)
|
if (this->src)
|
||||||
ID3D12Resource_Release(this->src);
|
ID3D12Resource_Release(this->src);
|
||||||
|
|
||||||
|
for(int i = 0; i < this->handleCacheCount; ++i)
|
||||||
|
CloseHandle(this->handleCache[i].handle);
|
||||||
|
|
||||||
if (this->commandQueue)
|
if (this->commandQueue)
|
||||||
ID3D12CommandQueue_Release(this->commandQueue);
|
ID3D12CommandQueue_Release(this->commandQueue);
|
||||||
|
|
||||||
@ -309,33 +322,63 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||||||
if (this->copySleep > 0)
|
if (this->copySleep > 0)
|
||||||
Sleep(this->copySleep);
|
Sleep(this->copySleep);
|
||||||
|
|
||||||
status = ID3D11Texture2D_QueryInterface(src, &IID_IDXGIResource1, (void **)&res1);
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
if (FAILED(status))
|
|
||||||
|
if (this->handleCacheCount > -1)
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to get IDXGIResource1 from texture", status);
|
// see if there is a cached handle already available for this texture
|
||||||
return CAPTURE_RESULT_ERROR;
|
for(int i = 0; i < this->handleCacheCount; ++i)
|
||||||
|
if (this->handleCache[i].tex == src)
|
||||||
|
{
|
||||||
|
handle = this->handleCache[i].handle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE handle;
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
status = IDXGIResource1_CreateSharedHandle(res1, NULL, DXGI_SHARED_RESOURCE_READ, NULL, &handle);
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
{
|
||||||
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
status = ID3D11Texture2D_QueryInterface(src, &IID_IDXGIResource1, (void **)&res1);
|
||||||
fail = true;
|
if (FAILED(status))
|
||||||
goto cleanup;
|
{
|
||||||
|
DEBUG_WINERROR("Failed to get IDXGIResource1 from texture", status);
|
||||||
|
return CAPTURE_RESULT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = IDXGIResource1_CreateSharedHandle(res1, NULL, DXGI_SHARED_RESOURCE_READ, NULL, &handle);
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
||||||
|
fail = true;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the handle for later use
|
||||||
|
if (this->handleCacheCount < ARRAY_LENGTH(this->handleCache))
|
||||||
|
{
|
||||||
|
this->handleCache[this->handleCacheCount].tex = src;
|
||||||
|
this->handleCache[this->handleCacheCount].handle = handle;
|
||||||
|
++this->handleCacheCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// too many handles to cache, disable the cache entirely
|
||||||
|
for(int i = 0; i < this->handleCacheCount; ++i)
|
||||||
|
CloseHandle(this->handleCache[i].handle);
|
||||||
|
this->handleCacheCount = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ID3D12Device_OpenSharedHandle(this->device, handle, &IID_ID3D12Resource, (void **)&this->src);
|
status = ID3D12Device_OpenSharedHandle(this->device, handle, &IID_ID3D12Resource, (void **)&this->src);
|
||||||
|
if (this->handleCacheCount == -1)
|
||||||
|
CloseHandle(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);
|
||||||
CloseHandle(handle);
|
|
||||||
fail = true;
|
fail = true;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(handle);
|
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLoc = {
|
D3D12_TEXTURE_COPY_LOCATION srcLoc = {
|
||||||
.pResource = this->src,
|
.pResource = this->src,
|
||||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||||
|
Loading…
Reference in New Issue
Block a user