CmD3D11RenderSystem.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #include "CmD3D11RenderSystem.h"
  2. #include "CmD3D11DriverList.h"
  3. #include "CmD3D11Driver.h"
  4. #include "CmD3D11Device.h"
  5. #include "CmD3D11TextureManager.h"
  6. #include "CmD3D11HardwareBufferManager.h"
  7. #include "CmD3D11GpuProgramManager.h"
  8. #include "CmD3D11RenderWindowManager.h"
  9. #include "CmD3D11HLSLProgramFactory.h"
  10. #include "CmRenderSystem.h"
  11. #include "CmDebug.h"
  12. #include "CmException.h"
  13. namespace CamelotEngine
  14. {
  15. D3D11RenderSystem::D3D11RenderSystem()
  16. : mDXGIFactory(nullptr), mDevice(nullptr), mDriverList(nullptr)
  17. , mActiveD3DDriver(nullptr), mFeatureLevel(D3D_FEATURE_LEVEL_9_1)
  18. , mHLSLFactory(nullptr)
  19. {
  20. }
  21. D3D11RenderSystem::~D3D11RenderSystem()
  22. {
  23. destroy_internal();
  24. }
  25. const String& D3D11RenderSystem::getName() const
  26. {
  27. static String strName("D3D11RenderSystem");
  28. return strName;
  29. }
  30. void D3D11RenderSystem::initialize_internal()
  31. {
  32. HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&mDXGIFactory);
  33. if(FAILED(hr))
  34. CM_EXCEPT(RenderingAPIException, "Failed to create Direct3D11 DXGIFactory");
  35. mDriverList = new D3D11DriverList(mDXGIFactory);
  36. mActiveD3DDriver = mDriverList->item(0); // TODO: Always get first driver, for now
  37. IDXGIAdapter* selectedAdapter = mActiveD3DDriver->getDeviceAdapter();
  38. D3D_FEATURE_LEVEL requestedLevels[] = {
  39. D3D_FEATURE_LEVEL_11_0,
  40. D3D_FEATURE_LEVEL_10_1,
  41. D3D_FEATURE_LEVEL_10_0,
  42. D3D_FEATURE_LEVEL_9_3,
  43. D3D_FEATURE_LEVEL_9_2,
  44. D3D_FEATURE_LEVEL_9_1
  45. };
  46. UINT32 numRequestedLevel = sizeof(requestedLevels) / sizeof(requestedLevels[0]);
  47. ID3D11Device* device;
  48. hr = D3D11CreateDevice(selectedAdapter, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0,
  49. requestedLevels, numRequestedLevel, D3D11_SDK_VERSION, &device, &mFeatureLevel, 0);
  50. if(FAILED(hr))
  51. CM_EXCEPT(RenderingAPIException, "Failed to create Direct3D11 object. D3D11CreateDeviceN returned this error code: " + toString(hr));
  52. mDevice = new D3D11Device(device);
  53. LARGE_INTEGER driverVersion;
  54. if(SUCCEEDED(selectedAdapter->CheckInterfaceSupport(IID_ID3D10Device /* intentionally D3D10, not D3D11 */, &driverVersion)))
  55. {
  56. mDriverVersion.major = HIWORD(driverVersion.HighPart);
  57. mDriverVersion.minor = LOWORD(driverVersion.HighPart);
  58. mDriverVersion.release = HIWORD(driverVersion.LowPart);
  59. mDriverVersion.build = LOWORD(driverVersion.LowPart);
  60. }
  61. // Create the texture manager for use by others
  62. TextureManager::startUp(new D3D11TextureManager());
  63. // Also create hardware buffer manager
  64. HardwareBufferManager::startUp(new D3D11HardwareBufferManager(*mDevice));
  65. // Create the GPU program manager
  66. GpuProgramManager::startUp(new D3D11GpuProgramManager(*mDevice));
  67. // Create render window manager
  68. RenderWindowManager::startUp(new D3D11RenderWindowManager(this));
  69. // Create & register HLSL factory
  70. mHLSLFactory = new D3D11HLSLProgramFactory();
  71. RenderSystem::initialize_internal();
  72. }
  73. void D3D11RenderSystem::destroy_internal()
  74. {
  75. SAFE_DELETE(mHLSLFactory);
  76. RenderWindowManager::shutDown();
  77. GpuProgramManager::shutDown();
  78. HardwareBufferManager::shutDown();
  79. TextureManager::shutDown();
  80. SAFE_RELEASE(mDXGIFactory);
  81. SAFE_DELETE(mDevice);
  82. SAFE_DELETE(mDriverList);
  83. mActiveD3DDriver = nullptr;
  84. RenderSystem::destroy_internal();
  85. }
  86. void D3D11RenderSystem::setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState)
  87. {
  88. throw std::exception("The method or operation is not implemented.");
  89. }
  90. void D3D11RenderSystem::setBlendState(const BlendState& blendState)
  91. {
  92. throw std::exception("The method or operation is not implemented.");
  93. }
  94. void D3D11RenderSystem::setRasterizerState(const RasterizerState& rasterizerState)
  95. {
  96. throw std::exception("The method or operation is not implemented.");
  97. }
  98. void D3D11RenderSystem::setDepthStencilState(const DepthStencilState& depthStencilState)
  99. {
  100. throw std::exception("The method or operation is not implemented.");
  101. }
  102. void D3D11RenderSystem::setStencilRefValue(UINT32 refValue)
  103. {
  104. throw std::exception("The method or operation is not implemented.");
  105. }
  106. void D3D11RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
  107. {
  108. throw std::exception("The method or operation is not implemented.");
  109. }
  110. void D3D11RenderSystem::disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
  111. {
  112. throw std::exception("The method or operation is not implemented.");
  113. }
  114. void D3D11RenderSystem::beginFrame()
  115. {
  116. // Not used
  117. }
  118. void D3D11RenderSystem::endFrame()
  119. {
  120. // Not used
  121. }
  122. void D3D11RenderSystem::setViewport(const Viewport& vp)
  123. {
  124. throw std::exception("The method or operation is not implemented.");
  125. }
  126. void D3D11RenderSystem::setVertexDeclaration(VertexDeclarationPtr decl)
  127. {
  128. throw std::exception("The method or operation is not implemented.");
  129. }
  130. void D3D11RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding)
  131. {
  132. throw std::exception("The method or operation is not implemented.");
  133. }
  134. void D3D11RenderSystem::bindGpuProgram(GpuProgramHandle prg)
  135. {
  136. throw std::exception("The method or operation is not implemented.");
  137. }
  138. void D3D11RenderSystem::unbindGpuProgram(GpuProgramType gptype)
  139. {
  140. throw std::exception("The method or operation is not implemented.");
  141. }
  142. void D3D11RenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
  143. {
  144. throw std::exception("The method or operation is not implemented.");
  145. }
  146. void D3D11RenderSystem::setScissorRect(UINT32 left /*= 0*/, UINT32 top /*= 0*/, UINT32 right /*= 800*/, UINT32 bottom /*= 600 */)
  147. {
  148. throw std::exception("The method or operation is not implemented.");
  149. }
  150. void D3D11RenderSystem::clear(RenderTargetPtr target, unsigned int buffers, const Color& color /*= Color::Black*/, float depth /*= 1.0f*/, unsigned short stencil /*= 0 */)
  151. {
  152. //mDevice->getImmediateContext()->c
  153. throw std::exception("The method or operation is not implemented.");
  154. }
  155. void D3D11RenderSystem::setRenderTarget(RenderTarget* target)
  156. {
  157. //if(target != nullptr)
  158. //{
  159. // mRenderViews
  160. //}
  161. //else
  162. //{
  163. //}
  164. throw std::exception("The method or operation is not implemented.");
  165. }
  166. void D3D11RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes)
  167. {
  168. LOGWRN("This call will be ignored. DX11 uses shaders for setting clip planes.");
  169. }
  170. RenderSystemCapabilities* D3D11RenderSystem::createRenderSystemCapabilities() const
  171. {
  172. throw std::exception("The method or operation is not implemented.");
  173. }
  174. void D3D11RenderSystem::initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps)
  175. {
  176. throw std::exception("The method or operation is not implemented.");
  177. }
  178. String D3D11RenderSystem::getErrorDescription(long errorNumber) const
  179. {
  180. return mDevice->getErrorDescription();
  181. }
  182. void D3D11RenderSystem::determineFSAASettings(UINT32 fsaa, const String& fsaaHint, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings)
  183. {
  184. bool ok = false;
  185. bool qualityHint = fsaaHint.find("Quality") != String::npos;
  186. size_t origFSAA = fsaa;
  187. bool tryCSAA = false;
  188. // NVIDIA, prefer CSAA if available for 8+
  189. // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but
  190. // if this is the first window, caps will not be initialised yet
  191. if (mActiveD3DDriver->getAdapterIdentifier().VendorId == 0x10DE &&
  192. fsaa >= 8)
  193. {
  194. tryCSAA = true;
  195. }
  196. while (!ok)
  197. {
  198. // Deal with special cases
  199. if (tryCSAA)
  200. {
  201. // see http://developer.nvidia.com/object/coverage-sampled-aa.html
  202. switch(fsaa)
  203. {
  204. case 8:
  205. if (qualityHint)
  206. {
  207. outFSAASettings->Count = 8;
  208. outFSAASettings->Quality = 8;
  209. }
  210. else
  211. {
  212. outFSAASettings->Count = 4;
  213. outFSAASettings->Quality = 8;
  214. }
  215. break;
  216. case 16:
  217. if (qualityHint)
  218. {
  219. outFSAASettings->Count = 8;
  220. outFSAASettings->Quality = 16;
  221. }
  222. else
  223. {
  224. outFSAASettings->Count = 4;
  225. outFSAASettings->Quality = 16;
  226. }
  227. break;
  228. }
  229. }
  230. else // !CSAA
  231. {
  232. outFSAASettings->Count = fsaa == 0 ? 1 : fsaa;
  233. outFSAASettings->Quality = 0;
  234. }
  235. HRESULT hr;
  236. UINT outQuality;
  237. hr = mDevice->getD3D11Device()->CheckMultisampleQualityLevels(format, outFSAASettings->Count, &outQuality);
  238. if (SUCCEEDED(hr) && (!tryCSAA || outQuality > outFSAASettings->Quality))
  239. {
  240. ok = true;
  241. }
  242. else
  243. {
  244. // downgrade
  245. if (tryCSAA && fsaa == 8)
  246. {
  247. // for CSAA, we'll try downgrading with quality mode at all samples.
  248. // then try without quality, then drop CSAA
  249. if (qualityHint)
  250. {
  251. // drop quality first
  252. qualityHint = false;
  253. }
  254. else
  255. {
  256. // drop CSAA entirely
  257. tryCSAA = false;
  258. }
  259. // return to original requested samples
  260. fsaa = static_cast<UINT32>(origFSAA);
  261. }
  262. else
  263. {
  264. // drop samples
  265. --fsaa;
  266. if (fsaa == 1)
  267. {
  268. // ran out of options, no FSAA
  269. fsaa = 0;
  270. ok = true;
  271. }
  272. }
  273. }
  274. } // while !ok
  275. }
  276. bool D3D11RenderSystem::checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage)
  277. {
  278. return true;
  279. }
  280. VertexElementType D3D11RenderSystem::getColorVertexElementType() const
  281. {
  282. return VET_COLOR_ABGR;
  283. }
  284. void D3D11RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram /*= false */)
  285. {
  286. dest = matrix;
  287. // Convert depth range from [-1,+1] to [0,1]
  288. dest[2][0] = (dest[2][0] + dest[3][0]) / 2;
  289. dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
  290. dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
  291. dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
  292. if (!forGpuProgram)
  293. {
  294. // Convert right-handed to left-handed
  295. dest[0][2] = -dest[0][2];
  296. dest[1][2] = -dest[1][2];
  297. dest[2][2] = -dest[2][2];
  298. dest[3][2] = -dest[3][2];
  299. }
  300. }
  301. float D3D11RenderSystem::getHorizontalTexelOffset()
  302. {
  303. return 0.0f;
  304. }
  305. float D3D11RenderSystem::getVerticalTexelOffset()
  306. {
  307. return 0.0f;
  308. }
  309. float D3D11RenderSystem::getMinimumDepthInputValue()
  310. {
  311. return 0.0f;
  312. }
  313. float D3D11RenderSystem::getMaximumDepthInputValue()
  314. {
  315. return -1.0f;
  316. }
  317. }