d3d11-subsystem.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. /******************************************************************************
  2. Copyright (C) 2023 by Lain Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #pragma once
  15. #include <util/AlignedNew.hpp>
  16. #include <util/windows/win-version.h>
  17. #include <vector>
  18. #include <string>
  19. #include <memory>
  20. #include <windows.h>
  21. #include <dxgi1_6.h>
  22. #include <d3d11_1.h>
  23. #include <d3dcompiler.h>
  24. #include <util/base.h>
  25. #include <graphics/matrix4.h>
  26. #include <graphics/graphics.h>
  27. #include <graphics/device-exports.h>
  28. #include <util/windows/ComPtr.hpp>
  29. #include <util/windows/HRError.hpp>
  30. // #define DISASSEMBLE_SHADERS
  31. typedef HRESULT(WINAPI *pD3DCreateBlob)(_In_ SIZE_T Size,
  32. _Out_ ID3DBlob **ppBlob);
  33. struct shader_var;
  34. struct shader_sampler;
  35. struct gs_vertex_shader;
  36. using namespace std;
  37. /*
  38. * Just to clarify, all structs, and all public. These are exporting only
  39. * via encapsulated C bindings, not C++ bindings, so the whole concept of
  40. * "public" and "private" does not matter at all for this subproject.
  41. */
  42. static inline uint32_t GetWinVer()
  43. {
  44. struct win_version_info ver;
  45. get_win_ver(&ver);
  46. return (ver.major << 8) | ver.minor;
  47. }
  48. static inline DXGI_FORMAT ConvertGSTextureFormatResource(gs_color_format format)
  49. {
  50. switch (format) {
  51. case GS_UNKNOWN:
  52. return DXGI_FORMAT_UNKNOWN;
  53. case GS_A8:
  54. return DXGI_FORMAT_A8_UNORM;
  55. case GS_R8:
  56. return DXGI_FORMAT_R8_UNORM;
  57. case GS_RGBA:
  58. return DXGI_FORMAT_R8G8B8A8_TYPELESS;
  59. case GS_BGRX:
  60. return DXGI_FORMAT_B8G8R8X8_TYPELESS;
  61. case GS_BGRA:
  62. return DXGI_FORMAT_B8G8R8A8_TYPELESS;
  63. case GS_R10G10B10A2:
  64. return DXGI_FORMAT_R10G10B10A2_UNORM;
  65. case GS_RGBA16:
  66. return DXGI_FORMAT_R16G16B16A16_UNORM;
  67. case GS_R16:
  68. return DXGI_FORMAT_R16_UNORM;
  69. case GS_RGBA16F:
  70. return DXGI_FORMAT_R16G16B16A16_FLOAT;
  71. case GS_RGBA32F:
  72. return DXGI_FORMAT_R32G32B32A32_FLOAT;
  73. case GS_RG16F:
  74. return DXGI_FORMAT_R16G16_FLOAT;
  75. case GS_RG32F:
  76. return DXGI_FORMAT_R32G32_FLOAT;
  77. case GS_R16F:
  78. return DXGI_FORMAT_R16_FLOAT;
  79. case GS_R32F:
  80. return DXGI_FORMAT_R32_FLOAT;
  81. case GS_DXT1:
  82. return DXGI_FORMAT_BC1_UNORM;
  83. case GS_DXT3:
  84. return DXGI_FORMAT_BC2_UNORM;
  85. case GS_DXT5:
  86. return DXGI_FORMAT_BC3_UNORM;
  87. case GS_R8G8:
  88. return DXGI_FORMAT_R8G8_UNORM;
  89. case GS_RGBA_UNORM:
  90. return DXGI_FORMAT_R8G8B8A8_UNORM;
  91. case GS_BGRX_UNORM:
  92. return DXGI_FORMAT_B8G8R8X8_UNORM;
  93. case GS_BGRA_UNORM:
  94. return DXGI_FORMAT_B8G8R8A8_UNORM;
  95. case GS_RG16:
  96. return DXGI_FORMAT_R16G16_UNORM;
  97. }
  98. return DXGI_FORMAT_UNKNOWN;
  99. }
  100. static inline DXGI_FORMAT ConvertGSTextureFormatView(gs_color_format format)
  101. {
  102. switch (format) {
  103. case GS_RGBA:
  104. return DXGI_FORMAT_R8G8B8A8_UNORM;
  105. case GS_BGRX:
  106. return DXGI_FORMAT_B8G8R8X8_UNORM;
  107. case GS_BGRA:
  108. return DXGI_FORMAT_B8G8R8A8_UNORM;
  109. default:
  110. return ConvertGSTextureFormatResource(format);
  111. }
  112. }
  113. static inline DXGI_FORMAT
  114. ConvertGSTextureFormatViewLinear(gs_color_format format)
  115. {
  116. switch (format) {
  117. case GS_RGBA:
  118. return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
  119. case GS_BGRX:
  120. return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
  121. case GS_BGRA:
  122. return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
  123. default:
  124. return ConvertGSTextureFormatResource(format);
  125. }
  126. }
  127. static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format)
  128. {
  129. switch (format) {
  130. case DXGI_FORMAT_A8_UNORM:
  131. return GS_A8;
  132. case DXGI_FORMAT_R8_UNORM:
  133. return GS_R8;
  134. case DXGI_FORMAT_R8G8_UNORM:
  135. return GS_R8G8;
  136. case DXGI_FORMAT_R8G8B8A8_TYPELESS:
  137. return GS_RGBA;
  138. case DXGI_FORMAT_B8G8R8X8_TYPELESS:
  139. return GS_BGRX;
  140. case DXGI_FORMAT_B8G8R8A8_TYPELESS:
  141. return GS_BGRA;
  142. case DXGI_FORMAT_R10G10B10A2_UNORM:
  143. return GS_R10G10B10A2;
  144. case DXGI_FORMAT_R16G16B16A16_UNORM:
  145. return GS_RGBA16;
  146. case DXGI_FORMAT_R16_UNORM:
  147. return GS_R16;
  148. case DXGI_FORMAT_R16G16B16A16_FLOAT:
  149. return GS_RGBA16F;
  150. case DXGI_FORMAT_R32G32B32A32_FLOAT:
  151. return GS_RGBA32F;
  152. case DXGI_FORMAT_R16G16_FLOAT:
  153. return GS_RG16F;
  154. case DXGI_FORMAT_R32G32_FLOAT:
  155. return GS_RG32F;
  156. case DXGI_FORMAT_R16_FLOAT:
  157. return GS_R16F;
  158. case DXGI_FORMAT_R32_FLOAT:
  159. return GS_R32F;
  160. case DXGI_FORMAT_BC1_UNORM:
  161. return GS_DXT1;
  162. case DXGI_FORMAT_BC2_UNORM:
  163. return GS_DXT3;
  164. case DXGI_FORMAT_BC3_UNORM:
  165. return GS_DXT5;
  166. case DXGI_FORMAT_R8G8B8A8_UNORM:
  167. return GS_RGBA_UNORM;
  168. case DXGI_FORMAT_B8G8R8X8_UNORM:
  169. return GS_BGRX_UNORM;
  170. case DXGI_FORMAT_B8G8R8A8_UNORM:
  171. return GS_BGRA_UNORM;
  172. case DXGI_FORMAT_R16G16_UNORM:
  173. return GS_RG16;
  174. }
  175. return GS_UNKNOWN;
  176. }
  177. static inline DXGI_FORMAT ConvertGSZStencilFormat(gs_zstencil_format format)
  178. {
  179. switch (format) {
  180. case GS_ZS_NONE:
  181. return DXGI_FORMAT_UNKNOWN;
  182. case GS_Z16:
  183. return DXGI_FORMAT_D16_UNORM;
  184. case GS_Z24_S8:
  185. return DXGI_FORMAT_D24_UNORM_S8_UINT;
  186. case GS_Z32F:
  187. return DXGI_FORMAT_D32_FLOAT;
  188. case GS_Z32F_S8X24:
  189. return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
  190. }
  191. return DXGI_FORMAT_UNKNOWN;
  192. }
  193. static inline D3D11_COMPARISON_FUNC ConvertGSDepthTest(gs_depth_test test)
  194. {
  195. switch (test) {
  196. case GS_NEVER:
  197. return D3D11_COMPARISON_NEVER;
  198. case GS_LESS:
  199. return D3D11_COMPARISON_LESS;
  200. case GS_LEQUAL:
  201. return D3D11_COMPARISON_LESS_EQUAL;
  202. case GS_EQUAL:
  203. return D3D11_COMPARISON_EQUAL;
  204. case GS_GEQUAL:
  205. return D3D11_COMPARISON_GREATER_EQUAL;
  206. case GS_GREATER:
  207. return D3D11_COMPARISON_GREATER;
  208. case GS_NOTEQUAL:
  209. return D3D11_COMPARISON_NOT_EQUAL;
  210. case GS_ALWAYS:
  211. return D3D11_COMPARISON_ALWAYS;
  212. }
  213. return D3D11_COMPARISON_NEVER;
  214. }
  215. static inline D3D11_STENCIL_OP ConvertGSStencilOp(gs_stencil_op_type op)
  216. {
  217. switch (op) {
  218. case GS_KEEP:
  219. return D3D11_STENCIL_OP_KEEP;
  220. case GS_ZERO:
  221. return D3D11_STENCIL_OP_ZERO;
  222. case GS_REPLACE:
  223. return D3D11_STENCIL_OP_REPLACE;
  224. case GS_INCR:
  225. return D3D11_STENCIL_OP_INCR;
  226. case GS_DECR:
  227. return D3D11_STENCIL_OP_DECR;
  228. case GS_INVERT:
  229. return D3D11_STENCIL_OP_INVERT;
  230. }
  231. return D3D11_STENCIL_OP_KEEP;
  232. }
  233. static inline D3D11_BLEND ConvertGSBlendType(gs_blend_type type)
  234. {
  235. switch (type) {
  236. case GS_BLEND_ZERO:
  237. return D3D11_BLEND_ZERO;
  238. case GS_BLEND_ONE:
  239. return D3D11_BLEND_ONE;
  240. case GS_BLEND_SRCCOLOR:
  241. return D3D11_BLEND_SRC_COLOR;
  242. case GS_BLEND_INVSRCCOLOR:
  243. return D3D11_BLEND_INV_SRC_COLOR;
  244. case GS_BLEND_SRCALPHA:
  245. return D3D11_BLEND_SRC_ALPHA;
  246. case GS_BLEND_INVSRCALPHA:
  247. return D3D11_BLEND_INV_SRC_ALPHA;
  248. case GS_BLEND_DSTCOLOR:
  249. return D3D11_BLEND_DEST_COLOR;
  250. case GS_BLEND_INVDSTCOLOR:
  251. return D3D11_BLEND_INV_DEST_COLOR;
  252. case GS_BLEND_DSTALPHA:
  253. return D3D11_BLEND_DEST_ALPHA;
  254. case GS_BLEND_INVDSTALPHA:
  255. return D3D11_BLEND_INV_DEST_ALPHA;
  256. case GS_BLEND_SRCALPHASAT:
  257. return D3D11_BLEND_SRC_ALPHA_SAT;
  258. }
  259. return D3D11_BLEND_ONE;
  260. }
  261. static inline D3D11_BLEND_OP ConvertGSBlendOpType(gs_blend_op_type type)
  262. {
  263. switch (type) {
  264. case GS_BLEND_OP_ADD:
  265. return D3D11_BLEND_OP_ADD;
  266. case GS_BLEND_OP_SUBTRACT:
  267. return D3D11_BLEND_OP_SUBTRACT;
  268. case GS_BLEND_OP_REVERSE_SUBTRACT:
  269. return D3D11_BLEND_OP_REV_SUBTRACT;
  270. case GS_BLEND_OP_MIN:
  271. return D3D11_BLEND_OP_MIN;
  272. case GS_BLEND_OP_MAX:
  273. return D3D11_BLEND_OP_MAX;
  274. }
  275. return D3D11_BLEND_OP_ADD;
  276. }
  277. static inline D3D11_CULL_MODE ConvertGSCullMode(gs_cull_mode mode)
  278. {
  279. switch (mode) {
  280. case GS_BACK:
  281. return D3D11_CULL_BACK;
  282. case GS_FRONT:
  283. return D3D11_CULL_FRONT;
  284. case GS_NEITHER:
  285. return D3D11_CULL_NONE;
  286. }
  287. return D3D11_CULL_BACK;
  288. }
  289. static inline D3D11_PRIMITIVE_TOPOLOGY ConvertGSTopology(gs_draw_mode mode)
  290. {
  291. switch (mode) {
  292. case GS_POINTS:
  293. return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
  294. case GS_LINES:
  295. return D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
  296. case GS_LINESTRIP:
  297. return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
  298. case GS_TRIS:
  299. return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
  300. case GS_TRISTRIP:
  301. return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
  302. }
  303. return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
  304. }
  305. /* exception-safe RAII wrapper for vertex buffer data (NOTE: not copy-safe) */
  306. struct VBDataPtr {
  307. gs_vb_data *data;
  308. inline VBDataPtr(gs_vb_data *data) : data(data) {}
  309. inline ~VBDataPtr() { gs_vbdata_destroy(data); }
  310. };
  311. enum class gs_type {
  312. gs_vertex_buffer,
  313. gs_index_buffer,
  314. gs_texture_2d,
  315. gs_zstencil_buffer,
  316. gs_stage_surface,
  317. gs_sampler_state,
  318. gs_vertex_shader,
  319. gs_pixel_shader,
  320. gs_duplicator,
  321. gs_swap_chain,
  322. gs_timer,
  323. gs_timer_range,
  324. gs_texture_3d,
  325. };
  326. struct gs_obj {
  327. gs_device_t *device;
  328. gs_type obj_type;
  329. gs_obj *next;
  330. gs_obj **prev_next;
  331. inline gs_obj() : device(nullptr), next(nullptr), prev_next(nullptr) {}
  332. gs_obj(gs_device_t *device, gs_type type);
  333. virtual ~gs_obj();
  334. };
  335. struct gs_vertex_buffer : gs_obj {
  336. ComPtr<ID3D11Buffer> vertexBuffer;
  337. ComPtr<ID3D11Buffer> normalBuffer;
  338. ComPtr<ID3D11Buffer> colorBuffer;
  339. ComPtr<ID3D11Buffer> tangentBuffer;
  340. vector<ComPtr<ID3D11Buffer>> uvBuffers;
  341. bool dynamic;
  342. VBDataPtr vbd;
  343. size_t numVerts;
  344. vector<size_t> uvSizes;
  345. void FlushBuffer(ID3D11Buffer *buffer, void *array, size_t elementSize);
  346. UINT MakeBufferList(gs_vertex_shader *shader, ID3D11Buffer **buffers,
  347. uint32_t *strides);
  348. void InitBuffer(const size_t elementSize, const size_t numVerts,
  349. void *array, ID3D11Buffer **buffer);
  350. void BuildBuffers();
  351. inline void Release()
  352. {
  353. vertexBuffer.Release();
  354. normalBuffer.Release();
  355. colorBuffer.Release();
  356. tangentBuffer.Release();
  357. uvBuffers.clear();
  358. }
  359. void Rebuild();
  360. gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data,
  361. uint32_t flags);
  362. };
  363. /* exception-safe RAII wrapper for index buffer data (NOTE: not copy-safe) */
  364. struct DataPtr {
  365. void *data;
  366. inline DataPtr(void *data) : data(data) {}
  367. inline ~DataPtr() { bfree(data); }
  368. };
  369. struct gs_index_buffer : gs_obj {
  370. ComPtr<ID3D11Buffer> indexBuffer;
  371. bool dynamic;
  372. gs_index_type type;
  373. size_t indexSize;
  374. size_t num;
  375. DataPtr indices;
  376. D3D11_BUFFER_DESC bd = {};
  377. D3D11_SUBRESOURCE_DATA srd = {};
  378. void InitBuffer();
  379. void Rebuild(ID3D11Device *dev);
  380. inline void Release() { indexBuffer.Release(); }
  381. gs_index_buffer(gs_device_t *device, enum gs_index_type type,
  382. void *indices, size_t num, uint32_t flags);
  383. };
  384. struct gs_timer : gs_obj {
  385. ComPtr<ID3D11Query> query_begin;
  386. ComPtr<ID3D11Query> query_end;
  387. void Rebuild(ID3D11Device *dev);
  388. inline void Release()
  389. {
  390. query_begin.Release();
  391. query_end.Release();
  392. }
  393. gs_timer(gs_device_t *device);
  394. };
  395. struct gs_timer_range : gs_obj {
  396. ComPtr<ID3D11Query> query_disjoint;
  397. void Rebuild(ID3D11Device *dev);
  398. inline void Release() { query_disjoint.Release(); }
  399. gs_timer_range(gs_device_t *device);
  400. };
  401. struct gs_texture : gs_obj {
  402. gs_texture_type type;
  403. uint32_t levels;
  404. gs_color_format format;
  405. ComPtr<ID3D11ShaderResourceView> shaderRes;
  406. ComPtr<ID3D11ShaderResourceView> shaderResLinear;
  407. D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc{};
  408. D3D11_SHADER_RESOURCE_VIEW_DESC viewDescLinear{};
  409. void Rebuild(ID3D11Device *dev);
  410. inline gs_texture(gs_texture_type type, uint32_t levels,
  411. gs_color_format format)
  412. : type(type),
  413. levels(levels),
  414. format(format)
  415. {
  416. }
  417. inline gs_texture(gs_device *device, gs_type obj_type,
  418. gs_texture_type type)
  419. : gs_obj(device, obj_type),
  420. type(type)
  421. {
  422. }
  423. inline gs_texture(gs_device *device, gs_type obj_type,
  424. gs_texture_type type, uint32_t levels,
  425. gs_color_format format)
  426. : gs_obj(device, obj_type),
  427. type(type),
  428. levels(levels),
  429. format(format)
  430. {
  431. }
  432. };
  433. struct gs_texture_2d : gs_texture {
  434. ComPtr<ID3D11Texture2D> texture;
  435. ComPtr<ID3D11RenderTargetView> renderTarget[6];
  436. ComPtr<ID3D11RenderTargetView> renderTargetLinear[6];
  437. ComPtr<IDXGISurface1> gdiSurface;
  438. uint32_t width = 0, height = 0;
  439. uint32_t flags = 0;
  440. DXGI_FORMAT dxgiFormatResource = DXGI_FORMAT_UNKNOWN;
  441. DXGI_FORMAT dxgiFormatView = DXGI_FORMAT_UNKNOWN;
  442. DXGI_FORMAT dxgiFormatViewLinear = DXGI_FORMAT_UNKNOWN;
  443. bool isRenderTarget = false;
  444. bool isGDICompatible = false;
  445. bool isDynamic = false;
  446. bool isShared = false;
  447. bool genMipmaps = false;
  448. uint32_t sharedHandle = GS_INVALID_HANDLE;
  449. gs_texture_2d *pairedTexture = nullptr;
  450. bool twoPlane = false;
  451. bool chroma = false;
  452. bool acquired = false;
  453. vector<vector<uint8_t>> data;
  454. vector<D3D11_SUBRESOURCE_DATA> srd;
  455. D3D11_TEXTURE2D_DESC td = {};
  456. void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
  457. void InitTexture(const uint8_t *const *data);
  458. void InitResourceView();
  459. void InitRenderTargets();
  460. void BackupTexture(const uint8_t *const *data);
  461. void GetSharedHandle(IDXGIResource *dxgi_res);
  462. void RebuildSharedTextureFallback();
  463. void Rebuild(ID3D11Device *dev);
  464. void RebuildPaired_Y(ID3D11Device *dev);
  465. void RebuildPaired_UV(ID3D11Device *dev);
  466. inline void Release()
  467. {
  468. texture.Release();
  469. for (ComPtr<ID3D11RenderTargetView> &rt : renderTarget)
  470. rt.Release();
  471. for (ComPtr<ID3D11RenderTargetView> &rt : renderTargetLinear)
  472. rt.Release();
  473. gdiSurface.Release();
  474. shaderRes.Release();
  475. shaderResLinear.Release();
  476. }
  477. inline gs_texture_2d() : gs_texture(GS_TEXTURE_2D, 0, GS_UNKNOWN) {}
  478. gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height,
  479. gs_color_format colorFormat, uint32_t levels,
  480. const uint8_t *const *data, uint32_t flags,
  481. gs_texture_type type, bool gdiCompatible,
  482. bool twoPlane = false);
  483. gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12,
  484. uint32_t flags);
  485. gs_texture_2d(gs_device_t *device, uint32_t handle,
  486. bool ntHandle = false);
  487. gs_texture_2d(gs_device_t *device, ID3D11Texture2D *obj);
  488. };
  489. struct gs_texture_3d : gs_texture {
  490. ComPtr<ID3D11Texture3D> texture;
  491. uint32_t width = 0, height = 0, depth = 0;
  492. uint32_t flags = 0;
  493. DXGI_FORMAT dxgiFormatResource = DXGI_FORMAT_UNKNOWN;
  494. DXGI_FORMAT dxgiFormatView = DXGI_FORMAT_UNKNOWN;
  495. DXGI_FORMAT dxgiFormatViewLinear = DXGI_FORMAT_UNKNOWN;
  496. bool isDynamic = false;
  497. bool isShared = false;
  498. bool genMipmaps = false;
  499. uint32_t sharedHandle = GS_INVALID_HANDLE;
  500. bool chroma = false;
  501. bool acquired = false;
  502. vector<vector<uint8_t>> data;
  503. vector<D3D11_SUBRESOURCE_DATA> srd;
  504. D3D11_TEXTURE3D_DESC td = {};
  505. void InitSRD(vector<D3D11_SUBRESOURCE_DATA> &srd);
  506. void InitTexture(const uint8_t *const *data);
  507. void InitResourceView();
  508. void BackupTexture(const uint8_t *const *data);
  509. void GetSharedHandle(IDXGIResource *dxgi_res);
  510. void RebuildSharedTextureFallback();
  511. void Rebuild(ID3D11Device *dev);
  512. void RebuildNV12_Y(ID3D11Device *dev);
  513. void RebuildNV12_UV(ID3D11Device *dev);
  514. inline void Release()
  515. {
  516. texture.Release();
  517. shaderRes.Release();
  518. }
  519. inline gs_texture_3d() : gs_texture(GS_TEXTURE_3D, 0, GS_UNKNOWN) {}
  520. gs_texture_3d(gs_device_t *device, uint32_t width, uint32_t height,
  521. uint32_t depth, gs_color_format colorFormat,
  522. uint32_t levels, const uint8_t *const *data,
  523. uint32_t flags);
  524. gs_texture_3d(gs_device_t *device, uint32_t handle);
  525. };
  526. struct gs_zstencil_buffer : gs_obj {
  527. ComPtr<ID3D11Texture2D> texture;
  528. ComPtr<ID3D11DepthStencilView> view;
  529. uint32_t width, height;
  530. gs_zstencil_format format;
  531. DXGI_FORMAT dxgiFormat;
  532. D3D11_TEXTURE2D_DESC td = {};
  533. D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = {};
  534. void InitBuffer();
  535. void Rebuild(ID3D11Device *dev);
  536. inline void Release()
  537. {
  538. texture.Release();
  539. view.Release();
  540. }
  541. inline gs_zstencil_buffer()
  542. : width(0),
  543. height(0),
  544. dxgiFormat(DXGI_FORMAT_UNKNOWN)
  545. {
  546. }
  547. gs_zstencil_buffer(gs_device_t *device, uint32_t width, uint32_t height,
  548. gs_zstencil_format format);
  549. };
  550. struct gs_stage_surface : gs_obj {
  551. ComPtr<ID3D11Texture2D> texture;
  552. D3D11_TEXTURE2D_DESC td = {};
  553. uint32_t width, height;
  554. gs_color_format format;
  555. DXGI_FORMAT dxgiFormat;
  556. void Rebuild(ID3D11Device *dev);
  557. inline void Release() { texture.Release(); }
  558. gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height,
  559. gs_color_format colorFormat);
  560. gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height,
  561. bool p010);
  562. };
  563. struct gs_sampler_state : gs_obj {
  564. ComPtr<ID3D11SamplerState> state;
  565. D3D11_SAMPLER_DESC sd = {};
  566. gs_sampler_info info;
  567. void Rebuild(ID3D11Device *dev);
  568. inline void Release() { state.Release(); }
  569. gs_sampler_state(gs_device_t *device, const gs_sampler_info *info);
  570. };
  571. struct gs_shader_param {
  572. string name;
  573. gs_shader_param_type type;
  574. uint32_t textureID;
  575. struct gs_sampler_state *nextSampler = nullptr;
  576. int arrayCount;
  577. size_t pos;
  578. vector<uint8_t> curValue;
  579. vector<uint8_t> defaultValue;
  580. bool changed;
  581. gs_shader_param(shader_var &var, uint32_t &texCounter);
  582. };
  583. struct ShaderError {
  584. ComPtr<ID3D10Blob> errors;
  585. HRESULT hr;
  586. inline ShaderError(const ComPtr<ID3D10Blob> &errors, HRESULT hr)
  587. : errors(errors),
  588. hr(hr)
  589. {
  590. }
  591. };
  592. struct gs_shader : gs_obj {
  593. gs_shader_type type;
  594. vector<gs_shader_param> params;
  595. ComPtr<ID3D11Buffer> constants;
  596. size_t constantSize;
  597. D3D11_BUFFER_DESC bd = {};
  598. vector<uint8_t> data;
  599. inline void UpdateParam(vector<uint8_t> &constData,
  600. gs_shader_param &param, bool &upload);
  601. void UploadParams();
  602. void BuildConstantBuffer();
  603. void Compile(const char *shaderStr, const char *file,
  604. const char *target, ID3D10Blob **shader);
  605. inline gs_shader(gs_device_t *device, gs_type obj_type,
  606. gs_shader_type type)
  607. : gs_obj(device, obj_type),
  608. type(type),
  609. constantSize(0)
  610. {
  611. }
  612. virtual ~gs_shader() {}
  613. };
  614. struct ShaderSampler {
  615. string name;
  616. gs_sampler_state sampler;
  617. inline ShaderSampler(const char *name, gs_device_t *device,
  618. gs_sampler_info *info)
  619. : name(name),
  620. sampler(device, info)
  621. {
  622. }
  623. };
  624. struct gs_vertex_shader : gs_shader {
  625. ComPtr<ID3D11VertexShader> shader;
  626. ComPtr<ID3D11InputLayout> layout;
  627. gs_shader_param *world, *viewProj;
  628. vector<D3D11_INPUT_ELEMENT_DESC> layoutData;
  629. bool hasNormals;
  630. bool hasColors;
  631. bool hasTangents;
  632. uint32_t nTexUnits;
  633. void Rebuild(ID3D11Device *dev);
  634. inline void Release()
  635. {
  636. shader.Release();
  637. layout.Release();
  638. constants.Release();
  639. }
  640. inline uint32_t NumBuffersExpected() const
  641. {
  642. uint32_t count = nTexUnits + 1;
  643. if (hasNormals)
  644. count++;
  645. if (hasColors)
  646. count++;
  647. if (hasTangents)
  648. count++;
  649. return count;
  650. }
  651. void GetBuffersExpected(const vector<D3D11_INPUT_ELEMENT_DESC> &inputs);
  652. gs_vertex_shader(gs_device_t *device, const char *file,
  653. const char *shaderString);
  654. };
  655. struct gs_duplicator : gs_obj {
  656. ComPtr<IDXGIOutputDuplication> duplicator;
  657. gs_texture_2d *texture;
  658. bool hdr = false;
  659. enum gs_color_space color_space = GS_CS_SRGB;
  660. float sdr_white_nits = 80.f;
  661. int idx;
  662. long refs;
  663. bool updated;
  664. void Start();
  665. inline void Release() { duplicator.Release(); }
  666. gs_duplicator(gs_device_t *device, int monitor_idx);
  667. ~gs_duplicator();
  668. };
  669. struct gs_pixel_shader : gs_shader {
  670. ComPtr<ID3D11PixelShader> shader;
  671. vector<unique_ptr<ShaderSampler>> samplers;
  672. void Rebuild(ID3D11Device *dev);
  673. inline void Release()
  674. {
  675. shader.Release();
  676. constants.Release();
  677. }
  678. inline void GetSamplerStates(ID3D11SamplerState **states)
  679. {
  680. size_t i;
  681. for (i = 0; i < samplers.size(); i++)
  682. states[i] = samplers[i]->sampler.state;
  683. for (; i < GS_MAX_TEXTURES; i++)
  684. states[i] = NULL;
  685. }
  686. gs_pixel_shader(gs_device_t *device, const char *file,
  687. const char *shaderString);
  688. };
  689. struct gs_swap_chain : gs_obj {
  690. HWND hwnd;
  691. gs_init_data initData;
  692. DXGI_SWAP_CHAIN_DESC swapDesc = {};
  693. gs_color_space space;
  694. gs_texture_2d target;
  695. gs_zstencil_buffer zs;
  696. ComPtr<IDXGISwapChain> swap;
  697. HANDLE hWaitable = NULL;
  698. void InitTarget(uint32_t cx, uint32_t cy);
  699. void InitZStencilBuffer(uint32_t cx, uint32_t cy);
  700. void Resize(uint32_t cx, uint32_t cy, gs_color_format format);
  701. void Init();
  702. void Rebuild(ID3D11Device *dev);
  703. inline void Release()
  704. {
  705. target.Release();
  706. zs.Release();
  707. if (hWaitable) {
  708. CloseHandle(hWaitable);
  709. hWaitable = NULL;
  710. }
  711. swap.Clear();
  712. }
  713. gs_swap_chain(gs_device *device, const gs_init_data *data);
  714. virtual ~gs_swap_chain();
  715. };
  716. struct BlendState {
  717. bool blendEnabled;
  718. gs_blend_type srcFactorC;
  719. gs_blend_type destFactorC;
  720. gs_blend_type srcFactorA;
  721. gs_blend_type destFactorA;
  722. gs_blend_op_type op;
  723. bool redEnabled;
  724. bool greenEnabled;
  725. bool blueEnabled;
  726. bool alphaEnabled;
  727. inline BlendState()
  728. : blendEnabled(true),
  729. srcFactorC(GS_BLEND_SRCALPHA),
  730. destFactorC(GS_BLEND_INVSRCALPHA),
  731. srcFactorA(GS_BLEND_ONE),
  732. destFactorA(GS_BLEND_INVSRCALPHA),
  733. op(GS_BLEND_OP_ADD),
  734. redEnabled(true),
  735. greenEnabled(true),
  736. blueEnabled(true),
  737. alphaEnabled(true)
  738. {
  739. }
  740. inline BlendState(const BlendState &state)
  741. {
  742. memcpy(this, &state, sizeof(BlendState));
  743. }
  744. };
  745. struct SavedBlendState : BlendState {
  746. ComPtr<ID3D11BlendState> state;
  747. D3D11_BLEND_DESC bd;
  748. void Rebuild(ID3D11Device *dev);
  749. inline void Release() { state.Release(); }
  750. inline SavedBlendState(const BlendState &val, D3D11_BLEND_DESC &desc)
  751. : BlendState(val),
  752. bd(desc)
  753. {
  754. }
  755. };
  756. struct StencilSide {
  757. gs_depth_test test;
  758. gs_stencil_op_type fail;
  759. gs_stencil_op_type zfail;
  760. gs_stencil_op_type zpass;
  761. inline StencilSide()
  762. : test(GS_ALWAYS),
  763. fail(GS_KEEP),
  764. zfail(GS_KEEP),
  765. zpass(GS_KEEP)
  766. {
  767. }
  768. };
  769. struct ZStencilState {
  770. bool depthEnabled;
  771. bool depthWriteEnabled;
  772. gs_depth_test depthFunc;
  773. bool stencilEnabled;
  774. bool stencilWriteEnabled;
  775. StencilSide stencilFront;
  776. StencilSide stencilBack;
  777. inline ZStencilState()
  778. : depthEnabled(true),
  779. depthWriteEnabled(true),
  780. depthFunc(GS_LESS),
  781. stencilEnabled(false),
  782. stencilWriteEnabled(true)
  783. {
  784. }
  785. inline ZStencilState(const ZStencilState &state)
  786. {
  787. memcpy(this, &state, sizeof(ZStencilState));
  788. }
  789. };
  790. struct SavedZStencilState : ZStencilState {
  791. ComPtr<ID3D11DepthStencilState> state;
  792. D3D11_DEPTH_STENCIL_DESC dsd;
  793. void Rebuild(ID3D11Device *dev);
  794. inline void Release() { state.Release(); }
  795. inline SavedZStencilState(const ZStencilState &val,
  796. D3D11_DEPTH_STENCIL_DESC desc)
  797. : ZStencilState(val),
  798. dsd(desc)
  799. {
  800. }
  801. };
  802. struct RasterState {
  803. gs_cull_mode cullMode;
  804. bool scissorEnabled;
  805. inline RasterState() : cullMode(GS_BACK), scissorEnabled(false) {}
  806. inline RasterState(const RasterState &state)
  807. {
  808. memcpy(this, &state, sizeof(RasterState));
  809. }
  810. };
  811. struct SavedRasterState : RasterState {
  812. ComPtr<ID3D11RasterizerState> state;
  813. D3D11_RASTERIZER_DESC rd;
  814. void Rebuild(ID3D11Device *dev);
  815. inline void Release() { state.Release(); }
  816. inline SavedRasterState(const RasterState &val,
  817. D3D11_RASTERIZER_DESC &desc)
  818. : RasterState(val),
  819. rd(desc)
  820. {
  821. }
  822. };
  823. struct mat4float {
  824. float mat[16];
  825. };
  826. struct gs_monitor_color_info {
  827. bool hdr;
  828. UINT bits_per_color;
  829. ULONG sdr_white_nits;
  830. gs_monitor_color_info(bool hdr, int bits_per_color,
  831. ULONG sdr_white_nits)
  832. : hdr(hdr),
  833. bits_per_color(bits_per_color),
  834. sdr_white_nits(sdr_white_nits)
  835. {
  836. }
  837. };
  838. struct gs_device {
  839. ComPtr<IDXGIFactory1> factory;
  840. ComPtr<IDXGIAdapter1> adapter;
  841. ComPtr<ID3D11Device> device;
  842. ComPtr<ID3D11DeviceContext> context;
  843. uint32_t adpIdx = 0;
  844. bool nv12Supported = false;
  845. bool p010Supported = false;
  846. bool fastClearSupported = false;
  847. gs_texture_2d *curRenderTarget = nullptr;
  848. gs_zstencil_buffer *curZStencilBuffer = nullptr;
  849. int curRenderSide = 0;
  850. enum gs_color_space curColorSpace = GS_CS_SRGB;
  851. bool curFramebufferSrgb = false;
  852. bool curFramebufferInvalidate = false;
  853. gs_texture *curTextures[GS_MAX_TEXTURES];
  854. gs_sampler_state *curSamplers[GS_MAX_TEXTURES];
  855. gs_vertex_buffer *curVertexBuffer = nullptr;
  856. gs_index_buffer *curIndexBuffer = nullptr;
  857. gs_vertex_shader *curVertexShader = nullptr;
  858. gs_pixel_shader *curPixelShader = nullptr;
  859. gs_swap_chain *curSwapChain = nullptr;
  860. gs_vertex_buffer *lastVertexBuffer = nullptr;
  861. gs_vertex_shader *lastVertexShader = nullptr;
  862. bool zstencilStateChanged = true;
  863. bool rasterStateChanged = true;
  864. bool blendStateChanged = true;
  865. ZStencilState zstencilState;
  866. RasterState rasterState;
  867. BlendState blendState;
  868. vector<SavedZStencilState> zstencilStates;
  869. vector<SavedRasterState> rasterStates;
  870. vector<SavedBlendState> blendStates;
  871. ID3D11DepthStencilState *curDepthStencilState = nullptr;
  872. ID3D11RasterizerState *curRasterState = nullptr;
  873. ID3D11BlendState *curBlendState = nullptr;
  874. D3D11_PRIMITIVE_TOPOLOGY curToplogy;
  875. pD3DCompile d3dCompile = nullptr;
  876. pD3DCreateBlob d3dCreateBlob = nullptr;
  877. #ifdef DISASSEMBLE_SHADERS
  878. pD3DDisassemble d3dDisassemble = nullptr;
  879. #endif
  880. gs_rect viewport;
  881. vector<mat4float> projStack;
  882. matrix4 curProjMatrix;
  883. matrix4 curViewMatrix;
  884. matrix4 curViewProjMatrix;
  885. vector<gs_device_loss> loss_callbacks;
  886. gs_obj *first_obj = nullptr;
  887. vector<std::pair<HMONITOR, gs_monitor_color_info>> monitor_to_hdr;
  888. void InitCompiler();
  889. void InitFactory();
  890. void InitAdapter(uint32_t adapterIdx);
  891. void InitDevice(uint32_t adapterIdx);
  892. ID3D11DepthStencilState *AddZStencilState();
  893. ID3D11RasterizerState *AddRasterState();
  894. ID3D11BlendState *AddBlendState();
  895. void UpdateZStencilState();
  896. void UpdateRasterState();
  897. void UpdateBlendState();
  898. void LoadVertexBufferData();
  899. void CopyTex(ID3D11Texture2D *dst, uint32_t dst_x, uint32_t dst_y,
  900. gs_texture_t *src, uint32_t src_x, uint32_t src_y,
  901. uint32_t src_w, uint32_t src_h);
  902. void UpdateViewProjMatrix();
  903. void FlushOutputViews();
  904. void RebuildDevice();
  905. bool HasBadNV12Output();
  906. gs_monitor_color_info GetMonitorColorInfo(HMONITOR hMonitor);
  907. gs_device(uint32_t adapterIdx);
  908. ~gs_device();
  909. };
  910. extern "C" EXPORT int device_texture_acquire_sync(gs_texture_t *tex,
  911. uint64_t key, uint32_t ms);