PageRenderTime 37ms CodeModel.GetById 14ms 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
  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. return gl::Error(GL_NO_ERROR);
  1097. }
  1098. }
  1099. gl::Error Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices,
  1100. gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
  1101. {
  1102. int minIndex = static_cast<int>(indexInfo.indexRange.start);
  1103. if (mode == GL_LINE_LOOP)
  1104. {
  1105. return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer);
  1106. }
  1107. else if (mode == GL_TRIANGLE_FAN)
  1108. {
  1109. return drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances);
  1110. }
  1111. else if (instances > 0)
  1112. {
  1113. mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0);
  1114. return gl::Error(GL_NO_ERROR);
  1115. }
  1116. else
  1117. {
  1118. mDeviceContext->DrawIndexed(count, 0, -minIndex);
  1119. return gl::Error(GL_NO_ERROR);
  1120. }
  1121. }
  1122. gl::Error Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
  1123. {
  1124. // Get the raw indices for an indexed draw
  1125. if (type != GL_NONE && elementArrayBuffer)
  1126. {
  1127. BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
  1128. intptr_t offset = reinterpret_cast<intptr_t>(indices);
  1129. const uint8_t *bufferData = NULL;
  1130. gl::Error error = storage->getData(&bufferData);
  1131. if (error.isError())
  1132. {
  1133. return error;
  1134. }
  1135. indices = bufferData + offset;
  1136. }
  1137. if (!mLineLoopIB)
  1138. {
  1139. mLineLoopIB = new StreamingIndexBufferInterface(this);
  1140. gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
  1141. if (error.isError())
  1142. {
  1143. SafeDelete(mLineLoopIB);
  1144. return error;
  1145. }
  1146. }
  1147. // Checked by Renderer11::applyPrimitiveType
  1148. ASSERT(count >= 0);
  1149. if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)))
  1150. {
  1151. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.");
  1152. }
  1153. const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
  1154. gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
  1155. if (error.isError())
  1156. {
  1157. return error;
  1158. }
  1159. void* mappedMemory = NULL;
  1160. unsigned int offset;
  1161. error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
  1162. if (error.isError())
  1163. {
  1164. return error;
  1165. }
  1166. unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
  1167. unsigned int indexBufferOffset = offset;
  1168. switch (type)
  1169. {
  1170. case GL_NONE: // Non-indexed draw
  1171. for (int i = 0; i < count; i++)
  1172. {
  1173. data[i] = i;
  1174. }
  1175. data[count] = 0;
  1176. break;
  1177. case GL_UNSIGNED_BYTE:
  1178. for (int i = 0; i < count; i++)
  1179. {
  1180. data[i] = static_cast<const GLubyte*>(indices)[i];
  1181. }
  1182. data[count] = static_cast<const GLubyte*>(indices)[0];
  1183. break;
  1184. case GL_UNSIGNED_SHORT:
  1185. for (int i = 0; i < count; i++)
  1186. {
  1187. data[i] = static_cast<const GLushort*>(indices)[i];
  1188. }
  1189. data[count] = static_cast<const GLushort*>(indices)[0];
  1190. break;
  1191. case GL_UNSIGNED_INT:
  1192. for (int i = 0; i < count; i++)
  1193. {
  1194. data[i] = static_cast<const GLuint*>(indices)[i];
  1195. }
  1196. data[count] = static_cast<const GLuint*>(indices)[0];
  1197. break;
  1198. default: UNREACHABLE();
  1199. }
  1200. error = mLineLoopIB->unmapBuffer();
  1201. if (error.isError())
  1202. {
  1203. return error;
  1204. }
  1205. IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
  1206. ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
  1207. DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
  1208. if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
  1209. {
  1210. mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
  1211. mAppliedIB = d3dIndexBuffer;
  1212. mAppliedIBFormat = indexFormat;
  1213. mAppliedIBOffset = indexBufferOffset;
  1214. }
  1215. mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
  1216. return gl::Error(GL_NO_ERROR);
  1217. }
  1218. gl::Error Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
  1219. {
  1220. // Get the raw indices for an indexed draw
  1221. if (type != GL_NONE && elementArrayBuffer)
  1222. {
  1223. BufferD3D *storage = BufferD3D::makeFromBuffer(elementArrayBuffer);
  1224. intptr_t offset = reinterpret_cast<intptr_t>(indices);
  1225. const uint8_t *bufferData = NULL;
  1226. gl::Error error = storage->getData(&bufferData);
  1227. if (error.isError())
  1228. {
  1229. return error;
  1230. }
  1231. indices = bufferData + offset;
  1232. }
  1233. if (!mTriangleFanIB)
  1234. {
  1235. mTriangleFanIB = new StreamingIndexBufferInterface(this);
  1236. gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
  1237. if (error.isError())
  1238. {
  1239. SafeDelete(mTriangleFanIB);
  1240. return error;
  1241. }
  1242. }
  1243. // Checked by Renderer11::applyPrimitiveType
  1244. ASSERT(count >= 3);
  1245. const unsigned int numTris = count - 2;
  1246. if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3)))
  1247. {
  1248. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.");
  1249. }
  1250. const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
  1251. gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
  1252. if (error.isError())
  1253. {
  1254. return error;
  1255. }
  1256. void* mappedMemory = NULL;
  1257. unsigned int offset;
  1258. error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset);
  1259. if (error.isError())
  1260. {
  1261. return error;
  1262. }
  1263. unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
  1264. unsigned int indexBufferOffset = offset;
  1265. switch (type)
  1266. {
  1267. case GL_NONE: // Non-indexed draw
  1268. for (unsigned int i = 0; i < numTris; i++)
  1269. {
  1270. data[i*3 + 0] = 0;
  1271. data[i*3 + 1] = i + 1;
  1272. data[i*3 + 2] = i + 2;
  1273. }
  1274. break;
  1275. case GL_UNSIGNED_BYTE:
  1276. for (unsigned int i = 0; i < numTris; i++)
  1277. {
  1278. data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
  1279. data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
  1280. data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
  1281. }
  1282. break;
  1283. case GL_UNSIGNED_SHORT:
  1284. for (unsigned int i = 0; i < numTris; i++)
  1285. {
  1286. data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
  1287. data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
  1288. data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
  1289. }
  1290. break;
  1291. case GL_UNSIGNED_INT:
  1292. for (unsigned int i = 0; i < numTris; i++)
  1293. {
  1294. data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
  1295. data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
  1296. data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
  1297. }
  1298. break;
  1299. default: UNREACHABLE();
  1300. }
  1301. error = mTriangleFanIB->unmapBuffer();
  1302. if (error.isError())
  1303. {
  1304. return error;
  1305. }
  1306. IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
  1307. ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer();
  1308. DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
  1309. if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset)
  1310. {
  1311. mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset);
  1312. mAppliedIB = d3dIndexBuffer;
  1313. mAppliedIBFormat = indexFormat;
  1314. mAppliedIBOffset = indexBufferOffset;
  1315. }
  1316. if (instances > 0)
  1317. {
  1318. mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
  1319. }
  1320. else
  1321. {
  1322. mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
  1323. }
  1324. return gl::Error(GL_NO_ERROR);
  1325. }
  1326. gl::Error Renderer11::applyShaders(gl::Program *program, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer,
  1327. bool rasterizerDiscard, bool transformFeedbackActive)
  1328. {
  1329. ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(program->getImplementation());
  1330. ShaderExecutableD3D *vertexExe = NULL;
  1331. gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr);
  1332. if (error.isError())
  1333. {
  1334. return error;
  1335. }
  1336. ShaderExecutableD3D *pixelExe = NULL;
  1337. error = programD3D->getPixelExecutableForFramebuffer(framebuffer, &pixelExe);
  1338. if (error.isError())
  1339. {
  1340. return error;
  1341. }
  1342. ShaderExecutableD3D *geometryExe = programD3D->getGeometryExecutable();
  1343. ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL);
  1344. ID3D11PixelShader *pixelShader = NULL;
  1345. // Skip pixel shader if we're doing rasterizer discard.
  1346. if (!rasterizerDiscard)
  1347. {
  1348. pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL);
  1349. }
  1350. ID3D11GeometryShader *geometryShader = NULL;
  1351. if (transformFeedbackActive)
  1352. {
  1353. geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL);
  1354. }
  1355. else if (mCurRasterState.pointDrawMode)
  1356. {
  1357. geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL);
  1358. }
  1359. bool dirtyUniforms = false;
  1360. if (reinterpret_cast<uintptr_t>(vertexShader) != mAppliedVertexShader)
  1361. {
  1362. mDeviceContext->VSSetShader(vertexShader, NULL, 0);
  1363. mAppliedVertexShader = reinterpret_cast<uintptr_t>(vertexShader);
  1364. dirtyUniforms = true;
  1365. }
  1366. if (reinterpret_cast<uintptr_t>(geometryShader) != mAppliedGeometryShader)
  1367. {
  1368. mDeviceContext->GSSetShader(geometryShader, NULL, 0);
  1369. mAppliedGeometryShader = reinterpret_cast<uintptr_t>(geometryShader);
  1370. dirtyUniforms = true;
  1371. }
  1372. if (reinterpret_cast<uintptr_t>(pixelShader) != mAppliedPixelShader)
  1373. {
  1374. mDeviceContext->PSSetShader(pixelShader, NULL, 0);
  1375. mAppliedPixelShader = reinterpret_cast<uintptr_t>(pixelShader);
  1376. dirtyUniforms = true;
  1377. }
  1378. if (dirtyUniforms)
  1379. {
  1380. programD3D->dirtyAllUniforms();
  1381. }
  1382. return gl::Error(GL_NO_ERROR);
  1383. }
  1384. gl::Error Renderer11::applyUniforms(const ProgramImpl &program, const std::vector<gl::LinkedUniform*> &uniformArray)
  1385. {
  1386. unsigned int totalRegisterCountVS = 0;
  1387. unsigned int totalRegisterCountPS = 0;
  1388. bool vertexUniformsDirty = false;
  1389. bool pixelUniformsDirty = false;
  1390. for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
  1391. {
  1392. const gl::LinkedUniform &uniform = *uniformArray[uniformIndex];
  1393. if (uniform.isReferencedByVertexShader() && !uniform.isSampler())
  1394. {
  1395. totalRegisterCountVS += uniform.registerCount;
  1396. vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty);
  1397. }
  1398. if (uniform.isReferencedByFragmentShader() && !uniform.isSampler())
  1399. {
  1400. totalRegisterCountPS += uniform.registerCount;
  1401. pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty);
  1402. }
  1403. }
  1404. const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(&program);
  1405. const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage());
  1406. const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage());
  1407. ASSERT(vertexUniformStorage);
  1408. ASSERT(fragmentUniformStorage);
  1409. ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer();
  1410. ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer();
  1411. float (*mapVS)[4] = NULL;
  1412. float (*mapPS)[4] = NULL;
  1413. if (totalRegisterCountVS > 0 && vertexUniformsDirty)
  1414. {
  1415. D3D11_MAPPED_SUBRESOURCE map = {0};
  1416. HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
  1417. UNUSED_ASSERTION_VARIABLE(result);
  1418. ASSERT(SUCCEEDED(result));
  1419. mapVS = (float(*)[4])map.pData;
  1420. }
  1421. if (totalRegisterCountPS > 0 && pixelUniformsDirty)
  1422. {
  1423. D3D11_MAPPED_SUBRESOURCE map = {0};
  1424. HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
  1425. UNUSED_ASSERTION_VARIABLE(result);
  1426. ASSERT(SUCCEEDED(result));
  1427. mapPS = (float(*)[4])map.pData;
  1428. }
  1429. for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++)
  1430. {
  1431. gl::LinkedUniform *uniform = uniformArray[uniformIndex];
  1432. if (!uniform->isSampler())
  1433. {
  1434. unsigned int componentCount = (4 - uniform->registerElement);
  1435. // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would
  1436. // overwrite previously written regions of memory.
  1437. if (uniform->isReferencedByVertexShader() && mapVS)
  1438. {
  1439. memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
  1440. }
  1441. if (uniform->isReferencedByFragmentShader() && mapPS)
  1442. {
  1443. memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount);
  1444. }
  1445. }
  1446. }
  1447. if (mapVS)
  1448. {
  1449. mDeviceContext->Unmap(vertexConstantBuffer, 0);
  1450. }
  1451. if (mapPS)
  1452. {
  1453. mDeviceContext->Unmap(pixelConstantBuffer, 0);
  1454. }
  1455. if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
  1456. {
  1457. mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
  1458. mCurrentVertexConstantBuffer = vertexConstantBuffer;
  1459. }
  1460. if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
  1461. {
  1462. mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
  1463. mCurrentPixelConstantBuffer = pixelConstantBuffer;
  1464. }
  1465. // Driver uniforms
  1466. if (!mDriverConstantBufferVS)
  1467. {
  1468. D3D11_BUFFER_DESC constantBufferDescription = {0};
  1469. constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
  1470. constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
  1471. constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  1472. constantBufferDescription.CPUAccessFlags = 0;
  1473. constantBufferDescription.MiscFlags = 0;
  1474. constantBufferDescription.StructureByteStride = 0;
  1475. HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
  1476. UNUSED_ASSERTION_VARIABLE(result);
  1477. ASSERT(SUCCEEDED(result));
  1478. mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
  1479. }
  1480. if (!mDriverConstantBufferPS)
  1481. {
  1482. D3D11_BUFFER_DESC constantBufferDescription = {0};
  1483. constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
  1484. constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
  1485. constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  1486. constantBufferDescription.CPUAccessFlags = 0;
  1487. constantBufferDescription.MiscFlags = 0;
  1488. constantBufferDescription.StructureByteStride = 0;
  1489. HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
  1490. UNUSED_ASSERTION_VARIABLE(result);
  1491. ASSERT(SUCCEEDED(result));
  1492. mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
  1493. }
  1494. if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
  1495. {
  1496. mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
  1497. memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
  1498. }
  1499. if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
  1500. {
  1501. mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
  1502. memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
  1503. }
  1504. // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary
  1505. if (programD3D->usesGeometryShader())
  1506. {
  1507. // needed for the point sprite geometry shader
  1508. if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
  1509. {
  1510. mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
  1511. mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
  1512. }
  1513. }
  1514. return gl::Error(GL_NO_ERROR);
  1515. }
  1516. void Renderer11::markAllStateDirty()
  1517. {
  1518. for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  1519. {
  1520. mAppliedRenderTargetSerials[rtIndex] = 0;
  1521. }
  1522. mAppliedDepthbufferSerial = 0;
  1523. mAppliedStencilbufferSerial = 0;
  1524. mDepthStencilInitialized = false;
  1525. mRenderTargetDescInitialized = false;
  1526. // We reset the current SRV data because it might not be in sync with D3D's state
  1527. // anymore. For example when a currently used SRV is used as an RTV, D3D silently
  1528. // remove it from its state.
  1529. memset(mCurVertexSRVs.data(), 0, sizeof(SRVRecord) * mCurVertexSRVs.size());
  1530. memset(mCurPixelSRVs.data(), 0, sizeof(SRVRecord) * mCurPixelSRVs.size());
  1531. ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size());
  1532. for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId)
  1533. {
  1534. mForceSetVertexSamplerStates[vsamplerId] = true;
  1535. }
  1536. ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size());
  1537. for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId)
  1538. {
  1539. mForceSetPixelSamplerStates[fsamplerId] = true;
  1540. }
  1541. mForceSetBlendState = true;
  1542. mForceSetRasterState = true;
  1543. mForceSetDepthStencilState = true;
  1544. mForceSetScissor = true;
  1545. mForceSetViewport = true;
  1546. mAppliedIB = NULL;
  1547. mAppliedIBFormat = DXGI_FORMAT_UNKNOWN;
  1548. mAppliedIBOffset = 0;
  1549. // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state.
  1550. const uintptr_t dirtyPointer = -1;
  1551. mAppliedVertexShader = dirtyPointer;
  1552. mAppliedGeometryShader = dirtyPointer;
  1553. mAppliedPixelShader = dirtyPointer;
  1554. for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
  1555. {
  1556. mAppliedTFBuffers[i] = NULL;
  1557. mAppliedTFOffsets[i] = 0;
  1558. }
  1559. memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
  1560. memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
  1561. mInputLayoutCache.markDirty();
  1562. for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++)
  1563. {
  1564. mCurrentConstantBufferVS[i] = -1;
  1565. mCurrentConstantBufferPS[i] = -1;
  1566. }
  1567. mCurrentVertexConstantBuffer = NULL;
  1568. mCurrentPixelConstantBuffer = NULL;
  1569. mCurrentGeometryConstantBuffer = NULL;
  1570. mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
  1571. }
  1572. void Renderer11::releaseDeviceResources()
  1573. {
  1574. mStateCache.clear();
  1575. mInputLayoutCache.clear();
  1576. SafeDelete(mVertexDataManager);
  1577. SafeDelete(mIndexDataManager);
  1578. SafeDelete(mLineLoopIB);
  1579. SafeDelete(mTriangleFanIB);
  1580. SafeDelete(mBlit);
  1581. SafeDelete(mClear);
  1582. SafeDelete(mTrim);
  1583. SafeDelete(mPixelTransfer);
  1584. SafeRelease(mDriverConstantBufferVS);
  1585. SafeRelease(mDriverConstantBufferPS);
  1586. SafeRelease(mSyncQuery);
  1587. }
  1588. // set notify to true to broadcast a message to all contexts of the device loss
  1589. bool Renderer11::testDeviceLost()
  1590. {
  1591. bool isLost = false;
  1592. // GetRemovedReason is used to test if the device is removed
  1593. HRESULT result = mDevice->GetDeviceRemovedReason();
  1594. isLost = d3d11::isDeviceLostError(result);
  1595. if (isLost)
  1596. {
  1597. // Log error if this is a new device lost event
  1598. if (mDeviceLost == false)
  1599. {
  1600. ERR("The D3D11 device was removed: 0x%08X", result);
  1601. }
  1602. // ensure we note the device loss --
  1603. // we'll probably get this done again by notifyDeviceLost
  1604. // but best to remember it!
  1605. // Note that we don't want to clear the device loss status here
  1606. // -- this needs to be done by resetDevice
  1607. mDeviceLost = true;
  1608. }
  1609. return isLost;
  1610. }
  1611. bool Renderer11::testDeviceResettable()
  1612. {
  1613. // determine if the device is resettable by creating a dummy device
  1614. PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
  1615. if (D3D11CreateDevice == NULL)
  1616. {
  1617. return false;
  1618. }
  1619. ID3D11Device* dummyDevice;
  1620. D3D_FEATURE_LEVEL dummyFeatureLevel;
  1621. ID3D11DeviceContext* dummyContext;
  1622. HRESULT result = D3D11CreateDevice(NULL,
  1623. mDriverType,
  1624. NULL,
  1625. #if defined(_DEBUG)
  1626. D3D11_CREATE_DEVICE_DEBUG,
  1627. #else
  1628. 0,
  1629. #endif
  1630. mAvailableFeatureLevels.data(),
  1631. mAvailableFeatureLevels.size(),
  1632. D3D11_SDK_VERSION,
  1633. &dummyDevice,
  1634. &dummyFeatureLevel,
  1635. &dummyContext);
  1636. if (!mDevice || FAILED(result))
  1637. {
  1638. return false;
  1639. }
  1640. SafeRelease(dummyContext);
  1641. SafeRelease(dummyDevice);
  1642. return true;
  1643. }
  1644. void Renderer11::release()
  1645. {
  1646. RendererD3D::cleanup();
  1647. releaseDeviceResources();
  1648. SafeRelease(mDxgiFactory);
  1649. SafeRelease(mDxgiAdapter);
  1650. SafeRelease(mDeviceContext1);
  1651. if (mDeviceContext)
  1652. {
  1653. mDeviceContext->ClearState();
  1654. mDeviceContext->Flush();
  1655. SafeRelease(mDeviceContext);
  1656. }
  1657. SafeRelease(mDevice);
  1658. if (mD3d11Module)
  1659. {
  1660. FreeLibrary(mD3d11Module);
  1661. mD3d11Module = NULL;
  1662. }
  1663. if (mDxgiModule)
  1664. {
  1665. FreeLibrary(mDxgiModule);
  1666. mDxgiModule = NULL;
  1667. }
  1668. mCompiler.release();
  1669. }
  1670. bool Renderer11::resetDevice()
  1671. {
  1672. // recreate everything
  1673. release();
  1674. EGLint result = initialize();
  1675. if (result != EGL_SUCCESS)
  1676. {
  1677. ERR("Could not reinitialize D3D11 device: %08X", result);
  1678. return false;
  1679. }
  1680. mDeviceLost = false;
  1681. return true;
  1682. }
  1683. VendorID Renderer11::getVendorId() const
  1684. {
  1685. return static_cast<VendorID>(mAdapterDescription.VendorId);
  1686. }
  1687. std::string Renderer11::getRendererDescription() const
  1688. {
  1689. std::ostringstream rendererString;
  1690. rendererString << mDescription;
  1691. rendererString << " Direct3D11";
  1692. rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix();
  1693. rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix();
  1694. return rendererString.str();
  1695. }
  1696. GUID Renderer11::getAdapterIdentifier() const
  1697. {
  1698. // Use the adapter LUID as our adapter ID
  1699. // This number is local to a machine is only guaranteed to be unique between restarts
  1700. META_ASSERT(sizeof(LUID) <= sizeof(GUID));
  1701. GUID adapterId = {0};
  1702. memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
  1703. return adapterId;
  1704. }
  1705. unsigned int Renderer11::getReservedVertexUniformVectors() const
  1706. {
  1707. return 0; // Driver uniforms are stored in a separate constant buffer
  1708. }
  1709. unsigned int Renderer11::getReservedFragmentUniformVectors() const
  1710. {
  1711. return 0; // Driver uniforms are stored in a separate constant buffer
  1712. }
  1713. unsigned int Renderer11::getReservedVertexUniformBuffers() const
  1714. {
  1715. // we reserve one buffer for the application uniforms, and one for driver uniforms
  1716. return 2;
  1717. }
  1718. unsigned int Renderer11::getReservedFragmentUniformBuffers() const
  1719. {
  1720. // we reserve one buffer for the application uniforms, and one for driver uniforms
  1721. return 2;
  1722. }
  1723. bool Renderer11::getShareHandleSupport() const
  1724. {
  1725. // We only currently support share handles with BGRA surfaces, because
  1726. // chrome needs BGRA. Once chrome fixes this, we should always support them.
  1727. // PIX doesn't seem to support using share handles, so disable them.
  1728. // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains.
  1729. return getRendererExtensions().textureFormatBGRA8888 && !gl::perfActive() && !(mFeatureLevel <= D3D_FEATURE_LEVEL_9_3);
  1730. }
  1731. bool Renderer11::getPostSubBufferSupport() const
  1732. {
  1733. // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
  1734. return false;
  1735. }
  1736. int Renderer11::getMajorShaderModel() const
  1737. {
  1738. switch (mFeatureLevel)
  1739. {
  1740. case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
  1741. case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
  1742. case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
  1743. case D3D_FEATURE_LEVEL_9_3: return D3D10_SHADER_MAJOR_VERSION; // 4
  1744. default: UNREACHABLE(); return 0;
  1745. }
  1746. }
  1747. int Renderer11::getMinorShaderModel() const
  1748. {
  1749. switch (mFeatureLevel)
  1750. {
  1751. case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
  1752. case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
  1753. case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0
  1754. case D3D_FEATURE_LEVEL_9_3: return D3D10_SHADER_MINOR_VERSION; // 0
  1755. default: UNREACHABLE(); return 0;
  1756. }
  1757. }
  1758. std::string Renderer11::getShaderModelSuffix() const
  1759. {
  1760. switch (mFeatureLevel)
  1761. {
  1762. case D3D_FEATURE_LEVEL_11_0: return "";
  1763. case D3D_FEATURE_LEVEL_10_1: return "";
  1764. case D3D_FEATURE_LEVEL_10_0: return "";
  1765. case D3D_FEATURE_LEVEL_9_3: return "_level_9_3";
  1766. default: UNREACHABLE(); return "";
  1767. }
  1768. }
  1769. int Renderer11::getMinSwapInterval() const
  1770. {
  1771. return 0;
  1772. }
  1773. int Renderer11::getMaxSwapInterval() const
  1774. {
  1775. return 4;
  1776. }
  1777. gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  1778. const gl::Offset &destOffset, TextureStorage *storage, GLint level)
  1779. {
  1780. gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
  1781. ASSERT(colorbuffer);
  1782. RenderTarget11 *sourceRenderTarget = NULL;
  1783. gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
  1784. if (error.isError())
  1785. {
  1786. return error;
  1787. }
  1788. ASSERT(sourceRenderTarget);
  1789. ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  1790. ASSERT(source);
  1791. TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage);
  1792. ASSERT(storage11);
  1793. gl::ImageIndex index = gl::ImageIndex::Make2D(level);
  1794. RenderTargetD3D *destRenderTarget = NULL;
  1795. error = storage11->getRenderTarget(index, &destRenderTarget);
  1796. if (error.isError())
  1797. {
  1798. return error;
  1799. }
  1800. ASSERT(destRenderTarget);
  1801. ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
  1802. ASSERT(dest);
  1803. gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
  1804. gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
  1805. gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
  1806. gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
  1807. // Use nearest filtering because source and destination are the same size for the direct
  1808. // copy
  1809. mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
  1810. if (error.isError())
  1811. {
  1812. return error;
  1813. }
  1814. storage11->invalidateSwizzleCacheLevel(level);
  1815. return gl::Error(GL_NO_ERROR);
  1816. }
  1817. gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  1818. const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
  1819. {
  1820. gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
  1821. ASSERT(colorbuffer);
  1822. RenderTarget11 *sourceRenderTarget = NULL;
  1823. gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
  1824. if (error.isError())
  1825. {
  1826. return error;
  1827. }
  1828. ASSERT(sourceRenderTarget);
  1829. ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  1830. ASSERT(source);
  1831. TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage);
  1832. ASSERT(storage11);
  1833. gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
  1834. RenderTargetD3D *destRenderTarget = NULL;
  1835. error = storage11->getRenderTarget(index, &destRenderTarget);
  1836. if (error.isError())
  1837. {
  1838. return error;
  1839. }
  1840. ASSERT(destRenderTarget);
  1841. ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
  1842. ASSERT(dest);
  1843. gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
  1844. gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
  1845. gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
  1846. gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
  1847. // Use nearest filtering because source and destination are the same size for the direct
  1848. // copy
  1849. error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
  1850. if (error.isError())
  1851. {
  1852. return error;
  1853. }
  1854. storage11->invalidateSwizzleCacheLevel(level);
  1855. return gl::Error(GL_NO_ERROR);
  1856. }
  1857. gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  1858. const gl::Offset &destOffset, TextureStorage *storage, GLint level)
  1859. {
  1860. gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
  1861. ASSERT(colorbuffer);
  1862. RenderTarget11 *sourceRenderTarget = NULL;
  1863. gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
  1864. if (error.isError())
  1865. {
  1866. return error;
  1867. }
  1868. ASSERT(sourceRenderTarget);
  1869. ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  1870. ASSERT(source);
  1871. TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage);
  1872. ASSERT(storage11);
  1873. gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z);
  1874. RenderTargetD3D *destRenderTarget = NULL;
  1875. error = storage11->getRenderTarget(index, &destRenderTarget);
  1876. if (error.isError())
  1877. {
  1878. return error;
  1879. }
  1880. ASSERT(destRenderTarget);
  1881. ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
  1882. ASSERT(dest);
  1883. gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
  1884. gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
  1885. gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
  1886. gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
  1887. // Use nearest filtering because source and destination are the same size for the direct
  1888. // copy
  1889. error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
  1890. if (error.isError())
  1891. {
  1892. return error;
  1893. }
  1894. storage11->invalidateSwizzleCacheLevel(level);
  1895. return gl::Error(GL_NO_ERROR);
  1896. }
  1897. gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
  1898. const gl::Offset &destOffset, TextureStorage *storage, GLint level)
  1899. {
  1900. gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer();
  1901. ASSERT(colorbuffer);
  1902. RenderTarget11 *sourceRenderTarget = NULL;
  1903. gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &sourceRenderTarget);
  1904. if (error.isError())
  1905. {
  1906. return error;
  1907. }
  1908. ASSERT(sourceRenderTarget);
  1909. ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
  1910. ASSERT(source);
  1911. TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage);
  1912. ASSERT(storage11);
  1913. gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
  1914. RenderTargetD3D *destRenderTarget = NULL;
  1915. error = storage11->getRenderTarget(index, &destRenderTarget);
  1916. if (error.isError())
  1917. {
  1918. return error;
  1919. }
  1920. ASSERT(destRenderTarget);
  1921. ID3D11RenderTargetView *dest = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
  1922. ASSERT(dest);
  1923. gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
  1924. gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
  1925. gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1);
  1926. gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
  1927. // Use nearest filtering because source and destination are the same size for the direct
  1928. // copy
  1929. error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, destFormat, GL_NEAREST);
  1930. if (error.isError())
  1931. {
  1932. return error;
  1933. }
  1934. storage11->invalidateSwizzleCacheLevel(level);
  1935. return gl::Error(GL_NO_ERROR);
  1936. }
  1937. void Renderer11::unapplyRenderTargets()
  1938. {
  1939. setOneTimeRenderTarget(NULL);
  1940. }
  1941. // When finished with this rendertarget, markAllStateDirty must be called.
  1942. void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
  1943. {
  1944. ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
  1945. rtvArray[0] = renderTargetView;
  1946. mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL);
  1947. // Do not preserve the serial for this one-time-use render target
  1948. for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
  1949. {
  1950. mAppliedRenderTargetSerials[rtIndex] = 0;
  1951. }
  1952. }
  1953. gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT)
  1954. {
  1955. const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mFeatureLevel);
  1956. const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format);
  1957. GLuint supportedSamples = textureCaps.getNearestSamples(samples);
  1958. if (width > 0 && height > 0)
  1959. {
  1960. // Create texture resource
  1961. D3D11_TEXTURE2D_DESC desc;
  1962. desc.Width = width;
  1963. desc.Height = height;
  1964. desc.MipLevels = 1;
  1965. desc.ArraySize = 1;
  1966. desc.Format = formatInfo.texFormat;
  1967. desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
  1968. desc.SampleDesc.Quality = 0;
  1969. desc.Usage = D3D11_USAGE_DEFAULT;
  1970. desc.CPUAccessFlags = 0;
  1971. desc.MiscFlags = 0;
  1972. // If a rendertarget or depthstencil format exists for this texture format,
  1973. // we'll flag it to allow binding that way. Shader resource views are a little
  1974. // more complicated.
  1975. bool bindRTV = false, bindDSV = false, bindSRV = false;
  1976. bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
  1977. bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
  1978. if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
  1979. {
  1980. // Multisample targets flagged for binding as depth stencil cannot also be
  1981. // flagged for binding as SRV, so make certain not to add the SRV flag for
  1982. // these targets.
  1983. bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
  1984. }
  1985. desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) |
  1986. (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) |
  1987. (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
  1988. // The format must be either an RTV or a DSV
  1989. ASSERT(bindRTV != bindDSV);
  1990. ID3D11Texture2D *texture = NULL;
  1991. HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture);
  1992. if (FAILED(result))
  1993. {
  1994. ASSERT(result == E_OUTOFMEMORY);
  1995. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result);
  1996. }
  1997. ID3D11ShaderResourceView *srv = NULL;
  1998. if (bindSRV)
  1999. {
  2000. D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
  2001. srvDesc.Format = formatInfo.srvFormat;
  2002. srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
  2003. srvDesc.Texture2D.MostDetailedMip = 0;
  2004. srvDesc.Texture2D.MipLevels = 1;
  2005. result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv);
  2006. if (FAILED(result))
  2007. {
  2008. ASSERT(result == E_OUTOFMEMORY);
  2009. SafeRelease(texture);
  2010. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result);
  2011. }
  2012. }
  2013. if (bindDSV)
  2014. {
  2015. D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
  2016. dsvDesc.Format = formatInfo.dsvFormat;
  2017. dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
  2018. dsvDesc.Texture2D.MipSlice = 0;
  2019. dsvDesc.Flags = 0;
  2020. ID3D11DepthStencilView *dsv = NULL;
  2021. result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv);
  2022. if (FAILED(result))
  2023. {
  2024. ASSERT(result == E_OUTOFMEMORY);
  2025. SafeRelease(texture);
  2026. SafeRelease(srv);
  2027. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result);
  2028. }
  2029. *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples);
  2030. SafeRelease(dsv);
  2031. }
  2032. else if (bindRTV)
  2033. {
  2034. D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
  2035. rtvDesc.Format = formatInfo.rtvFormat;
  2036. rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
  2037. rtvDesc.Texture2D.MipSlice = 0;
  2038. ID3D11RenderTargetView *rtv = NULL;
  2039. result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv);
  2040. if (FAILED(result))
  2041. {
  2042. ASSERT(result == E_OUTOFMEMORY);
  2043. SafeRelease(texture);
  2044. SafeRelease(srv);
  2045. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result);
  2046. }
  2047. if (formatInfo.dataInitializerFunction != NULL)
  2048. {
  2049. const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
  2050. mDeviceContext->ClearRenderTargetView(rtv, clearValues);
  2051. }
  2052. *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples);
  2053. SafeRelease(rtv);
  2054. }
  2055. else
  2056. {
  2057. UNREACHABLE();
  2058. }
  2059. SafeRelease(texture);
  2060. SafeRelease(srv);
  2061. }
  2062. else
  2063. {
  2064. *outRT = new TextureRenderTarget11(reinterpret_cast<ID3D11RenderTargetView*>(NULL), NULL, NULL, format, width, height, 1, supportedSamples);
  2065. }
  2066. return gl::Error(GL_NO_ERROR);
  2067. }
  2068. DefaultAttachmentImpl *Renderer11::createDefaultAttachment(GLenum type, egl::Surface *surface)
  2069. {
  2070. SurfaceD3D *surfaceD3D = SurfaceD3D::makeSurfaceD3D(surface);
  2071. SwapChain11 *swapChain = SwapChain11::makeSwapChain11(surfaceD3D->getSwapChain());
  2072. switch (type)
  2073. {
  2074. case GL_BACK:
  2075. return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, this, false));
  2076. case GL_DEPTH:
  2077. if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).depthBits > 0)
  2078. {
  2079. return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, this, true));
  2080. }
  2081. else
  2082. {
  2083. return NULL;
  2084. }
  2085. case GL_STENCIL:
  2086. if (gl::GetInternalFormatInfo(swapChain->GetDepthBufferInternalFormat()).stencilBits > 0)
  2087. {
  2088. return new DefaultAttachmentD3D(new SurfaceRenderTarget11(swapChain, this, true));
  2089. }
  2090. else
  2091. {
  2092. return NULL;
  2093. }
  2094. default:
  2095. UNREACHABLE();
  2096. return NULL;
  2097. }
  2098. }
  2099. FramebufferImpl *Renderer11::createFramebuffer()
  2100. {
  2101. return new Framebuffer11(this);
  2102. }
  2103. CompilerImpl *Renderer11::createCompiler(const gl::Data &data)
  2104. {
  2105. return new CompilerD3D(data, SH_HLSL11_OUTPUT);
  2106. }
  2107. ShaderImpl *Renderer11::createShader(GLenum type)
  2108. {
  2109. return new ShaderD3D(type);
  2110. }
  2111. ProgramImpl *Renderer11::createProgram()
  2112. {
  2113. return new ProgramD3D(this);
  2114. }
  2115. gl::Error Renderer11::loadExecutable(const void *function, size_t length, ShaderType type,
  2116. const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
  2117. bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable)
  2118. {
  2119. switch (type)
  2120. {
  2121. case SHADER_VERTEX:
  2122. {
  2123. ID3D11VertexShader *vertexShader = NULL;
  2124. ID3D11GeometryShader *streamOutShader = NULL;
  2125. HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader);
  2126. ASSERT(SUCCEEDED(result));
  2127. if (FAILED(result))
  2128. {
  2129. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result);
  2130. }
  2131. if (transformFeedbackVaryings.size() > 0)
  2132. {
  2133. std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
  2134. for (size_t i = 0; i < transformFeedbackVaryings.size(); i++)
  2135. {
  2136. const gl::LinkedVarying &varying = transformFeedbackVaryings[i];
  2137. GLenum transposedType = gl::TransposeMatrixType(varying.type);
  2138. for (size_t j = 0; j < varying.semanticIndexCount; j++)
  2139. {
  2140. D3D11_SO_DECLARATION_ENTRY entry = { 0 };
  2141. entry.Stream = 0;
  2142. entry.SemanticName = varying.semanticName.c_str();
  2143. entry.SemanticIndex = varying.semanticIndex + j;
  2144. entry.StartComponent = 0;
  2145. entry.ComponentCount = gl::VariableColumnCount(transposedType);
  2146. entry.OutputSlot = (separatedOutputBuffers ? i : 0);
  2147. soDeclaration.push_back(entry);
  2148. }
  2149. }
  2150. result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(),
  2151. NULL, 0, 0, NULL, &streamOutShader);
  2152. ASSERT(SUCCEEDED(result));
  2153. if (FAILED(result))
  2154. {
  2155. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result);
  2156. }
  2157. }
  2158. *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader);
  2159. }
  2160. break;
  2161. case SHADER_PIXEL:
  2162. {
  2163. ID3D11PixelShader *pixelShader = NULL;
  2164. HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader);
  2165. ASSERT(SUCCEEDED(result));
  2166. if (FAILED(result))
  2167. {
  2168. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result);
  2169. }
  2170. *outExecutable = new ShaderExecutable11(function, length, pixelShader);
  2171. }
  2172. break;
  2173. case SHADER_GEOMETRY:
  2174. {
  2175. ID3D11GeometryShader *geometryShader = NULL;
  2176. HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader);
  2177. ASSERT(SUCCEEDED(result));
  2178. if (FAILED(result))
  2179. {
  2180. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result);
  2181. }
  2182. *outExecutable = new ShaderExecutable11(function, length, geometryShader);
  2183. }
  2184. break;
  2185. default:
  2186. UNREACHABLE();
  2187. return gl::Error(GL_INVALID_OPERATION);
  2188. }
  2189. return gl::Error(GL_NO_ERROR);
  2190. }
  2191. gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, ShaderType type,
  2192. const std::vector<gl::LinkedVarying> &transformFeedbackVaryings,
  2193. bool separatedOutputBuffers, D3DWorkaroundType workaround,
  2194. ShaderExecutableD3D **outExectuable)
  2195. {
  2196. const char *profileType = NULL;
  2197. switch (type)
  2198. {
  2199. case SHADER_VERTEX:
  2200. profileType = "vs";
  2201. break;
  2202. case SHADER_PIXEL:
  2203. profileType = "ps";
  2204. break;
  2205. case SHADER_GEOMETRY:
  2206. profileType = "gs";
  2207. break;
  2208. default:
  2209. UNREACHABLE();
  2210. return gl::Error(GL_INVALID_OPERATION);
  2211. }
  2212. std::string profile = FormatString("%s_%d_%d%s", profileType, getMajorShaderModel(), getMinorShaderModel(), getShaderModelSuffix().c_str());
  2213. UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
  2214. if (gl::perfActive())
  2215. {
  2216. #ifndef NDEBUG
  2217. flags = D3DCOMPILE_SKIP_OPTIMIZATION;
  2218. #endif
  2219. flags |= D3DCOMPILE_DEBUG;
  2220. }
  2221. // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
  2222. // Try the default flags first and if compilation fails, try some alternatives.
  2223. std::vector<CompileConfig> configs;
  2224. configs.push_back(CompileConfig(flags, "default" ));
  2225. configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" ));
  2226. configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
  2227. D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} };
  2228. ID3DBlob *binary = NULL;
  2229. std::string debugInfo;
  2230. gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo);
  2231. if (error.isError())
  2232. {
  2233. return error;
  2234. }
  2235. // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL
  2236. // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK.
  2237. if (!binary)
  2238. {
  2239. *outExectuable = NULL;
  2240. return gl::Error(GL_NO_ERROR);
  2241. }
  2242. error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type,
  2243. transformFeedbackVaryings, separatedOutputBuffers, outExectuable);
  2244. SafeRelease(binary);
  2245. if (error.isError())
  2246. {
  2247. return error;
  2248. }
  2249. if (!debugInfo.empty())
  2250. {
  2251. (*outExectuable)->appendDebugInfo(debugInfo);
  2252. }
  2253. return gl::Error(GL_NO_ERROR);
  2254. }
  2255. UniformStorageD3D *Renderer11::createUniformStorage(size_t storageSize)
  2256. {
  2257. return new UniformStorage11(this, storageSize);
  2258. }
  2259. VertexBuffer *Renderer11::createVertexBuffer()
  2260. {
  2261. return new VertexBuffer11(this);
  2262. }
  2263. IndexBuffer *Renderer11::createIndexBuffer()
  2264. {
  2265. return new IndexBuffer11(this);
  2266. }
  2267. BufferImpl *Renderer11::createBuffer()
  2268. {
  2269. return new Buffer11(this);
  2270. }
  2271. VertexArrayImpl *Renderer11::createVertexArray()
  2272. {
  2273. return new VertexArray11(this);
  2274. }
  2275. QueryImpl *Renderer11::createQuery(GLenum type)
  2276. {
  2277. return new Query11(this, type);
  2278. }
  2279. FenceNVImpl *Renderer11::createFenceNV()
  2280. {
  2281. return new FenceNV11(this);
  2282. }
  2283. FenceSyncImpl *Renderer11::createFenceSync()
  2284. {
  2285. return new FenceSync11(this);
  2286. }
  2287. TransformFeedbackImpl* Renderer11::createTransformFeedback()
  2288. {
  2289. return new TransformFeedbackD3D();
  2290. }
  2291. bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
  2292. {
  2293. ASSERT(getRendererExtensions().pixelBufferObject);
  2294. const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
  2295. const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mFeatureLevel);
  2296. const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat);
  2297. // sRGB formats do not work with D3D11 buffer SRVs
  2298. if (internalFormatInfo.colorEncoding == GL_SRGB)
  2299. {
  2300. return false;
  2301. }
  2302. // We cannot support direct copies to non-color-renderable formats
  2303. if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN)
  2304. {
  2305. return false;
  2306. }
  2307. // We skip all 3-channel formats since sometimes format support is missing
  2308. if (internalFormatInfo.componentCount == 3)
  2309. {
  2310. return false;
  2311. }
  2312. // We don't support formats which we can't represent without conversion
  2313. if (dxgiFormatInfo.internalFormat != internalFormat)
  2314. {
  2315. return false;
  2316. }
  2317. return true;
  2318. }
  2319. gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
  2320. GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
  2321. {
  2322. ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
  2323. return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea);
  2324. }
  2325. ImageD3D *Renderer11::createImage()
  2326. {
  2327. return new Image11(this);
  2328. }
  2329. gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src)
  2330. {
  2331. Image11 *dest11 = Image11::makeImage11(dest);
  2332. Image11 *src11 = Image11::makeImage11(src);
  2333. return Image11::generateMipmap(dest11, src11);
  2334. }
  2335. TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain)
  2336. {
  2337. SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
  2338. return new TextureStorage11_2D(this, swapChain11);
  2339. }
  2340. TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly)
  2341. {
  2342. return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, hintLevelZeroOnly);
  2343. }
  2344. TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly)
  2345. {
  2346. return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly);
  2347. }
  2348. TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
  2349. {
  2350. return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels);
  2351. }
  2352. TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels)
  2353. {
  2354. return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels);
  2355. }
  2356. TextureImpl *Renderer11::createTexture(GLenum target)
  2357. {
  2358. switch(target)
  2359. {
  2360. case GL_TEXTURE_2D: return new TextureD3D_2D(this);
  2361. case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this);
  2362. case GL_TEXTURE_3D: return new TextureD3D_3D(this);
  2363. case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this);
  2364. default:
  2365. UNREACHABLE();
  2366. }
  2367. return NULL;
  2368. }
  2369. RenderbufferImpl *Renderer11::createRenderbuffer()
  2370. {
  2371. RenderbufferD3D *renderbuffer = new RenderbufferD3D(this);
  2372. return renderbuffer;
  2373. }
  2374. gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format,
  2375. GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels)
  2376. {
  2377. ASSERT(area.width >= 0);
  2378. ASSERT(area.height >= 0);
  2379. D3D11_TEXTURE2D_DESC textureDesc;
  2380. texture->GetDesc(&textureDesc);
  2381. // Clamp read region to the defined texture boundaries, preventing out of bounds reads
  2382. // and reads of uninitialized data.
  2383. gl::Rectangle safeArea;
  2384. safeArea.x = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width));
  2385. safeArea.y = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height));
  2386. safeArea.width = gl::clamp(area.width + std::min(area.x, 0), 0,
  2387. static_cast<int>(textureDesc.Width) - safeArea.x);
  2388. safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0,
  2389. static_cast<int>(textureDesc.Height) - safeArea.y);
  2390. ASSERT(safeArea.x >= 0 && safeArea.y >= 0);
  2391. ASSERT(safeArea.x + safeArea.width <= static_cast<int>(textureDesc.Width));
  2392. ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height));
  2393. if (safeArea.width == 0 || safeArea.height == 0)
  2394. {
  2395. // no work to do
  2396. return gl::Error(GL_NO_ERROR);
  2397. }
  2398. D3D11_TEXTURE2D_DESC stagingDesc;
  2399. stagingDesc.Width = safeArea.width;
  2400. stagingDesc.Height = safeArea.height;
  2401. stagingDesc.MipLevels = 1;
  2402. stagingDesc.ArraySize = 1;
  2403. stagingDesc.Format = textureDesc.Format;
  2404. stagingDesc.SampleDesc.Count = 1;
  2405. stagingDesc.SampleDesc.Quality = 0;
  2406. stagingDesc.Usage = D3D11_USAGE_STAGING;
  2407. stagingDesc.BindFlags = 0;
  2408. stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  2409. stagingDesc.MiscFlags = 0;
  2410. ID3D11Texture2D* stagingTex = NULL;
  2411. HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
  2412. if (FAILED(result))
  2413. {
  2414. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result);
  2415. }
  2416. ID3D11Texture2D* srcTex = NULL;
  2417. if (textureDesc.SampleDesc.Count > 1)
  2418. {
  2419. D3D11_TEXTURE2D_DESC resolveDesc;
  2420. resolveDesc.Width = textureDesc.Width;
  2421. resolveDesc.Height = textureDesc.Height;
  2422. resolveDesc.MipLevels = 1;
  2423. resolveDesc.ArraySize = 1;
  2424. resolveDesc.Format = textureDesc.Format;
  2425. resolveDesc.SampleDesc.Count = 1;
  2426. resolveDesc.SampleDesc.Quality = 0;
  2427. resolveDesc.Usage = D3D11_USAGE_DEFAULT;
  2428. resolveDesc.BindFlags = 0;
  2429. resolveDesc.CPUAccessFlags = 0;
  2430. resolveDesc.MiscFlags = 0;
  2431. result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
  2432. if (FAILED(result))
  2433. {
  2434. SafeRelease(stagingTex);
  2435. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result);
  2436. }
  2437. mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
  2438. subResource = 0;
  2439. }
  2440. else
  2441. {
  2442. srcTex = texture;
  2443. srcTex->AddRef();
  2444. }
  2445. D3D11_BOX srcBox;
  2446. srcBox.left = static_cast<UINT>(safeArea.x);
  2447. srcBox.right = static_cast<UINT>(safeArea.x + safeArea.width);
  2448. srcBox.top = static_cast<UINT>(safeArea.y);
  2449. srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height);
  2450. srcBox.front = 0;
  2451. srcBox.back = 1;
  2452. mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
  2453. SafeRelease(srcTex);
  2454. PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
  2455. gl::Error error = packPixels(stagingTex, packParams, pixels);
  2456. SafeRelease(stagingTex);
  2457. return error;
  2458. }
  2459. gl::Error Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams &params, uint8_t *pixelsOut)
  2460. {
  2461. D3D11_TEXTURE2D_DESC textureDesc;
  2462. readTexture->GetDesc(&textureDesc);
  2463. D3D11_MAPPED_SUBRESOURCE mapping;
  2464. HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping);
  2465. if (FAILED(hr))
  2466. {
  2467. ASSERT(hr == E_OUTOFMEMORY);
  2468. return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr);
  2469. }
  2470. uint8_t *source;
  2471. int inputPitch;
  2472. if (params.pack.reverseRowOrder)
  2473. {
  2474. source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1);
  2475. inputPitch = -static_cast<int>(mapping.RowPitch);
  2476. }
  2477. else
  2478. {
  2479. source = static_cast<uint8_t*>(mapping.pData);
  2480. inputPitch = static_cast<int>(mapping.RowPitch);
  2481. }
  2482. const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
  2483. const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat);
  2484. if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type)
  2485. {
  2486. uint8_t *dest = pixelsOut + params.offset;
  2487. for (int y = 0; y < params.area.height; y++)
  2488. {
  2489. memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes);
  2490. }
  2491. }
  2492. else
  2493. {
  2494. const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format);
  2495. ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type);
  2496. GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type);
  2497. const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat);
  2498. if (fastCopyFunc)
  2499. {
  2500. // Fast copy is possible through some special function
  2501. for (int y = 0; y < params.area.height; y++)
  2502. {
  2503. for (int x = 0; x < params.area.width; x++)
  2504. {
  2505. uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
  2506. const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
  2507. fastCopyFunc(src, dest);
  2508. }
  2509. }
  2510. }
  2511. else
  2512. {
  2513. ColorReadFunction colorReadFunction = sourceDXGIFormatInfo.colorReadFunction;
  2514. ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type);
  2515. uint8_t temp[16]; // Maximum size of any Color<T> type used.
  2516. META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) &&
  2517. sizeof(temp) >= sizeof(gl::ColorUI) &&
  2518. sizeof(temp) >= sizeof(gl::ColorI));
  2519. for (int y = 0; y < params.area.height; y++)
  2520. {
  2521. for (int x = 0; x < params.area.width; x++)
  2522. {
  2523. uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
  2524. const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes;
  2525. // readFunc and writeFunc will be using the same type of color, CopyTexImage
  2526. // will not allow the copy otherwise.
  2527. colorReadFunction(src, temp);
  2528. colorWriteFunction(temp, dest);
  2529. }
  2530. }
  2531. }
  2532. }
  2533. mDeviceContext->Unmap(readTexture, 0);
  2534. return gl::Error(GL_NO_ERROR);
  2535. }
  2536. gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget,
  2537. RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor,
  2538. bool colorBlit, bool depthBlit, bool stencilBlit)
  2539. {
  2540. // Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
  2541. // it should never be the case that both color and depth/stencil need to be blitted at
  2542. // at the same time.
  2543. ASSERT(colorBlit != (depthBlit || stencilBlit));
  2544. RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
  2545. if (!drawRenderTarget)
  2546. {
  2547. return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer.");
  2548. }
  2549. ID3D11Resource *drawTexture = drawRenderTarget11->getTexture();
  2550. unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
  2551. ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView();
  2552. ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView();
  2553. RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
  2554. if (!readRenderTarget)
  2555. {
  2556. return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer.");
  2557. }
  2558. ID3D11Resource *readTexture = NULL;
  2559. ID3D11ShaderResourceView *readSRV = NULL;
  2560. unsigned int readSubresource = 0;
  2561. if (readRenderTarget->getSamples() > 0)
  2562. {
  2563. ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture();
  2564. ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource);
  2565. if (unresolvedTexture)
  2566. {
  2567. readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
  2568. readSubresource = 0;
  2569. SafeRelease(unresolvedTexture);
  2570. HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV);
  2571. if (FAILED(hresult))
  2572. {
  2573. SafeRelease(readTexture);
  2574. return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer.");
  2575. }
  2576. }
  2577. }
  2578. else
  2579. {
  2580. readTexture = readRenderTarget11->getTexture();
  2581. readTexture->AddRef();
  2582. readSubresource = readRenderTarget11->getSubresourceIndex();
  2583. readSRV = readRenderTarget11->getShaderResourceView();
  2584. readSRV->AddRef();
  2585. }
  2586. if (!readTexture || !readSRV)
  2587. {
  2588. SafeRelease(readTexture);
  2589. SafeRelease(readSRV);
  2590. return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target.");
  2591. }
  2592. gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
  2593. gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
  2594. bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL);
  2595. bool wholeBufferCopy = !scissorNeeded &&
  2596. readRect.x == 0 && readRect.width == readSize.width &&
  2597. readRect.y == 0 && readRect.height == readSize.height &&
  2598. drawRect.x == 0 && drawRect.width == drawSize.width &&
  2599. drawRect.y == 0 && drawRect.height == drawSize.height;
  2600. bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height;
  2601. bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0;
  2602. bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width ||
  2603. readRect.y < 0 || readRect.y + readRect.height > readSize.height ||
  2604. drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
  2605. drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
  2606. const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat());
  2607. bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit);
  2608. gl::Error result(GL_NO_ERROR);
  2609. if (readRenderTarget11->getDXGIFormat() == drawRenderTarget11->getDXGIFormat() &&
  2610. !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
  2611. (!(depthBlit || stencilBlit) || wholeBufferCopy))
  2612. {
  2613. UINT dstX = drawRect.x;
  2614. UINT dstY = drawRect.y;
  2615. D3D11_BOX readBox;
  2616. readBox.left = readRect.x;
  2617. readBox.right = readRect.x + readRect.width;
  2618. readBox.top = readRect.y;
  2619. readBox.bottom = readRect.y + readRect.height;
  2620. readBox.front = 0;
  2621. readBox.back = 1;
  2622. if (scissorNeeded)
  2623. {
  2624. // drawRect is guaranteed to have positive width and height because stretchRequired is false.
  2625. ASSERT(drawRect.width >= 0 || drawRect.height >= 0);
  2626. if (drawRect.x < scissor->x)
  2627. {
  2628. dstX = scissor->x;
  2629. readBox.left += (scissor->x - drawRect.x);
  2630. }
  2631. if (drawRect.y < scissor->y)
  2632. {
  2633. dstY = scissor->y;
  2634. readBox.top += (scissor->y - drawRect.y);
  2635. }
  2636. if (drawRect.x + drawRect.width > scissor->x + scissor->width)
  2637. {
  2638. readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width));
  2639. }
  2640. if (drawRect.y + drawRect.height > scissor->y + scissor->height)
  2641. {
  2642. readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height));
  2643. }
  2644. }
  2645. // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
  2646. // We also require complete framebuffer copies for depth-stencil blit.
  2647. D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
  2648. mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0,
  2649. readTexture, readSubresource, pSrcBox);
  2650. result = gl::Error(GL_NO_ERROR);
  2651. }
  2652. else
  2653. {
  2654. gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1);
  2655. gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1);
  2656. if (depthBlit && stencilBlit)
  2657. {
  2658. result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize,
  2659. drawTexture, drawSubresource, drawArea, drawSize,
  2660. scissor);
  2661. }
  2662. else if (depthBlit)
  2663. {
  2664. result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize,
  2665. scissor);
  2666. }
  2667. else if (stencilBlit)
  2668. {
  2669. result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize,
  2670. drawTexture, drawSubresource, drawArea, drawSize,
  2671. scissor);
  2672. }
  2673. else
  2674. {
  2675. GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format;
  2676. result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
  2677. scissor, format, filter);
  2678. }
  2679. }
  2680. SafeRelease(readTexture);
  2681. SafeRelease(readSRV);
  2682. return result;
  2683. }
  2684. ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
  2685. {
  2686. D3D11_TEXTURE2D_DESC textureDesc;
  2687. source->GetDesc(&textureDesc);
  2688. if (textureDesc.SampleDesc.Count > 1)
  2689. {
  2690. D3D11_TEXTURE2D_DESC resolveDesc;
  2691. resolveDesc.Width = textureDesc.Width;
  2692. resolveDesc.Height = textureDesc.Height;
  2693. resolveDesc.MipLevels = 1;
  2694. resolveDesc.ArraySize = 1;
  2695. resolveDesc.Format = textureDesc.Format;
  2696. resolveDesc.SampleDesc.Count = 1;
  2697. resolveDesc.SampleDesc.Quality = 0;
  2698. resolveDesc.Usage = textureDesc.Usage;
  2699. resolveDesc.BindFlags = textureDesc.BindFlags;
  2700. resolveDesc.CPUAccessFlags = 0;
  2701. resolveDesc.MiscFlags = 0;
  2702. ID3D11Texture2D *resolveTexture = NULL;
  2703. HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture);
  2704. if (FAILED(result))
  2705. {
  2706. ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
  2707. return NULL;
  2708. }
  2709. mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
  2710. return resolveTexture;
  2711. }
  2712. else
  2713. {
  2714. source->AddRef();
  2715. return source;
  2716. }
  2717. }
  2718. void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel)
  2719. {
  2720. ASSERT(attachment->type() == GL_TEXTURE);
  2721. gl::Texture *texture = attachment->getTexture();
  2722. TextureD3D *textureD3D = TextureD3D::makeTextureD3D(texture->getImplementation());
  2723. TextureStorage *texStorage = textureD3D->getNativeTexture();
  2724. if (texStorage)
  2725. {
  2726. TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage);
  2727. if (!texStorage11)
  2728. {
  2729. ERR("texture storage pointer unexpectedly null.");
  2730. return;
  2731. }
  2732. texStorage11->invalidateSwizzleCacheLevel(mipLevel);
  2733. }
  2734. }
  2735. void Renderer11::invalidateFramebufferSwizzles(const gl::Framebuffer *framebuffer)
  2736. {
  2737. for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
  2738. {
  2739. gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment);
  2740. if (attachment && attachment->type() == GL_TEXTURE)
  2741. {
  2742. invalidateFBOAttachmentSwizzles(attachment, attachment->mipLevel());
  2743. }
  2744. }
  2745. gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer();
  2746. if (depthAttachment && depthAttachment->type() == GL_TEXTURE)
  2747. {
  2748. invalidateFBOAttachmentSwizzles(depthAttachment, depthAttachment->mipLevel());
  2749. }
  2750. gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer();
  2751. if (stencilAttachment && stencilAttachment->type() == GL_TEXTURE)
  2752. {
  2753. invalidateFBOAttachmentSwizzles(stencilAttachment, stencilAttachment->mipLevel());
  2754. }
  2755. }
  2756. bool Renderer11::getLUID(LUID *adapterLuid) const
  2757. {
  2758. adapterLuid->HighPart = 0;
  2759. adapterLuid->LowPart = 0;
  2760. if (!mDxgiAdapter)
  2761. {
  2762. return false;
  2763. }
  2764. DXGI_ADAPTER_DESC adapterDesc;
  2765. if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc)))
  2766. {
  2767. return false;
  2768. }
  2769. *adapterLuid = adapterDesc.AdapterLuid;
  2770. return true;
  2771. }
  2772. VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const
  2773. {
  2774. return d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).conversionType;
  2775. }
  2776. GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const
  2777. {
  2778. return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat, mFeatureLevel).nativeFormat).componentType;
  2779. }
  2780. void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const
  2781. {
  2782. d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions);
  2783. }
  2784. Workarounds Renderer11::generateWorkarounds() const
  2785. {
  2786. return d3d11::GenerateWorkarounds(mFeatureLevel);
  2787. }
  2788. void Renderer11::setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, ID3D11ShaderResourceView *srv)
  2789. {
  2790. auto &currentSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
  2791. ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs.size());
  2792. auto &record = currentSRVs[resourceSlot];
  2793. if (record.srv != srv)
  2794. {
  2795. if (shaderType == gl::SAMPLER_VERTEX)
  2796. {
  2797. mDeviceContext->VSSetShaderResources(resourceSlot, 1, &srv);
  2798. }
  2799. else
  2800. {
  2801. mDeviceContext->PSSetShaderResources(resourceSlot, 1, &srv);
  2802. }
  2803. record.srv = srv;
  2804. if (srv)
  2805. {
  2806. record.resource = GetSRVResource(srv);
  2807. srv->GetDesc(&record.desc);
  2808. }
  2809. }
  2810. }
  2811. }