mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-14 04:57:54 +00:00
[host] dxgi: add preRelease callback
This is meant to avoid freeing the texture before the copy has finished.
This commit is contained in:
parent
5a93f1e00c
commit
68e5b812a9
4 changed files with 74 additions and 8 deletions
|
@ -188,6 +188,11 @@ static void d3d11_unmapTexture(Texture * tex)
|
|||
tex->map = NULL;
|
||||
}
|
||||
|
||||
static void d3d11_preRelease(void)
|
||||
{
|
||||
// Nothing needs to be done.
|
||||
}
|
||||
|
||||
struct DXGICopyBackend copyBackendD3D11 = {
|
||||
.name = "Direct3D 11",
|
||||
.create = d3d11_create,
|
||||
|
@ -195,4 +200,5 @@ struct DXGICopyBackend copyBackendD3D11 = {
|
|||
.copyFrame = d3d11_copyFrame,
|
||||
.mapTexture = d3d11_mapTexture,
|
||||
.unmapTexture = d3d11_unmapTexture,
|
||||
.preRelease = d3d11_preRelease,
|
||||
};
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
struct D3D12Texture
|
||||
{
|
||||
ID3D12Resource * src;
|
||||
ID3D12Resource * tex;
|
||||
ID3D12CommandAllocator * commandAllocator;
|
||||
ID3D12CommandList * commandList;
|
||||
|
@ -43,7 +42,11 @@ struct D3D12Backend
|
|||
{
|
||||
ID3D12Device * device;
|
||||
ID3D12CommandQueue * commandQueue;
|
||||
ID3D12Resource * src;
|
||||
struct D3D12Texture * texture;
|
||||
UINT64 fenceValue;
|
||||
ID3D12Fence * fence;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
static struct DXGIInterface * dxgi = NULL;
|
||||
|
@ -122,6 +125,22 @@ static bool d3d12_create(struct DXGIInterface * intf)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
this->event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
if (!this->event)
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create capture event", status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
this->fenceValue = 0;
|
||||
status = ID3D12Device_CreateFence(this->device, 0, D3D12_FENCE_FLAG_NONE,
|
||||
&IID_ID3D12Fence, (void **)&this->fence);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to create capture fence", status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES readbackHeapProperties = {
|
||||
.Type = D3D12_HEAP_TYPE_READBACK,
|
||||
};
|
||||
|
@ -232,6 +251,15 @@ static void d3d12_free(void)
|
|||
free(this->texture);
|
||||
}
|
||||
|
||||
if (this->fence)
|
||||
ID3D12Fence_Release(this->fence);
|
||||
|
||||
if (this->event)
|
||||
CloseHandle(this->event);
|
||||
|
||||
if (this->src)
|
||||
ID3D12Resource_Release(this->src);
|
||||
|
||||
if (this->commandQueue)
|
||||
ID3D12CommandQueue_Release(this->commandQueue);
|
||||
|
||||
|
@ -265,7 +293,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
status = ID3D12Device_OpenSharedHandle(this->device, handle, &IID_ID3D12Resource, (void **)&tex->src);
|
||||
status = ID3D12Device_OpenSharedHandle(this->device, handle, &IID_ID3D12Resource, (void **)&this->src);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to get create shared handle for texture", status);
|
||||
|
@ -277,7 +305,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||
CloseHandle(handle);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLoc = {
|
||||
.pResource = tex->src,
|
||||
.pResource = this->src,
|
||||
.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
.SubresourceIndex = 0
|
||||
};
|
||||
|
@ -324,10 +352,27 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||
|
||||
ID3D12CommandQueue_ExecuteCommandLists(this->commandQueue, 1, &tex->commandList);
|
||||
|
||||
status = ID3D12CommandQueue_Signal(this->commandQueue, this->fence, ++this->fenceValue);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to signal capture fence", status);
|
||||
fail = true;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ResetEvent(this->event);
|
||||
status = ID3D12Fence_SetEventOnCompletion(this->fence, this->fenceValue, this->event);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to signal capture fence event", status);
|
||||
fail = true;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = ID3D12CommandQueue_Signal(this->commandQueue, tex->fence, ++tex->fenceValue);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to signal fence", status);
|
||||
DEBUG_WINERROR("Failed to signal texture fence", status);
|
||||
fail = true;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -335,7 +380,7 @@ static bool d3d12_copyFrame(Texture * parent, ID3D11Texture2D * src)
|
|||
status = ID3D12Fence_SetEventOnCompletion(tex->fence, tex->fenceValue, tex->event);
|
||||
if (FAILED(status))
|
||||
{
|
||||
DEBUG_WINERROR("Failed to signal fence event", status);
|
||||
DEBUG_WINERROR("Failed to signal texture fence event", status);
|
||||
fail = true;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -367,8 +412,6 @@ static CaptureResult d3d12_mapTexture(Texture * parent)
|
|||
return CAPTURE_RESULT_ERROR;
|
||||
}
|
||||
|
||||
ID3D12Resource_Release(tex->src);
|
||||
|
||||
D3D12_RANGE range = { .Begin = 0, .End = dxgi->pitch * dxgi->height };
|
||||
status = ID3D12Resource_Map(tex->tex, 0, &range, &parent->map);
|
||||
|
||||
|
@ -390,6 +433,17 @@ static void d3d12_unmapTexture(Texture * parent)
|
|||
parent->map = NULL;
|
||||
}
|
||||
|
||||
static void d3d12_preRelease(void)
|
||||
{
|
||||
WaitForSingleObject(this->event, INFINITE);
|
||||
|
||||
if (this->src)
|
||||
{
|
||||
ID3D12Resource_Release(this->src);
|
||||
this->src = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct DXGICopyBackend copyBackendD3D12 = {
|
||||
.name = "Direct3D 12",
|
||||
.create = d3d12_create,
|
||||
|
@ -397,4 +451,5 @@ struct DXGICopyBackend copyBackendD3D12 = {
|
|||
.copyFrame = d3d12_copyFrame,
|
||||
.mapTexture = d3d12_mapTexture,
|
||||
.unmapTexture = d3d12_unmapTexture,
|
||||
.preRelease = d3d12_preRelease,
|
||||
};
|
||||
|
|
|
@ -539,6 +539,9 @@ static bool dxgi_deinit(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (this->dup)
|
||||
dxgi_releaseFrame();
|
||||
|
||||
if (this->backend)
|
||||
{
|
||||
this->backend->free();
|
||||
|
@ -553,7 +556,6 @@ static bool dxgi_deinit(void)
|
|||
|
||||
if (this->dup)
|
||||
{
|
||||
dxgi_releaseFrame();
|
||||
IDXGIOutputDuplication_Release(this->dup);
|
||||
this->dup = NULL;
|
||||
}
|
||||
|
@ -1036,6 +1038,8 @@ static CaptureResult dxgi_releaseFrame(void)
|
|||
if (!this->needsRelease)
|
||||
return CAPTURE_RESULT_OK;
|
||||
|
||||
this->backend->preRelease();
|
||||
|
||||
HRESULT status;
|
||||
LOCKED({status = IDXGIOutputDuplication_ReleaseFrame(this->dup);});
|
||||
switch(status)
|
||||
|
|
|
@ -113,6 +113,7 @@ struct DXGICopyBackend
|
|||
bool (*copyFrame)(Texture * tex, ID3D11Texture2D * src);
|
||||
CaptureResult (*mapTexture)(Texture * tex);
|
||||
void (*unmapTexture)(Texture * tex);
|
||||
void (*preRelease)(void);
|
||||
};
|
||||
|
||||
const char * GetDXGIFormatStr(DXGI_FORMAT format);
|
||||
|
|
Loading…
Reference in a new issue