graphics-hook: Fix DXGI ref leak for D3D12 capture
Create ID3D11Resource dynamically to avoid reference inflation.
This commit is contained in:
parent
04788d30e2
commit
ea9df85512
@ -34,7 +34,6 @@ struct d3d12_data {
|
|||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
struct shtex_data *shtex_info;
|
struct shtex_data *shtex_info;
|
||||||
ID3D11Resource *backbuffer11[MAX_BACKBUFFERS];
|
|
||||||
UINT backbuffer_count;
|
UINT backbuffer_count;
|
||||||
UINT cur_backbuffer;
|
UINT cur_backbuffer;
|
||||||
ID3D11Texture2D *copy_tex;
|
ID3D11Texture2D *copy_tex;
|
||||||
@ -54,10 +53,6 @@ void d3d12_free(void)
|
|||||||
{
|
{
|
||||||
if (data.copy_tex)
|
if (data.copy_tex)
|
||||||
data.copy_tex->Release();
|
data.copy_tex->Release();
|
||||||
for (size_t i = 0; i < data.backbuffer_count; i++) {
|
|
||||||
if (data.backbuffer11[i])
|
|
||||||
data.backbuffer11[i]->Release();
|
|
||||||
}
|
|
||||||
if (data.device11)
|
if (data.device11)
|
||||||
data.device11->Release();
|
data.device11->Release();
|
||||||
if (data.context11)
|
if (data.context11)
|
||||||
@ -72,33 +67,14 @@ void d3d12_free(void)
|
|||||||
hlog("----------------- d3d12 capture freed ----------------");
|
hlog("----------------- d3d12 capture freed ----------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bb_info {
|
static bool create_d3d12_tex(UINT count)
|
||||||
ID3D12Resource *backbuffer[MAX_BACKBUFFERS];
|
|
||||||
UINT count;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool create_d3d12_tex(bb_info &bb)
|
|
||||||
{
|
{
|
||||||
D3D11_RESOURCE_FLAGS rf11 = {};
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!bb.count)
|
if (count == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
data.backbuffer_count = bb.count;
|
data.backbuffer_count = count;
|
||||||
|
|
||||||
for (UINT i = 0; i < bb.count; i++) {
|
|
||||||
hr = data.device11on12->CreateWrappedResource(
|
|
||||||
bb.backbuffer[i], &rf11, D3D12_RESOURCE_STATE_PRESENT,
|
|
||||||
D3D12_RESOURCE_STATE_PRESENT,
|
|
||||||
IID_PPV_ARGS(&data.backbuffer11[i]));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
hlog_hr("create_d3d12_tex: failed to create "
|
|
||||||
"backbuffer11",
|
|
||||||
hr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc11 = {};
|
D3D11_TEXTURE2D_DESC desc11 = {};
|
||||||
desc11.Width = data.cx;
|
desc11.Width = data.cx;
|
||||||
@ -206,12 +182,12 @@ static bool d3d12_init_11on12(ID3D12Device *device)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool d3d12_shtex_init(ID3D12Device *device, HWND window, bb_info &bb)
|
static bool d3d12_shtex_init(ID3D12Device *device, HWND window, UINT count)
|
||||||
{
|
{
|
||||||
if (!d3d12_init_11on12(device)) {
|
if (!d3d12_init_11on12(device)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!create_d3d12_tex(bb)) {
|
if (!create_d3d12_tex(count)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy,
|
if (!capture_init_shtex(&data.shtex_info, window, data.cx, data.cy,
|
||||||
@ -223,8 +199,7 @@ static bool d3d12_shtex_init(ID3D12Device *device, HWND window, bb_info &bb)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
|
static inline UINT d3d12_init_format(IDXGISwapChain *swap, HWND &window)
|
||||||
bb_info &bb)
|
|
||||||
{
|
{
|
||||||
DXGI_SWAP_CHAIN_DESC desc;
|
DXGI_SWAP_CHAIN_DESC desc;
|
||||||
IDXGISwapChain3 *swap3;
|
IDXGISwapChain3 *swap3;
|
||||||
@ -233,7 +208,7 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
|
|||||||
hr = swap->GetDesc(&desc);
|
hr = swap->GetDesc(&desc);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
hlog_hr("d3d12_init_format: swap->GetDesc failed", hr);
|
hlog_hr("d3d12_init_format: swap->GetDesc failed", hr);
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_swap_desc(&desc);
|
print_swap_desc(&desc);
|
||||||
@ -251,30 +226,21 @@ static inline bool d3d12_init_format(IDXGISwapChain *swap, HWND &window,
|
|||||||
swap3->Release();
|
swap3->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bb.count = desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD
|
UINT count = desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD
|
||||||
? 1
|
? 1
|
||||||
: desc.BufferCount;
|
: desc.BufferCount;
|
||||||
|
|
||||||
if (bb.count == 1)
|
if (count == 1)
|
||||||
data.dxgi_1_4 = false;
|
data.dxgi_1_4 = false;
|
||||||
|
|
||||||
if (bb.count > MAX_BACKBUFFERS) {
|
if (count > MAX_BACKBUFFERS) {
|
||||||
hlog("Somehow it's using more than the max backbuffers. "
|
hlog("Somehow it's using more than the max backbuffers. "
|
||||||
"Not sure why anyone would do that.");
|
"Not sure why anyone would do that.");
|
||||||
bb.count = 1;
|
count = 1;
|
||||||
data.dxgi_1_4 = false;
|
data.dxgi_1_4 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UINT i = 0; i < bb.count; i++) {
|
return count;
|
||||||
hr = swap->GetBuffer(i, IID_PPV_ARGS(&bb.backbuffer[i]));
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
bb.backbuffer[i]->Release();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void d3d12_init(IDXGISwapChain *swap)
|
static void d3d12_init(IDXGISwapChain *swap)
|
||||||
@ -286,14 +252,14 @@ static void d3d12_init(IDXGISwapChain *swap)
|
|||||||
(uint64_t)(uintptr_t)device);
|
(uint64_t)(uintptr_t)device);
|
||||||
|
|
||||||
HWND window;
|
HWND window;
|
||||||
bb_info bb = {};
|
UINT count = d3d12_init_format(swap, window);
|
||||||
if (d3d12_init_format(swap, window, bb)) {
|
if (count > 0) {
|
||||||
if (global_hook_info->force_shmem) {
|
if (global_hook_info->force_shmem) {
|
||||||
hlog("d3d12_init: shared memory capture currently "
|
hlog("d3d12_init: shared memory capture currently "
|
||||||
"unsupported; ignoring");
|
"unsupported; ignoring");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d3d12_shtex_init(device, window, bb))
|
if (!d3d12_shtex_init(device, window, count))
|
||||||
d3d12_free();
|
d3d12_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,16 +291,31 @@ static inline void d3d12_shtex_capture(IDXGISwapChain *swap)
|
|||||||
cur_idx = data.cur_backbuffer;
|
cur_idx = data.cur_backbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11Resource *backbuffer = data.backbuffer11[cur_idx];
|
ID3D12Resource *backbuffer12;
|
||||||
|
if (SUCCEEDED(swap->GetBuffer(cur_idx, IID_PPV_ARGS(&backbuffer12)))) {
|
||||||
|
D3D11_RESOURCE_FLAGS rf11 = {};
|
||||||
|
ID3D11Resource *backbuffer;
|
||||||
|
if (SUCCEEDED(data.device11on12->CreateWrappedResource(
|
||||||
|
backbuffer12, &rf11, D3D12_RESOURCE_STATE_PRESENT,
|
||||||
|
D3D12_RESOURCE_STATE_PRESENT,
|
||||||
|
IID_PPV_ARGS(&backbuffer)))) {
|
||||||
|
data.device11on12->AcquireWrappedResources(&backbuffer,
|
||||||
|
1);
|
||||||
|
d3d12_copy_texture(data.copy_tex, backbuffer);
|
||||||
|
data.device11on12->ReleaseWrappedResources(&backbuffer,
|
||||||
|
1);
|
||||||
|
data.context11->Flush();
|
||||||
|
|
||||||
data.device11on12->AcquireWrappedResources(&backbuffer, 1);
|
if (!dxgi_1_4) {
|
||||||
d3d12_copy_texture(data.copy_tex, backbuffer);
|
if (++data.cur_backbuffer >=
|
||||||
data.device11on12->ReleaseWrappedResources(&backbuffer, 1);
|
data.backbuffer_count)
|
||||||
data.context11->Flush();
|
data.cur_backbuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dxgi_1_4) {
|
backbuffer->Release();
|
||||||
if (++data.cur_backbuffer >= data.backbuffer_count)
|
}
|
||||||
data.cur_backbuffer = 0;
|
|
||||||
|
backbuffer12->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user