cancel
Showing results for 
Search instead for 
Did you mean: 

OpenGL & Vulkan

ockey
Journeyman III

NV_DX_interop2 leak in amd gpu

hello:

     I use NV_DX_interop2  to do some render with d3d11 and opengl.

I found it will be leak when app quit.(driver version is newest :
21.30.25.05-211005a-372545C-RadeonSoftware)

my gpu is rx560 and r7 200s

i suppose it will happen on any amd gpu.

the output of the ide show :

D3D11 WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Producer at 0x000001CD02A45D20, Refcount: 6. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02D6E8F0, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02CE9D90, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02C31F80, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02C2B2C0, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02EE6820, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD7D719020, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02CAEEE0, Refcount: 0. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02C86E50, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02C87230, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object at 0x000001CD02D6D540, Refcount: 1. [ STATE_CREATION WARNING #0: UNKNOWN]
D3D11 WARNING: Live Object : 10 [ STATE_CREATION WARNING #0: UNKNOWN]
DXGI WARNING: Live Producer at 0x000001CD029EA0A8, Refcount: 2. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live Object at 0x000001CD02CAB330, Refcount: 1. [ STATE_CREATION WARNING #0: ]
DXGI WARNING: Live Object : 1 [ STATE_CREATION WARNING #0: ]

and i found that, if i call wglDXLockObjectsNV ,driver? will create 2 d3d11Buffer but no release when i call wglDXUnlockObjectsNV

it only happen in amd cpu, nvidia and intel's gpu is work well.

I write an sample code :

#include "stdafx.h"
#include <atlbase.h>
#define COBJMACROS
#define INITGUID

#include <intrin.h>
#include <windows.h>
#include <d3d11.h>
#include <gl/GL.h>
#include <AccCtrl.h>
#include "glext.h"
#include "wglext.h"


#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "opengl32.lib")

#define Assert(cond) do { if (!(cond)) __debugbreak(); } while (0)
#define AssertHR(hr) Assert(SUCCEEDED(hr))

static GLuint glTexId;

static HANDLE dxDevice;
static HANDLE dxColor;

static CComPtr<ID3D11Device> device;

static PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV;
static PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV;
static PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV;
static PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV;
static PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV;
static PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV;

static PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
static PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
static PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
static PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
static PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
static PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;

static HWND temp;
static HDC tempdc;
static HGLRC temprc;

static void Create(HWND window)
{
// GL context on temporary window, no drawing will happen to this window
{
temp = CreateWindowA("STATIC", "temp", WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL);
Assert(temp);

tempdc = GetDC(temp);
Assert(tempdc);

PIXELFORMATDESCRIPTOR pfd =
{
pfd.nSize = sizeof(pfd),
pfd.nVersion = 1,
pfd.dwFlags = PFD_SUPPORT_OPENGL,
pfd.iPixelType = PFD_TYPE_RGBA,
pfd.iLayerType = PFD_MAIN_PLANE,
};

int format = ChoosePixelFormat(tempdc, &pfd);
Assert(format);

DescribePixelFormat(tempdc, format, sizeof(pfd), &pfd);
BOOL set = SetPixelFormat(tempdc, format, &pfd);
Assert(set);

temprc = wglCreateContext(tempdc);
Assert(temprc);

BOOL make = wglMakeCurrent(tempdc, temprc);
Assert(make);

PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");

int attrib[] =
{
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0,
};

HGLRC newrc = wglCreateContextAttribsARB(tempdc, NULL, attrib);
Assert(newrc);

make = wglMakeCurrent(tempdc, newrc);
Assert(make);

wglDeleteContext(temprc);
temprc = newrc;

glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}

wglDXOpenDeviceNV = (PFNWGLDXOPENDEVICENVPROC)wglGetProcAddress("wglDXOpenDeviceNV");
wglDXCloseDeviceNV = (PFNWGLDXCLOSEDEVICENVPROC)wglGetProcAddress("wglDXCloseDeviceNV");

wglDXRegisterObjectNV = (PFNWGLDXREGISTEROBJECTNVPROC)wglGetProcAddress("wglDXRegisterObjectNV");
wglDXUnregisterObjectNV = (PFNWGLDXUNREGISTEROBJECTNVPROC)wglGetProcAddress("wglDXUnregisterObjectNV");

wglDXLockObjectsNV = (PFNWGLDXLOCKOBJECTSNVPROC)wglGetProcAddress("wglDXLockObjectsNV");
wglDXUnlockObjectsNV = (PFNWGLDXUNLOCKOBJECTSNVPROC)wglGetProcAddress("wglDXUnlockObjectsNV");

glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)wglGetProcAddress("glGenFramebuffers");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)wglGetProcAddress("glDeleteFramebuffers");

glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)wglGetProcAddress("glGenRenderbuffers");
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress("glDeleteRenderbuffers");

glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)wglGetProcAddress("glBindFramebuffer");
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress("glFramebufferRenderbuffer");

}

