renderer_d3d9.h 10 KB

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