renderer_d3d.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright 2011-2020 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #ifndef BGFX_RENDERER_D3D_H_HEADER_GUARD
  6. #define BGFX_RENDERER_D3D_H_HEADER_GUARD
  7. #if 0 // BGFX_CONFIG_DEBUG && BGFX_CONFIG_RENDERER_DIRECT3D9 && !(BX_COMPILER_GCC || BX_COMPILER_CLANG)
  8. # include <sal.h>
  9. # include <dxerr.h>
  10. # if BX_COMPILER_MSVC
  11. # pragma comment(lib, "dxerr.lib")
  12. # endif // BX_COMPILER_MSVC
  13. # define DX_CHECK_EXTRA_F " (%s): %s"
  14. # define DX_CHECK_EXTRA_ARGS , DXGetErrorString(__hr__), DXGetErrorDescription(__hr__)
  15. #else
  16. # define DX_CHECK_EXTRA_F ""
  17. # define DX_CHECK_EXTRA_ARGS
  18. #endif // BGFX_CONFIG_DEBUG && BGFX_CONFIG_RENDERER_DIRECT3D9
  19. #define DXGI_FORMAT_ASTC_4X4_TYPELESS DXGI_FORMAT(133)
  20. #define DXGI_FORMAT_ASTC_4X4_UNORM DXGI_FORMAT(134)
  21. #define DXGI_FORMAT_ASTC_4X4_UNORM_SRGB DXGI_FORMAT(135)
  22. #define DXGI_FORMAT_ASTC_5X4_TYPELESS DXGI_FORMAT(137)
  23. #define DXGI_FORMAT_ASTC_5X4_UNORM DXGI_FORMAT(138)
  24. #define DXGI_FORMAT_ASTC_5X4_UNORM_SRGB DXGI_FORMAT(139)
  25. #define DXGI_FORMAT_ASTC_5X5_TYPELESS DXGI_FORMAT(141)
  26. #define DXGI_FORMAT_ASTC_5X5_UNORM DXGI_FORMAT(142)
  27. #define DXGI_FORMAT_ASTC_5X5_UNORM_SRGB DXGI_FORMAT(143)
  28. #define DXGI_FORMAT_ASTC_6X5_TYPELESS DXGI_FORMAT(145)
  29. #define DXGI_FORMAT_ASTC_6X5_UNORM DXGI_FORMAT(146)
  30. #define DXGI_FORMAT_ASTC_6X5_UNORM_SRGB DXGI_FORMAT(147)
  31. #define DXGI_FORMAT_ASTC_6X6_TYPELESS DXGI_FORMAT(149)
  32. #define DXGI_FORMAT_ASTC_6X6_UNORM DXGI_FORMAT(150)
  33. #define DXGI_FORMAT_ASTC_6X6_UNORM_SRGB DXGI_FORMAT(151)
  34. #define DXGI_FORMAT_ASTC_8X5_TYPELESS DXGI_FORMAT(153)
  35. #define DXGI_FORMAT_ASTC_8X5_UNORM DXGI_FORMAT(154)
  36. #define DXGI_FORMAT_ASTC_8X5_UNORM_SRGB DXGI_FORMAT(155)
  37. #define DXGI_FORMAT_ASTC_8X6_TYPELESS DXGI_FORMAT(157)
  38. #define DXGI_FORMAT_ASTC_8X6_UNORM DXGI_FORMAT(158)
  39. #define DXGI_FORMAT_ASTC_8X6_UNORM_SRGB DXGI_FORMAT(159)
  40. #define DXGI_FORMAT_ASTC_8X8_TYPELESS DXGI_FORMAT(161)
  41. #define DXGI_FORMAT_ASTC_8X8_UNORM DXGI_FORMAT(162)
  42. #define DXGI_FORMAT_ASTC_8X8_UNORM_SRGB DXGI_FORMAT(163)
  43. #define DXGI_FORMAT_ASTC_10X5_TYPELESS DXGI_FORMAT(165)
  44. #define DXGI_FORMAT_ASTC_10X5_UNORM DXGI_FORMAT(166)
  45. #define DXGI_FORMAT_ASTC_10X5_UNORM_SRGB DXGI_FORMAT(167)
  46. #define DXGI_FORMAT_ASTC_10X6_TYPELESS DXGI_FORMAT(169)
  47. #define DXGI_FORMAT_ASTC_10X6_UNORM DXGI_FORMAT(170)
  48. #define DXGI_FORMAT_ASTC_10X6_UNORM_SRGB DXGI_FORMAT(171)
  49. #define DXGI_FORMAT_ASTC_10X8_TYPELESS DXGI_FORMAT(173)
  50. #define DXGI_FORMAT_ASTC_10X8_UNORM DXGI_FORMAT(174)
  51. #define DXGI_FORMAT_ASTC_10X8_UNORM_SRGB DXGI_FORMAT(175)
  52. #define DXGI_FORMAT_ASTC_10X10_TYPELESS DXGI_FORMAT(177)
  53. #define DXGI_FORMAT_ASTC_10X10_UNORM DXGI_FORMAT(178)
  54. #define DXGI_FORMAT_ASTC_10X10_UNORM_SRGB DXGI_FORMAT(179)
  55. #define DXGI_FORMAT_ASTC_12X10_TYPELESS DXGI_FORMAT(181)
  56. #define DXGI_FORMAT_ASTC_12X10_UNORM DXGI_FORMAT(182)
  57. #define DXGI_FORMAT_ASTC_12X10_UNORM_SRGB DXGI_FORMAT(183)
  58. #define DXGI_FORMAT_ASTC_12X12_TYPELESS DXGI_FORMAT(185)
  59. #define DXGI_FORMAT_ASTC_12X12_UNORM DXGI_FORMAT(186)
  60. #define DXGI_FORMAT_ASTC_12X12_UNORM_SRGB DXGI_FORMAT(187)
  61. namespace bgfx
  62. {
  63. #if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
  64. typedef ::IUnknown IUnknown;
  65. #else
  66. typedef ::IGraphicsUnknown IUnknown;
  67. #endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
  68. #define _DX_CHECK(_call) \
  69. BX_MACRO_BLOCK_BEGIN \
  70. HRESULT __hr__ = _call; \
  71. BX_CHECK(SUCCEEDED(__hr__), #_call " FAILED 0x%08x" DX_CHECK_EXTRA_F "\n" \
  72. , (uint32_t)__hr__ \
  73. DX_CHECK_EXTRA_ARGS \
  74. ); \
  75. BX_MACRO_BLOCK_END
  76. #define _DX_RELEASE(_ptr, _expected, _check) \
  77. BX_MACRO_BLOCK_BEGIN \
  78. if (NULL != (_ptr) ) \
  79. { \
  80. ULONG count = (_ptr)->Release(); \
  81. _check(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); BX_UNUSED(count); \
  82. _ptr = NULL; \
  83. } \
  84. BX_MACRO_BLOCK_END
  85. #define _DX_CHECK_REFCOUNT(_ptr, _expected) \
  86. BX_MACRO_BLOCK_BEGIN \
  87. ULONG count = getRefCount(_ptr); \
  88. BX_CHECK(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); \
  89. BX_MACRO_BLOCK_END
  90. #define _DX_NAME(_ptr, _format, ...) setDebugObjectName(_ptr, _format, ##__VA_ARGS__)
  91. #if BGFX_CONFIG_DEBUG
  92. # define DX_CHECK(_call) _DX_CHECK(_call)
  93. # define DX_CHECK_REFCOUNT(_ptr, _expected) _DX_CHECK_REFCOUNT(_ptr, _expected)
  94. #else
  95. # define DX_CHECK(_call) _call
  96. # define DX_CHECK_REFCOUNT(_ptr, _expected)
  97. #endif // BGFX_CONFIG_DEBUG
  98. #if BGFX_CONFIG_DEBUG_OBJECT_NAME
  99. # define DX_NAME(_ptr, _format, ...) _DX_NAME(_ptr, _format, ##__VA_ARGS__)
  100. #else
  101. # define DX_NAME(_ptr, _format, ...)
  102. #endif // BGFX_CONFIG_DEBUG_OBJECT_NAME
  103. #define DX_RELEASE(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_CHECK)
  104. #define DX_RELEASE_W(_ptr, _expected) _DX_RELEASE(_ptr, _expected, BX_WARN)
  105. #define DX_RELEASE_I(_ptr) _DX_RELEASE(_ptr, 0, BX_NOOP)
  106. typedef int (WINAPI* PFN_D3DPERF_BEGIN_EVENT)(DWORD _color, LPCWSTR _name);
  107. typedef int (WINAPI* PFN_D3DPERF_END_EVENT)();
  108. typedef void (WINAPI* PFN_D3DPERF_SET_MARKER)(DWORD _color, LPCWSTR _name);
  109. typedef void (WINAPI* PFN_D3DPERF_SET_REGION)(DWORD _color, LPCWSTR _name);
  110. typedef BOOL (WINAPI* PFN_D3DPERF_QUERY_REPEAT_FRAME)();
  111. typedef void (WINAPI* PFN_D3DPERF_SET_OPTIONS)(DWORD _options);
  112. typedef DWORD (WINAPI* PFN_D3DPERF_GET_STATUS)();
  113. #define _PIX_SETMARKER(_color, _name) D3DPERF_SetMarker(_color, _name)
  114. #define _PIX_BEGINEVENT(_color, _name) D3DPERF_BeginEvent(_color, _name)
  115. #define _PIX_ENDEVENT() D3DPERF_EndEvent()
  116. #if BGFX_CONFIG_DEBUG_ANNOTATION
  117. # define PIX_SETMARKER(_color, _name) _PIX_SETMARKER(_color, _name)
  118. # define PIX_BEGINEVENT(_color, _name) _PIX_BEGINEVENT(_color, _name)
  119. # define PIX_ENDEVENT() _PIX_ENDEVENT()
  120. #else
  121. # define PIX_SETMARKER(_color, _name) BX_UNUSED(_name)
  122. # define PIX_BEGINEVENT(_color, _name) BX_UNUSED(_name)
  123. # define PIX_ENDEVENT()
  124. #endif // BGFX_CONFIG_DEBUG_ANNOTATION
  125. inline bool isType(IUnknown* _interface, const GUID& _id)
  126. {
  127. IUnknown* out;
  128. HRESULT hr = _interface->QueryInterface(_id, (void**)&out);
  129. if (FAILED(hr) )
  130. {
  131. return false;
  132. }
  133. out->Release();
  134. return true;
  135. }
  136. inline int getRefCount(IUnknown* _interface)
  137. {
  138. _interface->AddRef();
  139. return _interface->Release();
  140. }
  141. template<typename Ty>
  142. class StateCacheT
  143. {
  144. public:
  145. void add(uint64_t _key, Ty* _value)
  146. {
  147. invalidate(_key);
  148. m_hashMap.insert(stl::make_pair(_key, _value) );
  149. BX_CHECK(isGraphicsDebuggerPresent()
  150. || 1 == getRefCount(_value), "Interface ref count %d, hash %" PRIx64 "."
  151. , getRefCount(_value)
  152. , _key
  153. );
  154. }
  155. Ty* find(uint64_t _key)
  156. {
  157. typename HashMap::iterator it = m_hashMap.find(_key);
  158. if (it != m_hashMap.end() )
  159. {
  160. return it->second;
  161. }
  162. return NULL;
  163. }
  164. void invalidate(uint64_t _key)
  165. {
  166. typename HashMap::iterator it = m_hashMap.find(_key);
  167. if (it != m_hashMap.end() )
  168. {
  169. DX_RELEASE_W(it->second, 0);
  170. m_hashMap.erase(it);
  171. }
  172. }
  173. void invalidate()
  174. {
  175. for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
  176. {
  177. DX_CHECK_REFCOUNT(it->second, 1);
  178. it->second->Release();
  179. }
  180. m_hashMap.clear();
  181. }
  182. uint32_t getCount() const
  183. {
  184. return uint32_t(m_hashMap.size() );
  185. }
  186. private:
  187. typedef stl::unordered_map<uint64_t, Ty*> HashMap;
  188. HashMap m_hashMap;
  189. };
  190. template<>
  191. inline void release<IUnknown*>(IUnknown* _ptr)
  192. {
  193. DX_RELEASE(_ptr, 0);
  194. }
  195. } // namespace bgfx
  196. #endif // BGFX_RENDERER_D3D_H_HEADER_GUARD