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 7 // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. 8 9 #include "libGLESv2/main.h" 10 #include "libGLESv2/Buffer.h" 11 #include "libGLESv2/FramebufferAttachment.h" 12 #include "libGLESv2/ProgramBinary.h" 13 #include "libGLESv2/Framebuffer.h" 14 #include "libGLESv2/renderer/d3d/ProgramD3D.h" 15 #include "libGLESv2/renderer/d3d/ShaderD3D.h" 16 #include "libGLESv2/renderer/d3d/TextureD3D.h" 17 #include "libGLESv2/renderer/d3d/TransformFeedbackD3D.h" 18 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h" 19 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" 20 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" 21 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" 22 #include "libGLESv2/renderer/d3d/d3d11/ShaderExecutable11.h" 23 #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" 24 #include "libGLESv2/renderer/d3d/d3d11/Image11.h" 25 #include "libGLESv2/renderer/d3d/d3d11/VertexBuffer11.h" 26 #include "libGLESv2/renderer/d3d/d3d11/IndexBuffer11.h" 27 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" 28 #include "libGLESv2/renderer/d3d/VertexDataManager.h" 29 #include "libGLESv2/renderer/d3d/IndexDataManager.h" 30 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h" 31 #include "libGLESv2/renderer/d3d/d3d11/Query11.h" 32 #include "libGLESv2/renderer/d3d/d3d11/Fence11.h" 33 #include "libGLESv2/renderer/d3d/d3d11/Blit11.h" 34 #include "libGLESv2/renderer/d3d/d3d11/Clear11.h" 35 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h" 36 #include "libGLESv2/renderer/d3d/d3d11/VertexArray11.h" 37 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h" 38 39 #include "libEGL/Display.h" 40 41 #include "common/utilities.h" 42 43 #include <EGL/eglext.h> 44 45 #include <sstream> 46 47 // Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process 48 // HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed. 49 #ifndef ANGLE_SKIP_DXGI_1_2_CHECK 50 #define ANGLE_SKIP_DXGI_1_2_CHECK 0 51 #endif 52 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 59 namespace rx 60 { 61 static const DXGI_FORMAT RenderTargetFormats[] = 62 { 63 DXGI_FORMAT_B8G8R8A8_UNORM, 64 DXGI_FORMAT_R8G8B8A8_UNORM 65 }; 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 74 enum 75 { 76 MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 77 }; 78 79 Renderer11::Renderer11(egl::Display *display, EGLNativeDisplayType hDc, EGLint requestedDisplay) 80 : Renderer(display), 81 mDc(hDc), 82 mRequestedDisplay(requestedDisplay) 83 { 84 mVertexDataManager = NULL; 85 mIndexDataManager = NULL; 86 87 mLineLoopIB = NULL; 88 mTriangleFanIB = NULL; 89 90 mBlit = NULL; 91 mPixelTransfer = NULL; 92 93 mClear = NULL; 94 95 mSyncQuery = NULL; 96 97 mD3d11Module = NULL; 98 mDxgiModule = NULL; 99 100 mDeviceLost = false; 101 102 mDevice = NULL; 103 mDeviceContext = NULL; 104 mDxgiAdapter = NULL; 105 mDxgiFactory = NULL; 106 107 mDriverConstantBufferVS = NULL; 108 mDriverConstantBufferPS = NULL; 109 110 mAppliedVertexShader = NULL; 111 mAppliedGeometryShader = NULL; 112 mCurPointGeometryShader = NULL; 113 mAppliedPixelShader = NULL; 114 } 115 116 Renderer11::~Renderer11() 117 { 118 release(); 119 } 120 121 Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) 122 { 123 ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer)); 124 return static_cast<rx::Renderer11*>(renderer); 125 } 126 127 #ifndef __d3d11_1_h__ 128 #define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081) 129 #endif 130 131 EGLint Renderer11::initialize() 132 { 133 if (!mCompiler.initialize()) 134 { 135 return EGL_NOT_INITIALIZED; 136 } 137 138 mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); 139 mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); 140 141 if (mD3d11Module == NULL || mDxgiModule == NULL) 142 { 143 ERR("Could not load D3D11 or DXGI library - aborting!\n"); 144 return EGL_NOT_INITIALIZED; 145 } 146 147 // create the D3D11 device 148 ASSERT(mDevice == NULL); 149 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); 150 151 if (D3D11CreateDevice == NULL) 152 { 153 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n"); 154 return EGL_NOT_INITIALIZED; 155 } 156 157 D3D_FEATURE_LEVEL featureLevels[] = 158 { 159 D3D_FEATURE_LEVEL_11_0, 160 D3D_FEATURE_LEVEL_10_1, 161 D3D_FEATURE_LEVEL_10_0, 162 }; 163 164 D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE; 165 if (mRequestedDisplay == EGL_PLATFORM_ANGLE_TYPE_D3D11_WARP_ANGLE) 166 { 167 driverType = D3D_DRIVER_TYPE_WARP; 168 } 169 170 HRESULT result = S_OK; 171 172 #ifdef _DEBUG 173 result = D3D11CreateDevice(NULL, 174 driverType, 175 NULL, 176 D3D11_CREATE_DEVICE_DEBUG, 177 featureLevels, 178 ArraySize(featureLevels), 179 D3D11_SDK_VERSION, 180 &mDevice, 181 &mFeatureLevel, 182 &mDeviceContext); 183 184 if (!mDevice || FAILED(result)) 185 { 186 ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); 187 } 188 189 if (!mDevice || FAILED(result)) 190 #endif 191 { 192 result = D3D11CreateDevice(NULL, 193 driverType, 194 NULL, 195 0, 196 featureLevels, 197 ArraySize(featureLevels), 198 D3D11_SDK_VERSION, 199 &mDevice, 200 &mFeatureLevel, 201 &mDeviceContext); 202 203 if (!mDevice || FAILED(result)) 204 { 205 ERR("Could not create D3D11 device - aborting!\n"); 206 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer 207 } 208 } 209 210 #if !ANGLE_SKIP_DXGI_1_2_CHECK 211 // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. 212 // The easiest way to check is to query for a IDXGIDevice2. 213 bool requireDXGI1_2 = false; 214 HWND hwnd = WindowFromDC(mDc); 215 if (hwnd) 216 { 217 DWORD currentProcessId = GetCurrentProcessId(); 218 DWORD wndProcessId; 219 GetWindowThreadProcessId(hwnd, &wndProcessId); 220 requireDXGI1_2 = (currentProcessId != wndProcessId); 221 } 222 else 223 { 224 requireDXGI1_2 = true; 225 } 226 227 if (requireDXGI1_2) 228 { 229 IDXGIDevice2 *dxgiDevice2 = NULL; 230 result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2); 231 if (FAILED(result)) 232 { 233 ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n"); 234 return EGL_NOT_INITIALIZED; 235 } 236 SafeRelease(dxgiDevice2); 237 } 238 #endif 239 240 IDXGIDevice *dxgiDevice = NULL; 241 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); 242 243 if (FAILED(result)) 244 { 245 ERR("Could not query DXGI device - aborting!\n"); 246 return EGL_NOT_INITIALIZED; 247 } 248 249 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter); 250 251 if (FAILED(result)) 252 { 253 ERR("Could not retrieve DXGI adapter - aborting!\n"); 254 return EGL_NOT_INITIALIZED; 255 } 256 257 SafeRelease(dxgiDevice); 258 259 mDxgiAdapter->GetDesc(&mAdapterDescription); 260 memset(mDescription, 0, sizeof(mDescription)); 261 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); 262 263 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory); 264 265 if (!mDxgiFactory || FAILED(result)) 266 { 267 ERR("Could not create DXGI factory - aborting!\n"); 268 return EGL_NOT_INITIALIZED; 269 } 270 271 // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log 272 #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) 273 ID3D11InfoQueue *infoQueue; 274 result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); 275 276 if (SUCCEEDED(result)) 277 { 278 D3D11_MESSAGE_ID hideMessages[] = 279 { 280 D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET 281 }; 282 283 D3D11_INFO_QUEUE_FILTER filter = {0}; 284 filter.DenyList.NumIDs = ArraySize(hideMessages); 285 filter.DenyList.pIDList = hideMessages; 286 287 infoQueue->AddStorageFilterEntries(&filter); 288 SafeRelease(infoQueue); 289 } 290 #endif 291 292 initializeDevice(); 293 294 return EGL_SUCCESS; 295 } 296 297 // do any one-time device initialization 298 // NOTE: this is also needed after a device lost/reset 299 // to reset the scene status and ensure the default states are reset. 300 void Renderer11::initializeDevice() 301 { 302 mStateCache.initialize(mDevice); 303 mInputLayoutCache.initialize(mDevice, mDeviceContext); 304 305 ASSERT(!mVertexDataManager && !mIndexDataManager); 306 mVertexDataManager = new VertexDataManager(this); 307 mIndexDataManager = new IndexDataManager(this); 308 309 ASSERT(!mBlit); 310 mBlit = new Blit11(this); 311 312 ASSERT(!mClear); 313 mClear = new Clear11(this); 314 315 ASSERT(!mPixelTransfer); 316 mPixelTransfer = new PixelTransfer11(this); 317 318 const gl::Caps &rendererCaps = getRendererCaps(); 319 320 mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); 321 mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); 322 323 mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); 324 mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); 325 326 mCurVertexSRVs.resize(rendererCaps.maxVertexTextureImageUnits); 327 mCurPixelSRVs.resize(rendererCaps.maxTextureImageUnits); 328 329 markAllStateDirty(); 330 } 331 332 int Renderer11::generateConfigs(ConfigDesc **configDescList) 333 { 334 unsigned int numRenderFormats = ArraySize(RenderTargetFormats); 335 unsigned int numDepthFormats = ArraySize(DepthStencilFormats); 336 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; 337 int numConfigs = 0; 338 339 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) 340 { 341 const d3d11::DXGIFormat &renderTargetFormatInfo = d3d11::GetDXGIFormatInfo(RenderTargetFormats[formatIndex]); 342 const gl::TextureCaps &renderTargetFormatCaps = getRendererTextureCaps().get(renderTargetFormatInfo.internalFormat); 343 if (renderTargetFormatCaps.renderable) 344 { 345 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) 346 { 347 const d3d11::DXGIFormat &depthStencilFormatInfo = d3d11::GetDXGIFormatInfo(DepthStencilFormats[depthStencilIndex]); 348 const gl::TextureCaps &depthStencilFormatCaps = getRendererTextureCaps().get(depthStencilFormatInfo.internalFormat); 349 if (depthStencilFormatCaps.renderable || DepthStencilFormats[depthStencilIndex] == DXGI_FORMAT_UNKNOWN) 350 { 351 ConfigDesc newConfig; 352 newConfig.renderTargetFormat = renderTargetFormatInfo.internalFormat; 353 newConfig.depthStencilFormat = depthStencilFormatInfo.internalFormat; 354 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling 355 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast 356 newConfig.es3Capable = true; 357 358 (*configDescList)[numConfigs++] = newConfig; 359 } 360 } 361 } 362 } 363 364 return numConfigs; 365 } 366 367 void Renderer11::deleteConfigs(ConfigDesc *configDescList) 368 { 369 delete [] (configDescList); 370 } 371 372 void Renderer11::sync(bool block) 373 { 374 if (block) 375 { 376 HRESULT result; 377 378 if (!mSyncQuery) 379 { 380 D3D11_QUERY_DESC queryDesc; 381 queryDesc.Query = D3D11_QUERY_EVENT; 382 queryDesc.MiscFlags = 0; 383 384 result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); 385 ASSERT(SUCCEEDED(result)); 386 } 387 388 mDeviceContext->End(mSyncQuery); 389 mDeviceContext->Flush(); 390 391 do 392 { 393 result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); 394 395 // Keep polling, but allow other threads to do something useful first 396 Sleep(0); 397 398 if (testDeviceLost(true)) 399 { 400 return; 401 } 402 } 403 while (result == S_FALSE); 404 } 405 else 406 { 407 mDeviceContext->Flush(); 408 } 409 } 410 411 SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) 412 { 413 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); 414 } 415 416 void Renderer11::generateSwizzle(gl::Texture *texture) 417 { 418 if (texture) 419 { 420 TextureStorage *texStorage = texture->getNativeTexture(); 421 if (texStorage) 422 { 423 TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); 424 425 storage11->generateSwizzles(texture->getSamplerState().swizzleRed, 426 texture->getSamplerState().swizzleGreen, 427 texture->getSamplerState().swizzleBlue, 428 texture->getSamplerState().swizzleAlpha); 429 } 430 } 431 } 432 433 void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) 434 { 435 if (type == gl::SAMPLER_PIXEL) 436 { 437 ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); 438 439 if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) 440 { 441 ID3D11SamplerState *dxSamplerState = NULL; 442 gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); 443 if (error.isError()) 444 { 445 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" 446 "sampler state for pixel shaders at slot %i.", index); 447 dxSamplerState = NULL; 448 } 449 450 mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); 451 452 mCurPixelSamplerStates[index] = samplerState; 453 } 454 455 mForceSetPixelSamplerStates[index] = false; 456 } 457 else if (type == gl::SAMPLER_VERTEX) 458 { 459 ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); 460 461 if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) 462 { 463 ID3D11SamplerState *dxSamplerState = NULL; 464 gl::Error error = mStateCache.getSamplerState(samplerState, &dxSamplerState); 465 if (error.isError()) 466 { 467 ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" 468 "sampler state for vertex shaders at slot %i.", index); 469 dxSamplerState = NULL; 470 } 471 472 mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); 473 474 mCurVertexSamplerStates[index] = samplerState; 475 } 476 477 mForceSetVertexSamplerStates[index] = false; 478 } 479 else UNREACHABLE(); 480 } 481 482 void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) 483 { 484 ID3D11ShaderResourceView *textureSRV = NULL; 485 bool forceSetTexture = false; 486 487 if (texture) 488 { 489 TextureD3D* textureImpl = TextureD3D::makeTextureD3D(texture->getImplementation()); 490 491 TextureStorage *texStorage = textureImpl->getNativeTexture(); 492 if (texStorage) 493 { 494 TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage); 495 gl::SamplerState samplerState; 496 texture->getSamplerStateWithNativeOffset(&samplerState); 497 textureSRV = storage11->getSRV(samplerState); 498 } 499 500 // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly 501 // missing the shader resource view 502 ASSERT(textureSRV != NULL); 503 504 forceSetTexture = textureImpl->hasDirtyImages(); 505 textureImpl->resetDirty(); 506 } 507 508 if (type == gl::SAMPLER_PIXEL) 509 { 510 ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxTextureImageUnits); 511 512 if (forceSetTexture || mCurPixelSRVs[index] != textureSRV) 513 { 514 mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); 515 } 516 517 mCurPixelSRVs[index] = textureSRV; 518 } 519 else if (type == gl::SAMPLER_VERTEX) 520 { 521 ASSERT(static_cast<unsigned int>(index) < getRendererCaps().maxVertexTextureImageUnits); 522 523 if (forceSetTexture || mCurVertexSRVs[index] != textureSRV) 524 { 525 mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); 526 } 527 528 mCurVertexSRVs[index] = textureSRV; 529 } 530 else UNREACHABLE(); 531 } 532 533 bool Renderer11::setUniformBuffers(const gl::Buffer *vertexUniformBuffers[], const gl::Buffer *fragmentUniformBuffers[]) 534 { 535 for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) 536 { 537 const gl::Buffer *uniformBuffer = vertexUniformBuffers[uniformBufferIndex]; 538 if (uniformBuffer) 539 { 540 Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation()); 541 ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); 542 543 if (!constantBuffer) 544 { 545 return false; 546 } 547 548 if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial()) 549 { 550 mDeviceContext->VSSetConstantBuffers(getReservedVertexUniformBuffers() + uniformBufferIndex, 551 1, &constantBuffer); 552 mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); 553 } 554 } 555 } 556 557 for (unsigned int uniformBufferIndex = 0; uniformBufferIndex < gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS; uniformBufferIndex++) 558 { 559 const gl::Buffer *uniformBuffer = fragmentUniformBuffers[uniformBufferIndex]; 560 if (uniformBuffer) 561 { 562 Buffer11 *bufferStorage = Buffer11::makeBuffer11(uniformBuffer->getImplementation()); 563 ID3D11Buffer *constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); 564 565 if (!constantBuffer) 566 { 567 return false; 568 } 569 570 if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial()) 571 { 572 mDeviceContext->PSSetConstantBuffers(getReservedFragmentUniformBuffers() + uniformBufferIndex, 573 1, &constantBuffer); 574 mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); 575 } 576 } 577 } 578 579 return true; 580 } 581 582 void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) 583 { 584 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) 585 { 586 ID3D11RasterizerState *dxRasterState = NULL; 587 gl::Error error = mStateCache.getRasterizerState(rasterState, mScissorEnabled, &dxRasterState); 588 if (error.isError()) 589 { 590 ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" 591 "rasterizer state."); 592 dxRasterState = NULL; 593 } 594 595 mDeviceContext->RSSetState(dxRasterState); 596 597 mCurRasterState = rasterState; 598 } 599 600 mForceSetRasterState = false; 601 } 602 603 void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::ColorF &blendColor, 604 unsigned int sampleMask) 605 { 606 if (mForceSetBlendState || 607 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 || 608 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::ColorF)) != 0 || 609 sampleMask != mCurSampleMask) 610 { 611 ID3D11BlendState *dxBlendState = NULL; 612 gl::Error error = mStateCache.getBlendState(framebuffer, blendState, &dxBlendState); 613 if (error.isError()) 614 { 615 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " 616 "blend state."); 617 dxBlendState = NULL; 618 } 619 620 float blendColors[4] = {0.0f}; 621 if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && 622 blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) 623 { 624 blendColors[0] = blendColor.red; 625 blendColors[1] = blendColor.green; 626 blendColors[2] = blendColor.blue; 627 blendColors[3] = blendColor.alpha; 628 } 629 else 630 { 631 blendColors[0] = blendColor.alpha; 632 blendColors[1] = blendColor.alpha; 633 blendColors[2] = blendColor.alpha; 634 blendColors[3] = blendColor.alpha; 635 } 636 637 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); 638 639 mCurBlendState = blendState; 640 mCurBlendColor = blendColor; 641 mCurSampleMask = sampleMask; 642 } 643 644 mForceSetBlendState = false; 645 } 646 647 void 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 658 ID3D11DepthStencilState *dxDepthStencilState = NULL; 659 gl::Error error = mStateCache.getDepthStencilState(depthStencilState, &dxDepthStencilState); 660 if (error.isError()) 661 { 662 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, " 663 "setting the default depth stencil state."); 664 dxDepthStencilState = NULL; 665 } 666 667 // Max D3D11 stencil reference value is 0xFF, corresponding to the max 8 bits in a stencil buffer 668 // GL specifies we should clamp the ref value to the nearest bit depth when doing stencil ops 669 META_ASSERT(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF); 670 META_ASSERT(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF); 671 UINT dxStencilRef = std::min<UINT>(stencilRef, 0xFFu); 672 673 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); 674 675 mCurDepthStencilState = depthStencilState; 676 mCurStencilRef = stencilRef; 677 mCurStencilBackRef = stencilBackRef; 678 } 679 680 mForceSetDepthStencilState = false; 681 } 682 683 void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) 684 { 685 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || 686 enabled != mScissorEnabled) 687 { 688 if (enabled) 689 { 690 D3D11_RECT rect; 691 rect.left = std::max(0, scissor.x); 692 rect.top = std::max(0, scissor.y); 693 rect.right = scissor.x + std::max(0, scissor.width); 694 rect.bottom = scissor.y + std::max(0, scissor.height); 695 696 mDeviceContext->RSSetScissorRects(1, &rect); 697 } 698 699 if (enabled != mScissorEnabled) 700 { 701 mForceSetRasterState = true; 702 } 703 704 mCurScissor = scissor; 705 mScissorEnabled = enabled; 706 } 707 708 mForceSetScissor = false; 709 } 710 711 void Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, 712 bool ignoreViewport) 713 { 714 gl::Rectangle actualViewport = viewport; 715 float actualZNear = gl::clamp01(zNear); 716 float actualZFar = gl::clamp01(zFar); 717 if (ignoreViewport) 718 { 719 actualViewport.x = 0; 720 actualViewport.y = 0; 721 actualViewport.width = mRenderTargetDesc.width; 722 actualViewport.height = mRenderTargetDesc.height; 723 actualZNear = 0.0f; 724 actualZFar = 1.0f; 725 } 726 727 const gl::Caps& caps = getRendererCaps(); 728 729 // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds 730 D3D11_VIEWPORT dxViewport; 731 dxViewport.TopLeftX = gl::clamp(actualViewport.x, -static_cast<int>(caps.maxViewportWidth), static_cast<int>(caps.maxViewportWidth)); 732 dxViewport.TopLeftY = gl::clamp(actualViewport.y, -static_cast<int>(caps.maxViewportHeight), static_cast<int>(caps.maxViewportHeight)); 733 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(caps.maxViewportWidth - dxViewport.TopLeftX)); 734 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(caps.maxViewportHeight - dxViewport.TopLeftY)); 735 dxViewport.MinDepth = actualZNear; 736 dxViewport.MaxDepth = actualZFar; 737 738 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || 739 actualZNear != mCurNear || actualZFar != mCurFar; 740 741 if (viewportChanged) 742 { 743 mDeviceContext->RSSetViewports(1, &dxViewport); 744 745 mCurViewport = actualViewport; 746 mCurNear = actualZNear; 747 mCurFar = actualZFar; 748 749 mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f; 750 mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f; 751 mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); 752 mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); 753 754 mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; 755 mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; 756 757 mVertexConstants.depthRange[0] = actualZNear; 758 mVertexConstants.depthRange[1] = actualZFar; 759 mVertexConstants.depthRange[2] = actualZFar - actualZNear; 760 761 mPixelConstants.depthRange[0] = actualZNear; 762 mPixelConstants.depthRange[1] = actualZFar; 763 mPixelConstants.depthRange[2] = actualZFar - actualZNear; 764 } 765 766 mForceSetViewport = false; 767 } 768 769 bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) 770 { 771 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; 772 773 GLsizei minCount = 0; 774 775 switch (mode) 776 { 777 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break; 778 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break; 779 case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; 780 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; 781 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; 782 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break; 783 // emulate fans via rewriting index buffer 784 case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; 785 default: 786 UNREACHABLE(); 787 return false; 788 } 789 790 if (primitiveTopology != mCurrentPrimitiveTopology) 791 { 792 mDeviceContext->IASetPrimitiveTopology(primitiveTopology); 793 mCurrentPrimitiveTopology = primitiveTopology; 794 } 795 796 return count >= minCount; 797 } 798 799 bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) 800 { 801 // Get the color render buffer and serial 802 // Also extract the render target dimensions and view 803 unsigned int renderTargetWidth = 0; 804 unsigned int renderTargetHeight = 0; 805 GLenum renderTargetFormat = 0; 806 unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0}; 807 ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; 808 bool missingColorRenderTarget = true; 809 810 const gl::ColorbufferInfo &colorbuffers = framebuffer->getColorbuffersForRender(); 811 812 for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) 813 { 814 gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; 815 816 if (colorbuffer) 817 { 818 // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) 819 820 // check for zero-sized default framebuffer, which is a special case. 821 // in this case we do not wish to modify any state and just silently return false. 822 // this will not report any gl error but will cause the calling method to return. 823 if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) 824 { 825 return false; 826 } 827 828 renderTargetSerials[colorAttachment] = GetAttachmentSerial(colorbuffer); 829 830 // Extract the render target dimensions and view 831 RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 832 if (!renderTarget) 833 { 834 ERR("render target pointer unexpectedly null."); 835 return false; 836 } 837 838 framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); 839 if (!framebufferRTVs[colorAttachment]) 840 { 841 ERR("render target view pointer unexpectedly null."); 842 return false; 843 } 844 845 if (missingColorRenderTarget) 846 { 847 renderTargetWidth = colorbuffer->getWidth(); 848 renderTargetHeight = colorbuffer->getHeight(); 849 renderTargetFormat = colorbuffer->getActualFormat(); 850 missingColorRenderTarget = false; 851 } 852 853 // TODO: Detect if this color buffer is already bound as a texture and unbind it first to prevent 854 // D3D11 warnings. 855 } 856 } 857 858 // Get the depth stencil render buffter and serials 859 gl::FramebufferAttachment *depthStencil = framebuffer->getDepthbuffer(); 860 unsigned int depthbufferSerial = 0; 861 unsigned int stencilbufferSerial = 0; 862 if (depthStencil) 863 { 864 depthbufferSerial = GetAttachmentSerial(depthStencil); 865 } 866 else if (framebuffer->getStencilbuffer()) 867 { 868 depthStencil = framebuffer->getStencilbuffer(); 869 stencilbufferSerial = GetAttachmentSerial(depthStencil); 870 } 871 872 ID3D11DepthStencilView* framebufferDSV = NULL; 873 if (depthStencil) 874 { 875 RenderTarget11 *depthStencilRenderTarget = d3d11::GetAttachmentRenderTarget(depthStencil); 876 if (!depthStencilRenderTarget) 877 { 878 ERR("render target pointer unexpectedly null."); 879 SafeRelease(framebufferRTVs); 880 return false; 881 } 882 883 framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); 884 if (!framebufferDSV) 885 { 886 ERR("depth stencil view pointer unexpectedly null."); 887 SafeRelease(framebufferRTVs); 888 return false; 889 } 890 891 // If there is no render buffer, the width, height and format values come from 892 // the depth stencil 893 if (missingColorRenderTarget) 894 { 895 renderTargetWidth = depthStencil->getWidth(); 896 renderTargetHeight = depthStencil->getHeight(); 897 renderTargetFormat = depthStencil->getActualFormat(); 898 } 899 } 900 901 // Apply the render target and depth stencil 902 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized || 903 memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 || 904 depthbufferSerial != mAppliedDepthbufferSerial || 905 stencilbufferSerial != mAppliedStencilbufferSerial) 906 { 907 mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, framebufferRTVs, framebufferDSV); 908 909 mRenderTargetDesc.width = renderTargetWidth; 910 mRenderTargetDesc.height = renderTargetHeight; 911 mRenderTargetDesc.format = renderTargetFormat; 912 mForceSetViewport = true; 913 mForceSetScissor = true; 914 mForceSetBlendState = true; 915 916 if (!mDepthStencilInitialized) 917 { 918 mForceSetRasterState = true; 919 } 920 921 for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) 922 { 923 mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex]; 924 } 925 mAppliedDepthbufferSerial = depthbufferSerial; 926 mAppliedStencilbufferSerial = stencilbufferSerial; 927 mRenderTargetDescInitialized = true; 928 mDepthStencilInitialized = true; 929 } 930 931 invalidateFramebufferSwizzles(framebuffer); 932 933 return true; 934 } 935 936 gl::Error Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, const gl::VertexAttribute vertexAttributes[], const gl::VertexAttribCurrentValueData currentValues[], 937 GLint first, GLsizei count, GLsizei instances) 938 { 939 TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; 940 gl::Error error = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances); 941 if (error.isError()) 942 { 943 return error; 944 } 945 946 return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); 947 } 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 957 ID3D11Buffer *buffer = NULL; 958 DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; 959 960 if (indexInfo->storage) 961 { 962 Buffer11 *storage = Buffer11::makeBuffer11(indexInfo->storage); 963 buffer = storage->getBuffer(BUFFER_USAGE_INDEX); 964 } 965 else 966 { 967 IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); 968 buffer = indexBuffer->getBuffer(); 969 } 970 971 if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) 972 { 973 mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); 974 975 mAppliedIB = buffer; 976 mAppliedIBFormat = bufferFormat; 977 mAppliedIBOffset = indexInfo->startOffset; 978 } 979 980 return gl::Error(GL_NO_ERROR); 981 } 982 983 void Renderer11::applyTransformFeedbackBuffers(gl::Buffer *transformFeedbackBuffers[], GLintptr offsets[]) 984 { 985 ID3D11Buffer* d3dBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; 986 UINT d3dOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; 987 bool requiresUpdate = false; 988 for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 989 { 990 if (transformFeedbackBuffers[i]) 991 { 992 Buffer11 *storage = Buffer11::makeBuffer11(transformFeedbackBuffers[i]->getImplementation()); 993 ID3D11Buffer *buffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); 994 995 d3dBuffers[i] = buffer; 996 d3dOffsets[i] = (mAppliedTFBuffers[i] != buffer) ? static_cast<UINT>(offsets[i]) : -1; 997 } 998 else 999 { 1000 d3dBuffers[i] = NULL; 1001 d3dOffsets[i] = 0; 1002 } 1003 1004 if (d3dBuffers[i] != mAppliedTFBuffers[i] || offsets[i] != mAppliedTFOffsets[i]) 1005 { 1006 requiresUpdate = true; 1007 } 1008 } 1009 1010 if (requiresUpdate) 1011 { 1012 mDeviceContext->SOSetTargets(ArraySize(d3dBuffers), d3dBuffers, d3dOffsets); 1013 for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 1014 { 1015 mAppliedTFBuffers[i] = d3dBuffers[i]; 1016 mAppliedTFOffsets[i] = offsets[i]; 1017 } 1018 } 1019 } 1020 1021 void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances, bool transformFeedbackActive) 1022 { 1023 if (mode == GL_POINTS && transformFeedbackActive) 1024 { 1025 // Since point sprites are generated with a geometry shader, too many vertices will 1026 // be written if transform feedback is active. To work around this, draw only the points 1027 // with the stream out shader and no pixel shader to feed the stream out buffers and then 1028 // draw again with the point sprite geometry shader to rasterize the point sprites. 1029 1030 mDeviceContext->PSSetShader(NULL, NULL, 0); 1031 1032 if (instances > 0) 1033 { 1034 mDeviceContext->DrawInstanced(count, instances, 0, 0); 1035 } 1036 else 1037 { 1038 mDeviceContext->Draw(count, 0); 1039 } 1040 1041 mDeviceContext->GSSetShader(mCurPointGeometryShader, NULL, 0); 1042 mDeviceContext->PSSetShader(mAppliedPixelShader, NULL, 0); 1043 1044 if (instances > 0) 1045 { 1046 mDeviceContext->DrawInstanced(count, instances, 0, 0); 1047 } 1048 else 1049 { 1050 mDeviceContext->Draw(count, 0); 1051 } 1052 1053 mDeviceContext->GSSetShader(mAppliedGeometryShader, NULL, 0); 1054 } 1055 else if (mode == GL_LINE_LOOP) 1056 { 1057 drawLineLoop(count, GL_NONE, NULL, 0, NULL); 1058 } 1059 else if (mode == GL_TRIANGLE_FAN) 1060 { 1061 drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); 1062 } 1063 else if (instances > 0) 1064 { 1065 mDeviceContext->DrawInstanced(count, instances, 0, 0); 1066 } 1067 else 1068 { 1069 mDeviceContext->Draw(count, 0); 1070 } 1071 } 1072 1073 void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, 1074 gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) 1075 { 1076 int minIndex = static_cast<int>(indexInfo.indexRange.start); 1077 1078 if (mode == GL_LINE_LOOP) 1079 { 1080 drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); 1081 } 1082 else if (mode == GL_TRIANGLE_FAN) 1083 { 1084 drawTriangleFan(count, type, indices, minIndex, elementArrayBuffer, instances); 1085 } 1086 else if (instances > 0) 1087 { 1088 mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); 1089 } 1090 else 1091 { 1092 mDeviceContext->DrawIndexed(count, 0, -minIndex); 1093 } 1094 } 1095 1096 void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) 1097 { 1098 // Get the raw indices for an indexed draw 1099 if (type != GL_NONE && elementArrayBuffer) 1100 { 1101 gl::Buffer *indexBuffer = elementArrayBuffer; 1102 BufferImpl *storage = indexBuffer->getImplementation(); 1103 intptr_t offset = reinterpret_cast<intptr_t>(indices); 1104 indices = static_cast<const GLubyte*>(storage->getData()) + offset; 1105 } 1106 1107 if (!mLineLoopIB) 1108 { 1109 mLineLoopIB = new StreamingIndexBufferInterface(this); 1110 gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); 1111 if (error.isError()) 1112 { 1113 SafeDelete(mLineLoopIB); 1114 1115 ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); 1116 return gl::error(GL_OUT_OF_MEMORY); 1117 } 1118 } 1119 1120 // Checked by Renderer11::applyPrimitiveType 1121 ASSERT(count >= 0); 1122 1123 if (static_cast<unsigned int>(count) + 1 > (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int))) 1124 { 1125 ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); 1126 return gl::error(GL_OUT_OF_MEMORY); 1127 } 1128 1129 const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int); 1130 gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); 1131 if (error.isError()) 1132 { 1133 ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); 1134 return gl::error(GL_OUT_OF_MEMORY); 1135 } 1136 1137 void* mappedMemory = NULL; 1138 unsigned int offset; 1139 error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); 1140 if (error.isError()) 1141 { 1142 ERR("Could not map index buffer for GL_LINE_LOOP."); 1143 return gl::error(GL_OUT_OF_MEMORY); 1144 } 1145 1146 unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); 1147 unsigned int indexBufferOffset = offset; 1148 1149 switch (type) 1150 { 1151 case GL_NONE: // Non-indexed draw 1152 for (int i = 0; i < count; i++) 1153 { 1154 data[i] = i; 1155 } 1156 data[count] = 0; 1157 break; 1158 case GL_UNSIGNED_BYTE: 1159 for (int i = 0; i < count; i++) 1160 { 1161 data[i] = static_cast<const GLubyte*>(indices)[i]; 1162 } 1163 data[count] = static_cast<const GLubyte*>(indices)[0]; 1164 break; 1165 case GL_UNSIGNED_SHORT: 1166 for (int i = 0; i < count; i++) 1167 { 1168 data[i] = static_cast<const GLushort*>(indices)[i]; 1169 } 1170 data[count] = static_cast<const GLushort*>(indices)[0]; 1171 break; 1172 case GL_UNSIGNED_INT: 1173 for (int i = 0; i < count; i++) 1174 { 1175 data[i] = static_cast<const GLuint*>(indices)[i]; 1176 } 1177 data[count] = static_cast<const GLuint*>(indices)[0]; 1178 break; 1179 default: UNREACHABLE(); 1180 } 1181 1182 error = mLineLoopIB->unmapBuffer(); 1183 if (error.isError()) 1184 { 1185 ERR("Could not unmap index buffer for GL_LINE_LOOP."); 1186 return gl::error(GL_OUT_OF_MEMORY); 1187 } 1188 1189 IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); 1190 ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); 1191 DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); 1192 1193 if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) 1194 { 1195 mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); 1196 mAppliedIB = d3dIndexBuffer; 1197 mAppliedIBFormat = indexFormat; 1198 mAppliedIBOffset = indexBufferOffset; 1199 } 1200 1201 mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); 1202 } 1203 1204 void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) 1205 { 1206 // Get the raw indices for an indexed draw 1207 if (type != GL_NONE && elementArrayBuffer) 1208 { 1209 gl::Buffer *indexBuffer = elementArrayBuffer; 1210 BufferImpl *storage = indexBuffer->getImplementation(); 1211 intptr_t offset = reinterpret_cast<intptr_t>(indices); 1212 indices = static_cast<const GLubyte*>(storage->getData()) + offset; 1213 } 1214 1215 if (!mTriangleFanIB) 1216 { 1217 mTriangleFanIB = new StreamingIndexBufferInterface(this); 1218 gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); 1219 if (error.isError()) 1220 { 1221 SafeDelete(mTriangleFanIB); 1222 1223 ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN."); 1224 return gl::error(GL_OUT_OF_MEMORY); 1225 } 1226 } 1227 1228 // Checked by Renderer11::applyPrimitiveType 1229 ASSERT(count >= 3); 1230 1231 const unsigned int numTris = count - 2; 1232 1233 if (numTris > (std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3))) 1234 { 1235 ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); 1236 return gl::error(GL_OUT_OF_MEMORY); 1237 } 1238 1239 const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); 1240 gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); 1241 if (error.isError()) 1242 { 1243 ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); 1244 return gl::error(GL_OUT_OF_MEMORY); 1245 } 1246 1247 void* mappedMemory = NULL; 1248 unsigned int offset; 1249 error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); 1250 if (error.isError()) 1251 { 1252 ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); 1253 return gl::error(GL_OUT_OF_MEMORY); 1254 } 1255 1256 unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory); 1257 unsigned int indexBufferOffset = offset; 1258 1259 switch (type) 1260 { 1261 case GL_NONE: // Non-indexed draw 1262 for (unsigned int i = 0; i < numTris; i++) 1263 { 1264 data[i*3 + 0] = 0; 1265 data[i*3 + 1] = i + 1; 1266 data[i*3 + 2] = i + 2; 1267 } 1268 break; 1269 case GL_UNSIGNED_BYTE: 1270 for (unsigned int i = 0; i < numTris; i++) 1271 { 1272 data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0]; 1273 data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1]; 1274 data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2]; 1275 } 1276 break; 1277 case GL_UNSIGNED_SHORT: 1278 for (unsigned int i = 0; i < numTris; i++) 1279 { 1280 data[i*3 + 0] = static_cast<const GLushort*>(indices)[0]; 1281 data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1]; 1282 data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2]; 1283 } 1284 break; 1285 case GL_UNSIGNED_INT: 1286 for (unsigned int i = 0; i < numTris; i++) 1287 { 1288 data[i*3 + 0] = static_cast<const GLuint*>(indices)[0]; 1289 data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1]; 1290 data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2]; 1291 } 1292 break; 1293 default: UNREACHABLE(); 1294 } 1295 1296 error = mTriangleFanIB->unmapBuffer(); 1297 if (error.isError()) 1298 { 1299 ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN."); 1300 return gl::error(GL_OUT_OF_MEMORY); 1301 } 1302 1303 IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); 1304 ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); 1305 DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); 1306 1307 if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || mAppliedIBOffset != indexBufferOffset) 1308 { 1309 mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, indexBufferOffset); 1310 mAppliedIB = d3dIndexBuffer; 1311 mAppliedIBFormat = indexFormat; 1312 mAppliedIBOffset = indexBufferOffset; 1313 } 1314 1315 if (instances > 0) 1316 { 1317 mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0); 1318 } 1319 else 1320 { 1321 mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); 1322 } 1323 } 1324 1325 void Renderer11::applyShaders(gl::ProgramBinary *programBinary, const gl::VertexFormat inputLayout[], const gl::Framebuffer *framebuffer, 1326 bool rasterizerDiscard, bool transformFeedbackActive) 1327 { 1328 ShaderExecutable *vertexExe = programBinary->getVertexExecutableForInputLayout(inputLayout); 1329 ShaderExecutable *pixelExe = programBinary->getPixelExecutableForFramebuffer(framebuffer); 1330 ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); 1331 1332 ID3D11VertexShader *vertexShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader() : NULL); 1333 1334 ID3D11PixelShader *pixelShader = NULL; 1335 // Skip pixel shader if we're doing rasterizer discard. 1336 if (!rasterizerDiscard) 1337 { 1338 pixelShader = (pixelExe ? ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader() : NULL); 1339 } 1340 1341 ID3D11GeometryShader *geometryShader = NULL; 1342 if (transformFeedbackActive) 1343 { 1344 geometryShader = (vertexExe ? ShaderExecutable11::makeShaderExecutable11(vertexExe)->getStreamOutShader() : NULL); 1345 } 1346 else if (mCurRasterState.pointDrawMode) 1347 { 1348 geometryShader = (geometryExe ? ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader() : NULL); 1349 } 1350 1351 bool dirtyUniforms = false; 1352 1353 if (vertexShader != mAppliedVertexShader) 1354 { 1355 mDeviceContext->VSSetShader(vertexShader, NULL, 0); 1356 mAppliedVertexShader = vertexShader; 1357 dirtyUniforms = true; 1358 } 1359 1360 if (geometryShader != mAppliedGeometryShader) 1361 { 1362 mDeviceContext->GSSetShader(geometryShader, NULL, 0); 1363 mAppliedGeometryShader = geometryShader; 1364 dirtyUniforms = true; 1365 } 1366 1367 if (geometryExe && mCurRasterState.pointDrawMode) 1368 { 1369 mCurPointGeometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader(); 1370 } 1371 else 1372 { 1373 mCurPointGeometryShader = NULL; 1374 } 1375 1376 if (pixelShader != mAppliedPixelShader) 1377 { 1378 mDeviceContext->PSSetShader(pixelShader, NULL, 0); 1379 mAppliedPixelShader = pixelShader; 1380 dirtyUniforms = true; 1381 } 1382 1383 if (dirtyUniforms) 1384 { 1385 programBinary->dirtyAllUniforms(); 1386 } 1387 } 1388 1389 void Renderer11::applyUniforms(const gl::ProgramBinary &programBinary) 1390 { 1391 const std::vector<gl::LinkedUniform*> &uniformArray = programBinary.getUniforms(); 1392 1393 unsigned int totalRegisterCountVS = 0; 1394 unsigned int totalRegisterCountPS = 0; 1395 1396 bool vertexUniformsDirty = false; 1397 bool pixelUniformsDirty = false; 1398 1399 for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) 1400 { 1401 const gl::LinkedUniform &uniform = *uniformArray[uniformIndex]; 1402 1403 if (uniform.isReferencedByVertexShader() && !uniform.isSampler()) 1404 { 1405 totalRegisterCountVS += uniform.registerCount; 1406 vertexUniformsDirty = (vertexUniformsDirty || uniform.dirty); 1407 } 1408 1409 if (uniform.isReferencedByFragmentShader() && !uniform.isSampler()) 1410 { 1411 totalRegisterCountPS += uniform.registerCount; 1412 pixelUniformsDirty = (pixelUniformsDirty || uniform.dirty); 1413 } 1414 } 1415 1416 const ProgramD3D *programD3D = ProgramD3D::makeProgramD3D(programBinary.getImplementation()); 1417 const UniformStorage11 *vertexUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getVertexUniformStorage()); 1418 const UniformStorage11 *fragmentUniformStorage = UniformStorage11::makeUniformStorage11(&programD3D->getFragmentUniformStorage()); 1419 ASSERT(vertexUniformStorage); 1420 ASSERT(fragmentUniformStorage); 1421 1422 ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer(); 1423 ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer(); 1424 1425 float (*mapVS)[4] = NULL; 1426 float (*mapPS)[4] = NULL; 1427 1428 if (totalRegisterCountVS > 0 && vertexUniformsDirty) 1429 { 1430 D3D11_MAPPED_SUBRESOURCE map = {0}; 1431 HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); 1432 UNUSED_ASSERTION_VARIABLE(result); 1433 ASSERT(SUCCEEDED(result)); 1434 mapVS = (float(*)[4])map.pData; 1435 } 1436 1437 if (totalRegisterCountPS > 0 && pixelUniformsDirty) 1438 { 1439 D3D11_MAPPED_SUBRESOURCE map = {0}; 1440 HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); 1441 UNUSED_ASSERTION_VARIABLE(result); 1442 ASSERT(SUCCEEDED(result)); 1443 mapPS = (float(*)[4])map.pData; 1444 } 1445 1446 for (size_t uniformIndex = 0; uniformIndex < uniformArray.size(); uniformIndex++) 1447 { 1448 gl::LinkedUniform *uniform = uniformArray[uniformIndex]; 1449 1450 if (!uniform->isSampler()) 1451 { 1452 unsigned int componentCount = (4 - uniform->registerElement); 1453 1454 // we assume that uniforms from structs are arranged in struct order in our uniforms list. otherwise we would 1455 // overwrite previously written regions of memory. 1456 1457 if (uniform->isReferencedByVertexShader() && mapVS) 1458 { 1459 memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); 1460 } 1461 1462 if (uniform->isReferencedByFragmentShader() && mapPS) 1463 { 1464 memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, uniform->registerCount * sizeof(float) * componentCount); 1465 } 1466 } 1467 } 1468 1469 if (mapVS) 1470 { 1471 mDeviceContext->Unmap(vertexConstantBuffer, 0); 1472 } 1473 1474 if (mapPS) 1475 { 1476 mDeviceContext->Unmap(pixelConstantBuffer, 0); 1477 } 1478 1479 if (mCurrentVertexConstantBuffer != vertexConstantBuffer) 1480 { 1481 mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); 1482 mCurrentVertexConstantBuffer = vertexConstantBuffer; 1483 } 1484 1485 if (mCurrentPixelConstantBuffer != pixelConstantBuffer) 1486 { 1487 mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); 1488 mCurrentPixelConstantBuffer = pixelConstantBuffer; 1489 } 1490 1491 // Driver uniforms 1492 if (!mDriverConstantBufferVS) 1493 { 1494 D3D11_BUFFER_DESC constantBufferDescription = {0}; 1495 constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants); 1496 constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; 1497 constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 1498 constantBufferDescription.CPUAccessFlags = 0; 1499 constantBufferDescription.MiscFlags = 0; 1500 constantBufferDescription.StructureByteStride = 0; 1501 1502 HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); 1503 UNUSED_ASSERTION_VARIABLE(result); 1504 ASSERT(SUCCEEDED(result)); 1505 1506 mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); 1507 } 1508 1509 if (!mDriverConstantBufferPS) 1510 { 1511 D3D11_BUFFER_DESC constantBufferDescription = {0}; 1512 constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants); 1513 constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; 1514 constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 1515 constantBufferDescription.CPUAccessFlags = 0; 1516 constantBufferDescription.MiscFlags = 0; 1517 constantBufferDescription.StructureByteStride = 0; 1518 1519 HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); 1520 UNUSED_ASSERTION_VARIABLE(result); 1521 ASSERT(SUCCEEDED(result)); 1522 1523 mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); 1524 } 1525 1526 if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0) 1527 { 1528 mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0); 1529 memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants)); 1530 } 1531 1532 if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0) 1533 { 1534 mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0); 1535 memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants)); 1536 } 1537 1538 // needed for the point sprite geometry shader 1539 if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) 1540 { 1541 mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); 1542 mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; 1543 } 1544 } 1545 1546 gl::Error Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) 1547 { 1548 gl::Error error = mClear->clearFramebuffer(clearParams, frameBuffer); 1549 if (error.isError()) 1550 { 1551 return error; 1552 } 1553 1554 invalidateFramebufferSwizzles(frameBuffer); 1555 1556 return gl::Error(GL_NO_ERROR); 1557 } 1558 1559 void Renderer11::markAllStateDirty() 1560 { 1561 for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) 1562 { 1563 mAppliedRenderTargetSerials[rtIndex] = 0; 1564 } 1565 mAppliedDepthbufferSerial = 0; 1566 mAppliedStencilbufferSerial = 0; 1567 mDepthStencilInitialized = false; 1568 mRenderTargetDescInitialized = false; 1569 1570 ASSERT(mForceSetVertexSamplerStates.size() == mCurVertexSRVs.size()); 1571 for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) 1572 { 1573 mForceSetVertexSamplerStates[vsamplerId] = true; 1574 mCurVertexSRVs[vsamplerId] = NULL; 1575 } 1576 1577 ASSERT(mForceSetPixelSamplerStates.size() == mCurPixelSRVs.size()); 1578 for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) 1579 { 1580 mForceSetPixelSamplerStates[fsamplerId] = true; 1581 mCurPixelSRVs[fsamplerId] = NULL; 1582 } 1583 1584 mForceSetBlendState = true; 1585 mForceSetRasterState = true; 1586 mForceSetDepthStencilState = true; 1587 mForceSetScissor = true; 1588 mForceSetViewport = true; 1589 1590 mAppliedIB = NULL; 1591 mAppliedIBFormat = DXGI_FORMAT_UNKNOWN; 1592 mAppliedIBOffset = 0; 1593 1594 mAppliedVertexShader = NULL; 1595 mAppliedGeometryShader = NULL; 1596 mCurPointGeometryShader = NULL; 1597 mAppliedPixelShader = NULL; 1598 1599 for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) 1600 { 1601 mAppliedTFBuffers[i] = NULL; 1602 mAppliedTFOffsets[i] = 0; 1603 } 1604 1605 memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); 1606 memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); 1607 1608 mInputLayoutCache.markDirty(); 1609 1610 for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++) 1611 { 1612 mCurrentConstantBufferVS[i] = -1; 1613 mCurrentConstantBufferPS[i] = -1; 1614 } 1615 1616 mCurrentVertexConstantBuffer = NULL; 1617 mCurrentPixelConstantBuffer = NULL; 1618 mCurrentGeometryConstantBuffer = NULL; 1619 1620 mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; 1621 } 1622 1623 void Renderer11::releaseDeviceResources() 1624 { 1625 mStateCache.clear(); 1626 mInputLayoutCache.clear(); 1627 1628 SafeDelete(mVertexDataManager); 1629 SafeDelete(mIndexDataManager); 1630 SafeDelete(mLineLoopIB); 1631 SafeDelete(mTriangleFanIB); 1632 SafeDelete(mBlit); 1633 SafeDelete(mClear); 1634 SafeDelete(mPixelTransfer); 1635 1636 SafeRelease(mDriverConstantBufferVS); 1637 SafeRelease(mDriverConstantBufferPS); 1638 SafeRelease(mSyncQuery); 1639 } 1640 1641 void Renderer11::notifyDeviceLost() 1642 { 1643 mDeviceLost = true; 1644 mDisplay->notifyDeviceLost(); 1645 } 1646 1647 bool Renderer11::isDeviceLost() 1648 { 1649 return mDeviceLost; 1650 } 1651 1652 // set notify to true to broadcast a message to all contexts of the device loss 1653 bool Renderer11::testDeviceLost(bool notify) 1654 { 1655 bool isLost = false; 1656 1657 // GetRemovedReason is used to test if the device is removed 1658 HRESULT result = mDevice->GetDeviceRemovedReason(); 1659 isLost = d3d11::isDeviceLostError(result); 1660 1661 if (isLost) 1662 { 1663 // Log error if this is a new device lost event 1664 if (mDeviceLost == false) 1665 { 1666 ERR("The D3D11 device was removed: 0x%08X", result); 1667 } 1668 1669 // ensure we note the device loss -- 1670 // we'll probably get this done again by notifyDeviceLost 1671 // but best to remember it! 1672 // Note that we don't want to clear the device loss status here 1673 // -- this needs to be done by resetDevice 1674 mDeviceLost = true; 1675 if (notify) 1676 { 1677 notifyDeviceLost(); 1678 } 1679 } 1680 1681 return isLost; 1682 } 1683 1684 bool Renderer11::testDeviceResettable() 1685 { 1686 // determine if the device is resettable by creating a dummy device 1687 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); 1688 1689 if (D3D11CreateDevice == NULL) 1690 { 1691 return false; 1692 } 1693 1694 D3D_FEATURE_LEVEL featureLevels[] = 1695 { 1696 D3D_FEATURE_LEVEL_11_0, 1697 D3D_FEATURE_LEVEL_10_1, 1698 D3D_FEATURE_LEVEL_10_0, 1699 }; 1700 1701 ID3D11Device* dummyDevice; 1702 D3D_FEATURE_LEVEL dummyFeatureLevel; 1703 ID3D11DeviceContext* dummyContext; 1704 1705 HRESULT result = D3D11CreateDevice(NULL, 1706 D3D_DRIVER_TYPE_HARDWARE, 1707 NULL, 1708 #if defined(_DEBUG) 1709 D3D11_CREATE_DEVICE_DEBUG, 1710 #else 1711 0, 1712 #endif 1713 featureLevels, 1714 ArraySize(featureLevels), 1715 D3D11_SDK_VERSION, 1716 &dummyDevice, 1717 &dummyFeatureLevel, 1718 &dummyContext); 1719 1720 if (!mDevice || FAILED(result)) 1721 { 1722 return false; 1723 } 1724 1725 SafeRelease(dummyContext); 1726 SafeRelease(dummyDevice); 1727 1728 return true; 1729 } 1730 1731 void Renderer11::release() 1732 { 1733 releaseShaderCompiler(); 1734 releaseDeviceResources(); 1735 1736 SafeRelease(mDxgiFactory); 1737 SafeRelease(mDxgiAdapter); 1738 1739 if (mDeviceContext) 1740 { 1741 mDeviceContext->ClearState(); 1742 mDeviceContext->Flush(); 1743 SafeRelease(mDeviceContext); 1744 } 1745 1746 SafeRelease(mDevice); 1747 1748 if (mD3d11Module) 1749 { 1750 FreeLibrary(mD3d11Module); 1751 mD3d11Module = NULL; 1752 } 1753 1754 if (mDxgiModule) 1755 { 1756 FreeLibrary(mDxgiModule); 1757 mDxgiModule = NULL; 1758 } 1759 1760 mCompiler.release(); 1761 } 1762 1763 bool Renderer11::resetDevice() 1764 { 1765 // recreate everything 1766 release(); 1767 EGLint result = initialize(); 1768 1769 if (result != EGL_SUCCESS) 1770 { 1771 ERR("Could not reinitialize D3D11 device: %08X", result); 1772 return false; 1773 } 1774 1775 mDeviceLost = false; 1776 1777 return true; 1778 } 1779 1780 DWORD Renderer11::getAdapterVendor() const 1781 { 1782 return mAdapterDescription.VendorId; 1783 } 1784 1785 std::string Renderer11::getRendererDescription() const 1786 { 1787 std::ostringstream rendererString; 1788 1789 rendererString << mDescription; 1790 rendererString << " Direct3D11"; 1791 1792 rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel(); 1793 rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel(); 1794 1795 return rendererString.str(); 1796 } 1797 1798 GUID Renderer11::getAdapterIdentifier() const 1799 { 1800 // Use the adapter LUID as our adapter ID 1801 // This number is local to a machine is only guaranteed to be unique between restarts 1802 META_ASSERT(sizeof(LUID) <= sizeof(GUID)); 1803 GUID adapterId = {0}; 1804 memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID)); 1805 return adapterId; 1806 } 1807 1808 unsigned int Renderer11::getReservedVertexUniformVectors() const 1809 { 1810 return 0; // Driver uniforms are stored in a separate constant buffer 1811 } 1812 1813 unsigned int Renderer11::getReservedFragmentUniformVectors() const 1814 { 1815 return 0; // Driver uniforms are stored in a separate constant buffer 1816 } 1817 1818 unsigned int Renderer11::getReservedVertexUniformBuffers() const 1819 { 1820 // we reserve one buffer for the application uniforms, and one for driver uniforms 1821 return 2; 1822 } 1823 1824 unsigned int Renderer11::getReservedFragmentUniformBuffers() const 1825 { 1826 // we reserve one buffer for the application uniforms, and one for driver uniforms 1827 return 2; 1828 } 1829 1830 bool Renderer11::getShareHandleSupport() const 1831 { 1832 // We only currently support share handles with BGRA surfaces, because 1833 // chrome needs BGRA. Once chrome fixes this, we should always support them. 1834 // PIX doesn't seem to support using share handles, so disable them. 1835 return getRendererExtensions().textureFormatBGRA8888 && !gl::perfActive(); 1836 } 1837 1838 bool Renderer11::getPostSubBufferSupport() const 1839 { 1840 // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2. 1841 return false; 1842 } 1843 1844 int Renderer11::getMajorShaderModel() const 1845 { 1846 switch (mFeatureLevel) 1847 { 1848 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5 1849 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4 1850 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4 1851 default: UNREACHABLE(); return 0; 1852 } 1853 } 1854 1855 int Renderer11::getMinorShaderModel() const 1856 { 1857 switch (mFeatureLevel) 1858 { 1859 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0 1860 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1 1861 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0 1862 default: UNREACHABLE(); return 0; 1863 } 1864 } 1865 1866 int Renderer11::getMinSwapInterval() const 1867 { 1868 return 0; 1869 } 1870 1871 int Renderer11::getMaxSwapInterval() const 1872 { 1873 return 4; 1874 } 1875 1876 bool Renderer11::copyToRenderTarget2D(TextureStorage *dest, TextureStorage *source) 1877 { 1878 if (source && dest) 1879 { 1880 TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source); 1881 TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest); 1882 1883 mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); 1884 1885 dest11->invalidateSwizzleCache(); 1886 1887 return true; 1888 } 1889 1890 return false; 1891 } 1892 1893 bool Renderer11::copyToRenderTargetCube(TextureStorage *dest, TextureStorage *source) 1894 { 1895 if (source && dest) 1896 { 1897 TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source); 1898 TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest); 1899 1900 mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); 1901 1902 dest11->invalidateSwizzleCache(); 1903 1904 return true; 1905 } 1906 1907 return false; 1908 } 1909 1910 bool Renderer11::copyToRenderTarget3D(TextureStorage *dest, TextureStorage *source) 1911 { 1912 if (source && dest) 1913 { 1914 TextureStorage11_3D *source11 = TextureStorage11_3D::makeTextureStorage11_3D(source); 1915 TextureStorage11_3D *dest11 = TextureStorage11_3D::makeTextureStorage11_3D(dest); 1916 1917 mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); 1918 1919 dest11->invalidateSwizzleCache(); 1920 1921 return true; 1922 } 1923 1924 return false; 1925 } 1926 1927 bool Renderer11::copyToRenderTarget2DArray(TextureStorage *dest, TextureStorage *source) 1928 { 1929 if (source && dest) 1930 { 1931 TextureStorage11_2DArray *source11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(source); 1932 TextureStorage11_2DArray *dest11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(dest); 1933 1934 mDeviceContext->CopyResource(dest11->getResource(), source11->getResource()); 1935 1936 dest11->invalidateSwizzleCache(); 1937 1938 return true; 1939 } 1940 1941 return false; 1942 } 1943 1944 bool Renderer11::copyImage2D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, 1945 GLint xoffset, GLint yoffset, TextureStorage *storage, GLint level) 1946 { 1947 gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); 1948 if (!colorbuffer) 1949 { 1950 ERR("Failed to retrieve the color buffer from the frame buffer."); 1951 return gl::error(GL_OUT_OF_MEMORY, false); 1952 } 1953 1954 RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 1955 if (!sourceRenderTarget) 1956 { 1957 ERR("Failed to retrieve the render target from the frame buffer."); 1958 return gl::error(GL_OUT_OF_MEMORY, false); 1959 } 1960 1961 ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); 1962 if (!source) 1963 { 1964 ERR("Failed to retrieve the render target view from the render target."); 1965 return gl::error(GL_OUT_OF_MEMORY, false); 1966 } 1967 1968 TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage); 1969 if (!storage11) 1970 { 1971 ERR("Failed to retrieve the texture storage from the destination."); 1972 return gl::error(GL_OUT_OF_MEMORY, false); 1973 } 1974 1975 gl::ImageIndex index = gl::ImageIndex::Make2D(level); 1976 RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); 1977 if (!destRenderTarget) 1978 { 1979 ERR("Failed to retrieve the render target from the destination storage."); 1980 return gl::error(GL_OUT_OF_MEMORY, false); 1981 } 1982 1983 ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); 1984 if (!dest) 1985 { 1986 ERR("Failed to retrieve the render target view from the destination render target."); 1987 return gl::error(GL_OUT_OF_MEMORY, false); 1988 } 1989 1990 gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); 1991 gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); 1992 1993 gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); 1994 gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); 1995 1996 // Use nearest filtering because source and destination are the same size for the direct 1997 // copy 1998 bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, 1999 destFormat, GL_NEAREST); 2000 2001 storage11->invalidateSwizzleCacheLevel(level); 2002 2003 return ret; 2004 } 2005 2006 bool Renderer11::copyImageCube(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, 2007 GLint xoffset, GLint yoffset, TextureStorage *storage, GLenum target, GLint level) 2008 { 2009 gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); 2010 if (!colorbuffer) 2011 { 2012 ERR("Failed to retrieve the color buffer from the frame buffer."); 2013 return gl::error(GL_OUT_OF_MEMORY, false); 2014 } 2015 2016 RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 2017 if (!sourceRenderTarget) 2018 { 2019 ERR("Failed to retrieve the render target from the frame buffer."); 2020 return gl::error(GL_OUT_OF_MEMORY, false); 2021 } 2022 2023 ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); 2024 if (!source) 2025 { 2026 ERR("Failed to retrieve the render target view from the render target."); 2027 return gl::error(GL_OUT_OF_MEMORY, false); 2028 } 2029 2030 TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage); 2031 if (!storage11) 2032 { 2033 ERR("Failed to retrieve the texture storage from the destination."); 2034 return gl::error(GL_OUT_OF_MEMORY, false); 2035 } 2036 2037 gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); 2038 RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); 2039 if (!destRenderTarget) 2040 { 2041 ERR("Failed to retrieve the render target from the destination storage."); 2042 return gl::error(GL_OUT_OF_MEMORY, false); 2043 } 2044 2045 ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); 2046 if (!dest) 2047 { 2048 ERR("Failed to retrieve the render target view from the destination render target."); 2049 return gl::error(GL_OUT_OF_MEMORY, false); 2050 } 2051 2052 gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); 2053 gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); 2054 2055 gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); 2056 gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); 2057 2058 // Use nearest filtering because source and destination are the same size for the direct 2059 // copy 2060 bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, 2061 destFormat, GL_NEAREST); 2062 2063 storage11->invalidateSwizzleCacheLevel(level); 2064 2065 return ret; 2066 } 2067 2068 bool Renderer11::copyImage3D(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, 2069 GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) 2070 { 2071 gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); 2072 if (!colorbuffer) 2073 { 2074 ERR("Failed to retrieve the color buffer from the frame buffer."); 2075 return gl::error(GL_OUT_OF_MEMORY, false); 2076 } 2077 2078 RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 2079 if (!sourceRenderTarget) 2080 { 2081 ERR("Failed to retrieve the render target from the frame buffer."); 2082 return gl::error(GL_OUT_OF_MEMORY, false); 2083 } 2084 2085 ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); 2086 if (!source) 2087 { 2088 ERR("Failed to retrieve the render target view from the render target."); 2089 return gl::error(GL_OUT_OF_MEMORY, false); 2090 } 2091 2092 TextureStorage11_3D *storage11 = TextureStorage11_3D::makeTextureStorage11_3D(storage); 2093 if (!storage11) 2094 { 2095 ERR("Failed to retrieve the texture storage from the destination."); 2096 return gl::error(GL_OUT_OF_MEMORY, false); 2097 } 2098 2099 gl::ImageIndex index = gl::ImageIndex::Make3D(level, zOffset); 2100 RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); 2101 if (!destRenderTarget) 2102 { 2103 ERR("Failed to retrieve the render target from the destination storage."); 2104 return gl::error(GL_OUT_OF_MEMORY, false); 2105 } 2106 2107 ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); 2108 if (!dest) 2109 { 2110 ERR("Failed to retrieve the render target view from the destination render target."); 2111 return gl::error(GL_OUT_OF_MEMORY, false); 2112 } 2113 2114 gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); 2115 gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); 2116 2117 gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); 2118 gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); 2119 2120 // Use nearest filtering because source and destination are the same size for the direct 2121 // copy 2122 bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, 2123 destFormat, GL_NEAREST); 2124 2125 storage11->invalidateSwizzleCacheLevel(level); 2126 2127 return ret; 2128 } 2129 2130 bool Renderer11::copyImage2DArray(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, 2131 GLint xoffset, GLint yoffset, GLint zOffset, TextureStorage *storage, GLint level) 2132 { 2133 gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); 2134 if (!colorbuffer) 2135 { 2136 ERR("Failed to retrieve the color buffer from the frame buffer."); 2137 return gl::error(GL_OUT_OF_MEMORY, false); 2138 } 2139 2140 RenderTarget11 *sourceRenderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 2141 if (!sourceRenderTarget) 2142 { 2143 ERR("Failed to retrieve the render target from the frame buffer."); 2144 return gl::error(GL_OUT_OF_MEMORY, false); 2145 } 2146 2147 ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); 2148 if (!source) 2149 { 2150 ERR("Failed to retrieve the render target view from the render target."); 2151 return gl::error(GL_OUT_OF_MEMORY, false); 2152 } 2153 2154 TextureStorage11_2DArray *storage11 = TextureStorage11_2DArray::makeTextureStorage11_2DArray(storage); 2155 if (!storage11) 2156 { 2157 SafeRelease(source); 2158 ERR("Failed to retrieve the texture storage from the destination."); 2159 return gl::error(GL_OUT_OF_MEMORY, false); 2160 } 2161 2162 gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zOffset); 2163 RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(index)); 2164 if (!destRenderTarget) 2165 { 2166 SafeRelease(source); 2167 ERR("Failed to retrieve the render target from the destination storage."); 2168 return gl::error(GL_OUT_OF_MEMORY, false); 2169 } 2170 2171 ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); 2172 if (!dest) 2173 { 2174 ERR("Failed to retrieve the render target view from the destination render target."); 2175 return gl::error(GL_OUT_OF_MEMORY, false); 2176 } 2177 2178 gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); 2179 gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); 2180 2181 gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1); 2182 gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); 2183 2184 // Use nearest filtering because source and destination are the same size for the direct 2185 // copy 2186 bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, 2187 destFormat, GL_NEAREST); 2188 2189 storage11->invalidateSwizzleCacheLevel(level); 2190 2191 return ret; 2192 } 2193 2194 void Renderer11::unapplyRenderTargets() 2195 { 2196 setOneTimeRenderTarget(NULL); 2197 } 2198 2199 void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) 2200 { 2201 ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; 2202 2203 rtvArray[0] = renderTargetView; 2204 2205 mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL); 2206 2207 // Do not preserve the serial for this one-time-use render target 2208 for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) 2209 { 2210 mAppliedRenderTargetSerials[rtIndex] = 0; 2211 } 2212 } 2213 2214 RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) 2215 { 2216 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); 2217 RenderTarget11 *renderTarget = NULL; 2218 2219 if (depth) 2220 { 2221 // Note: depth stencil may be NULL for 0 sized surfaces 2222 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), 2223 swapChain11->getDepthStencilTexture(), 2224 swapChain11->getDepthStencilShaderResource(), 2225 swapChain11->getWidth(), swapChain11->getHeight(), 1); 2226 } 2227 else 2228 { 2229 // Note: render target may be NULL for 0 sized surfaces 2230 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), 2231 swapChain11->getOffscreenTexture(), 2232 swapChain11->getRenderTargetShaderResource(), 2233 swapChain11->getWidth(), swapChain11->getHeight(), 1); 2234 } 2235 return renderTarget; 2236 } 2237 2238 RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples) 2239 { 2240 RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples); 2241 return renderTarget; 2242 } 2243 2244 ShaderImpl *Renderer11::createShader(GLenum type) 2245 { 2246 return new ShaderD3D(type, this); 2247 } 2248 2249 ProgramImpl *Renderer11::createProgram() 2250 { 2251 return new ProgramD3D(this); 2252 } 2253 2254 void Renderer11::releaseShaderCompiler() 2255 { 2256 ShaderD3D::releaseCompiler(); 2257 } 2258 2259 ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type, 2260 const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, 2261 bool separatedOutputBuffers) 2262 { 2263 ShaderExecutable11 *executable = NULL; 2264 HRESULT result; 2265 2266 switch (type) 2267 { 2268 case rx::SHADER_VERTEX: 2269 { 2270 ID3D11VertexShader *vertexShader = NULL; 2271 ID3D11GeometryShader *streamOutShader = NULL; 2272 2273 result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); 2274 ASSERT(SUCCEEDED(result)); 2275 2276 if (transformFeedbackVaryings.size() > 0) 2277 { 2278 std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration; 2279 for (size_t i = 0; i < transformFeedbackVaryings.size(); i++) 2280 { 2281 const gl::LinkedVarying &varying = transformFeedbackVaryings[i]; 2282 GLenum transposedType = gl::TransposeMatrixType(varying.type); 2283 2284 for (size_t j = 0; j < varying.semanticIndexCount; j++) 2285 { 2286 D3D11_SO_DECLARATION_ENTRY entry = { 0 }; 2287 entry.Stream = 0; 2288 entry.SemanticName = varying.semanticName.c_str(); 2289 entry.SemanticIndex = varying.semanticIndex + j; 2290 entry.StartComponent = 0; 2291 entry.ComponentCount = gl::VariableColumnCount(transposedType); 2292 entry.OutputSlot = (separatedOutputBuffers ? i : 0); 2293 soDeclaration.push_back(entry); 2294 } 2295 } 2296 2297 result = mDevice->CreateGeometryShaderWithStreamOutput(function, length, soDeclaration.data(), soDeclaration.size(), 2298 NULL, 0, 0, NULL, &streamOutShader); 2299 ASSERT(SUCCEEDED(result)); 2300 } 2301 2302 if (vertexShader) 2303 { 2304 executable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); 2305 } 2306 } 2307 break; 2308 case rx::SHADER_PIXEL: 2309 { 2310 ID3D11PixelShader *pixelShader = NULL; 2311 2312 result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); 2313 ASSERT(SUCCEEDED(result)); 2314 2315 if (pixelShader) 2316 { 2317 executable = new ShaderExecutable11(function, length, pixelShader); 2318 } 2319 } 2320 break; 2321 case rx::SHADER_GEOMETRY: 2322 { 2323 ID3D11GeometryShader *geometryShader = NULL; 2324 2325 result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); 2326 ASSERT(SUCCEEDED(result)); 2327 2328 if (geometryShader) 2329 { 2330 executable = new ShaderExecutable11(function, length, geometryShader); 2331 } 2332 } 2333 break; 2334 default: 2335 UNREACHABLE(); 2336 break; 2337 } 2338 2339 return executable; 2340 } 2341 2342 ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, 2343 const std::vector<gl::LinkedVarying> &transformFeedbackVaryings, 2344 bool separatedOutputBuffers, D3DWorkaroundType workaround) 2345 { 2346 const char *profileType = NULL; 2347 switch (type) 2348 { 2349 case rx::SHADER_VERTEX: 2350 profileType = "vs"; 2351 break; 2352 case rx::SHADER_PIXEL: 2353 profileType = "ps"; 2354 break; 2355 case rx::SHADER_GEOMETRY: 2356 profileType = "gs"; 2357 break; 2358 default: 2359 UNREACHABLE(); 2360 return NULL; 2361 } 2362 2363 const char *profileVersion = NULL; 2364 switch (mFeatureLevel) 2365 { 2366 case D3D_FEATURE_LEVEL_11_0: 2367 profileVersion = "5_0"; 2368 break; 2369 case D3D_FEATURE_LEVEL_10_1: 2370 profileVersion = "4_1"; 2371 break; 2372 case D3D_FEATURE_LEVEL_10_0: 2373 profileVersion = "4_0"; 2374 break; 2375 default: 2376 UNREACHABLE(); 2377 return NULL; 2378 } 2379 2380 char profile[32]; 2381 snprintf(profile, ArraySize(profile), "%s_%s", profileType, profileVersion); 2382 2383 UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL0; 2384 2385 if (gl::perfActive()) 2386 { 2387 #ifndef NDEBUG 2388 flags = D3DCOMPILE_SKIP_OPTIMIZATION; 2389 #endif 2390 2391 flags |= D3DCOMPILE_DEBUG; 2392 2393 std::string sourcePath = getTempPath(); 2394 std::string sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(shaderHLSL); 2395 writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); 2396 } 2397 2398 // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. 2399 // Try the default flags first and if compilation fails, try some alternatives. 2400 const UINT extraFlags[] = 2401 { 2402 flags, 2403 flags | D3DCOMPILE_SKIP_VALIDATION, 2404 flags | D3DCOMPILE_SKIP_OPTIMIZATION 2405 }; 2406 2407 const static char *extraFlagNames[] = 2408 { 2409 "default", 2410 "skip validation", 2411 "skip optimization" 2412 }; 2413 2414 int attempts = ArraySize(extraFlags); 2415 2416 ID3DBlob *binary = (ID3DBlob*)mCompiler.compileToBinary(infoLog, shaderHLSL, profile, extraFlags, extraFlagNames, attempts); 2417 if (!binary) 2418 { 2419 return NULL; 2420 } 2421 2422 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, 2423 transformFeedbackVaryings, separatedOutputBuffers); 2424 SafeRelease(binary); 2425 2426 return executable; 2427 } 2428 2429 rx::UniformStorage *Renderer11::createUniformStorage(size_t storageSize) 2430 { 2431 return new UniformStorage11(this, storageSize); 2432 } 2433 2434 VertexBuffer *Renderer11::createVertexBuffer() 2435 { 2436 return new VertexBuffer11(this); 2437 } 2438 2439 IndexBuffer *Renderer11::createIndexBuffer() 2440 { 2441 return new IndexBuffer11(this); 2442 } 2443 2444 BufferImpl *Renderer11::createBuffer() 2445 { 2446 return new Buffer11(this); 2447 } 2448 2449 VertexArrayImpl *Renderer11::createVertexArray() 2450 { 2451 return new VertexArray11(this); 2452 } 2453 2454 QueryImpl *Renderer11::createQuery(GLenum type) 2455 { 2456 return new Query11(this, type); 2457 } 2458 2459 FenceImpl *Renderer11::createFence() 2460 { 2461 return new Fence11(this); 2462 } 2463 2464 TransformFeedbackImpl* Renderer11::createTransformFeedback() 2465 { 2466 return new TransformFeedbackD3D(); 2467 } 2468 2469 bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const 2470 { 2471 ASSERT(getRendererExtensions().pixelBufferObject); 2472 2473 const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); 2474 const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat); 2475 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat); 2476 2477 // sRGB formats do not work with D3D11 buffer SRVs 2478 if (internalFormatInfo.colorEncoding == GL_SRGB) 2479 { 2480 return false; 2481 } 2482 2483 // We cannot support direct copies to non-color-renderable formats 2484 if (d3d11FormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 2485 { 2486 return false; 2487 } 2488 2489 // We skip all 3-channel formats since sometimes format support is missing 2490 if (internalFormatInfo.componentCount == 3) 2491 { 2492 return false; 2493 } 2494 2495 // We don't support formats which we can't represent without conversion 2496 if (dxgiFormatInfo.internalFormat != internalFormat) 2497 { 2498 return false; 2499 } 2500 2501 return true; 2502 } 2503 2504 bool Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget, 2505 GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) 2506 { 2507 ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); 2508 return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); 2509 } 2510 2511 bool Renderer11::getRenderTargetResource(gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) 2512 { 2513 ASSERT(colorbuffer != NULL); 2514 2515 RenderTarget11 *renderTarget = d3d11::GetAttachmentRenderTarget(colorbuffer); 2516 if (renderTarget) 2517 { 2518 *subresourceIndex = renderTarget->getSubresourceIndex(); 2519 2520 ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView(); 2521 if (colorBufferRTV) 2522 { 2523 ID3D11Resource *textureResource = NULL; 2524 colorBufferRTV->GetResource(&textureResource); 2525 2526 if (textureResource) 2527 { 2528 HRESULT result = textureResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)resource); 2529 SafeRelease(textureResource); 2530 2531 if (SUCCEEDED(result)) 2532 { 2533 return true; 2534 } 2535 else 2536 { 2537 ERR("Failed to extract the ID3D11Texture2D from the render target resource, " 2538 "HRESULT: 0x%X.", result); 2539 } 2540 } 2541 } 2542 } 2543 2544 return false; 2545 } 2546 2547 bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, 2548 const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter) 2549 { 2550 if (blitRenderTarget) 2551 { 2552 gl::FramebufferAttachment *readBuffer = readTarget->getReadColorbuffer(); 2553 2554 if (!readBuffer) 2555 { 2556 ERR("Failed to retrieve the read buffer from the read framebuffer."); 2557 return gl::error(GL_OUT_OF_MEMORY, false); 2558 } 2559 2560 RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); 2561 2562 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 2563 { 2564 if (drawTarget->isEnabledColorAttachment(colorAttachment)) 2565 { 2566 gl::FramebufferAttachment *drawBuffer = drawTarget->getColorbuffer(colorAttachment); 2567 2568 if (!drawBuffer) 2569 { 2570 ERR("Failed to retrieve the draw buffer from the draw framebuffer."); 2571 return gl::error(GL_OUT_OF_MEMORY, false); 2572 } 2573 2574 RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); 2575 2576 if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, 2577 blitRenderTarget, false, false)) 2578 { 2579 return false; 2580 } 2581 } 2582 } 2583 } 2584 2585 if (blitDepth || blitStencil) 2586 { 2587 gl::FramebufferAttachment *readBuffer = readTarget->getDepthOrStencilbuffer(); 2588 gl::FramebufferAttachment *drawBuffer = drawTarget->getDepthOrStencilbuffer(); 2589 2590 if (!readBuffer) 2591 { 2592 ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer."); 2593 return gl::error(GL_OUT_OF_MEMORY, false); 2594 } 2595 2596 if (!drawBuffer) 2597 { 2598 ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer."); 2599 return gl::error(GL_OUT_OF_MEMORY, false); 2600 } 2601 2602 RenderTarget *readRenderTarget = GetAttachmentRenderTarget(readBuffer); 2603 RenderTarget *drawRenderTarget = GetAttachmentRenderTarget(drawBuffer); 2604 ASSERT(readRenderTarget && drawRenderTarget); 2605 2606 if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, filter, scissor, 2607 false, blitDepth, blitStencil)) 2608 { 2609 return false; 2610 } 2611 } 2612 2613 invalidateFramebufferSwizzles(drawTarget); 2614 2615 return true; 2616 } 2617 2618 gl::Error Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, 2619 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) 2620 { 2621 ID3D11Texture2D *colorBufferTexture = NULL; 2622 unsigned int subresourceIndex = 0; 2623 2624 gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); 2625 2626 if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) 2627 { 2628 gl::Rectangle area; 2629 area.x = x; 2630 area.y = y; 2631 area.width = width; 2632 area.height = height; 2633 2634 gl::Buffer *packBuffer = pack.pixelBuffer.get(); 2635 if (packBuffer != NULL) 2636 { 2637 rx::Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); 2638 PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); 2639 2640 gl::Error error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); 2641 if (error.isError()) 2642 { 2643 return error; 2644 } 2645 2646 packBuffer->getIndexRangeCache()->clear(); 2647 } 2648 else 2649 { 2650 gl::Error error = readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); 2651 if (error.isError()) 2652 { 2653 return error; 2654 } 2655 } 2656 2657 SafeRelease(colorBufferTexture); 2658 } 2659 2660 return gl::Error(GL_NO_ERROR); 2661 } 2662 2663 Image *Renderer11::createImage() 2664 { 2665 return new Image11(); 2666 } 2667 2668 void Renderer11::generateMipmap(Image *dest, Image *src) 2669 { 2670 Image11 *dest11 = Image11::makeImage11(dest); 2671 Image11 *src11 = Image11::makeImage11(src); 2672 Image11::generateMipmap(dest11, src11); 2673 } 2674 2675 TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) 2676 { 2677 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); 2678 return new TextureStorage11_2D(this, swapChain11); 2679 } 2680 2681 TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) 2682 { 2683 return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels); 2684 } 2685 2686 TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels) 2687 { 2688 return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels); 2689 } 2690 2691 TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) 2692 { 2693 return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels); 2694 } 2695 2696 TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) 2697 { 2698 return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); 2699 } 2700 2701 TextureImpl *Renderer11::createTexture(GLenum target) 2702 { 2703 switch(target) 2704 { 2705 case GL_TEXTURE_2D: return new TextureD3D_2D(this); 2706 case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); 2707 case GL_TEXTURE_3D: return new TextureD3D_3D(this); 2708 case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this); 2709 default: 2710 UNREACHABLE(); 2711 } 2712 2713 return NULL; 2714 } 2715 2716 gl::Error Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, GLenum format, 2717 GLenum type, GLuint outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) 2718 { 2719 ASSERT(area.width >= 0); 2720 ASSERT(area.height >= 0); 2721 2722 D3D11_TEXTURE2D_DESC textureDesc; 2723 texture->GetDesc(&textureDesc); 2724 2725 // Clamp read region to the defined texture boundaries, preventing out of bounds reads 2726 // and reads of uninitialized data. 2727 gl::Rectangle safeArea; 2728 safeArea.x = gl::clamp(area.x, 0, static_cast<int>(textureDesc.Width)); 2729 safeArea.y = gl::clamp(area.y, 0, static_cast<int>(textureDesc.Height)); 2730 safeArea.width = gl::clamp(area.width + std::min(area.x, 0), 0, 2731 static_cast<int>(textureDesc.Width) - safeArea.x); 2732 safeArea.height = gl::clamp(area.height + std::min(area.y, 0), 0, 2733 static_cast<int>(textureDesc.Height) - safeArea.y); 2734 2735 ASSERT(safeArea.x >= 0 && safeArea.y >= 0); 2736 ASSERT(safeArea.x + safeArea.width <= static_cast<int>(textureDesc.Width)); 2737 ASSERT(safeArea.y + safeArea.height <= static_cast<int>(textureDesc.Height)); 2738 2739 if (safeArea.width == 0 || safeArea.height == 0) 2740 { 2741 // no work to do 2742 return gl::Error(GL_NO_ERROR); 2743 } 2744 2745 D3D11_TEXTURE2D_DESC stagingDesc; 2746 stagingDesc.Width = safeArea.width; 2747 stagingDesc.Height = safeArea.height; 2748 stagingDesc.MipLevels = 1; 2749 stagingDesc.ArraySize = 1; 2750 stagingDesc.Format = textureDesc.Format; 2751 stagingDesc.SampleDesc.Count = 1; 2752 stagingDesc.SampleDesc.Quality = 0; 2753 stagingDesc.Usage = D3D11_USAGE_STAGING; 2754 stagingDesc.BindFlags = 0; 2755 stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; 2756 stagingDesc.MiscFlags = 0; 2757 2758 ID3D11Texture2D* stagingTex = NULL; 2759 HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); 2760 if (FAILED(result)) 2761 { 2762 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging texture for ReadPixels, HRESULT: 0x%X.", result); 2763 } 2764 2765 ID3D11Texture2D* srcTex = NULL; 2766 if (textureDesc.SampleDesc.Count > 1) 2767 { 2768 D3D11_TEXTURE2D_DESC resolveDesc; 2769 resolveDesc.Width = textureDesc.Width; 2770 resolveDesc.Height = textureDesc.Height; 2771 resolveDesc.MipLevels = 1; 2772 resolveDesc.ArraySize = 1; 2773 resolveDesc.Format = textureDesc.Format; 2774 resolveDesc.SampleDesc.Count = 1; 2775 resolveDesc.SampleDesc.Quality = 0; 2776 resolveDesc.Usage = D3D11_USAGE_DEFAULT; 2777 resolveDesc.BindFlags = 0; 2778 resolveDesc.CPUAccessFlags = 0; 2779 resolveDesc.MiscFlags = 0; 2780 2781 result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); 2782 if (FAILED(result)) 2783 { 2784 SafeRelease(stagingTex); 2785 return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal resolve texture for ReadPixels, HRESULT: 0x%X.", result); 2786 } 2787 2788 mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); 2789 subResource = 0; 2790 } 2791 else 2792 { 2793 srcTex = texture; 2794 srcTex->AddRef(); 2795 } 2796 2797 D3D11_BOX srcBox; 2798 srcBox.left = static_cast<UINT>(safeArea.x); 2799 srcBox.right = static_cast<UINT>(safeArea.x + safeArea.width); 2800 srcBox.top = static_cast<UINT>(safeArea.y); 2801 srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height); 2802 srcBox.front = 0; 2803 srcBox.back = 1; 2804 2805 mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox); 2806 2807 SafeRelease(srcTex); 2808 2809 PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); 2810 packPixels(stagingTex, packParams, pixels); 2811 2812 SafeRelease(stagingTex); 2813 2814 return gl::Error(GL_NO_ERROR); 2815 } 2816 2817 void Renderer11::packPixels(ID3D11Texture2D *readTexture, const PackPixelsParams ¶ms, uint8_t *pixelsOut) 2818 { 2819 D3D11_TEXTURE2D_DESC textureDesc; 2820 readTexture->GetDesc(&textureDesc); 2821 2822 D3D11_MAPPED_SUBRESOURCE mapping; 2823 HRESULT hr = mDeviceContext->Map(readTexture, 0, D3D11_MAP_READ, 0, &mapping); 2824 UNUSED_ASSERTION_VARIABLE(hr); 2825 ASSERT(SUCCEEDED(hr)); 2826 2827 uint8_t *source; 2828 int inputPitch; 2829 if (params.pack.reverseRowOrder) 2830 { 2831 source = static_cast<uint8_t*>(mapping.pData) + mapping.RowPitch * (params.area.height - 1); 2832 inputPitch = -static_cast<int>(mapping.RowPitch); 2833 } 2834 else 2835 { 2836 source = static_cast<uint8_t*>(mapping.pData); 2837 inputPitch = static_cast<int>(mapping.RowPitch); 2838 } 2839 2840 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); 2841 const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); 2842 if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) 2843 { 2844 uint8_t *dest = pixelsOut + params.offset; 2845 for (int y = 0; y < params.area.height; y++) 2846 { 2847 memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes); 2848 } 2849 } 2850 else 2851 { 2852 const d3d11::DXGIFormat &sourceDXGIFormatInfo = d3d11::GetDXGIFormatInfo(textureDesc.Format); 2853 ColorCopyFunction fastCopyFunc = sourceDXGIFormatInfo.getFastCopyFunction(params.format, params.type); 2854 2855 const gl::FormatType &destFormatTypeInfo = gl::GetFormatTypeInfo(params.format, params.type); 2856 const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(destFormatTypeInfo.internalFormat); 2857 2858 if (fastCopyFunc) 2859 { 2860 // Fast copy is possible through some special function 2861 for (int y = 0; y < params.area.height; y++) 2862 { 2863 for (int x = 0; x < params.area.width; x++) 2864 { 2865 uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; 2866 const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; 2867 2868 fastCopyFunc(src, dest); 2869 } 2870 } 2871 } 2872 else 2873 { 2874 uint8_t temp[16]; // Maximum size of any Color<T> type used. 2875 META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) && 2876 sizeof(temp) >= sizeof(gl::ColorUI) && 2877 sizeof(temp) >= sizeof(gl::ColorI)); 2878 2879 for (int y = 0; y < params.area.height; y++) 2880 { 2881 for (int x = 0; x < params.area.width; x++) 2882 { 2883 uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; 2884 const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; 2885 2886 // readFunc and writeFunc will be using the same type of color, CopyTexImage 2887 // will not allow the copy otherwise. 2888 sourceDXGIFormatInfo.colorReadFunction(src, temp); 2889 destFormatTypeInfo.colorWriteFunction(temp, dest); 2890 } 2891 } 2892 } 2893 } 2894 2895 mDeviceContext->Unmap(readTexture, 0); 2896 } 2897 2898 bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, 2899 RenderTarget *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, 2900 bool colorBlit, bool depthBlit, bool stencilBlit) 2901 { 2902 // Since blitRenderbufferRect is called for each render buffer that needs to be blitted, 2903 // it should never be the case that both color and depth/stencil need to be blitted at 2904 // at the same time. 2905 ASSERT(colorBlit != (depthBlit || stencilBlit)); 2906 2907 bool result = true; 2908 2909 RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); 2910 if (!drawRenderTarget) 2911 { 2912 ERR("Failed to retrieve the draw render target from the draw framebuffer."); 2913 return gl::error(GL_OUT_OF_MEMORY, false); 2914 } 2915 2916 ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); 2917 unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); 2918 ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView(); 2919 ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView(); 2920 2921 RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); 2922 if (!readRenderTarget) 2923 { 2924 ERR("Failed to retrieve the read render target from the read framebuffer."); 2925 return gl::error(GL_OUT_OF_MEMORY, false); 2926 } 2927 2928 ID3D11Resource *readTexture = NULL; 2929 ID3D11ShaderResourceView *readSRV = NULL; 2930 unsigned int readSubresource = 0; 2931 if (readRenderTarget->getSamples() > 0) 2932 { 2933 ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture(); 2934 ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource); 2935 2936 if (unresolvedTexture) 2937 { 2938 readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex()); 2939 readSubresource = 0; 2940 2941 SafeRelease(unresolvedTexture); 2942 2943 HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV); 2944 if (FAILED(hresult)) 2945 { 2946 SafeRelease(readTexture); 2947 return gl::error(GL_OUT_OF_MEMORY, false); 2948 } 2949 } 2950 } 2951 else 2952 { 2953 readTexture = readRenderTarget11->getTexture(); 2954 readTexture->AddRef(); 2955 readSubresource = readRenderTarget11->getSubresourceIndex(); 2956 readSRV = readRenderTarget11->getShaderResourceView(); 2957 readSRV->AddRef(); 2958 } 2959 2960 if (!readTexture || !readSRV) 2961 { 2962 SafeRelease(readTexture); 2963 SafeRelease(readSRV); 2964 ERR("Failed to retrieve the read render target view from the read render target."); 2965 return gl::error(GL_OUT_OF_MEMORY, false); 2966 } 2967 2968 gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); 2969 gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); 2970 2971 bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); 2972 2973 bool wholeBufferCopy = !scissorNeeded && 2974 readRect.x == 0 && readRect.width == readSize.width && 2975 readRect.y == 0 && readRect.height == readSize.height && 2976 drawRect.x == 0 && drawRect.width == drawSize.width && 2977 drawRect.y == 0 && drawRect.height == drawSize.height; 2978 2979 bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height; 2980 2981 bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0; 2982 2983 bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width || 2984 readRect.y < 0 || readRect.y + readRect.height > readSize.height || 2985 drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || 2986 drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; 2987 2988 const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getActualFormat()); 2989 bool partialDSBlit = (actualFormatInfo.depthBits > 0 && depthBlit) != (actualFormatInfo.stencilBits > 0 && stencilBlit); 2990 2991 if (readRenderTarget11->getActualFormat() == drawRenderTarget->getActualFormat() && 2992 !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && 2993 (!(depthBlit || stencilBlit) || wholeBufferCopy)) 2994 { 2995 UINT dstX = drawRect.x; 2996 UINT dstY = drawRect.y; 2997 2998 D3D11_BOX readBox; 2999 readBox.left = readRect.x; 3000 readBox.right = readRect.x + readRect.width; 3001 readBox.top = readRect.y; 3002 readBox.bottom = readRect.y + readRect.height; 3003 readBox.front = 0; 3004 readBox.back = 1; 3005 3006 if (scissorNeeded) 3007 { 3008 // drawRect is guaranteed to have positive width and height because stretchRequired is false. 3009 ASSERT(drawRect.width >= 0 || drawRect.height >= 0); 3010 3011 if (drawRect.x < scissor->x) 3012 { 3013 dstX = scissor->x; 3014 readBox.left += (scissor->x - drawRect.x); 3015 } 3016 if (drawRect.y < scissor->y) 3017 { 3018 dstY = scissor->y; 3019 readBox.top += (scissor->y - drawRect.y); 3020 } 3021 if (drawRect.x + drawRect.width > scissor->x + scissor->width) 3022 { 3023 readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width)); 3024 } 3025 if (drawRect.y + drawRect.height > scissor->y + scissor->height) 3026 { 3027 readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height)); 3028 } 3029 } 3030 3031 // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox 3032 // We also require complete framebuffer copies for depth-stencil blit. 3033 D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; 3034 3035 mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, 3036 readTexture, readSubresource, pSrcBox); 3037 result = true; 3038 } 3039 else 3040 { 3041 gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1); 3042 gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1); 3043 3044 if (depthBlit && stencilBlit) 3045 { 3046 result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize, 3047 drawTexture, drawSubresource, drawArea, drawSize, 3048 scissor); 3049 } 3050 else if (depthBlit) 3051 { 3052 result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize, 3053 scissor); 3054 } 3055 else if (stencilBlit) 3056 { 3057 result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize, 3058 drawTexture, drawSubresource, drawArea, drawSize, 3059 scissor); 3060 } 3061 else 3062 { 3063 GLenum format = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()).format; 3064 result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, 3065 scissor, format, filter); 3066 } 3067 } 3068 3069 SafeRelease(readTexture); 3070 SafeRelease(readSRV); 3071 3072 return result; 3073 } 3074 3075 ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) 3076 { 3077 D3D11_TEXTURE2D_DESC textureDesc; 3078 source->GetDesc(&textureDesc); 3079 3080 if (textureDesc.SampleDesc.Count > 1) 3081 { 3082 D3D11_TEXTURE2D_DESC resolveDesc; 3083 resolveDesc.Width = textureDesc.Width; 3084 resolveDesc.Height = textureDesc.Height; 3085 resolveDesc.MipLevels = 1; 3086 resolveDesc.ArraySize = 1; 3087 resolveDesc.Format = textureDesc.Format; 3088 resolveDesc.SampleDesc.Count = 1; 3089 resolveDesc.SampleDesc.Quality = 0; 3090 resolveDesc.Usage = textureDesc.Usage; 3091 resolveDesc.BindFlags = textureDesc.BindFlags; 3092 resolveDesc.CPUAccessFlags = 0; 3093 resolveDesc.MiscFlags = 0; 3094 3095 ID3D11Texture2D *resolveTexture = NULL; 3096 HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture); 3097 if (FAILED(result)) 3098 { 3099 ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result); 3100 return NULL; 3101 } 3102 3103 mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format); 3104 return resolveTexture; 3105 } 3106 else 3107 { 3108 source->AddRef(); 3109 return source; 3110 } 3111 } 3112 3113 void Renderer11::invalidateFBOAttachmentSwizzles(gl::FramebufferAttachment *attachment, int mipLevel) 3114 { 3115 ASSERT(attachment->isTexture()); 3116 gl::Texture *texture = attachment->getTexture(); 3117 3118 TextureStorage *texStorage = texture->getNativeTexture(); 3119 if (texStorage) 3120 { 3121 TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); 3122 if (!texStorage11) 3123 { 3124 ERR("texture storage pointer unexpectedly null."); 3125 return; 3126 } 3127 3128 texStorage11->invalidateSwizzleCacheLevel(mipLevel); 3129 } 3130 } 3131 3132 void Renderer11::invalidateFramebufferSwizzles(gl::Framebuffer *framebuffer) 3133 { 3134 for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) 3135 { 3136 gl::FramebufferAttachment *attachment = framebuffer->getColorbuffer(colorAttachment); 3137 if (attachment && attachment->isTexture()) 3138 { 3139 invalidateFBOAttachmentSwizzles(attachment, attachment->mipLevel()); 3140 } 3141 } 3142 3143 gl::FramebufferAttachment *depthAttachment = framebuffer->getDepthbuffer(); 3144 if (depthAttachment && depthAttachment->isTexture()) 3145 { 3146 invalidateFBOAttachmentSwizzles(depthAttachment, depthAttachment->mipLevel()); 3147 } 3148 3149 gl::FramebufferAttachment *stencilAttachment = framebuffer->getStencilbuffer(); 3150 if (stencilAttachment && stencilAttachment->isTexture()) 3151 { 3152 invalidateFBOAttachmentSwizzles(stencilAttachment, stencilAttachment->mipLevel()); 3153 } 3154 } 3155 3156 bool Renderer11::getLUID(LUID *adapterLuid) const 3157 { 3158 adapterLuid->HighPart = 0; 3159 adapterLuid->LowPart = 0; 3160 3161 if (!mDxgiAdapter) 3162 { 3163 return false; 3164 } 3165 3166 DXGI_ADAPTER_DESC adapterDesc; 3167 if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc))) 3168 { 3169 return false; 3170 } 3171 3172 *adapterLuid = adapterDesc.AdapterLuid; 3173 return true; 3174 } 3175 3176 rx::VertexConversionType Renderer11::getVertexConversionType(const gl::VertexFormat &vertexFormat) const 3177 { 3178 return d3d11::GetVertexFormatInfo(vertexFormat).conversionType; 3179 } 3180 3181 GLenum Renderer11::getVertexComponentType(const gl::VertexFormat &vertexFormat) const 3182 { 3183 return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormat).nativeFormat).componentType; 3184 } 3185 3186 void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions) const 3187 { 3188 d3d11_gl::GenerateCaps(mDevice, outCaps, outTextureCaps, outExtensions); 3189 } 3190 3191 } 3192