renderer_d3d9.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. /*
  2. * Copyright 2011-2023 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #ifndef BGFX_RENDERER_D3D9_H_HEADER_GUARD
  6. #define BGFX_RENDERER_D3D9_H_HEADER_GUARD
  7. #define BGFX_CONFIG_RENDERER_DIRECT3D9EX (BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS)
  8. #include <sal.h>
  9. #include <unknwn.h>
  10. #include <d3d9.h>
  11. #ifndef D3DSTREAMSOURCE_INDEXEDDATA
  12. # define D3DSTREAMSOURCE_INDEXEDDATA (1<<30)
  13. #endif// D3DSTREAMSOURCE_INDEXEDDATA
  14. #ifndef D3DSTREAMSOURCE_INSTANCEDATA
  15. # define D3DSTREAMSOURCE_INSTANCEDATA (2<<30)
  16. #endif // D3DSTREAMSOURCE_INSTANCEDATA
  17. #include "renderer.h"
  18. #include "renderer_d3d.h"
  19. #include "nvapi.h"
  20. #define BGFX_D3D9_PROFILER_BEGIN(_view, _abgr) \
  21. BX_MACRO_BLOCK_BEGIN \
  22. PIX_BEGINEVENT(_abgr, s_viewNameW[_view]); \
  23. BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
  24. BX_MACRO_BLOCK_END
  25. #define BGFX_D3D9_PROFILER_BEGIN_LITERAL(_name, _abgr) \
  26. BX_MACRO_BLOCK_BEGIN \
  27. PIX_BEGINEVENT(_abgr, L"" _name); \
  28. BGFX_PROFILER_BEGIN_LITERAL("" _name, _abgr); \
  29. BX_MACRO_BLOCK_END
  30. #define BGFX_D3D9_PROFILER_END() \
  31. BX_MACRO_BLOCK_BEGIN \
  32. BGFX_PROFILER_END(); \
  33. PIX_ENDEVENT(); \
  34. BX_MACRO_BLOCK_END
  35. namespace bgfx { namespace d3d9
  36. {
  37. # if defined(D3D_DISABLE_9EX)
  38. # define D3DFMT_S8_LOCKABLE D3DFORMAT( 85)
  39. # define D3DFMT_A1 D3DFORMAT(118)
  40. # endif // defined(D3D_DISABLE_9EX)
  41. # ifndef D3DFMT_ATI1
  42. # define D3DFMT_ATI1 ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'I', '1') )
  43. # endif // D3DFMT_ATI1
  44. # ifndef D3DFMT_ATI2
  45. # define D3DFMT_ATI2 ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'I', '2') )
  46. # endif // D3DFMT_ATI2
  47. # ifndef D3DFMT_ATOC
  48. # define D3DFMT_ATOC ( (D3DFORMAT)BX_MAKEFOURCC('A', 'T', 'O', 'C') )
  49. # endif // D3DFMT_ATOC
  50. # ifndef D3DFMT_DF16
  51. # define D3DFMT_DF16 ( (D3DFORMAT)BX_MAKEFOURCC('D', 'F', '1', '6') )
  52. # endif // D3DFMT_DF16
  53. # ifndef D3DFMT_DF24
  54. # define D3DFMT_DF24 ( (D3DFORMAT)BX_MAKEFOURCC('D', 'F', '2', '4') )
  55. # endif // D3DFMT_DF24
  56. # ifndef D3DFMT_INST
  57. # define D3DFMT_INST ( (D3DFORMAT)BX_MAKEFOURCC('I', 'N', 'S', 'T') )
  58. # endif // D3DFMT_INST
  59. # ifndef D3DFMT_INTZ
  60. # define D3DFMT_INTZ ( (D3DFORMAT)BX_MAKEFOURCC('I', 'N', 'T', 'Z') )
  61. # endif // D3DFMT_INTZ
  62. # ifndef D3DFMT_NULL
  63. # define D3DFMT_NULL ( (D3DFORMAT)BX_MAKEFOURCC('N', 'U', 'L', 'L') )
  64. # endif // D3DFMT_NULL
  65. # ifndef D3DFMT_RESZ
  66. # define D3DFMT_RESZ ( (D3DFORMAT)BX_MAKEFOURCC('R', 'E', 'S', 'Z') )
  67. # endif // D3DFMT_RESZ
  68. # ifndef D3DFMT_RAWZ
  69. # define D3DFMT_RAWZ ( (D3DFORMAT)BX_MAKEFOURCC('R', 'A', 'W', 'Z') )
  70. # endif // D3DFMT_RAWZ
  71. # ifndef D3DFMT_S8_LOCKABLE
  72. # define D3DFMT_S8_LOCKABLE ( (D3DFORMAT)85)
  73. # endif // D3DFMT_S8_LOCKABLE
  74. # ifndef D3DFMT_A1
  75. # define D3DFMT_A1 ( (D3DFORMAT)118)
  76. # endif // D3DFMT_A1
  77. struct ExtendedFormat
  78. {
  79. enum Enum
  80. {
  81. Ati1,
  82. Ati2,
  83. Df16,
  84. Df24,
  85. Inst,
  86. Intz,
  87. Null,
  88. Resz,
  89. Rawz,
  90. Atoc,
  91. Count,
  92. };
  93. D3DFORMAT m_fmt;
  94. DWORD m_usage;
  95. D3DRESOURCETYPE m_type;
  96. bool m_supported;
  97. };
  98. struct Msaa
  99. {
  100. D3DMULTISAMPLE_TYPE m_type;
  101. DWORD m_quality;
  102. };
  103. struct IndexBufferD3D9
  104. {
  105. IndexBufferD3D9()
  106. : m_ptr(NULL)
  107. , m_dynamic(NULL)
  108. , m_size(0)
  109. , m_flags(BGFX_BUFFER_NONE)
  110. {
  111. }
  112. void create(uint32_t _size, void* _data, uint16_t _flags);
  113. void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
  114. {
  115. if (NULL != m_dynamic
  116. && _data != m_dynamic)
  117. {
  118. bx::memCopy(&m_dynamic[_offset], _data, _size);
  119. }
  120. void* buffer;
  121. DX_CHECK(m_ptr->Lock(_offset
  122. , _size
  123. , &buffer
  124. , _discard || (m_dynamic && 0 == _offset && m_size == _size) ? D3DLOCK_DISCARD : 0
  125. ) );
  126. bx::memCopy(buffer, _data, _size);
  127. DX_CHECK(m_ptr->Unlock() );
  128. }
  129. void destroy()
  130. {
  131. if (NULL != m_ptr)
  132. {
  133. DX_RELEASE(m_ptr, 0);
  134. if (NULL != m_dynamic)
  135. {
  136. BX_FREE(g_allocator, m_dynamic);
  137. m_dynamic = NULL;
  138. }
  139. }
  140. }
  141. void preReset();
  142. void postReset();
  143. IDirect3DIndexBuffer9* m_ptr;
  144. uint8_t* m_dynamic;
  145. uint32_t m_size;
  146. uint16_t m_flags;
  147. };
  148. struct VertexBufferD3D9
  149. {
  150. VertexBufferD3D9()
  151. : m_ptr(NULL)
  152. , m_dynamic(NULL)
  153. , m_size(0)
  154. {
  155. }
  156. void create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle);
  157. void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false)
  158. {
  159. if (NULL != m_dynamic
  160. && _data != m_dynamic)
  161. {
  162. bx::memCopy(&m_dynamic[_offset], _data, _size);
  163. }
  164. void* buffer;
  165. DX_CHECK(m_ptr->Lock(_offset
  166. , _size
  167. , &buffer
  168. , _discard || (m_dynamic && 0 == _offset && m_size == _size) ? D3DLOCK_DISCARD : 0
  169. ) );
  170. bx::memCopy(buffer, _data, _size);
  171. DX_CHECK(m_ptr->Unlock() );
  172. }
  173. void destroy()
  174. {
  175. if (NULL != m_ptr)
  176. {
  177. DX_RELEASE(m_ptr, 0);
  178. if (NULL != m_dynamic)
  179. {
  180. BX_FREE(g_allocator, m_dynamic);
  181. m_dynamic = NULL;
  182. }
  183. }
  184. }
  185. void preReset();
  186. void postReset();
  187. IDirect3DVertexBuffer9* m_ptr;
  188. uint8_t* m_dynamic;
  189. uint32_t m_size;
  190. VertexLayoutHandle m_layoutHandle;
  191. };
  192. struct ShaderD3D9
  193. {
  194. ShaderD3D9()
  195. : m_vertexShader(NULL)
  196. , m_constantBuffer(NULL)
  197. , m_numPredefined(0)
  198. , m_type(0)
  199. {
  200. }
  201. void create(const Memory* _mem);
  202. void destroy()
  203. {
  204. if (NULL != m_constantBuffer)
  205. {
  206. UniformBuffer::destroy(m_constantBuffer);
  207. m_constantBuffer = NULL;
  208. }
  209. m_numPredefined = 0;
  210. switch (m_type)
  211. {
  212. case 0: DX_RELEASE(m_vertexShader, 0); BX_FALLTHROUGH;
  213. default: DX_RELEASE(m_pixelShader, 0);
  214. }
  215. }
  216. union
  217. {
  218. // X360 doesn't have interface inheritance (can't use IUnknown*).
  219. IDirect3DVertexShader9* m_vertexShader;
  220. IDirect3DPixelShader9* m_pixelShader;
  221. };
  222. UniformBuffer* m_constantBuffer;
  223. PredefinedUniform m_predefined[PredefinedUniform::Count];
  224. uint8_t m_numPredefined;
  225. uint8_t m_type;
  226. };
  227. struct ProgramD3D9
  228. {
  229. void create(const ShaderD3D9* _vsh, const ShaderD3D9* _fsh)
  230. {
  231. m_vsh = _vsh;
  232. m_fsh = _fsh;
  233. bx::memCopy(&m_predefined[0], _vsh->m_predefined, _vsh->m_numPredefined*sizeof(PredefinedUniform) );
  234. m_numPredefined = _vsh->m_numPredefined;
  235. if (NULL != _fsh)
  236. {
  237. bx::memCopy(&m_predefined[_vsh->m_numPredefined], _fsh->m_predefined, _fsh->m_numPredefined*sizeof(PredefinedUniform) );
  238. m_numPredefined += _fsh->m_numPredefined;
  239. }
  240. }
  241. void destroy()
  242. {
  243. m_numPredefined = 0;
  244. m_vsh = NULL;
  245. m_fsh = NULL;
  246. }
  247. const ShaderD3D9* m_vsh;
  248. const ShaderD3D9* m_fsh;
  249. PredefinedUniform m_predefined[PredefinedUniform::Count*2];
  250. uint8_t m_numPredefined;
  251. };
  252. struct TextureD3D9
  253. {
  254. enum Enum
  255. {
  256. Texture2D,
  257. Texture3D,
  258. TextureCube,
  259. };
  260. TextureD3D9()
  261. : m_ptr(NULL)
  262. , m_surface(NULL)
  263. , m_staging(NULL)
  264. , m_textureFormat(TextureFormat::Unknown)
  265. {
  266. }
  267. void createTexture(uint32_t _width, uint32_t _height, uint8_t _numMips);
  268. void createVolumeTexture(uint32_t _width, uint32_t _height, uint32_t _depth, uint8_t _numMips);
  269. void createCubeTexture(uint32_t _width, uint8_t _numMips);
  270. uint8_t* lock(uint8_t _side, uint8_t _lod, uint32_t& _pitch, uint32_t& _slicePitch, const Rect* _rect = NULL);
  271. void unlock(uint8_t _side, uint8_t _lod);
  272. void dirty(uint8_t _side, const Rect& _rect, uint16_t _z, uint16_t _depth);
  273. IDirect3DSurface9* getSurface(uint8_t _side = 0, uint8_t _mip = 0) const;
  274. void create(const Memory* _mem, uint64_t _flags, uint8_t _skip);
  275. void destroy(bool _resize = false)
  276. {
  277. if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) )
  278. {
  279. if (_resize)
  280. {
  281. // BK - at the time of resize there might be one reference held by frame buffer
  282. // surface. This frame buffer will be recreated later, and release reference
  283. // to existing surface. That's why here we don't care about ref count.
  284. m_ptr->Release();
  285. }
  286. else
  287. {
  288. DX_RELEASE(m_ptr, 0);
  289. }
  290. }
  291. DX_RELEASE(m_surface, 0);
  292. DX_RELEASE(m_staging, 0);
  293. m_textureFormat = TextureFormat::Unknown;
  294. }
  295. void overrideInternal(uintptr_t _ptr)
  296. {
  297. destroy();
  298. m_flags |= BGFX_SAMPLER_INTERNAL_SHARED;
  299. m_ptr = (IDirect3DBaseTexture9*)_ptr;
  300. }
  301. void updateBegin(uint8_t _side, uint8_t _mip);
  302. void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
  303. void updateEnd();
  304. void commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]);
  305. void resolve(uint8_t _resolve) const;
  306. void preReset();
  307. void postReset();
  308. union
  309. {
  310. IDirect3DBaseTexture9* m_ptr;
  311. IDirect3DTexture9* m_texture2d;
  312. IDirect3DVolumeTexture9* m_texture3d;
  313. IDirect3DCubeTexture9* m_textureCube;
  314. };
  315. IDirect3DSurface9* m_surface;
  316. union
  317. {
  318. IDirect3DBaseTexture9* m_staging;
  319. IDirect3DTexture9* m_staging2d;
  320. IDirect3DVolumeTexture9* m_staging3d;
  321. IDirect3DCubeTexture9* m_stagingCube;
  322. };
  323. uint64_t m_flags;
  324. uint32_t m_width;
  325. uint32_t m_height;
  326. uint32_t m_depth;
  327. uint8_t m_numMips;
  328. uint8_t m_type;
  329. uint8_t m_requestedFormat;
  330. uint8_t m_textureFormat;
  331. };
  332. struct FrameBufferD3D9
  333. {
  334. FrameBufferD3D9()
  335. : m_hwnd(NULL)
  336. , m_denseIdx(UINT16_MAX)
  337. , m_num(0)
  338. , m_numTh(0)
  339. , m_dsIdx(UINT8_MAX)
  340. , m_needResolve(false)
  341. , m_needPresent(false)
  342. {
  343. }
  344. void create(uint8_t _num, const Attachment* _attachment);
  345. void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat);
  346. uint16_t destroy();
  347. HRESULT present();
  348. void resolve() const;
  349. void preReset();
  350. void postReset();
  351. void createNullColorRT();
  352. void set();
  353. IDirect3DSurface9* m_surface[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
  354. IDirect3DSwapChain9* m_swapChain;
  355. HWND m_hwnd;
  356. uint32_t m_width;
  357. uint32_t m_height;
  358. Attachment m_attachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
  359. uint16_t m_denseIdx;
  360. uint8_t m_num;
  361. uint8_t m_numTh;
  362. uint8_t m_dsIdx;
  363. bool m_needResolve;
  364. bool m_needPresent;
  365. };
  366. struct TimerQueryD3D9
  367. {
  368. TimerQueryD3D9()
  369. : m_control(BX_COUNTOF(m_query) )
  370. {
  371. }
  372. void postReset();
  373. void preReset();
  374. uint32_t begin(uint32_t _resultIdx, uint32_t _frameNum);
  375. void end(uint32_t _idx);
  376. bool update();
  377. struct Query
  378. {
  379. IDirect3DQuery9* m_disjoint;
  380. IDirect3DQuery9* m_begin;
  381. IDirect3DQuery9* m_end;
  382. IDirect3DQuery9* m_freq;
  383. uint32_t m_resultIdx;
  384. uint32_t m_frameNum;
  385. bool m_ready;
  386. };
  387. struct Result
  388. {
  389. void reset()
  390. {
  391. m_begin = 0;
  392. m_end = 0;
  393. m_frequency = 1;
  394. m_pending = 0;
  395. m_frameNum = 0;
  396. }
  397. uint64_t m_begin;
  398. uint64_t m_end;
  399. uint64_t m_frequency;
  400. uint32_t m_pending;
  401. uint32_t m_frameNum;
  402. };
  403. Result m_result[BGFX_CONFIG_MAX_VIEWS+1];
  404. Query m_query[BGFX_CONFIG_MAX_VIEWS*4];
  405. bx::RingBufferControl m_control;
  406. };
  407. struct OcclusionQueryD3D9
  408. {
  409. OcclusionQueryD3D9()
  410. : m_control(BX_COUNTOF(m_query) )
  411. {
  412. }
  413. void postReset();
  414. void preReset();
  415. void begin(Frame* _render, OcclusionQueryHandle _handle);
  416. void end();
  417. void resolve(Frame* _render, bool _wait = false);
  418. void invalidate(OcclusionQueryHandle _handle);
  419. struct Query
  420. {
  421. IDirect3DQuery9* m_ptr;
  422. OcclusionQueryHandle m_handle;
  423. };
  424. Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
  425. bx::RingBufferControl m_control;
  426. };
  427. } /* namespace d3d9 */ } // namespace bgfx
  428. #endif // BGFX_RENDERER_D3D9_H_HEADER_GUARD