d3d11-rebuild.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /******************************************************************************
  2. Copyright (C) 2016 by Hugh 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. #include "d3d11-subsystem.hpp"
  15. inline void gs_vertex_buffer::Rebuild()
  16. {
  17. uvBuffers.clear();
  18. uvSizes.clear();
  19. BuildBuffers();
  20. }
  21. inline void gs_index_buffer::Rebuild(ID3D11Device *dev)
  22. {
  23. HRESULT hr = dev->CreateBuffer(&bd, &srd, &indexBuffer);
  24. if (FAILED(hr))
  25. throw HRError("Failed to create buffer", hr);
  26. }
  27. inline void gs_texture_2d::Rebuild(ID3D11Device *dev)
  28. {
  29. HRESULT hr;
  30. if (isShared) {
  31. hr = dev->OpenSharedResource((HANDLE)(uintptr_t)sharedHandle,
  32. __uuidof(ID3D11Texture2D), (void**)&texture);
  33. if (FAILED(hr))
  34. throw HRError("Failed to open shared 2D texture", hr);
  35. } else {
  36. hr = dev->CreateTexture2D(&td,
  37. data.size() ? srd.data() : nullptr,
  38. &texture);
  39. if (FAILED(hr))
  40. throw HRError("Failed to create 2D texture", hr);
  41. }
  42. hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes);
  43. if (FAILED(hr))
  44. throw HRError("Failed to create resource view", hr);
  45. if (isRenderTarget)
  46. InitRenderTargets();
  47. }
  48. inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev)
  49. {
  50. HRESULT hr;
  51. hr = dev->CreateTexture2D(&td, nullptr, &texture);
  52. if (FAILED(hr))
  53. throw HRError("Failed to create depth stencil texture", hr);
  54. hr = dev->CreateDepthStencilView(texture, &dsvd, &view);
  55. if (FAILED(hr))
  56. throw HRError("Failed to create depth stencil view", hr);
  57. }
  58. inline void gs_stage_surface::Rebuild(ID3D11Device *dev)
  59. {
  60. HRESULT hr = dev->CreateTexture2D(&td, nullptr, &texture);
  61. if (FAILED(hr))
  62. throw HRError("Failed to create staging surface", hr);
  63. }
  64. inline void gs_sampler_state::Rebuild(ID3D11Device *dev)
  65. {
  66. HRESULT hr = dev->CreateSamplerState(&sd, state.Assign());
  67. if (FAILED(hr))
  68. throw HRError("Failed to create sampler state", hr);
  69. }
  70. inline void gs_vertex_shader::Rebuild(ID3D11Device *dev)
  71. {
  72. HRESULT hr;
  73. hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, &shader);
  74. if (FAILED(hr))
  75. throw HRError("Failed to create vertex shader", hr);
  76. hr = dev->CreateInputLayout(layoutData.data(), (UINT)layoutData.size(),
  77. data.data(), data.size(), &layout);
  78. if (FAILED(hr))
  79. throw HRError("Failed to create input layout", hr);
  80. if (constantSize) {
  81. hr = dev->CreateBuffer(&bd, NULL, &constants);
  82. if (FAILED(hr))
  83. throw HRError("Failed to create constant buffer", hr);
  84. }
  85. for (gs_shader_param &param : params) {
  86. param.nextSampler = nullptr;
  87. param.curValue.clear();
  88. gs_shader_set_default(&param);
  89. }
  90. }
  91. inline void gs_pixel_shader::Rebuild(ID3D11Device *dev)
  92. {
  93. HRESULT hr;
  94. hr = dev->CreatePixelShader(data.data(), data.size(), nullptr,
  95. &shader);
  96. if (FAILED(hr))
  97. throw HRError("Failed to create pixel shader", hr);
  98. if (constantSize) {
  99. hr = dev->CreateBuffer(&bd, NULL, &constants);
  100. if (FAILED(hr))
  101. throw HRError("Failed to create constant buffer", hr);
  102. }
  103. for (gs_shader_param &param : params) {
  104. param.nextSampler = nullptr;
  105. param.curValue.clear();
  106. gs_shader_set_default(&param);
  107. }
  108. }
  109. inline void gs_swap_chain::Rebuild(ID3D11Device *dev)
  110. {
  111. HRESULT hr = device->factory->CreateSwapChain(dev, &swapDesc, &swap);
  112. if (FAILED(hr))
  113. throw HRError("Failed to create swap chain", hr);
  114. Init();
  115. }
  116. inline void SavedBlendState::Rebuild(ID3D11Device *dev)
  117. {
  118. HRESULT hr = dev->CreateBlendState(&bd, &state);
  119. if (FAILED(hr))
  120. throw HRError("Failed to create blend state", hr);
  121. }
  122. inline void SavedZStencilState::Rebuild(ID3D11Device *dev)
  123. {
  124. HRESULT hr = dev->CreateDepthStencilState(&dsd, &state);
  125. if (FAILED(hr))
  126. throw HRError("Failed to create depth stencil state", hr);
  127. }
  128. inline void SavedRasterState::Rebuild(ID3D11Device *dev)
  129. {
  130. HRESULT hr = dev->CreateRasterizerState(&rd, &state);
  131. if (FAILED(hr))
  132. throw HRError("Failed to create rasterizer state", hr);
  133. }
  134. const static D3D_FEATURE_LEVEL featureLevels[] =
  135. {
  136. D3D_FEATURE_LEVEL_11_0,
  137. D3D_FEATURE_LEVEL_10_1,
  138. D3D_FEATURE_LEVEL_10_0,
  139. D3D_FEATURE_LEVEL_9_3,
  140. };
  141. void gs_device::RebuildDevice()
  142. try {
  143. ID3D11Device *dev = nullptr;
  144. HRESULT hr;
  145. blog(LOG_WARNING, "Device Remove/Reset! Rebuilding all assets...");
  146. /* ----------------------------------------------------------------- */
  147. gs_obj *obj = first_obj;
  148. while (obj) {
  149. switch (obj->obj_type) {
  150. case gs_type::gs_vertex_buffer:
  151. ((gs_vertex_buffer*)obj)->Release();
  152. break;
  153. case gs_type::gs_index_buffer:
  154. ((gs_index_buffer*)obj)->Release();
  155. break;
  156. case gs_type::gs_texture_2d:
  157. ((gs_texture_2d*)obj)->Release();
  158. break;
  159. case gs_type::gs_zstencil_buffer:
  160. ((gs_zstencil_buffer*)obj)->Release();
  161. break;
  162. case gs_type::gs_stage_surface:
  163. ((gs_stage_surface*)obj)->Release();
  164. break;
  165. case gs_type::gs_sampler_state:
  166. ((gs_sampler_state*)obj)->Release();
  167. break;
  168. case gs_type::gs_vertex_shader:
  169. ((gs_vertex_shader*)obj)->Release();
  170. break;
  171. case gs_type::gs_pixel_shader:
  172. ((gs_pixel_shader*)obj)->Release();
  173. break;
  174. case gs_type::gs_duplicator:
  175. ((gs_duplicator*)obj)->Release();
  176. break;
  177. case gs_type::gs_swap_chain:
  178. ((gs_swap_chain*)obj)->Release();
  179. break;
  180. }
  181. obj = obj->next;
  182. }
  183. for (auto &state : zstencilStates)
  184. state.Release();
  185. for (auto &state : rasterStates)
  186. state.Release();
  187. for (auto &state : blendStates)
  188. state.Release();
  189. context->ClearState();
  190. context.Release();
  191. device.Release();
  192. adapter.Release();
  193. factory.Release();
  194. /* ----------------------------------------------------------------- */
  195. InitFactory(adpIdx);
  196. uint32_t createFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
  197. hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN,
  198. nullptr, createFlags, featureLevels,
  199. sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
  200. D3D11_SDK_VERSION, &device, nullptr, &context);
  201. if (FAILED(hr))
  202. throw HRError("Failed to create device", hr);
  203. dev = device;
  204. obj = first_obj;
  205. while (obj) {
  206. switch (obj->obj_type) {
  207. case gs_type::gs_vertex_buffer:
  208. ((gs_vertex_buffer*)obj)->Rebuild();
  209. break;
  210. case gs_type::gs_index_buffer:
  211. ((gs_index_buffer*)obj)->Rebuild(dev);
  212. break;
  213. case gs_type::gs_texture_2d:
  214. ((gs_texture_2d*)obj)->Rebuild(dev);
  215. break;
  216. case gs_type::gs_zstencil_buffer:
  217. ((gs_zstencil_buffer*)obj)->Rebuild(dev);
  218. break;
  219. case gs_type::gs_stage_surface:
  220. ((gs_stage_surface*)obj)->Rebuild(dev);
  221. break;
  222. case gs_type::gs_sampler_state:
  223. ((gs_sampler_state*)obj)->Rebuild(dev);
  224. break;
  225. case gs_type::gs_vertex_shader:
  226. ((gs_vertex_shader*)obj)->Rebuild(dev);
  227. break;
  228. case gs_type::gs_pixel_shader:
  229. ((gs_pixel_shader*)obj)->Rebuild(dev);
  230. break;
  231. case gs_type::gs_duplicator:
  232. ((gs_duplicator*)obj)->Start();
  233. break;
  234. case gs_type::gs_swap_chain:
  235. ((gs_swap_chain*)obj)->Rebuild(dev);
  236. break;
  237. }
  238. obj = obj->next;
  239. }
  240. curRenderTarget = nullptr;
  241. curZStencilBuffer = nullptr;
  242. curRenderSide = 0;
  243. memset(&curTextures, 0, sizeof(curTextures));
  244. memset(&curSamplers, 0, sizeof(curSamplers));
  245. curVertexBuffer = nullptr;
  246. curIndexBuffer = nullptr;
  247. curVertexShader = nullptr;
  248. curPixelShader = nullptr;
  249. curSwapChain = nullptr;
  250. zstencilStateChanged = true;
  251. rasterStateChanged = true;
  252. blendStateChanged = true;
  253. curDepthStencilState = nullptr;
  254. curRasterState = nullptr;
  255. curBlendState = nullptr;
  256. curToplogy = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
  257. for (auto &state : zstencilStates)
  258. state.Rebuild(dev);
  259. for (auto &state : rasterStates)
  260. state.Rebuild(dev);
  261. for (auto &state : blendStates)
  262. state.Rebuild(dev);
  263. } catch (const char *error) {
  264. bcrash("Failed to recreate D3D11: %s", error);
  265. } catch (HRError error) {
  266. bcrash("Failed to recreate D3D11: %s (%08lX)",
  267. error.str, error.hr);
  268. }