d3dHelpers.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #include "composition.interop.h"
  3. struct SurfaceContext
  4. {
  5. public:
  6. SurfaceContext(std::nullptr_t) {}
  7. SurfaceContext(
  8. winrt::Windows::UI::Composition::CompositionDrawingSurface surface)
  9. {
  10. m_surface = surface;
  11. m_d2dContext = SurfaceBeginDraw(m_surface);
  12. }
  13. ~SurfaceContext()
  14. {
  15. SurfaceEndDraw(m_surface);
  16. m_d2dContext = nullptr;
  17. m_surface = nullptr;
  18. }
  19. winrt::com_ptr<ID2D1DeviceContext> GetDeviceContext() { return m_d2dContext; }
  20. private:
  21. winrt::com_ptr<ID2D1DeviceContext> m_d2dContext;
  22. winrt::Windows::UI::Composition::CompositionDrawingSurface m_surface{ nullptr };
  23. };
  24. struct D3D11DeviceLock
  25. {
  26. public:
  27. D3D11DeviceLock(std::nullopt_t) {}
  28. D3D11DeviceLock(ID3D11Multithread* pMultithread)
  29. {
  30. m_multithread.copy_from(pMultithread);
  31. m_multithread->Enter();
  32. }
  33. ~D3D11DeviceLock()
  34. {
  35. m_multithread->Leave();
  36. m_multithread = nullptr;
  37. }
  38. private:
  39. winrt::com_ptr<ID3D11Multithread> m_multithread;
  40. };
  41. inline auto
  42. CreateWICFactory()
  43. {
  44. winrt::com_ptr<IWICImagingFactory2> wicFactory;
  45. winrt::check_hresult(
  46. ::CoCreateInstance(
  47. CLSID_WICImagingFactory,
  48. nullptr,
  49. CLSCTX_INPROC_SERVER,
  50. winrt::guid_of<IWICImagingFactory>(),
  51. wicFactory.put_void()));
  52. return wicFactory;
  53. }
  54. inline auto
  55. CreateD2DDevice(
  56. winrt::com_ptr<ID2D1Factory1> const& factory,
  57. winrt::com_ptr<ID3D11Device> const& device)
  58. {
  59. winrt::com_ptr<ID2D1Device> result;
  60. winrt::check_hresult(factory->CreateDevice(device.as<IDXGIDevice>().get(), result.put()));
  61. return result;
  62. }
  63. inline auto
  64. CreateD3DDevice(
  65. D3D_DRIVER_TYPE const type,
  66. winrt::com_ptr<ID3D11Device>& device)
  67. {
  68. WINRT_ASSERT(!device);
  69. UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
  70. //#ifdef _DEBUG
  71. // flags |= D3D11_CREATE_DEVICE_DEBUG;
  72. //#endif
  73. return D3D11CreateDevice(
  74. nullptr,
  75. type,
  76. nullptr,
  77. flags,
  78. nullptr, 0,
  79. D3D11_SDK_VERSION,
  80. device.put(),
  81. nullptr,
  82. nullptr);
  83. }
  84. inline auto
  85. CreateD3DDevice()
  86. {
  87. winrt::com_ptr<ID3D11Device> device;
  88. HRESULT hr = CreateD3DDevice(D3D_DRIVER_TYPE_HARDWARE, device);
  89. if (DXGI_ERROR_UNSUPPORTED == hr)
  90. {
  91. hr = CreateD3DDevice(D3D_DRIVER_TYPE_WARP, device);
  92. }
  93. winrt::check_hresult(hr);
  94. return device;
  95. }
  96. inline auto
  97. CreateD2DFactory()
  98. {
  99. D2D1_FACTORY_OPTIONS options{};
  100. //#ifdef _DEBUG
  101. // options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
  102. //#endif
  103. winrt::com_ptr<ID2D1Factory1> factory;
  104. winrt::check_hresult(D2D1CreateFactory(
  105. D2D1_FACTORY_TYPE_SINGLE_THREADED,
  106. options,
  107. factory.put()));
  108. return factory;
  109. }
  110. inline auto
  111. CreateDXGISwapChain(
  112. winrt::com_ptr<ID3D11Device> const& device,
  113. const DXGI_SWAP_CHAIN_DESC1* desc)
  114. {
  115. auto dxgiDevice = device.as<IDXGIDevice2>();
  116. winrt::com_ptr<IDXGIAdapter> adapter;
  117. winrt::check_hresult(dxgiDevice->GetParent(winrt::guid_of<IDXGIAdapter>(), adapter.put_void()));
  118. winrt::com_ptr<IDXGIFactory2> factory;
  119. winrt::check_hresult(adapter->GetParent(winrt::guid_of<IDXGIFactory2>(), factory.put_void()));
  120. winrt::com_ptr<IDXGISwapChain1> swapchain;
  121. winrt::check_hresult(factory->CreateSwapChainForComposition(
  122. device.get(),
  123. desc,
  124. nullptr,
  125. swapchain.put()));
  126. return swapchain;
  127. }
  128. inline auto
  129. CreateDXGISwapChain(
  130. winrt::com_ptr<ID3D11Device> const& device,
  131. uint32_t width,
  132. uint32_t height,
  133. DXGI_FORMAT format,
  134. uint32_t bufferCount)
  135. {
  136. DXGI_SWAP_CHAIN_DESC1 desc = {};
  137. desc.Width = width;
  138. desc.Height = height;
  139. desc.Format = format;
  140. desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  141. desc.SampleDesc.Count = 1;
  142. desc.SampleDesc.Quality = 0;
  143. desc.BufferCount = bufferCount;
  144. desc.Scaling = DXGI_SCALING_STRETCH;
  145. desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
  146. desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
  147. return CreateDXGISwapChain(device, &desc);
  148. }