DX11: Fixed refcount checks on release.

This commit is contained in:
bkaradzic 2013-10-18 22:34:23 -07:00
parent 7654826ffa
commit dcd0452d82
5 changed files with 50 additions and 30 deletions

View file

@ -187,6 +187,7 @@ namespace bgfx
static CallbackStub* s_callbackStub = NULL; static CallbackStub* s_callbackStub = NULL;
static AllocatorStub* s_allocatorStub = NULL; static AllocatorStub* s_allocatorStub = NULL;
static bool s_graphicsDebuggerPresent = false;
CallbackI* g_callback = NULL; CallbackI* g_callback = NULL;
bx::ReallocatorI* g_allocator = NULL; bx::ReallocatorI* g_allocator = NULL;
@ -201,6 +202,17 @@ namespace bgfx
return NULL != s_ctx; return NULL != s_ctx;
} }
void setGraphicsDebuggerPresent(bool _present)
{
BX_TRACE("Graphics debugger is %spresent.", _present ? "" : "not ");
s_graphicsDebuggerPresent = _present;
}
bool isGraphicsDebuggerPresent()
{
return s_graphicsDebuggerPresent;
}
void fatal(Fatal::Enum _code, const char* _format, ...) void fatal(Fatal::Enum _code, const char* _format, ...)
{ {
char temp[8192]; char temp[8192];

View file

@ -229,6 +229,8 @@ namespace bgfx
extern bx::ReallocatorI* g_allocator; extern bx::ReallocatorI* g_allocator;
extern Caps g_caps; extern Caps g_caps;
void setGraphicsDebuggerPresent(bool _present);
bool isGraphicsDebuggerPresent();
void release(const Memory* _mem); void release(const Memory* _mem);
const char* getAttribName(Attrib::Enum _attr); const char* getAttribName(Attrib::Enum _attr);
bool renderFrame(); bool renderFrame();

View file

@ -30,12 +30,33 @@ namespace bgfx
); \ ); \
} while (0) } while (0)
#define _DX_RELEASE(_ptr, _expected, _check) \
do { \
if (NULL != _ptr) \
{ \
ULONG count = _ptr->Release(); \
_check(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); BX_UNUSED(count); \
_ptr = NULL; \
} \
} while (0)
# define _DX_CHECK_REFCOUNT(_ptr, _expected) \
do { \
ULONG count = getRefCount(_ptr); \
BX_CHECK(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); \
} while (0)
#if BGFX_CONFIG_DEBUG #if BGFX_CONFIG_DEBUG
# define DX_CHECK(_call) _DX_CHECK(_call) # define DX_CHECK(_call) _DX_CHECK(_call)
# define DX_CHECK_REFCOUNT(_ptr, _expected) _DX_CHECK_REFCOUNT(_ptr, _expected)
#else #else
# define DX_CHECK(_call) _call # define DX_CHECK(_call) _call
# define DX_CHECK_REFCOUNT(_ptr, _expected)
#endif // BGFX_CONFIG_DEBUG #endif // BGFX_CONFIG_DEBUG
#define DX_RELEASE(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_CHECK)
#define DX_RELEASE_WARNONLY(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_WARN)
typedef int (WINAPI *D3DPERF_BeginEventFunc)(DWORD _color, LPCWSTR _wszName); typedef int (WINAPI *D3DPERF_BeginEventFunc)(DWORD _color, LPCWSTR _wszName);
typedef int (WINAPI *D3DPERF_EndEventFunc)(); typedef int (WINAPI *D3DPERF_EndEventFunc)();
typedef void (WINAPI *D3DPERF_SetMarkerFunc)(DWORD _color, LPCWSTR _wszName); typedef void (WINAPI *D3DPERF_SetMarkerFunc)(DWORD _color, LPCWSTR _wszName);
@ -58,30 +79,6 @@ namespace bgfx
# define PIX_ENDEVENT() # define PIX_ENDEVENT()
#endif // BGFX_CONFIG_DEBUG_PIX #endif // BGFX_CONFIG_DEBUG_PIX
#if BGFX_CONFIG_DEBUG
# define DX_CHECK_REFCOUNT(_ptr, _expected) \
do { \
ULONG count = getRefCount(_ptr); \
BX_CHECK(_expected == count, "RefCount is %d (expected %d).", count, _expected); \
} while (0)
#else
# define DX_CHECK_REFCOUNT(_ptr, _expected)
#endif // BGFX_CONFIG_DEBUG
#define _DX_RELEASE(_ptr, _expected, _check) \
do { \
if (NULL != _ptr) \
{ \
ULONG count = _ptr->Release(); \
_check(_expected == count, "RefCount is %d (expected %d).", count, _expected); BX_UNUSED(count); \
_ptr = NULL; \
} \
} while (0)
#define DX_RELEASE(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_CHECK)
#define DX_RELEASE_WARNONLY(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_WARN)
inline int getRefCount(IUnknown* _interface) inline int getRefCount(IUnknown* _interface)
{ {
_interface->AddRef(); _interface->AddRef();

View file

@ -66,7 +66,7 @@ namespace bgfx
static const D3D11_COMPARISON_FUNC s_depthFunc[] = static const D3D11_COMPARISON_FUNC s_depthFunc[] =
{ {
D3D11_COMPARISON_LESS, // ignored D3D11_COMPARISON_FUNC(0), // ignored
D3D11_COMPARISON_LESS, D3D11_COMPARISON_LESS,
D3D11_COMPARISON_LESS_EQUAL, D3D11_COMPARISON_LESS_EQUAL,
D3D11_COMPARISON_EQUAL, D3D11_COMPARISON_EQUAL,
@ -79,7 +79,7 @@ namespace bgfx
static const D3D11_COMPARISON_FUNC s_stencilFunc[] = static const D3D11_COMPARISON_FUNC s_stencilFunc[] =
{ {
D3D11_COMPARISON_LESS, // ignored D3D11_COMPARISON_FUNC(0), // ignored
D3D11_COMPARISON_LESS, D3D11_COMPARISON_LESS,
D3D11_COMPARISON_LESS_EQUAL, D3D11_COMPARISON_LESS_EQUAL,
D3D11_COMPARISON_EQUAL, D3D11_COMPARISON_EQUAL,
@ -456,8 +456,9 @@ namespace bgfx
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
// GPA increases device ref count and triggers assert in debug // GPA increases device ref count and triggers assert in debug
// build. Warn only instead. // build. Set flag to disable reference count checks.
DX_RELEASE_WARNONLY(device, 2); setGraphicsDebuggerPresent(3 < getRefCount(device) );
DX_RELEASE(device, 2);
hr = adapter->GetDesc(&m_adapterDesc); hr = adapter->GetDesc(&m_adapterDesc);
BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");

View file

@ -43,7 +43,7 @@ namespace bgfx
HashMap::iterator it = m_hashMap.find(_id); HashMap::iterator it = m_hashMap.find(_id);
if (it != m_hashMap.end() ) if (it != m_hashMap.end() )
{ {
DX_RELEASE(it->second, 0); DX_RELEASE_WARNONLY(it->second, 0);
m_hashMap.erase(it); m_hashMap.erase(it);
} }
} }
@ -52,8 +52,16 @@ namespace bgfx
{ {
for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it) for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
{ {
DX_RELEASE(it->second, 0); it->second->Release();
} }
#if BGFX_CONFIG_DEBUG
for (HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
{
DX_CHECK_REFCOUNT(it->second, 0);
}
#endif // BGFX_CONFIG_DEBUG
m_hashMap.clear(); m_hashMap.clear();
} }