PageRenderTime 69ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/lib_angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp

https://bitbucket.org/xixs/lua
C++ | 3375 lines | 2674 code | 564 blank | 137 comment | 518 complexity | f4a36269050b3819983316f65a5f964b MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, CC0-1.0, GPL-3.0, GPL-2.0, CPL-1.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, LGPL-2.1, LGPL-3.0, 0BSD, Cube

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style license that can be
  4. // found in the LICENSE file.
  5. //
  6. // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
  7. #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
  8. #include "common/utilities.h"
  9. #include "common/tls.h"
  10. #include "libANGLE/Buffer.h"
  11. #include "libANGLE/Display.h"
  12. #include "libANGLE/Framebuffer.h"
  13. #include "libANGLE/FramebufferAttachment.h"
  14. #include "libANGLE/Program.h"
  15. #include "libANGLE/State.h"
  16. #include "libANGLE/Surface.h"
  17. #include "libANGLE/formatutils.h"
  18. #include "libANGLE/renderer/d3d/CompilerD3D.h"
  19. #include "libANGLE/renderer/d3d/FramebufferD3D.h"
  20. #include "libANGLE/renderer/d3d/IndexDataManager.h"
  21. #include "libANGLE/renderer/d3d/ProgramD3D.h"
  22. #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
  23. #include "libANGLE/renderer/d3d/ShaderD3D.h"
  24. #include "libANGLE/renderer/d3d/SurfaceD3D.h"
  25. #include "libANGLE/renderer/d3d/TextureD3D.h"
  26. #include "libANGLE/renderer/d3d/TransformFeedbackD3D.h"
  27. #include "libANGLE/renderer/d3d/VertexDataManager.h"
  28. #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
  29. #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
  30. #include "libANGLE/renderer/d3d/d3d11/Clear11.h"
  31. #include "libANGLE/renderer/d3d/d3d11/Fence11.h"
  32. #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
  33. #include "libANGLE/renderer/d3d/d3d11/Image11.h"
  34. #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
  35. #include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
  36. #include "libANGLE/renderer/d3d/d3d11/Query11.h"
  37. #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
  38. #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
  39. #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
  40. #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
  41. #include "libANGLE/renderer/d3d/d3d11/Trim11.h"
  42. #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
  43. #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
  44. #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
  45. #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
  46. #include <sstream>
  47. #include <EGL/eglext.h>
  48. // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
  49. // HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
  50. #ifndef ANGLE_SKIP_DXGI_1_2_CHECK
  51. #define ANGLE_SKIP_DXGI_1_2_CHECK 0
  52. #endif
  53. #ifdef _DEBUG
  54. // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
  55. // and conformance tests. to enable all warnings, remove this define.
  56. #define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
  57. #endif
  58. namespace rx
  59. {
  60. namespace
  61. {
  62. static const DXGI_FORMAT RenderTargetFormats[] =
  63. {
  64. DXGI_FORMAT_B8G8R8A8_UNORM,
  65. DXGI_FORMAT_R8G8B8A8_UNORM
  66. };
  67. static const DXGI_FORMAT DepthStencilFormats[] =
  68. {
  69. DXGI_FORMAT_UNKNOWN,
  70. DXGI_FORMAT_D24_UNORM_S8_UINT,
  71. DXGI_FORMAT_D16_UNORM
  72. };
  73. enum
  74. {
  75. MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
  76. };
  77. static bool ImageIndexConflictsWithSRV(const gl::ImageIndex *index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
  78. {
  79. unsigned mipLevel = index->mipIndex;
  80. unsigned layerIndex = index->layerIndex;
  81. GLenum type = index->type;
  82. switch (desc.ViewDimension)
  83. {
  84. case D3D11_SRV_DIMENSION_TEXTURE2D:
  85. {
  86. unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
  87. maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip;
  88. unsigned mipMin = index->mipIndex;
  89. unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex;
  90. return type == GL_TEXTURE_2D && RangeUI(mipMin, mipMax).intersects(RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
  91. }
  92. case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
  93. {
  94. unsigned maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
  95. maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip;
  96. unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
  97. // Cube maps can be mapped to Texture2DArray SRVs
  98. return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) &&
  99. desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
  100. desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice;
  101. }
  102. case D3D11_SRV_DIMENSION_TEXTURECUBE:
  103. {
  104. unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
  105. maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip;
  106. return gl::IsCubeMapTextureTarget(type) &&
  107. desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
  108. }
  109. case D3D11_SRV_DIMENSION_TEXTURE3D:
  110. {
  111. unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
  112. maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip;
  113. return type == GL_TEXTURE_3D &&
  114. desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
  115. }
  116. default:
  117. // We only handle the cases corresponding to valid image indexes
  118. UNIMPLEMENTED();
  119. }
  120. return false;
  121. }
  122. // Does *not* increment the resource ref count!!
  123. ID3D11Resource *GetSRVResource(ID3D11ShaderResourceView *srv)
  124. {
  125. ID3D11Resource *resource = NULL;
  126. ASSERT(srv);
  127. srv->GetResource(&resource);
  128. resource->Release();
  129. return resource;
  130. }
  131. }
  132. Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, const egl::AttributeMap &attributes)
  133. : RendererD3D(display),
  134. mDc(hDc),
  135. mStateCache(this)
  136. {
  137. mVertexDataManager = NULL;
  138. mIndexDataManager = NULL;
  139. mLineLoopIB = NULL;
  140. mTriangleFanIB = NULL;
  141. mBlit = NULL;
  142. mPixelTransfer = NULL;
  143. mClear = NULL;
  144. mTrim = NULL;
  145. mSyncQuery = NULL;
  146. mD3d11Module = NULL;
  147. mDxgiModule = NULL;
  148. mDevice = NULL;
  149. mDeviceContext = NULL;
  150. mDeviceContext1 = NULL;
  151. mDxgiAdapter = NULL;
  152. mDxgiFactory = NULL;
  153. mDriverConstantBufferVS = NULL;
  154. mDriverConstantBufferPS = NULL;
  155. mAppliedVertexShader = NULL;
  156. mAppliedGeometryShader = NULL;
  157. mAppliedPixelShader = NULL;
  158. EGLint requestedMajorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE);
  159. EGLint requestedMinorVersion = attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE);
  160. if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
  161. {
  162. if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
  163. {
  164. mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
  165. }
  166. }
  167. if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
  168. {
  169. if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
  170. {
  171. mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
  172. }
  173. if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
  174. {
  175. mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
  176. }
  177. }
  178. if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
  179. {
  180. mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
  181. }
  182. mDriverType = (attributes.get(EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_FALSE) == EGL_TRUE) ? D3D_DRIVER_TYPE_WARP
  183. : D3D_DRIVER_TYPE_HARDWARE;
  184. }
  185. Renderer11::~Renderer11()
  186. {
  187. release();
  188. }
  189. Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
  190. {
  191. ASSERT(HAS_DYNAMIC_TYPE(Renderer11*, renderer));
  192. return static_cast<Renderer11*>(renderer);
  193. }
  194. #ifndef __d3d11_1_h__
  195. #define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
  196. #endif
  197. EGLint Renderer11::initialize()
  198. {
  199. if (!mCompiler.initialize())
  200. {
  201. return EGL_NOT_INITIALIZED;
  202. }
  203. #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
  204. mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
  205. mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
  206. if (mD3d11Module == NULL || mDxgiModule == NULL)
  207. {
  208. ERR("Could not load D3D11 or DXGI library - aborting!\n");
  209. return EGL_NOT_INITIALIZED;
  210. }
  211. // create the D3D11 device
  212. ASSERT(mDevice == NULL);
  213. PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
  214. if (D3D11CreateDevice == NULL)
  215. {
  216. ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
  217. return EGL_NOT_INITIALIZED;
  218. }
  219. #endif
  220. HRESULT result = S_OK;
  221. #ifdef _DEBUG
  222. result = D3D11CreateDevice(NULL,
  223. mDriverType,
  224. NULL,
  225. D3D11_CREATE_DEVICE_DEBUG,
  226. mAvailableFeatureLevels.data(),
  227. mAvailableFeatureLevels.size(),
  228. D3D11_SDK_VERSION,
  229. &mDevice,
  230. &mFeatureLevel,
  231. &mDeviceContext);
  232. if (!mDevice || FAILED(result))
  233. {
  234. ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
  235. }
  236. if (!mDevice || FAILED(result))
  237. #endif
  238. {
  239. result = D3D11CreateDevice(NULL,
  240. mDriverType,
  241. NULL,
  242. 0,
  243. mAvailableFeatureLevels.data(),
  244. mAvailableFeatureLevels.size(),
  245. D3D11_SDK_VERSION,
  246. &mDevice,
  247. &mFeatureLevel,
  248. &mDeviceContext);
  249. if (!mDevice || FAILED(result))
  250. {
  251. ERR("Could not create D3D11 device - aborting!\n");
  252. return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
  253. }
  254. }
  255. #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
  256. #if !ANGLE_SKIP_DXGI_1_2_CHECK
  257. // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
  258. // The easiest way to check is to query for a IDXGIDevice2.
  259. bool requireDXGI1_2 = false;
  260. HWND hwnd = WindowFromDC(mDc);
  261. if (hwnd)
  262. {
  263. DWORD currentProcessId = GetCurrentProcessId();
  264. DWORD wndProcessId;
  265. GetWindowThreadProcessId(hwnd, &wndProcessId);
  266. requireDXGI1_2 = (currentProcessId != wndProcessId);
  267. }
  268. else
  269. {
  270. requireDXGI1_2 = true;
  271. }
  272. if (requireDXGI1_2)
  273. {
  274. IDXGIDevice2 *dxgiDevice2 = NULL;
  275. result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
  276. if (FAILED(result))
  277. {
  278. ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n");
  279. return EGL_NOT_INITIALIZED;
  280. }
  281. SafeRelease(dxgiDevice2);
  282. }
  283. #endif
  284. #endif
  285. // Cast the DeviceContext to a DeviceContext1.
  286. // This could fail on Windows 7 without the Platform Update.
  287. // Don't error in this case- just don't use mDeviceContext1.
  288. mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
  289. IDXGIDevice *dxgiDevice = NULL;
  290. result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
  291. if (FAILED(result))
  292. {
  293. ERR("Could not query DXGI device - aborting!\n");
  294. return EGL_NOT_INITIALIZED;
  295. }
  296. result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
  297. if (FAILED(result))
  298. {
  299. ERR("Could not retrieve DXGI adapter - aborting!\n");
  300. return EGL_NOT_INITIALIZED;
  301. }
  302. SafeRelease(dxgiDevice);
  303. IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
  304. // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string.
  305. // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual hardware values.
  306. if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL)
  307. {
  308. DXGI_ADAPTER_DESC2 adapterDesc2 = {0};
  309. dxgiAdapter2->GetDesc2(&adapterDesc2);
  310. // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a DXGI_ADAPTER_DESC).
  311. memcpy(mAdapterDescription.Description, adapterDesc2.Description, sizeof(mAdapterDescription.Description));
  312. mAdapterDescription.VendorId = adapterDesc2.VendorId;
  313. mAdapterDescription.DeviceId = adapterDesc2.DeviceId;
  314. mAdapterDescription.SubSysId = adapterDesc2.SubSysId;
  315. mAdapterDescription.Revision = adapterDesc2.Revision;
  316. mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory;
  317. mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory;
  318. mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory;
  319. mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid;
  320. }
  321. else
  322. {
  323. mDxgiAdapter->GetDesc(&mAdapterDescription);
  324. }
  325. SafeRelease(dxgiAdapter2);
  326. memset(mDescription, 0, sizeof(mDescription));
  327. wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
  328. result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
  329. if (!mDxgiFactory || FAILED(result))
  330. {
  331. ERR("Could not create DXGI factory - aborting!\n");
  332. return EGL_NOT_INITIALIZED;
  333. }
  334. // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
  335. #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
  336. ID3D11InfoQueue *infoQueue;
  337. result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
  338. if (SUCCEEDED(result))
  339. {
  340. D3D11_MESSAGE_ID hideMessages[] =
  341. {
  342. D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
  343. };
  344. D3D11_INFO_QUEUE_FILTER filter = {0};
  345. filter.DenyList.NumIDs = ArraySize(hideMessages);
  346. filter.DenyList.pIDList = hideMessages;
  347. infoQueue->AddStorageFilterEntries(&filter);
  348. SafeRelease(infoQueue);
  349. }
  350. #endif
  351. initializeDevice();
  352. return EGL_SUCCESS;
  353. }
  354. // do any one-time device initialization
  355. // NOTE: this is also needed after a device lost/reset
  356. // to reset the scene status and ensure the default states are reset.
  357. void Renderer11::initializeDevice()
  358. {
  359. mStateCache.initialize(mDevice);
  360. mInputLayoutCache.initialize(mDevice, mDeviceContext);
  361. ASSERT(!mVertexDataManager && !mIndexDataManager);
  362. mVertexDataManager = new VertexDataManager(this);
  363. mIndexDataManager = new IndexDataManager(this);
  364. ASSERT(!mBlit);
  365. mBlit = new Blit11(this);
  366. ASSERT(!mClear);
  367. mClear = new Clear11(this);
  368. ASSERT(!mTrim);
  369. mTrim = new Trim11(this);
  370. ASSERT(!mPixelTransfer);
  371. mPixelTransfer = new PixelTransfer11(this);
  372. const gl::Caps &rendererCaps = getRendererCaps();
  373. mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
  374. mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits);
  375. mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
  376. mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits);
  377. mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits);
  378. mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits);
  379. markAllStateDirty();
  380. }
  381. std::vector<ConfigDesc> Renderer11::generateConfigs() const
  382. {
  383. std::vector<ConfigDesc> configs;
  384. unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
  385. unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
  386. for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
  387. {
  388. const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]);
  389. const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat);
  390. if (renderTargetFormatCaps.renderable)
  391. {
  392. for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
  393. {
  394. const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]);
  395. const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat);
  396. if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN)
  397. {
  398. ConfigDesc newConfig;
  399. newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat;
  400. newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat;
  401. newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
  402. newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
  403. // Before we check mFeatureLevel, we need to ensure that the D3D device has been created.
  404. ASSERT(mDevice != NULL);
  405. newConfig.es2Conformant = (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
  406. newConfig.es3Capable = isES3Capable();
  407. configs.push_back(newConfig);
  408. }
  409. }
  410. }
  411. }
  412. return configs;
  413. }
  414. gl::Error Renderer11::flush()
  415. {
  416. mDeviceContext->Flush();
  417. return gl::Error(GL_NO_ERROR);
  418. }
  419. gl::Error Renderer11::finish()
  420. {
  421. HRESULT result;
  422. if (!mSyncQuery)
  423. {
  424. D3D11_QUERY_DESC queryDesc;
  425. queryDesc.Query = D3D11_QUERY_EVENT;
  426. queryDesc.MiscFlags = 0;
  427. result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
  428. ASSERT(SUCCEEDED(result));
  429. if (FAILED(result))
  430. {
  431. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result);
  432. }
  433. }
  434. mDeviceContext->End(mSyncQuery);
  435. mDeviceContext->Flush();
  436. do
  437. {
  438. result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
  439. if (FAILED(result))
  440. {
  441. return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result);
  442. }
  443. // Keep polling, but allow other threads to do something useful first
  444. ScheduleYield();
  445. if (testDeviceLost())
  446. {
  447. mDisplay->notifyDeviceLost();
  448. return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync.");
  449. }
  450. }
  451. while (result == S_FALSE);
  452. return gl::Error(GL_NO_ERROR);
  453. }
  454. SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
  455. {
  456. return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat);
  457. }
  458. gl::Error Renderer11::generateSwizzle(gl::Texture *texture)
  459. {
  460. if (texture)
  461. {
  462. TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
  463. ASSERT(textureD3D);
  464. TextureStorage *texStorage = textureD3D->getNativeTexture();
  465. if (texStorage)
  466. {
  467. TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
  468. gl::Error error = storage11->generateSwizzles(texture->getSamplerState().swizzleRed,
  469. texture->getSamplerState().swizzleGreen,
  470. texture->getSamplerState().swizzleBlue,
  471. texture->getSamplerState().swizzleAlpha);
  472. if (error.isError())
  473. {
  474. return error;
  475. }
  476. }
  477. }
  478. return gl::Error(GL_NO_ERROR);
  479. }
  480. gl::Error Renderer11::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerStateParam)
  481. {
  482. // Make sure to add the level offset for our tiny compressed texture workaround
  483. TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
  484. gl::SamplerState samplerStateInternal = samplerStateParam;
  485. samplerStateInternal.baseLevel += textureD3D->getNativeTexture()->getTopLevel();
  486. if (type == gl::SAMPLER_PIXEL)
  487. {
  488. ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits);
  489. if (mForceSetPixelSamplerStates[index] || memcmp(&samplerStateInternal, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
  490. {
  491. ID3D11SamplerState *dxSamplerState = NULL;
  492. gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
  493. if (error.isError())
  494. {
  495. return error;
  496. }
  497. ASSERT(dxSamplerState != NULL);
  498. mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
  499. mCurPixelSamplerStates[index] = samplerStateInternal;
  500. }
  501. mForceSetPixelSamplerStates[index] = false;
  502. }
  503. else if (type == gl::SAMPLER_VERTEX)
  504. {
  505. ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits);
  506. if (mForceSetVertexSamplerStates[index] || memcmp(&samplerStateInternal, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
  507. {
  508. ID3D11SamplerState *dxSamplerState = NULL;
  509. gl::Error error = mStateCache.getSamplerState(samplerStateInternal, &dxSamplerState);
  510. if (error.isError())
  511. {
  512. return error;
  513. }
  514. ASSERT(dxSamplerState != NULL);
  515. mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
  516. mCurVertexSamplerStates[index] = samplerStateInternal;
  517. }
  518. mForceSetVertexSamplerStates[index] = false;
  519. }
  520. else UNREACHABLE();
  521. return gl::Error(GL_NO_ERROR);
  522. }
  523. gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
  524. {
  525. ID3D11ShaderResourceView *textureSRV = NULL;
  526. if (texture)
  527. {
  528. TextureD3D *textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation());
  529. TextureStorage *texStorage = textureImpl->getNativeTexture();
  530. ASSERT(texStorage != NULL);
  531. TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage);
  532. // Make sure to add the level offset for our tiny compressed texture workaround
  533. gl::SamplerState samplerState = texture->getSamplerState();
  534. samplerState.baseLevel += storage11->getTopLevel();
  535. gl::Error error = storage11->getSRV(samplerState, &textureSRV);
  536. if (error.isError())
  537. {
  538. return error;
  539. }
  540. // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
  541. // missing the shader resource view
  542. ASSERT(textureSRV != NULL);
  543. textureImpl->resetDirty();
  544. }
  545. ASSERT((type == gl::SAMPLER_PIXEL && static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits) ||
  546. (type == gl::SAMPLER_VERTEX && static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits));
  547. setShaderResource(type, index, textureSRV);
  548. return gl::Error(GL_NO_ERROR);
  549. }
  550. gl::Error Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[])
  551. {
  552. for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
  553. {
  554. const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex];
  555. if (uniformBuffer)
  556. {
  557. Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
  558. ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
  559. if (!constantBuffer)
  560. {
  561. return gl::Error(GL_OUT_OF_MEMORY);
  562. }
  563. if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial())
  564. {
  565. mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex,
  566. 1, &constantBuffer);
  567. mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial();
  568. }
  569. }
  570. }
  571. for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++)
  572. {
  573. const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex];
  574. if (uniformBuffer)
  575. {
  576. Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation());
  577. ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM);
  578. if (!constantBuffer)
  579. {
  580. return gl::Error(GL_OUT_OF_MEMORY);
  581. }
  582. if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial())
  583. {
  584. mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex,
  585. 1, &constantBuffer);
  586. mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial();
  587. }
  588. }
  589. }
  590. return gl::Error(GL_NO_ERROR);
  591. }
  592. gl::Error Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
  593. {
  594. if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
  595. {
  596. ID3D11RasterizerState *dxRasterState = NULL;
  597. gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState);
  598. if (error.isError())
  599. {
  600. return error;
  601. }
  602. mDeviceContext->RSSetState(dxRasterState);
  603. mCurRasterState = rasterState;
  604. }
  605. mForceSetRasterState = false;
  606. return gl::Error(GL_NO_ERROR);
  607. }
  608. gl::Error Renderer11::setBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor,
  609. unsigned int sampleMask)
  610. {
  611. if (mForceSetBlendState ||
  612. memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
  613. memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 ||
  614. sampleMask != mCurSampleMask)
  615. {
  616. ID3D11BlendState *dxBlendState = NULL;
  617. gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState);
  618. if (error.isError())
  619. {
  620. return error;
  621. }
  622. ASSERT(dxBlendState != NULL);
  623. float blendColors[4] = {0.0f};
  624. if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
  625. blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
  626. {
  627. blendColors[0] = blendColor.red;
  628. blendColors[1] = blendColor.green;
  629. blendColors[2] = blendColor.blue;
  630. blendColors[3] = blendColor.alpha;
  631. }
  632. else
  633. {
  634. blendColors[0] = blendColor.alpha;
  635. blendColors[1] = blendColor.alpha;
  636. blendColors[2] = blendColor.alpha;
  637. blendColors[3] = blendColor.alpha;
  638. }
  639. mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
  640. mCurBlendState = blendState;
  641. mCurBlendColor = blendColor;
  642. mCurSampleMask = sampleMask;
  643. }
  644. mForceSetBlendState = false;
  645. return gl::Error(GL_NO_ERROR);
  646. }
  647. gl::Error Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
  648. int stencilBackRef, bool frontFaceCCW)
  649. {
  650. if (mForceSetDepthStencilState ||
  651. memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
  652. stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
  653. {
  654. ASSERT(depthStencilState.stencilWritemask == depthStencilState.stencilBackWritemask);
  655. ASSERT(stencilRef == stencilBackRef);
  656. ASSERT(depthStencilState.stencilMask == depthStencilState.stencilBackMask);
  657. ID3D11DepthStencilState *dxDepthStencilState = NULL;
  658. gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState);
  659. if (error.isError())
  660. {
  661. return error;
  662. }
  663. ASSERT(dxDepthStencilState);
  664. // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer
  665. // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops
  666. META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF);
  667. META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF);
  668. UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu);
  669. mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef);
  670. mCurDepthStencilState = depthStencilState;
  671. mCurStencilRef = stencilRef;
  672. mCurStencilBackRef = stencilBackRef;
  673. }
  674. mForceSetDepthStencilState = false;
  675. return gl::Error(GL_NO_ERROR);
  676. }
  677. void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
  678. {
  679. if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
  680. enabled != mScissorEnabled)
  681. {
  682. if (enabled)
  683. {
  684. D3D11_RECT rect;
  685. rect.left = std::max(0, scissor.x);
  686. rect.top = std::max(0, scissor.y);
  687. rect.right = scissor.x + std::max(0, scissor.width);
  688. rect.bottom = scissor.y + std::max(0, scissor.height);
  689. mDeviceContext->RSSetScissorRects(1, &rect);
  690. }
  691. if (enabled != mScissorEnabled)
  692. {
  693. mForceSetRasterState = true;
  694. }
  695. mCurScissor = scissor;
  696. mScissorEnabled = enabled;
  697. }
  698. mForceSetScissor = false;
  699. }
  700. void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
  701. bool ignoreViewport)
  702. {
  703. gl::Rectangle actualViewport = viewport;
  704. float actualZNear = gl::clamp01(zNear);
  705. float actualZFar = gl::clamp01(zFar);
  706. if (ignoreViewport)
  707. {
  708. actualViewport.x = 0;
  709. actualViewport.y = 0;
  710. actualViewport.width = mRenderTargetDesc.width;
  711. actualViewport.height = mRenderTargetDesc.height;
  712. actualZNear = 0.0f;
  713. actualZFar = 1.0f;
  714. }
  715. bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
  716. actualZNear != mCurNear || actualZFar != mCurFar;
  717. if (viewportChanged)
  718. {
  719. const gl::Caps& caps = getRendererCaps();
  720. int dxMaxViewportBoundsX = static_cast<int>(caps.maxViewportWidth);
  721. int dxMaxViewportBoundsY = static_cast<int>(caps.maxViewportHeight);
  722. int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
  723. int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
  724. if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
  725. {
  726. // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
  727. dxMaxViewportBoundsX = mRenderTargetDesc.width;
  728. dxMaxViewportBoundsY = mRenderTargetDesc.height;
  729. dxMinViewportBoundsX = 0;
  730. dxMinViewportBoundsY = 0;
  731. }
  732. int dxViewportTopLeftX = gl::clamp(actualViewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
  733. int dxViewportTopLeftY = gl::clamp(actualViewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
  734. int dxViewportWidth = gl::clamp(actualViewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
  735. int dxViewportHeight = gl::clamp(actualViewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
  736. D3D11_VIEWPORT dxViewport;
  737. dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
  738. dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
  739. dxViewport.Width = static_cast<float>(dxViewportWidth);
  740. dxViewport.Height = static_cast<float>(dxViewportHeight);
  741. dxViewport.MinDepth = actualZNear;
  742. dxViewport.MaxDepth = actualZFar;
  743. mDeviceContext->RSSetViewports(1, &dxViewport);
  744. mCurViewport = actualViewport;
  745. mCurNear = actualZNear;
  746. mCurFar = actualZFar;
  747. // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders using viewAdjust (like the D3D9 renderer).
  748. if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3)
  749. {
  750. mVertexConstants.viewAdjust[0] = static_cast<float>((actualViewport.width - dxViewportWidth) + 2 * (actualViewport.x - dxViewportTopLeftX)) / dxViewport.Width;
  751. mVertexConstants.viewAdjust[1] = static_cast<float>((actualViewport.height - dxViewportHeight) + 2 * (actualViewport.y - dxViewportTopLeftY)) / dxViewport.Height;
  752. mVertexConstants.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
  753. mVertexConstants.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
  754. }
  755. mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f;
  756. mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
  757. mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
  758. mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
  759. // Instanced pointsprite emulation requires ViewCoords to be defined in the
  760. // the vertex shader.
  761. mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0];
  762. mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1];
  763. mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2];
  764. mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3];
  765. mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
  766. mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
  767. mVertexConstants.depthRange[0] = actualZNear;
  768. mVertexConstants.depthRange[1] = actualZFar;
  769. mVertexConstants.depthRange[2] = actualZFar - actualZNear;
  770. mPixelConstants.depthRange[0] = actualZNear;
  771. mPixelConstants.depthRange[1] = actualZFar;
  772. mPixelConstants.depthRange[2] = actualZFar - actualZNear;
  773. }
  774. mForceSetViewport = false;
  775. }
  776. bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize)
  777. {
  778. D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
  779. GLsizei minCount = 0;
  780. switch (mode)
  781. {
  782. case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break;
  783. case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break;
  784. case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break;
  785. case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break;
  786. case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break;
  787. case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break;
  788. // emulate fans via rewriting index buffer
  789. case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break;
  790. default:
  791. UNREACHABLE();
  792. return false;
  793. }
  794. // If instanced pointsprite emulation is being used and If gl_PointSize is used in the shader,
  795. // GL_POINTS mode is expected to render pointsprites.
  796. // Instanced PointSprite emulation requires that the topology to be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
  797. if (mode == GL_POINTS && usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation)
  798. {
  799. primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
  800. }
  801. if (primitiveTopology != mCurrentPrimitiveTopology)
  802. {
  803. mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
  804. mCurrentPrimitiveTopology = primitiveTopology;
  805. }
  806. return count >= minCount;
  807. }
  808. void Renderer11::unsetConflictingSRVs(gl::SamplerType samplerType, const ID3D11Resource *resource, const gl::ImageIndex* index)
  809. {
  810. auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
  811. for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex)
  812. {
  813. auto &record = currentSRVs[resourceIndex];
  814. if (record.srv && record.resource == resource && ImageIndexConflictsWithSRV(index, record.desc))
  815. {
  816. setShaderResource(samplerType, static_cast<UINT>(resourceIndex), NULL);
  817. }
  818. }
  819. }
  820. gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer)
  821. {
  822. // Get the color render buffer and serial
  823. // Also extract the render target dimensions and view
  824. unsigned int renderTargetWidth = 0;
  825. unsigned int renderTargetHeight = 0;
  826. DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN;
  827. unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
  828. ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
  829. bool missingColorRenderTarget = true;
  830. const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(getWorkarounds());
  831. for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
  832. {
  833. gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
  834. if (colorbuffer)
  835. {
  836. // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
  837. // check for zero-sized default framebuffer, which is a special case.
  838. // in this case we do not wish to modify any state and just silently return false.
  839. // this will not report any gl error but will cause the calling method to return.
  840. if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
  841. {
  842. return gl::Error(GL_NO_ERROR);
  843. }
  844. renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer);
  845. // Extract the render target dimensions and view
  846. RenderTarget11 *renderTarget = NULL;
  847. gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget);
  848. if (error.isError())
  849. {
  850. return error;
  851. }
  852. ASSERT(renderTarget);
  853. framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
  854. ASSERT(framebufferRTVs[colorAttachment]);
  855. if (missingColorRenderTarget)
  856. {
  857. renderTargetWidth = renderTarget->getWidth();
  858. renderTargetHeight = renderTarget->getHeight();
  859. renderTargetFormat = renderTarget->getDXGIFormat();
  860. missingColorRenderTarget = false;
  861. }
  862. // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
  863. if (colorbuffer->type() == GL_TEXTURE)
  864. {
  865. ID3D11Resource *renderTargetResource = renderTarget->getTexture();
  866. const gl::ImageIndex *index = colorbuffer->getTextureImageIndex();
  867. ASSERT(index);
  868. // The index doesn't need to be corrected for the small compressed texture workaround
  869. // because a rendertarget is never compressed.
  870. unsetConflictingSRVs(gl::SAMPLER_VERTEX, renderTargetResource, index);
  871. unsetConflictingSRVs(gl::SAMPLER_PIXEL, renderTargetResource, index);
  872. }
  873. }
  874. }
  875. // Get the depth stencil render buffter and serials
  876. gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer();
  877. unsigned int depthbufferSerial = 0;
  878. unsigned int stencilbufferSerial = 0;
  879. if (depthStencil)
  880. {
  881. depthbufferSerial = GetAttachmentSerial(depthStencil);
  882. }
  883. else if (framebuffer->getStencilbuffer())
  884. {
  885. depthStencil = framebuffer->getStencilbuffer();
  886. stencilbufferSerial = GetAttachmentSerial(depthStencil);
  887. }
  888. ID3D11DepthStencilView* framebufferDSV = NULL;
  889. if (depthStencil)
  890. {
  891. RenderTarget11 *depthStencilRenderTarget = NULL;
  892. gl::Error error = d3d11::GetAttachmentRenderTarget(depthStencil, &depthStencilRenderTarget);
  893. if (error.isError())
  894. {
  895. SafeRelease(framebufferRTVs);
  896. return error;
  897. }
  898. ASSERT(depthStencilRenderTarget);
  899. framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
  900. ASSERT(framebufferDSV);
  901. // If there is no render buffer, the width, height and format values come from
  902. // the depth stencil
  903. if (missingColorRenderTarget)
  904. {
  905. renderTargetWidth = depthStencilRenderTarget->getWidth();
  906. renderTargetHeight = depthStencilRenderTarget->getHeight();
  907. renderTargetFormat = depthStencilRenderTarget->getDXGIFormat();
  908. }
  909. }
  910. // Apply the render target and depth stencil
  911. if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
  912. memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
  913. depthbufferSerial != mAppliedDepthbufferSerial ||
  914. stencilbufferSerial != mAppliedStencilbufferSerial)
  915. {
  916. mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV);
  917. mRenderTargetDesc.width = renderTargetWidth;
  918. mRenderTargetDesc.height = renderTargetHeight;
  919. mRenderTargetDesc.format = renderTargetFormat;
  920. mForceSetViewport = true;
  921. mForceSetScissor = true;
  922. mForceSetBlendState = true;
  923. if (!mDepthStencilInitialized)
  924. {
  925. mForceSetRasterState = true;
  926. }
  927. for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  928. {
  929. mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
  930. }
  931. mAppliedDepthbufferSerial = depthbufferSerial;
  932. mAppliedStencilbufferSerial = stencilbufferSerial;
  933. mRenderTargetDescInitialized = true;
  934. mDepthStencilInitialized = true;
  935. }
  936. invalidateFramebufferSwizzles(framebuffer);
  937. return gl::Error(GL_NO_ERROR);
  938. }
  939. gl::Error Renderer11::applyVertexBuffer(const gl::State &state, GLint first, GLsizei count, GLsizei instances)
  940. {
  941. TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
  942. gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, attributes, instances);
  943. if (error.isError())
  944. {
  945. return error;
  946. }
  947. return mInputLayoutCache.applyVertexBuffers(attributes, state.getProgram());
  948. }
  949. gl::Error Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
  950. {
  951. gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
  952. if (error.isError())
  953. {
  954. return error;
  955. }
  956. ID3D11Buffer *buffer = NULL;
  957. DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
  958. if (indexInfo->storage)
  959. {
  960. Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage);
  961. buffer = storage->getBuffer(BUFFER_USAGE_INDEX);
  962. }
  963. else
  964. {
  965. IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
  966. buffer = indexBuffer->getBuffer();
  967. }
  968. if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset)
  969. {
  970. mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset);
  971. mAppliedIB = buffer;
  972. mAppliedIBFormat = bufferFormat;
  973. mAppliedIBOffset = indexInfo->startOffset;
  974. }
  975. return gl::Error(GL_NO_ERROR);
  976. }
  977. void Renderer11::applyTransformFeedbackBuffers(const gl::State& state)
  978. {
  979. size_t numXFBBindings = state.getTransformFeedbackBufferIndexRange();
  980. ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
  981. bool requiresUpdate = false;
  982. for (size_t i = 0; i < numXFBBindings; i++)
  983. {
  984. gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
  985. GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
  986. ID3D11Buffer *d3dBuffer = NULL;
  987. if (curXFBBuffer)
  988. {
  989. Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
  990. d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
  991. }
  992. // TODO: mAppliedTFBuffers and friends should also be kept in a vector.
  993. if (d3dBuffer != mAppliedTFBuffers[i] || curXFBOffset != mAppliedTFOffsets[i])
  994. {
  995. requiresUpdate = true;
  996. }
  997. }
  998. if (requiresUpdate)
  999. {
  1000. for (size_t i = 0; i < numXFBBindings; ++i)
  1001. {
  1002. gl::Buffer *curXFBBuffer = state.getIndexedTransformFeedbackBuffer(i);
  1003. GLintptr curXFBOffset = state.getIndexedTransformFeedbackBufferOffset(i);
  1004. if (curXFBBuffer)
  1005. {
  1006. Buffer11 *storage = Buffer11::makeBuffer11(curXFBBuffer->getImplementation());
  1007. ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK);
  1008. mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != curXFBOffset) ?
  1009. static_cast<UINT>(curXFBOffset) : -1;
  1010. mAppliedTFBuffers[i] = d3dBuffer;
  1011. }
  1012. else
  1013. {
  1014. mAppliedTFBuffers[i] = NULL;
  1015. mCurrentD3DOffsets[i] = 0;
  1016. }
  1017. mAppliedTFOffsets[i] = curXFBOffset;
  1018. }
  1019. mDeviceContext->SOSetTargets(numXFBBindings, mAppliedTFBuffers, mCurrentD3DOffsets);
  1020. }
  1021. }
  1022. gl::Error Renderer11::drawArrays(const gl::Data &data, GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive, bool usesPointSize)
  1023. {
  1024. bool useInstancedPointSpriteEmulation = usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation;
  1025. if (mode == GL_POINTS && transformFeedbackActive)
  1026. {
  1027. // Since point sprites are generated with a geometry shader, too many vertices will
  1028. // be written if transform feedback is active. To work around this, draw only the points
  1029. // with the stream out shader and no pixel shader to feed the stream out buffers and then
  1030. // draw again with the point sprite geometry shader to rasterize the point sprites.
  1031. mDeviceContext->PSSetShader(NULL, NULL, 0);
  1032. if (instances > 0)
  1033. {
  1034. mDeviceContext->DrawInstanced(count, instances, 0, 0);
  1035. }
  1036. else
  1037. {
  1038. mDeviceContext->Draw(count, 0);
  1039. }
  1040. ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(data.state->getProgram()->getImplementation());
  1041. rx::ShaderExecutableD3D *pixelExe = NULL;
  1042. gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe);
  1043. if (error.isError())
  1044. {
  1045. return error;
  1046. }
  1047. // Skip this step if we're doing rasterizer discard.
  1048. if (pixelExe && !data.state->getRasterizerState().rasterizerDiscard)
  1049. {
  1050. ID3D11PixelShader *pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
  1051. ASSERT(reinterpret_cast<uintptr_t>(pixelShader) == mAppliedPixelShader);
  1052. mDeviceContext->PSSetShader(pixelShader, NULL, 0);
  1053. // Retrieve the point sprite geometry shader
  1054. rx::ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
  1055. ID3D11GeometryShader *geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
  1056. mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
  1057. ASSERT(geometryShader);
  1058. mDeviceContext->GSSetShader(geometryShader, NULL, 0);
  1059. if (instances > 0)
  1060. {
  1061. mDeviceContext->DrawInstanced(count, instances, 0, 0);
  1062. }
  1063. else
  1064. {
  1065. mDeviceContext->Draw(count, 0);
  1066. }
  1067. }
  1068. return gl::Error(GL_NO_ERROR);
  1069. }
  1070. else if (mode == GL_LINE_LOOP)
  1071. {
  1072. return drawLineLoop(count, GL_NONE, NULL, 0, NULL);
  1073. }
  1074. else if (mode == GL_TRIANGLE_FAN)
  1075. {
  1076. return drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
  1077. }
  1078. else if (instances > 0)
  1079. {
  1080. mDeviceContext->DrawInstanced(count, instances, 0, 0);
  1081. return gl::Error(GL_NO_ERROR);
  1082. }
  1083. else
  1084. {
  1085. // If gl_PointSize is used and GL_POINTS is specified, then it is expected to render pointsprites.
  1086. // If instanced pointsprite emulation is being used the topology is expexted to be
  1087. // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced must be used.
  1088. if (mode == GL_POINTS && useInstancedPointSpriteEmulation)
  1089. {
  1090. mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0);
  1091. }
  1092. else
  1093. {
  1094. mDeviceContext->Draw(count, 0);
  1095. }
  1096. r

Large files files are truncated, but you can click here to view the full file