bgfx/src/renderer_d3d.h

320 lines
7.6 KiB
C
Raw Normal View History

2013-02-22 00:07:31 -05:00
/*
2015-01-01 18:04:46 -05:00
* Copyright 2011-2015 Branimir Karadzic. All rights reserved.
2013-02-22 00:07:31 -05:00
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#ifndef BGFX_RENDERER_D3D_H_HEADER_GUARD
#define BGFX_RENDERER_D3D_H_HEADER_GUARD
2013-02-22 00:07:31 -05:00
#if 0 // BGFX_CONFIG_DEBUG && BGFX_CONFIG_RENDERER_DIRECT3D9 && !(BX_COMPILER_GCC || BX_COMPILER_CLANG)
2013-04-07 16:44:10 -04:00
# include <sal.h>
2013-02-22 00:07:31 -05:00
# include <dxerr.h>
2013-04-07 17:08:20 -04:00
# if BX_COMPILER_MSVC
# pragma comment(lib, "dxerr.lib")
# endif // BX_COMPILER_MSVC
2013-02-22 00:07:31 -05:00
# define DX_CHECK_EXTRA_F " (%s): %s"
# define DX_CHECK_EXTRA_ARGS , DXGetErrorString(__hr__), DXGetErrorDescription(__hr__)
#else
# define DX_CHECK_EXTRA_F ""
# define DX_CHECK_EXTRA_ARGS
2013-04-07 17:08:20 -04:00
#endif // BGFX_CONFIG_DEBUG && BGFX_CONFIG_RENDERER_DIRECT3D9
2013-02-22 00:07:31 -05:00
namespace bgfx
{
#define _DX_CHECK(_call) \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_BEGIN \
2013-02-22 00:07:31 -05:00
HRESULT __hr__ = _call; \
BX_CHECK(SUCCEEDED(__hr__), #_call " FAILED 0x%08x" DX_CHECK_EXTRA_F "\n" \
, (uint32_t)__hr__ \
DX_CHECK_EXTRA_ARGS \
); \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_END
2013-02-22 00:07:31 -05:00
#define _DX_RELEASE(_ptr, _expected, _check) \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_BEGIN \
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; \
} \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_END
2015-07-29 02:18:25 -04:00
#define _DX_CHECK_REFCOUNT(_ptr, _expected) \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_BEGIN \
ULONG count = getRefCount(_ptr); \
BX_CHECK(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); \
2014-06-08 23:57:39 -04:00
BX_MACRO_BLOCK_END
2015-07-29 02:18:25 -04:00
#define _DX_NAME(_ptr, _format, ...) setDebugObjectName(_ptr, _format, ##__VA_ARGS__)
2013-02-22 00:07:31 -05:00
#if BGFX_CONFIG_DEBUG
# define DX_CHECK(_call) _DX_CHECK(_call)
# define DX_CHECK_REFCOUNT(_ptr, _expected) _DX_CHECK_REFCOUNT(_ptr, _expected)
2013-02-22 00:07:31 -05:00
#else
# define DX_CHECK(_call) _call
# define DX_CHECK_REFCOUNT(_ptr, _expected)
2013-02-22 00:07:31 -05:00
#endif // BGFX_CONFIG_DEBUG
2015-07-29 02:18:25 -04:00
#if BGFX_CONFIG_DEBUG_OBJECT_NAME
# define DX_NAME(_ptr, _format, ...) _DX_NAME(_ptr, _format, ##__VA_ARGS__)
#else
# define DX_NAME(_ptr, _format, ...)
#endif // BGFX_CONFIG_DEBUG_OBJECT_NAME
#define DX_RELEASE(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_CHECK)
#define DX_RELEASE_WARNONLY(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_WARN)
2014-10-07 01:10:55 -04:00
typedef int (WINAPI* PFN_D3DPERF_BEGIN_EVENT)(DWORD _color, LPCWSTR _wszName);
typedef int (WINAPI* PFN_D3DPERF_END_EVENT)();
typedef void (WINAPI* PFN_D3DPERF_SET_MARKER)(DWORD _color, LPCWSTR _wszName);
typedef void (WINAPI* PFN_D3DPERF_SET_REGION)(DWORD _color, LPCWSTR _wszName);
typedef BOOL (WINAPI* PFN_D3DPERF_QUERY_REPEAT_FRAME)();
typedef void (WINAPI* PFN_D3DPERF_SET_OPTIONS)(DWORD _options);
typedef DWORD (WINAPI* PFN_D3DPERF_GET_STATUS)();
typedef HRESULT (WINAPI* PFN_CREATE_DXGI_FACTORY)(REFIID _riid, void** _factory);
2015-07-29 17:49:24 -04:00
typedef HRESULT (WINAPI* PFN_GET_DEBUG_INTERFACE)(REFIID _riid, void** _debug);
typedef HRESULT (WINAPI* PFN_GET_DEBUG_INTERFACE1)(UINT _flags, REFIID _riid, void** _debug);
2014-10-07 01:10:55 -04:00
#define _PIX_SETMARKER(_col, _name) D3DPERF_SetMarker(_col, _name)
#define _PIX_BEGINEVENT(_col, _name) D3DPERF_BeginEvent(_col, _name)
#define _PIX_ENDEVENT() D3DPERF_EndEvent()
#if BGFX_CONFIG_DEBUG_PIX
2014-10-26 03:55:49 -04:00
# define PIX_SETMARKER(_color, _name) _PIX_SETMARKER(_color, _name)
# define PIX_BEGINEVENT(_color, _name) _PIX_BEGINEVENT(_color, _name)
# define PIX_ENDEVENT() _PIX_ENDEVENT()
#else
2014-10-26 03:55:49 -04:00
# define PIX_SETMARKER(_color, _name) BX_UNUSED(_name)
# define PIX_BEGINEVENT(_color, _name) BX_UNUSED(_name)
# define PIX_ENDEVENT()
#endif // BGFX_CONFIG_DEBUG_PIX
2013-02-22 00:07:31 -05:00
inline int getRefCount(IUnknown* _interface)
{
_interface->AddRef();
return _interface->Release();
}
2014-10-08 01:05:35 -04:00
template <typename Ty>
class StateCacheT
{
public:
void add(uint64_t _key, Ty* _value)
2014-10-08 01:05:35 -04:00
{
invalidate(_key);
m_hashMap.insert(stl::make_pair(_key, _value) );
2014-10-08 01:05:35 -04:00
}
Ty* find(uint64_t _key)
2014-10-08 01:05:35 -04:00
{
typename HashMap::iterator it = m_hashMap.find(_key);
2014-10-08 01:05:35 -04:00
if (it != m_hashMap.end() )
{
return it->second;
}
return NULL;
}
void invalidate(uint64_t _key)
2014-10-08 01:05:35 -04:00
{
typename HashMap::iterator it = m_hashMap.find(_key);
2014-10-08 01:05:35 -04:00
if (it != m_hashMap.end() )
{
DX_RELEASE_WARNONLY(it->second, 0);
m_hashMap.erase(it);
}
}
void invalidate()
{
for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
{
DX_CHECK_REFCOUNT(it->second, 1);
it->second->Release();
}
m_hashMap.clear();
}
uint32_t getCount() const
{
return uint32_t(m_hashMap.size() );
}
private:
typedef stl::unordered_map<uint64_t, Ty*> HashMap;
HashMap m_hashMap;
};
2015-03-06 00:11:44 -05:00
class StateCache
{
public:
void add(uint64_t _key, uint16_t _value)
2015-03-06 00:11:44 -05:00
{
invalidate(_key);
m_hashMap.insert(stl::make_pair(_key, _value) );
2015-03-06 00:11:44 -05:00
}
uint16_t find(uint64_t _key)
2015-03-06 00:11:44 -05:00
{
HashMap::iterator it = m_hashMap.find(_key);
2015-07-16 23:28:43 -04:00
if (it != m_hashMap.end() )
2015-03-06 00:11:44 -05:00
{
return it->second;
}
return UINT16_MAX;
}
void invalidate(uint64_t _key)
2015-03-06 00:11:44 -05:00
{
HashMap::iterator it = m_hashMap.find(_key);
2015-07-16 23:28:43 -04:00
if (it != m_hashMap.end() )
2015-03-06 00:11:44 -05:00
{
m_hashMap.erase(it);
}
}
void invalidate()
{
m_hashMap.clear();
}
uint32_t getCount() const
{
2015-07-16 23:28:43 -04:00
return uint32_t(m_hashMap.size() );
2015-03-06 00:11:44 -05:00
}
private:
typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
HashMap m_hashMap;
};
2015-08-17 14:25:27 -04:00
template<typename Ty>
inline void release(Ty)
{
}
template<>
inline void release<IUnknown*>(IUnknown* _ptr)
{
DX_RELEASE(_ptr, 0);
}
2015-08-14 01:56:28 -04:00
template <typename Ty, uint16_t MaxHandleT>
class StateCacheLru
{
public:
void add(uint64_t _key, Ty _value, uint16_t _parent)
2015-08-14 01:56:28 -04:00
{
uint16_t handle = m_alloc.alloc();
if (UINT16_MAX == handle)
{
uint16_t back = m_alloc.getBack();
invalidate(back);
2015-08-14 01:56:28 -04:00
handle = m_alloc.alloc();
}
BX_CHECK(UINT16_MAX != handle, "Failed to find handle.");
Data& data = m_data[handle];
data.m_hash = _key;
data.m_value = _value;
data.m_parent = _parent;
m_hashMap.insert(stl::make_pair(_key, handle) );
2015-08-14 01:56:28 -04:00
}
Ty* find(uint64_t _key)
2015-08-14 01:56:28 -04:00
{
HashMap::iterator it = m_hashMap.find(_key);
2015-08-14 01:56:28 -04:00
if (it != m_hashMap.end() )
{
2015-08-14 22:32:36 -04:00
uint16_t handle = it->second;
m_alloc.touch(handle);
return &m_data[handle].m_value;
2015-08-14 01:56:28 -04:00
}
return NULL;
}
void invalidate(uint64_t _key)
{
HashMap::iterator it = m_hashMap.find(_key);
if (it != m_hashMap.end() )
{
uint16_t handle = it->second;
2015-08-17 14:25:27 -04:00
m_alloc.free(handle);
m_hashMap.erase(it);
release(m_data[handle].m_value);
}
}
void invalidate(uint16_t _handle)
{
if (m_alloc.isValid(_handle) )
{
m_alloc.free(_handle);
Data& data = m_data[_handle];
m_hashMap.erase(m_hashMap.find(data.m_hash) );
release(data.m_value);
}
}
void invalidateWithParent(uint16_t _parent)
{
2015-08-17 14:25:27 -04:00
for (uint16_t ii = 0; ii < m_alloc.getNumHandles();)
{
uint16_t handle = m_alloc.getHandleAt(ii);
Data& data = m_data[handle];
if (data.m_parent == _parent)
{
m_alloc.free(handle);
m_hashMap.erase(m_hashMap.find(data.m_hash) );
release(data.m_value);
}
else
{
++ii;
}
}
}
2015-08-14 01:56:28 -04:00
void invalidate()
{
2015-08-17 14:25:27 -04:00
for (uint16_t ii = 0, num = m_alloc.getNumHandles(); ii < num; ++ii)
{
uint16_t handle = m_alloc.getHandleAt(ii);
Data& data = m_data[handle];
release(data.m_value);
}
2015-08-14 01:56:28 -04:00
m_hashMap.clear();
m_alloc.reset();
}
uint32_t getCount() const
{
return uint32_t(m_hashMap.size() );
}
private:
typedef stl::unordered_map<uint64_t, uint16_t> HashMap;
HashMap m_hashMap;
bx::HandleAllocLruT<MaxHandleT> m_alloc;
struct Data
{
uint64_t m_hash;
Ty m_value;
uint16_t m_parent;
2015-08-14 01:56:28 -04:00
};
Data m_data[MaxHandleT];
};
2013-02-22 00:07:31 -05:00
} // namespace bgfx
#endif // BGFX_RENDERER_D3D_H_HEADER_GUARD