int main()
{
WNDCLASSA wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "DXGL";
// Register the window cass
::RegisterClassA(&wc);

HWND window = CreateWindowA(wc.lpszClassName, "DXGL",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
Assert(window);
Create(window);

const D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1 };
D3D11CreateDevice(nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
D3D11_CREATE_DEVICE_DEBUG,
levels,
ARRAYSIZE(levels),
D3D11_SDK_VERSION,
&device,
nullptr,
nullptr);
dxDevice = wglDXOpenDeviceNV(device);

glGenTextures(1, &glTexId);

CComPtr<ID3D11Texture2D> interopD3DTexture2D;
D3D11_TEXTURE2D_DESC description;
description.Width = 1920;
description.Height = 1080;
description.MipLevels = 1;
description.ArraySize = 1;
description.SampleDesc.Count = 1;
description.SampleDesc.Quality = 0;
description.MiscFlags = 0;
description.BindFlags = D3D11_BIND_RENDER_TARGET;
description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
description.CPUAccessFlags = 0;
description.Usage = D3D11_USAGE_DEFAULT;
device->CreateTexture2D(&description, NULL, &interopD3DTexture2D);
dxColor = wglDXRegisterObjectNV(dxDevice,interopD3DTexture2D,glTexId,GL_TEXTURE_2D,/*WGL_ACCESS_READ_ONLY_NV*/0x00000000);

HANDLE dxObjects[] = { dxColor };
wglDXLockObjectsNV(dxDevice, _countof(dxObjects), dxObjects);
wglDXUnlockObjectsNV(dxDevice, _countof(dxObjects), dxObjects);

wglDXUnregisterObjectNV(dxDevice, dxColor);
glDeleteTextures(1, &glTexId);
wglDXCloseDeviceNV(dxDevice);

wglMakeCurrent(tempdc, NULL);
wglDeleteContext(temprc);
ReleaseDC(temp, tempdc);
}

#include "glext.h" // https://www.opengl.org/registry/api/GL/glext.h

#include "wglext.h" // https://www.opengl.org/registry/api/GL/wglext.h

2 Replies
leadedge
Journeyman III

Hello to all,

I manage a library that depends on the NV_DX_interop2 extensions.

I can confirm these findings with a Radeon R9 200 / HD 7900 with the same driver version 21.5.2. I can't confirm with other AMD hardware, but can say that there is no leak with Nvidia Geforce GT 640 or RTX 2060. I reproduced the sample code and find the same result.

This was an issue quite some time back in 2014 with Nvidia, but at that time it was resolved. It appears to have re-emerged with AMD.

 

Hi @ockey ,

Thank you for reporting the issue and providing the reproducible test-case

I have reported the issue to the DX team. As I have been informed, a ticket has been opened to investigate the issue in detail. I will notify you if I get any update on this.

Also, thanks @leadedge for testing the sample code and sharing your feedback.

 

Thanks.