renderer11_utils.cpp (97657B)
1 // 2 // Copyright 2012 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_utils.cpp: Conversion functions and other utility routines 8 // specific to the D3D11 renderer. 9 10 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" 11 12 #include <versionhelpers.h> 13 #include <algorithm> 14 15 #include "common/debug.h" 16 #include "libANGLE/Buffer.h" 17 #include "libANGLE/Context.h" 18 #include "libANGLE/Framebuffer.h" 19 #include "libANGLE/Program.h" 20 #include "libANGLE/State.h" 21 #include "libANGLE/VertexArray.h" 22 #include "libANGLE/formatutils.h" 23 #include "libANGLE/renderer/d3d/BufferD3D.h" 24 #include "libANGLE/renderer/d3d/FramebufferD3D.h" 25 #include "libANGLE/renderer/d3d/d3d11/Context11.h" 26 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" 27 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" 28 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" 29 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" 30 #include "libANGLE/renderer/driver_utils.h" 31 #include "libANGLE/renderer/dxgi_support_table.h" 32 #include "platform/FeaturesD3D_autogen.h" 33 #include "platform/PlatformMethods.h" 34 35 namespace rx 36 { 37 38 namespace d3d11_gl 39 { 40 namespace 41 { 42 // TODO(xinghua.cao@intel.com): Get a more accurate limit. 43 static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0; 44 45 // Helper functor for querying DXGI support. Saves passing the parameters repeatedly. 46 class DXGISupportHelper : angle::NonCopyable 47 { 48 public: 49 DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel) 50 : mDevice(device), mFeatureLevel(featureLevel) 51 {} 52 53 bool query(DXGI_FORMAT dxgiFormat, UINT supportMask) 54 { 55 if (dxgiFormat == DXGI_FORMAT_UNKNOWN) 56 return false; 57 58 auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel); 59 60 UINT supportedBits = dxgiSupport.alwaysSupportedFlags; 61 62 if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0) 63 { 64 UINT formatSupport; 65 if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport))) 66 { 67 supportedBits |= (formatSupport & supportMask); 68 } 69 else 70 { 71 // TODO(jmadill): find out why we fail this call sometimes in FL9_3 72 // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat; 73 } 74 } 75 76 return ((supportedBits & supportMask) == supportMask); 77 } 78 79 private: 80 ID3D11Device *mDevice; 81 D3D_FEATURE_LEVEL mFeatureLevel; 82 }; 83 84 gl::TextureCaps GenerateTextureFormatCaps(gl::Version maxClientVersion, 85 GLenum internalFormat, 86 ID3D11Device *device, 87 const Renderer11DeviceCaps &renderer11DeviceCaps) 88 { 89 gl::TextureCaps textureCaps; 90 91 DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); 92 const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); 93 94 const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat); 95 96 UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; 97 if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) 98 { 99 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; 100 if (maxClientVersion.major > 2) 101 { 102 texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; 103 } 104 } 105 106 textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask); 107 textureCaps.filterable = 108 support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); 109 textureCaps.textureAttachment = 110 (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || 111 (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); 112 textureCaps.renderbuffer = textureCaps.textureAttachment; 113 textureCaps.blendable = textureCaps.renderbuffer; 114 115 DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; 116 if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) 117 { 118 renderFormat = formatInfo.dsvFormat; 119 } 120 else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) 121 { 122 renderFormat = formatInfo.rtvFormat; 123 } 124 if (renderFormat != DXGI_FORMAT_UNKNOWN && 125 support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) 126 { 127 // Assume 1x 128 textureCaps.sampleCounts.insert(1); 129 130 for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; 131 sampleCount *= 2) 132 { 133 UINT qualityCount = 0; 134 if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, 135 &qualityCount))) 136 { 137 // Assume we always support lower sample counts 138 if (qualityCount == 0) 139 { 140 break; 141 } 142 textureCaps.sampleCounts.insert(sampleCount); 143 } 144 } 145 } 146 147 return textureCaps; 148 } 149 150 bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) 151 { 152 switch (featureLevel) 153 { 154 case D3D_FEATURE_LEVEL_11_1: 155 case D3D_FEATURE_LEVEL_11_0: 156 case D3D_FEATURE_LEVEL_10_1: 157 case D3D_FEATURE_LEVEL_10_0: 158 return true; 159 160 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx 161 case D3D_FEATURE_LEVEL_9_3: 162 case D3D_FEATURE_LEVEL_9_2: 163 case D3D_FEATURE_LEVEL_9_1: 164 return false; 165 166 default: 167 UNREACHABLE(); 168 return false; 169 } 170 } 171 172 float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) 173 { 174 switch (featureLevel) 175 { 176 case D3D_FEATURE_LEVEL_11_1: 177 case D3D_FEATURE_LEVEL_11_0: 178 return D3D11_MAX_MAXANISOTROPY; 179 180 case D3D_FEATURE_LEVEL_10_1: 181 case D3D_FEATURE_LEVEL_10_0: 182 return D3D10_MAX_MAXANISOTROPY; 183 184 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx 185 case D3D_FEATURE_LEVEL_9_3: 186 case D3D_FEATURE_LEVEL_9_2: 187 return 16; 188 189 case D3D_FEATURE_LEVEL_9_1: 190 return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; 191 192 default: 193 UNREACHABLE(); 194 return 0; 195 } 196 } 197 198 bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) 199 { 200 switch (featureLevel) 201 { 202 case D3D_FEATURE_LEVEL_11_1: 203 case D3D_FEATURE_LEVEL_11_0: 204 case D3D_FEATURE_LEVEL_10_1: 205 case D3D_FEATURE_LEVEL_10_0: 206 return true; 207 208 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx 209 // ID3D11Device::CreateQuery 210 case D3D_FEATURE_LEVEL_9_3: 211 case D3D_FEATURE_LEVEL_9_2: 212 return true; 213 case D3D_FEATURE_LEVEL_9_1: 214 return false; 215 216 default: 217 UNREACHABLE(); 218 return false; 219 } 220 } 221 222 bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) 223 { 224 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx 225 // ID3D11Device::CreateQuery 226 227 switch (featureLevel) 228 { 229 case D3D_FEATURE_LEVEL_11_1: 230 case D3D_FEATURE_LEVEL_11_0: 231 case D3D_FEATURE_LEVEL_10_1: 232 case D3D_FEATURE_LEVEL_10_0: 233 case D3D_FEATURE_LEVEL_9_3: 234 case D3D_FEATURE_LEVEL_9_2: 235 case D3D_FEATURE_LEVEL_9_1: 236 return true; 237 238 default: 239 UNREACHABLE(); 240 return false; 241 } 242 } 243 244 bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) 245 { 246 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx 247 // ID3D11Device::CreateInputLayout 248 249 switch (featureLevel) 250 { 251 case D3D_FEATURE_LEVEL_11_1: 252 case D3D_FEATURE_LEVEL_11_0: 253 case D3D_FEATURE_LEVEL_10_1: 254 case D3D_FEATURE_LEVEL_10_0: 255 return true; 256 257 // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be 258 // instanced. 259 // D3D9 has a similar restriction, where stream 0 must not be instanced. 260 // This restriction can be worked around by remapping any non-instanced slot to slot 261 // 0. 262 // This works because HLSL uses shader semantics to match the vertex inputs to the 263 // elements in the input layout, rather than the slots. 264 // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3 265 // doesn't support OpenGL ES 3.0 266 case D3D_FEATURE_LEVEL_9_3: 267 return true; 268 269 case D3D_FEATURE_LEVEL_9_2: 270 case D3D_FEATURE_LEVEL_9_1: 271 return false; 272 273 default: 274 UNREACHABLE(); 275 return false; 276 } 277 } 278 279 bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel) 280 { 281 switch (featureLevel) 282 { 283 case D3D_FEATURE_LEVEL_11_1: 284 case D3D_FEATURE_LEVEL_11_0: 285 case D3D_FEATURE_LEVEL_10_1: 286 case D3D_FEATURE_LEVEL_10_0: 287 return true; 288 289 case D3D_FEATURE_LEVEL_9_3: 290 case D3D_FEATURE_LEVEL_9_2: 291 case D3D_FEATURE_LEVEL_9_1: 292 return false; 293 294 default: 295 UNREACHABLE(); 296 return false; 297 } 298 } 299 300 bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel) 301 { 302 switch (featureLevel) 303 { 304 case D3D_FEATURE_LEVEL_11_1: 305 case D3D_FEATURE_LEVEL_11_0: 306 case D3D_FEATURE_LEVEL_10_1: 307 case D3D_FEATURE_LEVEL_10_0: 308 return true; 309 310 case D3D_FEATURE_LEVEL_9_3: 311 case D3D_FEATURE_LEVEL_9_2: 312 case D3D_FEATURE_LEVEL_9_1: 313 return false; 314 315 default: 316 UNREACHABLE(); 317 return false; 318 } 319 } 320 321 bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) 322 { 323 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that 324 // shader model 325 // ps_2_x is required for the ddx (and other derivative functions). 326 327 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that 328 // feature level 329 // 9.3 supports shader model ps_2_x. 330 331 switch (featureLevel) 332 { 333 case D3D_FEATURE_LEVEL_11_1: 334 case D3D_FEATURE_LEVEL_11_0: 335 case D3D_FEATURE_LEVEL_10_1: 336 case D3D_FEATURE_LEVEL_10_0: 337 case D3D_FEATURE_LEVEL_9_3: 338 return true; 339 case D3D_FEATURE_LEVEL_9_2: 340 case D3D_FEATURE_LEVEL_9_1: 341 return false; 342 343 default: 344 UNREACHABLE(); 345 return false; 346 } 347 } 348 349 bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel) 350 { 351 switch (featureLevel) 352 { 353 case D3D_FEATURE_LEVEL_11_1: 354 case D3D_FEATURE_LEVEL_11_0: 355 case D3D_FEATURE_LEVEL_10_1: 356 case D3D_FEATURE_LEVEL_10_0: 357 return true; 358 359 case D3D_FEATURE_LEVEL_9_3: 360 case D3D_FEATURE_LEVEL_9_2: 361 case D3D_FEATURE_LEVEL_9_1: 362 return false; 363 364 default: 365 UNREACHABLE(); 366 return false; 367 } 368 } 369 370 int GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel) 371 { 372 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx 373 // ID3D11Device::CreateInputLayout 374 375 switch (featureLevel) 376 { 377 case D3D_FEATURE_LEVEL_11_1: 378 case D3D_FEATURE_LEVEL_11_0: 379 return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; 380 381 case D3D_FEATURE_LEVEL_10_1: 382 case D3D_FEATURE_LEVEL_10_0: 383 return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; 384 385 case D3D_FEATURE_LEVEL_9_3: 386 return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; 387 case D3D_FEATURE_LEVEL_9_2: 388 case D3D_FEATURE_LEVEL_9_1: 389 return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; 390 391 default: 392 UNREACHABLE(); 393 return 0; 394 } 395 } 396 397 int GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) 398 { 399 switch (featureLevel) 400 { 401 case D3D_FEATURE_LEVEL_11_1: 402 case D3D_FEATURE_LEVEL_11_0: 403 return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; 404 405 case D3D_FEATURE_LEVEL_10_1: 406 case D3D_FEATURE_LEVEL_10_0: 407 return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; 408 409 case D3D_FEATURE_LEVEL_9_3: 410 return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; 411 case D3D_FEATURE_LEVEL_9_2: 412 case D3D_FEATURE_LEVEL_9_1: 413 return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; 414 415 default: 416 UNREACHABLE(); 417 return 0; 418 } 419 } 420 421 int GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) 422 { 423 switch (featureLevel) 424 { 425 case D3D_FEATURE_LEVEL_11_1: 426 case D3D_FEATURE_LEVEL_11_0: 427 return D3D11_REQ_TEXTURECUBE_DIMENSION; 428 429 case D3D_FEATURE_LEVEL_10_1: 430 case D3D_FEATURE_LEVEL_10_0: 431 return D3D10_REQ_TEXTURECUBE_DIMENSION; 432 433 case D3D_FEATURE_LEVEL_9_3: 434 return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION; 435 case D3D_FEATURE_LEVEL_9_2: 436 case D3D_FEATURE_LEVEL_9_1: 437 return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION; 438 439 default: 440 UNREACHABLE(); 441 return 0; 442 } 443 } 444 445 int GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) 446 { 447 switch (featureLevel) 448 { 449 case D3D_FEATURE_LEVEL_11_1: 450 case D3D_FEATURE_LEVEL_11_0: 451 return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; 452 453 case D3D_FEATURE_LEVEL_10_1: 454 case D3D_FEATURE_LEVEL_10_0: 455 return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; 456 457 case D3D_FEATURE_LEVEL_9_3: 458 case D3D_FEATURE_LEVEL_9_2: 459 case D3D_FEATURE_LEVEL_9_1: 460 return 0; 461 462 default: 463 UNREACHABLE(); 464 return 0; 465 } 466 } 467 468 int GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) 469 { 470 switch (featureLevel) 471 { 472 case D3D_FEATURE_LEVEL_11_1: 473 case D3D_FEATURE_LEVEL_11_0: 474 return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 475 476 case D3D_FEATURE_LEVEL_10_1: 477 case D3D_FEATURE_LEVEL_10_0: 478 return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 479 480 case D3D_FEATURE_LEVEL_9_3: 481 case D3D_FEATURE_LEVEL_9_2: 482 case D3D_FEATURE_LEVEL_9_1: 483 return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 484 485 default: 486 UNREACHABLE(); 487 return 0; 488 } 489 } 490 491 int GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) 492 { 493 switch (featureLevel) 494 { 495 case D3D_FEATURE_LEVEL_11_1: 496 case D3D_FEATURE_LEVEL_11_0: 497 return D3D11_VIEWPORT_BOUNDS_MAX; 498 499 case D3D_FEATURE_LEVEL_10_1: 500 case D3D_FEATURE_LEVEL_10_0: 501 return D3D10_VIEWPORT_BOUNDS_MAX; 502 503 // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum 504 // texture sizes 505 case D3D_FEATURE_LEVEL_9_3: 506 return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; 507 case D3D_FEATURE_LEVEL_9_2: 508 case D3D_FEATURE_LEVEL_9_1: 509 return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; 510 511 default: 512 UNREACHABLE(); 513 return 0; 514 } 515 } 516 517 int GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) 518 { 519 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since 520 // that's what's 521 // returned from glGetInteger 522 static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, 523 "Unexpected D3D11 constant value."); 524 static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, 525 "Unexpected D3D11 constant value."); 526 527 switch (featureLevel) 528 { 529 case D3D_FEATURE_LEVEL_11_1: 530 case D3D_FEATURE_LEVEL_11_0: 531 case D3D_FEATURE_LEVEL_10_1: 532 case D3D_FEATURE_LEVEL_10_0: 533 return std::numeric_limits<GLint>::max(); 534 535 case D3D_FEATURE_LEVEL_9_3: 536 case D3D_FEATURE_LEVEL_9_2: 537 return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; 538 case D3D_FEATURE_LEVEL_9_1: 539 return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; 540 541 default: 542 UNREACHABLE(); 543 return 0; 544 } 545 } 546 547 int GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) 548 { 549 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since 550 // that's what's 551 // returned from glGetInteger 552 static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); 553 static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); 554 555 switch (featureLevel) 556 { 557 case D3D_FEATURE_LEVEL_11_1: 558 case D3D_FEATURE_LEVEL_11_0: 559 case D3D_FEATURE_LEVEL_10_1: 560 case D3D_FEATURE_LEVEL_10_0: 561 return std::numeric_limits<GLint>::max(); 562 563 case D3D_FEATURE_LEVEL_9_3: 564 case D3D_FEATURE_LEVEL_9_2: 565 return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; 566 case D3D_FEATURE_LEVEL_9_1: 567 return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; 568 569 default: 570 UNREACHABLE(); 571 return 0; 572 } 573 } 574 575 int GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) 576 { 577 switch (featureLevel) 578 { 579 case D3D_FEATURE_LEVEL_11_1: 580 case D3D_FEATURE_LEVEL_11_0: 581 return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; 582 583 case D3D_FEATURE_LEVEL_10_1: 584 return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; 585 case D3D_FEATURE_LEVEL_10_0: 586 return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; 587 588 // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx 589 // "Max Input Slots" 590 case D3D_FEATURE_LEVEL_9_3: 591 case D3D_FEATURE_LEVEL_9_2: 592 case D3D_FEATURE_LEVEL_9_1: 593 return 16; 594 595 default: 596 UNREACHABLE(); 597 return 0; 598 } 599 } 600 601 int GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) 602 { 603 switch (featureLevel) 604 { 605 case D3D_FEATURE_LEVEL_11_1: 606 case D3D_FEATURE_LEVEL_11_0: 607 return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 608 609 case D3D_FEATURE_LEVEL_10_1: 610 case D3D_FEATURE_LEVEL_10_0: 611 return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 612 613 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx 614 // ID3D11DeviceContext::VSSetConstantBuffers 615 case D3D_FEATURE_LEVEL_9_3: 616 case D3D_FEATURE_LEVEL_9_2: 617 case D3D_FEATURE_LEVEL_9_1: 618 return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel); 619 620 default: 621 UNREACHABLE(); 622 return 0; 623 } 624 } 625 626 int GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) 627 { 628 switch (featureLevel) 629 { 630 case D3D_FEATURE_LEVEL_11_1: 631 case D3D_FEATURE_LEVEL_11_0: 632 return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 633 d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; 634 635 case D3D_FEATURE_LEVEL_10_1: 636 case D3D_FEATURE_LEVEL_10_0: 637 return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 638 d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; 639 640 // Uniform blocks not supported on D3D11 Feature Level 9 641 case D3D_FEATURE_LEVEL_9_3: 642 case D3D_FEATURE_LEVEL_9_2: 643 case D3D_FEATURE_LEVEL_9_1: 644 return 0; 645 646 default: 647 UNREACHABLE(); 648 return 0; 649 } 650 } 651 652 int GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) 653 { 654 // According to The OpenGL ES Shading Language specifications 655 // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21) 656 // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord) 657 // which are statically used in the shader should be included in the variable packing 658 // algorithm. 659 // Therefore, we should not reserve output vectors for them. 660 661 switch (featureLevel) 662 { 663 // We must reserve one output vector for dx_Position. 664 // We also reserve one for gl_Position, which we unconditionally output on Feature 665 // Levels 10_0+, 666 // even if it's unused in the shader (e.g. for transform feedback). TODO: This could 667 // be improved. 668 case D3D_FEATURE_LEVEL_11_1: 669 case D3D_FEATURE_LEVEL_11_0: 670 case D3D_FEATURE_LEVEL_10_1: 671 case D3D_FEATURE_LEVEL_10_0: 672 return 2; 673 674 // Just reserve dx_Position on Feature Level 9, since we don't ever need to output 675 // gl_Position. 676 case D3D_FEATURE_LEVEL_9_3: 677 case D3D_FEATURE_LEVEL_9_2: 678 case D3D_FEATURE_LEVEL_9_1: 679 return 1; 680 681 default: 682 UNREACHABLE(); 683 return 0; 684 } 685 } 686 687 int GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) 688 { 689 static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT, 690 "Unexpected D3D11 constant value."); 691 692 switch (featureLevel) 693 { 694 case D3D_FEATURE_LEVEL_11_1: 695 case D3D_FEATURE_LEVEL_11_0: 696 return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); 697 698 case D3D_FEATURE_LEVEL_10_1: 699 return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); 700 case D3D_FEATURE_LEVEL_10_0: 701 return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); 702 703 // Use Shader Model 2.X limits 704 case D3D_FEATURE_LEVEL_9_3: 705 case D3D_FEATURE_LEVEL_9_2: 706 case D3D_FEATURE_LEVEL_9_1: 707 return 8 - GetReservedVertexOutputVectors(featureLevel); 708 709 default: 710 UNREACHABLE(); 711 return 0; 712 } 713 } 714 715 int GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) 716 { 717 switch (featureLevel) 718 { 719 case D3D_FEATURE_LEVEL_11_1: 720 case D3D_FEATURE_LEVEL_11_0: 721 return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; 722 723 case D3D_FEATURE_LEVEL_10_1: 724 case D3D_FEATURE_LEVEL_10_0: 725 return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; 726 727 // Vertex textures not supported on D3D11 Feature Level 9 according to 728 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx 729 // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources 730 case D3D_FEATURE_LEVEL_9_3: 731 case D3D_FEATURE_LEVEL_9_2: 732 case D3D_FEATURE_LEVEL_9_1: 733 return 0; 734 735 default: 736 UNREACHABLE(); 737 return 0; 738 } 739 } 740 741 int GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) 742 { 743 // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass 744 switch (featureLevel) 745 { 746 case D3D_FEATURE_LEVEL_11_1: 747 case D3D_FEATURE_LEVEL_11_0: 748 return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 749 750 case D3D_FEATURE_LEVEL_10_1: 751 case D3D_FEATURE_LEVEL_10_0: 752 return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 753 754 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx 755 // ID3D11DeviceContext::PSSetConstantBuffers 756 case D3D_FEATURE_LEVEL_9_3: 757 case D3D_FEATURE_LEVEL_9_2: 758 case D3D_FEATURE_LEVEL_9_1: 759 return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel); 760 761 default: 762 UNREACHABLE(); 763 return 0; 764 } 765 } 766 767 int GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) 768 { 769 switch (featureLevel) 770 { 771 case D3D_FEATURE_LEVEL_11_1: 772 case D3D_FEATURE_LEVEL_11_0: 773 return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 774 d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; 775 776 case D3D_FEATURE_LEVEL_10_1: 777 case D3D_FEATURE_LEVEL_10_0: 778 return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 779 d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; 780 781 // Uniform blocks not supported on D3D11 Feature Level 9 782 case D3D_FEATURE_LEVEL_9_3: 783 case D3D_FEATURE_LEVEL_9_2: 784 case D3D_FEATURE_LEVEL_9_1: 785 return 0; 786 787 default: 788 UNREACHABLE(); 789 return 0; 790 } 791 } 792 793 int GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) 794 { 795 switch (featureLevel) 796 { 797 case D3D_FEATURE_LEVEL_11_1: 798 case D3D_FEATURE_LEVEL_11_0: 799 return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); 800 801 case D3D_FEATURE_LEVEL_10_1: 802 case D3D_FEATURE_LEVEL_10_0: 803 return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); 804 805 // Use Shader Model 2.X limits 806 case D3D_FEATURE_LEVEL_9_3: 807 return 8 - GetReservedVertexOutputVectors(featureLevel); 808 case D3D_FEATURE_LEVEL_9_2: 809 case D3D_FEATURE_LEVEL_9_1: 810 return 8 - GetReservedVertexOutputVectors(featureLevel); 811 812 default: 813 UNREACHABLE(); 814 return 0; 815 } 816 } 817 818 int GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) 819 { 820 switch (featureLevel) 821 { 822 case D3D_FEATURE_LEVEL_11_1: 823 case D3D_FEATURE_LEVEL_11_0: 824 return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; 825 826 case D3D_FEATURE_LEVEL_10_1: 827 case D3D_FEATURE_LEVEL_10_0: 828 return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; 829 830 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx 831 // ID3D11DeviceContext::PSSetShaderResources 832 case D3D_FEATURE_LEVEL_9_3: 833 case D3D_FEATURE_LEVEL_9_2: 834 case D3D_FEATURE_LEVEL_9_1: 835 return 16; 836 837 default: 838 UNREACHABLE(); 839 return 0; 840 } 841 } 842 843 std::array<GLint, 3> GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel) 844 { 845 switch (featureLevel) 846 { 847 case D3D_FEATURE_LEVEL_11_1: 848 case D3D_FEATURE_LEVEL_11_0: 849 return {{D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, 850 D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, 851 D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION}}; 852 default: 853 return {{0, 0, 0}}; 854 } 855 } 856 857 std::array<GLint, 3> GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel) 858 { 859 switch (featureLevel) 860 { 861 case D3D_FEATURE_LEVEL_11_1: 862 case D3D_FEATURE_LEVEL_11_0: 863 return {{D3D11_CS_THREAD_GROUP_MAX_X, D3D11_CS_THREAD_GROUP_MAX_Y, 864 D3D11_CS_THREAD_GROUP_MAX_Z}}; 865 default: 866 return {{0, 0, 0}}; 867 } 868 } 869 870 int GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel) 871 { 872 switch (featureLevel) 873 { 874 case D3D_FEATURE_LEVEL_11_1: 875 case D3D_FEATURE_LEVEL_11_0: 876 return D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; 877 default: 878 return 0; 879 } 880 } 881 882 int GetMaxComputeSharedMemorySize(D3D_FEATURE_LEVEL featureLevel) 883 { 884 switch (featureLevel) 885 { 886 // In D3D11 the maximum total size of all variables with the groupshared storage class is 887 // 32kb. 888 // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax 889 case D3D_FEATURE_LEVEL_11_1: 890 case D3D_FEATURE_LEVEL_11_0: 891 return 32768; 892 default: 893 return 0; 894 } 895 } 896 897 int GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel) 898 { 899 switch (featureLevel) 900 { 901 case D3D_FEATURE_LEVEL_11_1: 902 case D3D_FEATURE_LEVEL_11_0: 903 return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 904 default: 905 return 0; 906 } 907 } 908 909 int GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel) 910 { 911 switch (featureLevel) 912 { 913 case D3D_FEATURE_LEVEL_11_1: 914 case D3D_FEATURE_LEVEL_11_0: 915 return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 916 d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; 917 default: 918 return 0; 919 } 920 } 921 922 int GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel) 923 { 924 switch (featureLevel) 925 { 926 case D3D_FEATURE_LEVEL_11_1: 927 case D3D_FEATURE_LEVEL_11_0: 928 return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; 929 default: 930 return 0; 931 } 932 } 933 934 void SetUAVRelatedResourceLimits(D3D_FEATURE_LEVEL featureLevel, gl::Caps *caps) 935 { 936 ASSERT(caps); 937 938 GLuint reservedUAVsForAtomicCounterBuffers = 0u; 939 940 // For pixel shaders, the render targets and unordered access views share the same resource 941 // slots when being written out. 942 // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476465(v=vs.85).aspx 943 GLuint maxNumRTVsAndUAVs = 0u; 944 945 switch (featureLevel) 946 { 947 case D3D_FEATURE_LEVEL_11_1: 948 // Currently we allocate 4 UAV slots for atomic counter buffers on feature level 11_1. 949 reservedUAVsForAtomicCounterBuffers = 4u; 950 maxNumRTVsAndUAVs = D3D11_1_UAV_SLOT_COUNT; 951 break; 952 case D3D_FEATURE_LEVEL_11_0: 953 // Currently we allocate 1 UAV slot for atomic counter buffers on feature level 11_0. 954 reservedUAVsForAtomicCounterBuffers = 1u; 955 maxNumRTVsAndUAVs = D3D11_PS_CS_UAV_REGISTER_COUNT; 956 break; 957 default: 958 return; 959 } 960 961 // Set limits on atomic counter buffers in fragment shaders and compute shaders. 962 caps->maxCombinedAtomicCounterBuffers = reservedUAVsForAtomicCounterBuffers; 963 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] = 964 reservedUAVsForAtomicCounterBuffers; 965 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] = 966 reservedUAVsForAtomicCounterBuffers; 967 caps->maxAtomicCounterBufferBindings = reservedUAVsForAtomicCounterBuffers; 968 969 // Setting MAX_COMPUTE_ATOMIC_COUNTERS to a conservative number of 1024 * the number of UAV 970 // reserved for atomic counters. It could theoretically be set to max buffer size / 4 but that 971 // number could cause problems. 972 caps->maxCombinedAtomicCounters = reservedUAVsForAtomicCounterBuffers * 1024; 973 caps->maxShaderAtomicCounters[gl::ShaderType::Compute] = caps->maxCombinedAtomicCounters; 974 975 // See 976 // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-resources-limits 977 // Resource size (in MB) for any of the preceding resources is min(max(128,0.25f * (amount of 978 // dedicated VRAM)), 2048) MB. So we set it to 128MB to keep same with GL backend. 979 caps->maxShaderStorageBlockSize = 980 D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024 * 1024; 981 982 // Allocate the remaining slots for images and shader storage blocks. 983 // The maximum number of fragment shader outputs depends on the current context version, so we 984 // will not set it here. See comments in Context11::initialize(). 985 caps->maxCombinedShaderOutputResources = 986 maxNumRTVsAndUAVs - reservedUAVsForAtomicCounterBuffers; 987 988 // Set limits on images and shader storage blocks in fragment shaders and compute shaders. 989 caps->maxCombinedShaderStorageBlocks = caps->maxCombinedShaderOutputResources; 990 caps->maxShaderStorageBlocks[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources; 991 caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources; 992 caps->maxShaderStorageBufferBindings = caps->maxCombinedShaderOutputResources; 993 994 caps->maxImageUnits = caps->maxCombinedShaderOutputResources; 995 caps->maxCombinedImageUniforms = caps->maxCombinedShaderOutputResources; 996 caps->maxShaderImageUniforms[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources; 997 caps->maxShaderImageUniforms[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources; 998 999 // On feature level 11_1, UAVs are also available in vertex shaders and geometry shaders. 1000 if (featureLevel == D3D_FEATURE_LEVEL_11_1) 1001 { 1002 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] = 1003 caps->maxCombinedAtomicCounterBuffers; 1004 caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] = 1005 caps->maxCombinedAtomicCounterBuffers; 1006 1007 caps->maxShaderImageUniforms[gl::ShaderType::Vertex] = 1008 caps->maxCombinedShaderOutputResources; 1009 caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] = 1010 caps->maxCombinedShaderOutputResources; 1011 caps->maxShaderImageUniforms[gl::ShaderType::Geometry] = 1012 caps->maxCombinedShaderOutputResources; 1013 caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] = 1014 caps->maxCombinedShaderOutputResources; 1015 } 1016 } 1017 1018 int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) 1019 { 1020 switch (featureLevel) 1021 { 1022 case D3D_FEATURE_LEVEL_11_1: 1023 case D3D_FEATURE_LEVEL_11_0: 1024 return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; 1025 1026 case D3D_FEATURE_LEVEL_10_1: 1027 case D3D_FEATURE_LEVEL_10_0: 1028 return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; 1029 1030 // Sampling functions with offsets are not available below shader model 4.0. 1031 case D3D_FEATURE_LEVEL_9_3: 1032 case D3D_FEATURE_LEVEL_9_2: 1033 case D3D_FEATURE_LEVEL_9_1: 1034 return 0; 1035 1036 default: 1037 UNREACHABLE(); 1038 return 0; 1039 } 1040 } 1041 1042 int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) 1043 { 1044 switch (featureLevel) 1045 { 1046 case D3D_FEATURE_LEVEL_11_1: 1047 case D3D_FEATURE_LEVEL_11_0: 1048 return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; 1049 case D3D_FEATURE_LEVEL_10_1: 1050 case D3D_FEATURE_LEVEL_10_0: 1051 return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; 1052 1053 // Sampling functions with offsets are not available below shader model 4.0. 1054 case D3D_FEATURE_LEVEL_9_3: 1055 case D3D_FEATURE_LEVEL_9_2: 1056 case D3D_FEATURE_LEVEL_9_1: 1057 return 0; 1058 1059 default: 1060 UNREACHABLE(); 1061 return 0; 1062 } 1063 } 1064 1065 int GetMinimumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel) 1066 { 1067 switch (featureLevel) 1068 { 1069 // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm- 1070 case D3D_FEATURE_LEVEL_11_1: 1071 case D3D_FEATURE_LEVEL_11_0: 1072 return -32; 1073 1074 case D3D_FEATURE_LEVEL_10_1: 1075 case D3D_FEATURE_LEVEL_10_0: 1076 case D3D_FEATURE_LEVEL_9_3: 1077 case D3D_FEATURE_LEVEL_9_2: 1078 case D3D_FEATURE_LEVEL_9_1: 1079 return 0; 1080 1081 default: 1082 UNREACHABLE(); 1083 return 0; 1084 } 1085 } 1086 1087 int GetMaximumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel) 1088 { 1089 switch (featureLevel) 1090 { 1091 // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm- 1092 case D3D_FEATURE_LEVEL_11_1: 1093 case D3D_FEATURE_LEVEL_11_0: 1094 return 31; 1095 1096 case D3D_FEATURE_LEVEL_10_1: 1097 case D3D_FEATURE_LEVEL_10_0: 1098 case D3D_FEATURE_LEVEL_9_3: 1099 case D3D_FEATURE_LEVEL_9_2: 1100 case D3D_FEATURE_LEVEL_9_1: 1101 return 0; 1102 1103 default: 1104 UNREACHABLE(); 1105 return 0; 1106 } 1107 } 1108 1109 size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) 1110 { 1111 // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum 1112 // size of 1113 // any buffer that could be allocated. 1114 1115 const size_t bytesPerComponent = 4 * sizeof(float); 1116 1117 switch (featureLevel) 1118 { 1119 case D3D_FEATURE_LEVEL_11_1: 1120 case D3D_FEATURE_LEVEL_11_0: 1121 return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; 1122 1123 case D3D_FEATURE_LEVEL_10_1: 1124 case D3D_FEATURE_LEVEL_10_0: 1125 return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; 1126 1127 // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx 1128 // remarks section 1129 case D3D_FEATURE_LEVEL_9_3: 1130 case D3D_FEATURE_LEVEL_9_2: 1131 case D3D_FEATURE_LEVEL_9_1: 1132 return 4096 * bytesPerComponent; 1133 1134 default: 1135 UNREACHABLE(); 1136 return 0; 1137 } 1138 } 1139 1140 int GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) 1141 { 1142 switch (featureLevel) 1143 { 1144 case D3D_FEATURE_LEVEL_11_1: 1145 case D3D_FEATURE_LEVEL_11_0: 1146 return D3D11_SO_BUFFER_SLOT_COUNT; 1147 1148 case D3D_FEATURE_LEVEL_10_1: 1149 return D3D10_1_SO_BUFFER_SLOT_COUNT; 1150 case D3D_FEATURE_LEVEL_10_0: 1151 return D3D10_SO_BUFFER_SLOT_COUNT; 1152 1153 case D3D_FEATURE_LEVEL_9_3: 1154 case D3D_FEATURE_LEVEL_9_2: 1155 case D3D_FEATURE_LEVEL_9_1: 1156 return 0; 1157 1158 default: 1159 UNREACHABLE(); 1160 return 0; 1161 } 1162 } 1163 1164 int GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) 1165 { 1166 switch (featureLevel) 1167 { 1168 case D3D_FEATURE_LEVEL_11_1: 1169 case D3D_FEATURE_LEVEL_11_0: 1170 1171 case D3D_FEATURE_LEVEL_10_1: 1172 case D3D_FEATURE_LEVEL_10_0: 1173 return GetMaximumVertexOutputVectors(featureLevel) * 4; 1174 1175 case D3D_FEATURE_LEVEL_9_3: 1176 case D3D_FEATURE_LEVEL_9_2: 1177 case D3D_FEATURE_LEVEL_9_1: 1178 return 0; 1179 1180 default: 1181 UNREACHABLE(); 1182 return 0; 1183 } 1184 } 1185 1186 int GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) 1187 { 1188 switch (featureLevel) 1189 { 1190 case D3D_FEATURE_LEVEL_11_1: 1191 case D3D_FEATURE_LEVEL_11_0: 1192 return GetMaximumStreamOutputInterleavedComponents(featureLevel) / 1193 GetMaximumStreamOutputBuffers(featureLevel); 1194 1195 // D3D 10 and 10.1 only allow one output per output slot if an output slot other 1196 // than zero is used. 1197 case D3D_FEATURE_LEVEL_10_1: 1198 case D3D_FEATURE_LEVEL_10_0: 1199 return 4; 1200 1201 case D3D_FEATURE_LEVEL_9_3: 1202 case D3D_FEATURE_LEVEL_9_2: 1203 case D3D_FEATURE_LEVEL_9_1: 1204 return 0; 1205 1206 default: 1207 UNREACHABLE(); 1208 return 0; 1209 } 1210 } 1211 1212 int GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel) 1213 { 1214 switch (featureLevel) 1215 { 1216 case D3D_FEATURE_LEVEL_11_1: 1217 case D3D_FEATURE_LEVEL_11_0: 1218 return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; 1219 case D3D_FEATURE_LEVEL_10_1: 1220 case D3D_FEATURE_LEVEL_10_0: 1221 return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; 1222 1223 // REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9, 1224 // use the maximum texture sizes 1225 case D3D_FEATURE_LEVEL_9_3: 1226 return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; 1227 case D3D_FEATURE_LEVEL_9_2: 1228 case D3D_FEATURE_LEVEL_9_1: 1229 return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; 1230 1231 default: 1232 UNREACHABLE(); 1233 return 0; 1234 } 1235 } 1236 1237 IntelDriverVersion GetIntelDriverVersion(const Optional<LARGE_INTEGER> driverVersion) 1238 { 1239 if (!driverVersion.valid()) 1240 return IntelDriverVersion(0); 1241 1242 DWORD lowPart = driverVersion.value().LowPart; 1243 return IntelDriverVersion(HIWORD(lowPart) * 10000 + LOWORD(lowPart)); 1244 } 1245 1246 } // anonymous namespace 1247 1248 unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) 1249 { 1250 switch (featureLevel) 1251 { 1252 case D3D_FEATURE_LEVEL_11_1: 1253 case D3D_FEATURE_LEVEL_11_0: 1254 case D3D_FEATURE_LEVEL_10_1: 1255 case D3D_FEATURE_LEVEL_10_0: 1256 return 0; 1257 1258 case D3D_FEATURE_LEVEL_9_3: 1259 case D3D_FEATURE_LEVEL_9_2: 1260 case D3D_FEATURE_LEVEL_9_1: 1261 return 3; // dx_ViewAdjust, dx_ViewCoords and dx_ViewScale 1262 1263 default: 1264 UNREACHABLE(); 1265 return 0; 1266 } 1267 } 1268 1269 unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel) 1270 { 1271 switch (featureLevel) 1272 { 1273 case D3D_FEATURE_LEVEL_11_1: 1274 case D3D_FEATURE_LEVEL_11_0: 1275 case D3D_FEATURE_LEVEL_10_1: 1276 case D3D_FEATURE_LEVEL_10_0: 1277 return 0; 1278 1279 case D3D_FEATURE_LEVEL_9_3: 1280 case D3D_FEATURE_LEVEL_9_2: 1281 case D3D_FEATURE_LEVEL_9_1: 1282 return 4; // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordOffset 1283 1284 default: 1285 UNREACHABLE(); 1286 return 0; 1287 } 1288 } 1289 1290 gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps) 1291 { 1292 switch (caps.featureLevel) 1293 { 1294 case D3D_FEATURE_LEVEL_11_1: 1295 case D3D_FEATURE_LEVEL_11_0: 1296 return gl::Version(3, 1); 1297 case D3D_FEATURE_LEVEL_10_1: 1298 return gl::Version(3, 0); 1299 1300 case D3D_FEATURE_LEVEL_10_0: 1301 if (caps.allowES3OnFL10_0) 1302 { 1303 return gl::Version(3, 0); 1304 } 1305 else 1306 { 1307 return gl::Version(2, 0); 1308 } 1309 case D3D_FEATURE_LEVEL_9_3: 1310 case D3D_FEATURE_LEVEL_9_2: 1311 case D3D_FEATURE_LEVEL_9_1: 1312 return gl::Version(2, 0); 1313 1314 default: 1315 UNREACHABLE(); 1316 return gl::Version(0, 0); 1317 } 1318 } 1319 1320 D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31() 1321 { 1322 return kMinimumFeatureLevelForES31; 1323 } 1324 1325 unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel) 1326 { 1327 switch (featureLevel) 1328 { 1329 case D3D_FEATURE_LEVEL_11_1: 1330 case D3D_FEATURE_LEVEL_11_0: 1331 return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; 1332 case D3D_FEATURE_LEVEL_10_1: 1333 case D3D_FEATURE_LEVEL_10_0: 1334 case D3D_FEATURE_LEVEL_9_3: 1335 case D3D_FEATURE_LEVEL_9_2: 1336 case D3D_FEATURE_LEVEL_9_1: 1337 return 1; 1338 default: 1339 UNREACHABLE(); 1340 return 0; 1341 } 1342 } 1343 1344 bool IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel) 1345 { 1346 // The ANGLE_multiview extension can always be supported in D3D11 through geometry shaders. 1347 switch (featureLevel) 1348 { 1349 case D3D_FEATURE_LEVEL_11_1: 1350 case D3D_FEATURE_LEVEL_11_0: 1351 return true; 1352 default: 1353 return false; 1354 } 1355 } 1356 1357 int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel) 1358 { 1359 switch (featureLevel) 1360 { 1361 // D3D10+ only allows 1 sample mask. 1362 case D3D_FEATURE_LEVEL_11_1: 1363 case D3D_FEATURE_LEVEL_11_0: 1364 case D3D_FEATURE_LEVEL_10_1: 1365 case D3D_FEATURE_LEVEL_10_0: 1366 return 1; 1367 case D3D_FEATURE_LEVEL_9_3: 1368 case D3D_FEATURE_LEVEL_9_2: 1369 case D3D_FEATURE_LEVEL_9_1: 1370 return 0; 1371 default: 1372 UNREACHABLE(); 1373 return 0; 1374 } 1375 } 1376 1377 bool HasTextureBufferSupport(ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps) 1378 { 1379 if (renderer11DeviceCaps.featureLevel < D3D_FEATURE_LEVEL_11_0) 1380 return false; 1381 1382 if (!renderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats) 1383 return false; 1384 1385 // https://docs.microsoft.com/en-us/windows/win32/direct3d12/typed-unordered-access-view-loads 1386 // we don't need to check the typed store. from the spec, 1387 // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FormatList 1388 // all the following format support typed stored. 1389 // According to spec, 1390 // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glBindImageTexture.xhtml the 1391 // required image unit format are GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I, GL_RGBA16F, GL_RGBA16UI, 1392 // GL_RGBA16I, GL_RGBA8, GL_RGBAUI, GL_RGBA8I, GL_RGBA8_SNORM, GL_R32F, GL_R32UI, GL_R32I, 1393 const std::array<DXGI_FORMAT, 2> &optionalFormats = { 1394 DXGI_FORMAT_R32G32B32A32_FLOAT, // test for GL_RGBA32(UIF), GL_RGBA16(UIF), 1395 // GL_RGBA8(UIUnorm) 1396 DXGI_FORMAT_R8G8B8A8_SNORM, // test for GL_RGBA8_SNORM, 1397 }; 1398 1399 for (DXGI_FORMAT dxgiFormat : optionalFormats) 1400 { 1401 D3D11_FEATURE_DATA_FORMAT_SUPPORT FormatSupport = {dxgiFormat, 0}; 1402 if (!SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &FormatSupport, 1403 sizeof(FormatSupport)))) 1404 { 1405 WARN() << "Error checking typed load support for format 0x" << std::hex << dxgiFormat; 1406 return false; 1407 } 1408 if ((FormatSupport.OutFormatSupport & D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD) == 0) 1409 return false; 1410 } 1411 return true; 1412 } 1413 1414 void GenerateCaps(ID3D11Device *device, 1415 ID3D11DeviceContext *deviceContext, 1416 const Renderer11DeviceCaps &renderer11DeviceCaps, 1417 const angle::FeaturesD3D &features, 1418 const char *description, 1419 gl::Caps *caps, 1420 gl::TextureCapsMap *textureCapsMap, 1421 gl::Extensions *extensions, 1422 gl::Limitations *limitations) 1423 { 1424 D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel; 1425 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); 1426 for (GLenum internalFormat : allFormats) 1427 { 1428 gl::TextureCaps textureCaps = 1429 GenerateTextureFormatCaps(GetMaximumClientVersion(renderer11DeviceCaps), internalFormat, 1430 device, renderer11DeviceCaps); 1431 textureCapsMap->insert(internalFormat, textureCaps); 1432 } 1433 1434 // GL core feature limits 1435 // Reserve MAX_UINT for D3D11's primitive restart. 1436 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max() - 1); 1437 caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel); 1438 caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel); 1439 caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel); 1440 caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel); 1441 1442 // Unimplemented, set to minimum required 1443 caps->maxLODBias = 2.0f; 1444 1445 // No specific limits on render target size, maximum 2D texture size is equivalent 1446 caps->maxRenderbufferSize = caps->max2DTextureSize; 1447 1448 // Maximum draw buffers and color attachments are the same, max color attachments could 1449 // eventually be increased to 16 1450 caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel); 1451 caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel); 1452 1453 // D3D11 has the same limit for viewport width and height 1454 caps->maxViewportWidth = GetMaximumViewportSize(featureLevel); 1455 caps->maxViewportHeight = caps->maxViewportWidth; 1456 1457 // Choose a reasonable maximum, enforced in the shader. 1458 caps->minAliasedPointSize = 1.0f; 1459 caps->maxAliasedPointSize = 1024.0f; 1460 1461 // Wide lines not supported 1462 caps->minAliasedLineWidth = 1.0f; 1463 caps->maxAliasedLineWidth = 1.0f; 1464 1465 // Primitive count limits 1466 caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); 1467 caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); 1468 1469 // Program and shader binary formats (no supported shader binary formats) 1470 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); 1471 1472 caps->vertexHighpFloat.setIEEEFloat(); 1473 caps->vertexMediumpFloat.setIEEEFloat(); 1474 caps->vertexLowpFloat.setIEEEFloat(); 1475 caps->fragmentHighpFloat.setIEEEFloat(); 1476 caps->fragmentMediumpFloat.setIEEEFloat(); 1477 caps->fragmentLowpFloat.setIEEEFloat(); 1478 1479 // 32-bit integers are natively supported 1480 caps->vertexHighpInt.setTwosComplementInt(32); 1481 caps->vertexMediumpInt.setTwosComplementInt(32); 1482 caps->vertexLowpInt.setTwosComplementInt(32); 1483 caps->fragmentHighpInt.setTwosComplementInt(32); 1484 caps->fragmentMediumpInt.setTwosComplementInt(32); 1485 caps->fragmentLowpInt.setTwosComplementInt(32); 1486 1487 // We do not wait for server fence objects internally, so report a max timeout of zero. 1488 caps->maxServerWaitTimeout = 0; 1489 1490 // Vertex shader limits 1491 caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel); 1492 caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel); 1493 if (features.skipVSConstantRegisterZero.enabled) 1494 { 1495 caps->maxVertexUniformVectors -= 1; 1496 } 1497 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4; 1498 caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] = 1499 GetMaximumVertexUniformBlocks(featureLevel); 1500 caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; 1501 caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = 1502 GetMaximumVertexTextureUnits(featureLevel); 1503 1504 // Vertex Attribute Bindings are emulated on D3D11. 1505 caps->maxVertexAttribBindings = caps->maxVertexAttributes; 1506 // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11. 1507 caps->maxVertexAttribRelativeOffset = std::numeric_limits<GLint>::max(); 1508 // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all 1509 // platforms. 1510 caps->maxVertexAttribStride = 2048; 1511 1512 // Fragment shader limits 1513 caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel); 1514 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] = 1515 caps->maxFragmentUniformVectors * 4; 1516 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] = 1517 GetMaximumPixelUniformBlocks(featureLevel); 1518 caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4; 1519 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] = 1520 GetMaximumPixelTextureUnits(featureLevel); 1521 caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); 1522 caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); 1523 1524 // Compute shader limits 1525 caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel); 1526 caps->maxComputeWorkGroupSize = GetMaxComputeWorkGroupSize(featureLevel); 1527 caps->maxComputeWorkGroupInvocations = GetMaxComputeWorkGroupInvocations(featureLevel); 1528 caps->maxComputeSharedMemorySize = GetMaxComputeSharedMemorySize(featureLevel); 1529 caps->maxShaderUniformComponents[gl::ShaderType::Compute] = 1530 GetMaximumComputeUniformVectors(featureLevel) * 4; 1531 caps->maxShaderUniformBlocks[gl::ShaderType::Compute] = 1532 GetMaximumComputeUniformBlocks(featureLevel); 1533 caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] = 1534 GetMaximumComputeTextureUnits(featureLevel); 1535 1536 SetUAVRelatedResourceLimits(featureLevel, caps); 1537 1538 // Aggregate shader limits 1539 caps->maxUniformBufferBindings = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] + 1540 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment]; 1541 caps->maxUniformBlockSize = static_cast<GLuint64>(GetMaximumConstantBufferSize(featureLevel)); 1542 1543 // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1. 1544 caps->maxUniformLocations = 1024; 1545 1546 // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16 1547 // bytes each. 1548 // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx 1549 // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however 1550 // we still keep the same alignment as 11.1 for consistency. 1551 caps->uniformBufferOffsetAlignment = 256; 1552 1553 caps->maxCombinedUniformBlocks = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] + 1554 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment]; 1555 1556 // A shader storage block will be translated to a structure in HLSL. So We reference the HLSL 1557 // structure packing rules 1558 // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx. The 1559 // resulting size of any structure will always be evenly divisible by sizeof(four-component 1560 // vector). 1561 caps->shaderStorageBufferOffsetAlignment = 16; 1562 1563 for (gl::ShaderType shaderType : gl::AllShaderTypes()) 1564 { 1565 caps->maxCombinedShaderUniformComponents[shaderType] = 1566 static_cast<GLint64>(caps->maxShaderUniformBlocks[shaderType]) * 1567 static_cast<GLint64>(caps->maxUniformBlockSize / 4) + 1568 static_cast<GLint64>(caps->maxShaderUniformComponents[shaderType]); 1569 } 1570 1571 caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; 1572 caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel); 1573 caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] + 1574 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment]; 1575 1576 // Transform feedback limits 1577 caps->maxTransformFeedbackInterleavedComponents = 1578 GetMaximumStreamOutputInterleavedComponents(featureLevel); 1579 caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); 1580 caps->maxTransformFeedbackSeparateComponents = 1581 GetMaximumStreamOutputSeparateComponents(featureLevel); 1582 1583 // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values 1584 // are determined according to available sample counts for each individual format. 1585 caps->maxSamples = std::numeric_limits<GLint>::max(); 1586 caps->maxColorTextureSamples = std::numeric_limits<GLint>::max(); 1587 caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max(); 1588 caps->maxIntegerSamples = std::numeric_limits<GLint>::max(); 1589 1590 // Sample mask words limits 1591 caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel); 1592 1593 // Framebuffer limits 1594 caps->maxFramebufferSamples = std::numeric_limits<GLint>::max(); 1595 caps->maxFramebufferWidth = GetMaximumRenderToBufferWindowSize(featureLevel); 1596 caps->maxFramebufferHeight = caps->maxFramebufferWidth; 1597 1598 // Texture gather offset limits 1599 caps->minProgramTextureGatherOffset = GetMinimumTextureGatherOffset(featureLevel); 1600 caps->maxProgramTextureGatherOffset = GetMaximumTextureGatherOffset(featureLevel); 1601 1602 caps->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel); 1603 caps->queryCounterBitsTimeElapsed = 64; 1604 caps->queryCounterBitsTimestamp = 0; // Timestamps cannot be supported due to D3D11 limitations 1605 caps->maxDualSourceDrawBuffers = 1; 1606 1607 // GL extension support 1608 extensions->setTextureExtensionSupport(*textureCapsMap); 1609 1610 // Explicitly disable GL_OES_compressed_ETC1_RGB8_texture because it's emulated and never 1611 // becomes core. WebGL doesn't want to expose it unless there is native support. 1612 extensions->compressedETC1RGB8TextureOES = false; 1613 extensions->compressedETC1RGB8SubTextureEXT = false; 1614 1615 extensions->elementIndexUintOES = true; 1616 extensions->getProgramBinaryOES = true; 1617 extensions->rgb8Rgba8OES = true; 1618 extensions->readFormatBgraEXT = true; 1619 extensions->pixelBufferObjectNV = true; 1620 extensions->mapbufferOES = true; 1621 extensions->mapBufferRangeEXT = true; 1622 extensions->textureNpotOES = GetNPOTTextureSupport(featureLevel); 1623 extensions->drawBuffersEXT = GetMaximumSimultaneousRenderTargets(featureLevel) > 1; 1624 extensions->drawBuffersIndexedEXT = 1625 (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_1); 1626 extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT; 1627 extensions->textureStorageEXT = true; 1628 extensions->textureFilterAnisotropicEXT = true; 1629 extensions->occlusionQueryBooleanEXT = GetOcclusionQuerySupport(featureLevel); 1630 extensions->fenceNV = GetEventQuerySupport(featureLevel); 1631 extensions->disjointTimerQueryEXT = true; 1632 extensions->robustnessEXT = true; 1633 // Direct3D guarantees to return zero for any resource that is accessed out of bounds. 1634 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx 1635 // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx 1636 extensions->robustBufferAccessBehaviorKHR = true; 1637 extensions->blendMinmaxEXT = true; 1638 // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware 1639 extensions->floatBlendEXT = true; 1640 extensions->framebufferBlitANGLE = GetFramebufferBlitSupport(featureLevel); 1641 extensions->framebufferBlitNV = extensions->framebufferBlitANGLE; 1642 extensions->framebufferMultisampleANGLE = GetFramebufferMultisampleSupport(featureLevel); 1643 extensions->instancedArraysANGLE = GetInstancingSupport(featureLevel); 1644 extensions->instancedArraysEXT = GetInstancingSupport(featureLevel); 1645 extensions->packReverseRowOrderANGLE = true; 1646 extensions->standardDerivativesOES = GetDerivativeInstructionSupport(featureLevel); 1647 extensions->shaderTextureLodEXT = GetShaderTextureLODSupport(featureLevel); 1648 extensions->fragDepthEXT = true; 1649 extensions->multiviewOVR = IsMultiviewSupported(featureLevel); 1650 extensions->multiview2OVR = IsMultiviewSupported(featureLevel); 1651 if (extensions->multiviewOVR || extensions->multiview2OVR) 1652 { 1653 caps->maxViews = std::min(static_cast<GLuint>(GetMaximum2DTextureArraySize(featureLevel)), 1654 GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel)); 1655 } 1656 extensions->textureUsageANGLE = true; // This could be false since it has no effect in D3D11 1657 extensions->discardFramebufferEXT = true; 1658 extensions->translatedShaderSourceANGLE = true; 1659 extensions->fboRenderMipmapOES = true; 1660 extensions->debugMarkerEXT = true; 1661 extensions->EGLImageOES = true; 1662 extensions->EGLImageExternalOES = true; 1663 extensions->EGLImageExternalWrapModesEXT = true; 1664 extensions->EGLImageExternalEssl3OES = true; 1665 extensions->EGLStreamConsumerExternalNV = true; 1666 extensions->unpackSubimageEXT = true; 1667 extensions->packSubimageNV = true; 1668 extensions->lossyEtcDecodeANGLE = true; 1669 extensions->syncQueryCHROMIUM = GetEventQuerySupport(featureLevel); 1670 extensions->copyTextureCHROMIUM = true; 1671 extensions->copyCompressedTextureCHROMIUM = true; 1672 extensions->textureStorageMultisample2dArrayOES = true; 1673 extensions->multiviewMultisampleANGLE = 1674 ((extensions->multiviewOVR || extensions->multiview2OVR) && 1675 extensions->textureStorageMultisample2dArrayOES); 1676 extensions->copyTexture3dANGLE = true; 1677 extensions->textureBorderClampOES = true; 1678 extensions->multiDrawIndirectEXT = true; 1679 extensions->textureMultisampleANGLE = true; 1680 extensions->provokingVertexANGLE = true; 1681 extensions->blendFuncExtendedEXT = true; 1682 // http://anglebug.com/4926 1683 extensions->texture3DOES = false; 1684 extensions->baseInstanceEXT = true; 1685 extensions->baseVertexBaseInstanceANGLE = true; 1686 extensions->baseVertexBaseInstanceShaderBuiltinANGLE = true; 1687 extensions->drawElementsBaseVertexOES = true; 1688 extensions->drawElementsBaseVertexEXT = true; 1689 if (!strstr(description, "Adreno")) 1690 { 1691 extensions->multisampledRenderToTextureEXT = true; 1692 } 1693 extensions->videoTextureWEBGL = true; 1694 1695 // D3D11 cannot support reading depth texture as a luminance texture. 1696 // It treats it as a red-channel-only texture. 1697 extensions->depthTextureOES = false; 1698 1699 // readPixels on depth & stencil not working with D3D11 backend. 1700 extensions->readDepthNV = false; 1701 extensions->readStencilNV = false; 1702 extensions->depthBufferFloat2NV = false; 1703 1704 // GL_EXT_clip_control 1705 extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3); 1706 1707 // GL_KHR_parallel_shader_compile 1708 extensions->parallelShaderCompileKHR = true; 1709 1710 // GL_EXT_texture_buffer 1711 extensions->textureBufferEXT = HasTextureBufferSupport(device, renderer11DeviceCaps); 1712 1713 // GL_OES_texture_buffer 1714 extensions->textureBufferOES = extensions->textureBufferEXT; 1715 1716 // ANGLE_shader_pixel_local_storage -- fragment shader UAVs appear in D3D 11.0. 1717 extensions->shaderPixelLocalStorageANGLE = (featureLevel >= D3D_FEATURE_LEVEL_11_0); 1718 extensions->shaderPixelLocalStorageCoherentANGLE = 1719 renderer11DeviceCaps.supportsRasterizerOrderViews; 1720 1721 // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. 1722 // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't 1723 // support gl_FrontFacing. 1724 limitations->noFrontFacingSupport = 1725 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); 1726 1727 // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage 1728 limitations->noSampleAlphaToCoverageSupport = 1729 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); 1730 1731 // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require 1732 // additional 1733 // pre-validation of the shader at compile time to produce a better error message. 1734 limitations->shadersRequireIndexedLoopValidation = 1735 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); 1736 1737 // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil 1738 // state. 1739 limitations->noSeparateStencilRefsAndMasks = true; 1740 1741 // D3D11 cannot support constant color and alpha blend funcs together 1742 limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true; 1743 1744 // D3D11 does not support multiple transform feedback outputs writing to the same buffer. 1745 limitations->noDoubleBoundTransformFeedbackBuffers = true; 1746 1747 // D3D11 does not support vertex attribute aliasing 1748 limitations->noVertexAttributeAliasing = true; 1749 1750 // D3D11 does not support compressed textures where the base mip level is not a multiple of 4 1751 limitations->compressedBaseMipLevelMultipleOfFour = true; 1752 1753 if (extensions->textureBufferAny()) 1754 { 1755 caps->maxTextureBufferSize = 1 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP; 1756 // this maybe touble for RGB32 format. 1757 caps->textureBufferOffsetAlignment = 16; 1758 } 1759 1760 #ifdef ANGLE_ENABLE_WINDOWS_UWP 1761 // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era 1762 // devices. We should prevent developers from doing this on ALL Windows Store devices. This will 1763 // maintain consistency across all Windows devices. We allow non-zero divisors on attribute zero 1764 // if the Client Version >= 3, since devices affected by this issue don't support ES3+. 1765 limitations->attributeZeroRequiresZeroDivisorInEXT = true; 1766 #endif 1767 } 1768 1769 } // namespace d3d11_gl 1770 1771 namespace gl_d3d11 1772 { 1773 1774 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) 1775 { 1776 D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; 1777 1778 switch (glBlend) 1779 { 1780 case GL_ZERO: 1781 d3dBlend = D3D11_BLEND_ZERO; 1782 break; 1783 case GL_ONE: 1784 d3dBlend = D3D11_BLEND_ONE; 1785 break; 1786 case GL_SRC_COLOR: 1787 d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); 1788 break; 1789 case GL_ONE_MINUS_SRC_COLOR: 1790 d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); 1791 break; 1792 case GL_DST_COLOR: 1793 d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); 1794 break; 1795 case GL_ONE_MINUS_DST_COLOR: 1796 d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); 1797 break; 1798 case GL_SRC_ALPHA: 1799 d3dBlend = D3D11_BLEND_SRC_ALPHA; 1800 break; 1801 case GL_ONE_MINUS_SRC_ALPHA: 1802 d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; 1803 break; 1804 case GL_DST_ALPHA: 1805 d3dBlend = D3D11_BLEND_DEST_ALPHA; 1806 break; 1807 case GL_ONE_MINUS_DST_ALPHA: 1808 d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; 1809 break; 1810 case GL_CONSTANT_COLOR: 1811 d3dBlend = D3D11_BLEND_BLEND_FACTOR; 1812 break; 1813 case GL_ONE_MINUS_CONSTANT_COLOR: 1814 d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; 1815 break; 1816 case GL_CONSTANT_ALPHA: 1817 d3dBlend = D3D11_BLEND_BLEND_FACTOR; 1818 break; 1819 case GL_ONE_MINUS_CONSTANT_ALPHA: 1820 d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; 1821 break; 1822 case GL_SRC_ALPHA_SATURATE: 1823 d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; 1824 break; 1825 case GL_SRC1_COLOR_EXT: 1826 d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR); 1827 break; 1828 case GL_SRC1_ALPHA_EXT: 1829 d3dBlend = D3D11_BLEND_SRC1_ALPHA; 1830 break; 1831 case GL_ONE_MINUS_SRC1_COLOR_EXT: 1832 d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR); 1833 break; 1834 case GL_ONE_MINUS_SRC1_ALPHA_EXT: 1835 d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA; 1836 break; 1837 default: 1838 UNREACHABLE(); 1839 } 1840 1841 return d3dBlend; 1842 } 1843 1844 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) 1845 { 1846 D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; 1847 1848 switch (glBlendOp) 1849 { 1850 case GL_FUNC_ADD: 1851 d3dBlendOp = D3D11_BLEND_OP_ADD; 1852 break; 1853 case GL_FUNC_SUBTRACT: 1854 d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; 1855 break; 1856 case GL_FUNC_REVERSE_SUBTRACT: 1857 d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; 1858 break; 1859 case GL_MIN: 1860 d3dBlendOp = D3D11_BLEND_OP_MIN; 1861 break; 1862 case GL_MAX: 1863 d3dBlendOp = D3D11_BLEND_OP_MAX; 1864 break; 1865 default: 1866 UNREACHABLE(); 1867 } 1868 1869 return d3dBlendOp; 1870 } 1871 1872 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) 1873 { 1874 UINT8 mask = 0; 1875 if (red) 1876 { 1877 mask |= D3D11_COLOR_WRITE_ENABLE_RED; 1878 } 1879 if (green) 1880 { 1881 mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; 1882 } 1883 if (blue) 1884 { 1885 mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; 1886 } 1887 if (alpha) 1888 { 1889 mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; 1890 } 1891 return mask; 1892 } 1893 1894 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode) 1895 { 1896 D3D11_CULL_MODE cull = D3D11_CULL_NONE; 1897 1898 if (cullEnabled) 1899 { 1900 switch (cullMode) 1901 { 1902 case gl::CullFaceMode::Front: 1903 cull = D3D11_CULL_FRONT; 1904 break; 1905 case gl::CullFaceMode::Back: 1906 cull = D3D11_CULL_BACK; 1907 break; 1908 case gl::CullFaceMode::FrontAndBack: 1909 cull = D3D11_CULL_NONE; 1910 break; 1911 default: 1912 UNREACHABLE(); 1913 } 1914 } 1915 else 1916 { 1917 cull = D3D11_CULL_NONE; 1918 } 1919 1920 return cull; 1921 } 1922 1923 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) 1924 { 1925 D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; 1926 switch (comparison) 1927 { 1928 case GL_NEVER: 1929 d3dComp = D3D11_COMPARISON_NEVER; 1930 break; 1931 case GL_ALWAYS: 1932 d3dComp = D3D11_COMPARISON_ALWAYS; 1933 break; 1934 case GL_LESS: 1935 d3dComp = D3D11_COMPARISON_LESS; 1936 break; 1937 case GL_LEQUAL: 1938 d3dComp = D3D11_COMPARISON_LESS_EQUAL; 1939 break; 1940 case GL_EQUAL: 1941 d3dComp = D3D11_COMPARISON_EQUAL; 1942 break; 1943 case GL_GREATER: 1944 d3dComp = D3D11_COMPARISON_GREATER; 1945 break; 1946 case GL_GEQUAL: 1947 d3dComp = D3D11_COMPARISON_GREATER_EQUAL; 1948 break; 1949 case GL_NOTEQUAL: 1950 d3dComp = D3D11_COMPARISON_NOT_EQUAL; 1951 break; 1952 default: 1953 UNREACHABLE(); 1954 } 1955 1956 return d3dComp; 1957 } 1958 1959 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) 1960 { 1961 return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; 1962 } 1963 1964 UINT8 ConvertStencilMask(GLuint stencilmask) 1965 { 1966 return static_cast<UINT8>(stencilmask); 1967 } 1968 1969 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) 1970 { 1971 D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; 1972 1973 switch (stencilOp) 1974 { 1975 case GL_ZERO: 1976 d3dStencilOp = D3D11_STENCIL_OP_ZERO; 1977 break; 1978 case GL_KEEP: 1979 d3dStencilOp = D3D11_STENCIL_OP_KEEP; 1980 break; 1981 case GL_REPLACE: 1982 d3dStencilOp = D3D11_STENCIL_OP_REPLACE; 1983 break; 1984 case GL_INCR: 1985 d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; 1986 break; 1987 case GL_DECR: 1988 d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; 1989 break; 1990 case GL_INVERT: 1991 d3dStencilOp = D3D11_STENCIL_OP_INVERT; 1992 break; 1993 case GL_INCR_WRAP: 1994 d3dStencilOp = D3D11_STENCIL_OP_INCR; 1995 break; 1996 case GL_DECR_WRAP: 1997 d3dStencilOp = D3D11_STENCIL_OP_DECR; 1998 break; 1999 default: 2000 UNREACHABLE(); 2001 } 2002 2003 return d3dStencilOp; 2004 } 2005 2006 D3D11_FILTER ConvertFilter(GLenum minFilter, 2007 GLenum magFilter, 2008 float maxAnisotropy, 2009 GLenum comparisonMode) 2010 { 2011 bool comparison = comparisonMode != GL_NONE; 2012 2013 if (maxAnisotropy > 1.0f) 2014 { 2015 return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison)); 2016 } 2017 else 2018 { 2019 D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; 2020 D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; 2021 switch (minFilter) 2022 { 2023 case GL_NEAREST: 2024 dxMin = D3D11_FILTER_TYPE_POINT; 2025 dxMip = D3D11_FILTER_TYPE_POINT; 2026 break; 2027 case GL_LINEAR: 2028 dxMin = D3D11_FILTER_TYPE_LINEAR; 2029 dxMip = D3D11_FILTER_TYPE_POINT; 2030 break; 2031 case GL_NEAREST_MIPMAP_NEAREST: 2032 dxMin = D3D11_FILTER_TYPE_POINT; 2033 dxMip = D3D11_FILTER_TYPE_POINT; 2034 break; 2035 case GL_LINEAR_MIPMAP_NEAREST: 2036 dxMin = D3D11_FILTER_TYPE_LINEAR; 2037 dxMip = D3D11_FILTER_TYPE_POINT; 2038 break; 2039 case GL_NEAREST_MIPMAP_LINEAR: 2040 dxMin = D3D11_FILTER_TYPE_POINT; 2041 dxMip = D3D11_FILTER_TYPE_LINEAR; 2042 break; 2043 case GL_LINEAR_MIPMAP_LINEAR: 2044 dxMin = D3D11_FILTER_TYPE_LINEAR; 2045 dxMip = D3D11_FILTER_TYPE_LINEAR; 2046 break; 2047 default: 2048 UNREACHABLE(); 2049 } 2050 2051 D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; 2052 switch (magFilter) 2053 { 2054 case GL_NEAREST: 2055 dxMag = D3D11_FILTER_TYPE_POINT; 2056 break; 2057 case GL_LINEAR: 2058 dxMag = D3D11_FILTER_TYPE_LINEAR; 2059 break; 2060 default: 2061 UNREACHABLE(); 2062 } 2063 2064 return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, 2065 static_cast<D3D11_COMPARISON_FUNC>(comparison)); 2066 } 2067 } 2068 2069 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) 2070 { 2071 switch (wrap) 2072 { 2073 case GL_REPEAT: 2074 return D3D11_TEXTURE_ADDRESS_WRAP; 2075 case GL_CLAMP_TO_EDGE: 2076 return D3D11_TEXTURE_ADDRESS_CLAMP; 2077 case GL_CLAMP_TO_BORDER: 2078 return D3D11_TEXTURE_ADDRESS_BORDER; 2079 case GL_MIRRORED_REPEAT: 2080 return D3D11_TEXTURE_ADDRESS_MIRROR; 2081 default: 2082 UNREACHABLE(); 2083 } 2084 2085 return D3D11_TEXTURE_ADDRESS_WRAP; 2086 } 2087 2088 UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel) 2089 { 2090 return static_cast<UINT>(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel))); 2091 } 2092 2093 D3D11_QUERY ConvertQueryType(gl::QueryType type) 2094 { 2095 switch (type) 2096 { 2097 case gl::QueryType::AnySamples: 2098 case gl::QueryType::AnySamplesConservative: 2099 return D3D11_QUERY_OCCLUSION; 2100 case gl::QueryType::TransformFeedbackPrimitivesWritten: 2101 return D3D11_QUERY_SO_STATISTICS; 2102 case gl::QueryType::TimeElapsed: 2103 // Two internal queries are also created for begin/end timestamps 2104 return D3D11_QUERY_TIMESTAMP_DISJOINT; 2105 case gl::QueryType::CommandsCompleted: 2106 return D3D11_QUERY_EVENT; 2107 default: 2108 UNREACHABLE(); 2109 return D3D11_QUERY_EVENT; 2110 } 2111 } 2112 2113 // Get the D3D11 write mask covering all color channels of a given format 2114 UINT8 GetColorMask(const gl::InternalFormat &format) 2115 { 2116 return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0, 2117 format.alphaBits > 0); 2118 } 2119 2120 } // namespace gl_d3d11 2121 2122 namespace d3d11 2123 { 2124 2125 ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) 2126 { 2127 // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value, 2128 // since it is difficult to tell Software and Reference devices apart 2129 2130 IDXGIDevice *dxgiDevice = nullptr; 2131 IDXGIAdapter *dxgiAdapter = nullptr; 2132 IDXGIAdapter2 *dxgiAdapter2 = nullptr; 2133 2134 ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN; 2135 2136 HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice); 2137 if (SUCCEEDED(hr)) 2138 { 2139 hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter); 2140 if (SUCCEEDED(hr)) 2141 { 2142 std::wstring adapterString; 2143 HRESULT adapter2hr = 2144 dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2); 2145 if (SUCCEEDED(adapter2hr)) 2146 { 2147 // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" 2148 // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the 2149 // actual hardware values if possible. 2150 DXGI_ADAPTER_DESC2 adapterDesc2; 2151 dxgiAdapter2->GetDesc2(&adapterDesc2); 2152 adapterString = std::wstring(adapterDesc2.Description); 2153 } 2154 else 2155 { 2156 DXGI_ADAPTER_DESC adapterDesc; 2157 dxgiAdapter->GetDesc(&adapterDesc); 2158 adapterString = std::wstring(adapterDesc.Description); 2159 } 2160 2161 // Both Reference and Software adapters will be 'Software Adapter' 2162 const bool isSoftwareDevice = 2163 (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos); 2164 const bool isNullDevice = (adapterString == L""); 2165 const bool isWARPDevice = 2166 (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos); 2167 2168 if (isSoftwareDevice || isNullDevice) 2169 { 2170 ASSERT(!isWARPDevice); 2171 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL; 2172 } 2173 else if (isWARPDevice) 2174 { 2175 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP; 2176 } 2177 else 2178 { 2179 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE; 2180 } 2181 } 2182 } 2183 2184 SafeRelease(dxgiDevice); 2185 SafeRelease(dxgiAdapter); 2186 SafeRelease(dxgiAdapter2); 2187 2188 return retDeviceType; 2189 } 2190 2191 void MakeValidSize(bool isImage, 2192 DXGI_FORMAT format, 2193 GLsizei *requestWidth, 2194 GLsizei *requestHeight, 2195 int *levelOffset) 2196 { 2197 const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format); 2198 bool validFormat = format != DXGI_FORMAT_UNKNOWN; 2199 bool validImage = isImage && validFormat; 2200 2201 int upsampleCount = 0; 2202 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. 2203 if (validImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) || 2204 *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight)) 2205 { 2206 while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || 2207 *requestHeight % dxgiFormatInfo.blockHeight != 0) 2208 { 2209 *requestWidth <<= 1; 2210 *requestHeight <<= 1; 2211 upsampleCount++; 2212 } 2213 } 2214 else if (validFormat) 2215 { 2216 if (*requestWidth % dxgiFormatInfo.blockWidth != 0) 2217 { 2218 *requestWidth = roundUp(*requestWidth, static_cast<GLsizei>(dxgiFormatInfo.blockWidth)); 2219 } 2220 2221 if (*requestHeight % dxgiFormatInfo.blockHeight != 0) 2222 { 2223 *requestHeight = 2224 roundUp(*requestHeight, static_cast<GLsizei>(dxgiFormatInfo.blockHeight)); 2225 } 2226 } 2227 2228 if (levelOffset) 2229 { 2230 *levelOffset = upsampleCount; 2231 } 2232 } 2233 2234 angle::Result GenerateInitialTextureData( 2235 const gl::Context *context, 2236 GLint internalFormat, 2237 const Renderer11DeviceCaps &renderer11DeviceCaps, 2238 GLuint width, 2239 GLuint height, 2240 GLuint depth, 2241 GLuint mipLevels, 2242 gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData) 2243 { 2244 const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); 2245 ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr); 2246 2247 const d3d11::DXGIFormatSize &dxgiFormatInfo = 2248 d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat); 2249 2250 using CheckedSize = angle::CheckedNumeric<size_t>; 2251 CheckedSize rowPitch = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width); 2252 CheckedSize depthPitch = rowPitch * CheckedSize(height); 2253 CheckedSize maxImageSize = depthPitch * CheckedSize(depth); 2254 2255 Context11 *context11 = GetImplAs<Context11>(context); 2256 ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid()); 2257 2258 angle::MemoryBuffer *scratchBuffer = nullptr; 2259 ANGLE_CHECK_GL_ALLOC(context11, 2260 context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer)); 2261 2262 d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(), 2263 rowPitch.ValueOrDie(), depthPitch.ValueOrDie()); 2264 2265 for (unsigned int i = 0; i < mipLevels; i++) 2266 { 2267 unsigned int mipWidth = std::max(width >> i, 1U); 2268 unsigned int mipHeight = std::max(height >> i, 1U); 2269 2270 using CheckedUINT = angle::CheckedNumeric<UINT>; 2271 CheckedUINT mipRowPitch = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth); 2272 CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight); 2273 2274 ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid()); 2275 2276 outSubresourceData->at(i).pSysMem = scratchBuffer->data(); 2277 outSubresourceData->at(i).SysMemPitch = mipRowPitch.ValueOrDie(); 2278 outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie(); 2279 } 2280 2281 return angle::Result::Continue; 2282 } 2283 2284 UINT GetPrimitiveRestartIndex() 2285 { 2286 return std::numeric_limits<UINT>::max(); 2287 } 2288 2289 void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v) 2290 { 2291 vertex->x = x; 2292 vertex->y = y; 2293 vertex->u = u; 2294 vertex->v = v; 2295 } 2296 2297 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex, 2298 float x, 2299 float y, 2300 unsigned int layer, 2301 float u, 2302 float v, 2303 float s) 2304 { 2305 vertex->x = x; 2306 vertex->y = y; 2307 vertex->l = layer; 2308 vertex->u = u; 2309 vertex->v = v; 2310 vertex->s = s; 2311 } 2312 2313 BlendStateKey::BlendStateKey() 2314 { 2315 memset(this, 0, sizeof(BlendStateKey)); 2316 blendStateExt = gl::BlendStateExt(); 2317 } 2318 2319 BlendStateKey::BlendStateKey(const BlendStateKey &other) 2320 { 2321 memcpy(this, &other, sizeof(BlendStateKey)); 2322 } 2323 2324 bool operator==(const BlendStateKey &a, const BlendStateKey &b) 2325 { 2326 return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; 2327 } 2328 2329 bool operator!=(const BlendStateKey &a, const BlendStateKey &b) 2330 { 2331 return !(a == b); 2332 } 2333 2334 RasterizerStateKey::RasterizerStateKey() 2335 { 2336 memset(this, 0, sizeof(RasterizerStateKey)); 2337 } 2338 2339 bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b) 2340 { 2341 return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; 2342 } 2343 2344 bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b) 2345 { 2346 return !(a == b); 2347 } 2348 2349 HRESULT SetDebugName(ID3D11DeviceChild *resource, 2350 const char *internalName, 2351 const std::string *khrDebugName) 2352 { 2353 // Prepend ANGLE to separate names from other components in the same process. 2354 std::string d3dName = "ANGLE"; 2355 bool sendNameToD3D = false; 2356 if (internalName && internalName[0] != '\0') 2357 { 2358 d3dName += std::string("_") + internalName; 2359 sendNameToD3D = true; 2360 } 2361 if (khrDebugName && !khrDebugName->empty()) 2362 { 2363 d3dName += std::string("_") + *khrDebugName; 2364 sendNameToD3D = true; 2365 } 2366 // If both internalName and khrDebugName are empty, avoid sending the string to d3d. 2367 if (sendNameToD3D) 2368 { 2369 return resource->SetPrivateData(WKPDID_D3DDebugObjectName, 2370 static_cast<UINT>(d3dName.size()), d3dName.c_str()); 2371 } 2372 return S_OK; 2373 } 2374 2375 // Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling 2376 // allocateResource is only compatible with Clang and MSVS, which support calling a 2377 // method on a forward declared class in a template. 2378 template <ResourceType ResourceT> 2379 angle::Result LazyResource<ResourceT>::resolveImpl(d3d::Context *context, 2380 Renderer11 *renderer, 2381 const GetDescType<ResourceT> &desc, 2382 GetInitDataType<ResourceT> *initData, 2383 const char *name) 2384 { 2385 if (!mResource.valid()) 2386 { 2387 ANGLE_TRY(renderer->allocateResource(context, desc, initData, &mResource)); 2388 mResource.setInternalName(name); 2389 } 2390 return angle::Result::Continue; 2391 } 2392 2393 template angle::Result LazyResource<ResourceType::BlendState>::resolveImpl( 2394 d3d::Context *context, 2395 Renderer11 *renderer, 2396 const D3D11_BLEND_DESC &desc, 2397 void *initData, 2398 const char *name); 2399 template angle::Result LazyResource<ResourceType::ComputeShader>::resolveImpl( 2400 d3d::Context *context, 2401 Renderer11 *renderer, 2402 const ShaderData &desc, 2403 void *initData, 2404 const char *name); 2405 template angle::Result LazyResource<ResourceType::GeometryShader>::resolveImpl( 2406 d3d::Context *context, 2407 Renderer11 *renderer, 2408 const ShaderData &desc, 2409 const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData, 2410 const char *name); 2411 template angle::Result LazyResource<ResourceType::InputLayout>::resolveImpl( 2412 d3d::Context *context, 2413 Renderer11 *renderer, 2414 const InputElementArray &desc, 2415 const ShaderData *initData, 2416 const char *name); 2417 template angle::Result LazyResource<ResourceType::PixelShader>::resolveImpl(d3d::Context *context, 2418 Renderer11 *renderer, 2419 const ShaderData &desc, 2420 void *initData, 2421 const char *name); 2422 template angle::Result LazyResource<ResourceType::VertexShader>::resolveImpl(d3d::Context *context, 2423 Renderer11 *renderer, 2424 const ShaderData &desc, 2425 void *initData, 2426 const char *name); 2427 2428 LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, 2429 size_t inputDescLen, 2430 const BYTE *byteCode, 2431 size_t byteCodeLen, 2432 const char *debugName) 2433 : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName) 2434 {} 2435 2436 LazyInputLayout::~LazyInputLayout() {} 2437 2438 angle::Result LazyInputLayout::resolve(d3d::Context *context, Renderer11 *renderer) 2439 { 2440 return resolveImpl(context, renderer, mInputDesc, &mByteCode, mDebugName); 2441 } 2442 2443 LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName) 2444 : mDesc(desc), mDebugName(debugName) 2445 {} 2446 2447 angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *renderer) 2448 { 2449 return resolveImpl(context, renderer, mDesc, nullptr, mDebugName); 2450 } 2451 2452 void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps, 2453 const DXGI_ADAPTER_DESC &adapterDesc, 2454 angle::FeaturesD3D *features) 2455 { 2456 bool isNvidia = IsNvidia(adapterDesc.VendorId); 2457 bool isIntel = IsIntel(adapterDesc.VendorId); 2458 bool isSkylake = false; 2459 bool isBroadwell = false; 2460 bool isHaswell = false; 2461 bool isIvyBridge = false; 2462 bool isSandyBridge = false; 2463 bool isAMD = IsAMD(adapterDesc.VendorId); 2464 bool isFeatureLevel9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); 2465 2466 IntelDriverVersion capsVersion = IntelDriverVersion(0); 2467 if (isIntel) 2468 { 2469 capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion); 2470 2471 isSkylake = IsSkylake(adapterDesc.DeviceId); 2472 isBroadwell = IsBroadwell(adapterDesc.DeviceId); 2473 isHaswell = IsHaswell(adapterDesc.DeviceId); 2474 isIvyBridge = IsIvyBridge(adapterDesc.DeviceId); 2475 isSandyBridge = IsSandyBridge(adapterDesc.DeviceId); 2476 } 2477 2478 if (isNvidia) 2479 { 2480 // TODO(jmadill): Narrow problematic driver range. 2481 bool driverVersionValid = deviceCaps.driverVersion.valid(); 2482 if (driverVersionValid) 2483 { 2484 WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart); 2485 WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart); 2486 2487 // Disable the workaround to fix a second driver bug on newer NVIDIA. 2488 ANGLE_FEATURE_CONDITION( 2489 features, depthStencilBlitExtraCopy, 2490 (part1 <= 13u && part2 < 6881) && isNvidia && driverVersionValid); 2491 } 2492 else 2493 { 2494 ANGLE_FEATURE_CONDITION(features, depthStencilBlitExtraCopy, 2495 isNvidia && !driverVersionValid); 2496 } 2497 } 2498 2499 ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true); 2500 ANGLE_FEATURE_CONDITION(features, zeroMaxLodWorkaround, isFeatureLevel9_3); 2501 ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, isFeatureLevel9_3); 2502 ANGLE_FEATURE_CONDITION(features, allowES3OnFL100, false); 2503 2504 // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. 2505 ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true); 2506 2507 ANGLE_FEATURE_CONDITION(features, flushAfterEndingTransformFeedback, isNvidia); 2508 ANGLE_FEATURE_CONDITION(features, getDimensionsIgnoresBaseLevel, isNvidia); 2509 ANGLE_FEATURE_CONDITION(features, skipVSConstantRegisterZero, isNvidia); 2510 ANGLE_FEATURE_CONDITION(features, forceAtomicValueResolution, isNvidia); 2511 2512 ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, isIntel); 2513 ANGLE_FEATURE_CONDITION(features, useSystemMemoryForConstantBuffers, isIntel); 2514 2515 // ClearView on Skylake seems to incorrectly clear with unaligned rects (edge has saw tooth 2516 // pattern instead of straight). 2517 ANGLE_FEATURE_CONDITION(features, scissoredClearArtifacts, isIntel && isSkylake); 2518 2519 ANGLE_FEATURE_CONDITION(features, callClearTwice, 2520 isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) && 2521 capsVersion < IntelDriverVersion(164771)); 2522 ANGLE_FEATURE_CONDITION(features, emulateIsnanFloat, 2523 isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) && 2524 capsVersion < IntelDriverVersion(164542)); 2525 ANGLE_FEATURE_CONDITION(features, rewriteUnaryMinusOperator, 2526 isIntel && (isBroadwell || isHaswell) && 2527 capsVersion >= IntelDriverVersion(150000) && 2528 capsVersion < IntelDriverVersion(154624)); 2529 2530 ANGLE_FEATURE_CONDITION(features, addMockTextureNoRenderTarget, 2531 isIntel && capsVersion >= IntelDriverVersion(160000) && 2532 capsVersion < IntelDriverVersion(164815)); 2533 2534 // Haswell drivers occasionally corrupt (small?) (vertex?) texture data uploads for 128bit 2535 // formats. 2536 ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, true); 2537 ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, 2538 !(isIvyBridge || isBroadwell || isHaswell)); 2539 2540 ANGLE_FEATURE_CONDITION(features, emulateClearViewAfterDualSourceBlending, isSandyBridge); 2541 2542 ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support, 2543 (isIntel && capsVersion >= IntelDriverVersion(150000) && 2544 capsVersion < IntelDriverVersion(154539)) || 2545 isAMD); 2546 2547 // TODO(jmadill): Disable when we have a fixed driver version. 2548 // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a 2549 // depth stencil texture. This is not allowed until feature level 10.1 but since it is not 2550 // possible to support ES3 on these devices, there is no need for the workaround to begin with 2551 // (anglebug.com/1572). 2552 ANGLE_FEATURE_CONDITION(features, emulateTinyStencilTextures, 2553 isAMD && !(deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1)); 2554 2555 // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to 2556 // select the viewport / RT array index in the geometry shader. 2557 ANGLE_FEATURE_CONDITION(features, selectViewInGeometryShader, 2558 !deviceCaps.supportsVpRtIndexWriteFromVertexShader); 2559 2560 // NVidia drivers have no trouble clearing textures without showing corruption. 2561 // Intel and AMD drivers that have trouble have been blocklisted by Chromium. In the case of 2562 // Intel, they've been blocklisted to the DX9 runtime. 2563 ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true); 2564 2565 // Allow translating uniform block to StructuredBuffer on Windows 10. This is targeted 2566 // to work around a slow fxc compile performance issue with dynamic uniform indexing. 2567 ANGLE_FEATURE_CONDITION(features, allowTranslateUniformBlockToStructuredBuffer, 2568 IsWin10OrGreater()); 2569 } 2570 2571 void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc, 2572 angle::FrontendFeatures *features) 2573 { 2574 bool isAMD = IsAMD(adapterDesc.VendorId); 2575 2576 ANGLE_FEATURE_CONDITION(features, forceDepthAttachmentInitOnClear, isAMD); 2577 } 2578 2579 void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth) 2580 { 2581 constantBufferDescription->ByteWidth = static_cast<UINT>(byteWidth); 2582 constantBufferDescription->Usage = D3D11_USAGE_DYNAMIC; 2583 constantBufferDescription->BindFlags = D3D11_BIND_CONSTANT_BUFFER; 2584 constantBufferDescription->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 2585 constantBufferDescription->MiscFlags = 0; 2586 constantBufferDescription->StructureByteStride = 0; 2587 } 2588 2589 } // namespace d3d11 2590 2591 // TextureHelper11 implementation. 2592 TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) {} 2593 2594 TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11() 2595 { 2596 *this = std::move(toCopy); 2597 } 2598 2599 TextureHelper11::TextureHelper11(const TextureHelper11 &other) 2600 : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount) 2601 { 2602 mData = other.mData; 2603 } 2604 2605 TextureHelper11::~TextureHelper11() {} 2606 2607 void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const 2608 { 2609 static_cast<ID3D11Texture2D *>(mData->object)->GetDesc(desc); 2610 } 2611 2612 void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const 2613 { 2614 static_cast<ID3D11Texture3D *>(mData->object)->GetDesc(desc); 2615 } 2616 2617 void TextureHelper11::getDesc(D3D11_BUFFER_DESC *desc) const 2618 { 2619 static_cast<ID3D11Buffer *>(mData->object)->GetDesc(desc); 2620 } 2621 2622 void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D) 2623 { 2624 mData->resourceType = ResourceType::Texture2D; 2625 mExtents.width = static_cast<int>(desc2D.Width); 2626 mExtents.height = static_cast<int>(desc2D.Height); 2627 mExtents.depth = 1; 2628 mSampleCount = desc2D.SampleDesc.Count; 2629 } 2630 2631 void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D) 2632 { 2633 mData->resourceType = ResourceType::Texture3D; 2634 mExtents.width = static_cast<int>(desc3D.Width); 2635 mExtents.height = static_cast<int>(desc3D.Height); 2636 mExtents.depth = static_cast<int>(desc3D.Depth); 2637 mSampleCount = 1; 2638 } 2639 2640 void TextureHelper11::initDesc(const D3D11_BUFFER_DESC &descBuffer) 2641 { 2642 mData->resourceType = ResourceType::Buffer; 2643 mExtents.width = static_cast<int>(descBuffer.ByteWidth); 2644 mExtents.height = 1; 2645 mExtents.depth = 1; 2646 mSampleCount = 1; 2647 } 2648 2649 TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other) 2650 { 2651 std::swap(mData, other.mData); 2652 std::swap(mExtents, other.mExtents); 2653 std::swap(mFormatSet, other.mFormatSet); 2654 std::swap(mSampleCount, other.mSampleCount); 2655 return *this; 2656 } 2657 2658 TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other) 2659 { 2660 mData = other.mData; 2661 mExtents = other.mExtents; 2662 mFormatSet = other.mFormatSet; 2663 mSampleCount = other.mSampleCount; 2664 return *this; 2665 } 2666 2667 bool TextureHelper11::operator==(const TextureHelper11 &other) const 2668 { 2669 return mData->object == other.mData->object; 2670 } 2671 2672 bool TextureHelper11::operator!=(const TextureHelper11 &other) const 2673 { 2674 return mData->object != other.mData->object; 2675 } 2676 2677 bool UsePresentPathFast(const Renderer11 *renderer, 2678 const gl::FramebufferAttachment *framebufferAttachment) 2679 { 2680 if (framebufferAttachment == nullptr) 2681 { 2682 return false; 2683 } 2684 2685 return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT && 2686 renderer->presentPathFastEnabled()); 2687 } 2688 2689 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, 2690 gl::DrawElementsType type) 2691 { 2692 // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT 2693 // indices, since we restrict it via MAX_ELEMENT_INDEX. 2694 return (!primitiveRestartFixedIndexEnabled && type == gl::DrawElementsType::UnsignedShort); 2695 } 2696 2697 IndexStorageType ClassifyIndexStorage(const gl::State &glState, 2698 const gl::Buffer *elementArrayBuffer, 2699 gl::DrawElementsType elementType, 2700 gl::DrawElementsType destElementType, 2701 unsigned int offset) 2702 { 2703 // No buffer bound means we are streaming from a client pointer. 2704 if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset)) 2705 { 2706 return IndexStorageType::Dynamic; 2707 } 2708 2709 // The buffer can be used directly if the storage supports it and no translation needed. 2710 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer); 2711 if (bufferD3D->supportsDirectBinding() && destElementType == elementType) 2712 { 2713 return IndexStorageType::Direct; 2714 } 2715 2716 // Use a static copy when available. 2717 StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer(); 2718 if (staticBuffer != nullptr) 2719 { 2720 return IndexStorageType::Static; 2721 } 2722 2723 // Static buffer not available, fall back to streaming. 2724 return IndexStorageType::Dynamic; 2725 } 2726 2727 bool SwizzleRequired(const gl::TextureState &textureState) 2728 { 2729 // When sampling stencil, a swizzle is needed to move the stencil channel from G to R. 2730 return textureState.swizzleRequired() || textureState.isStencilMode(); 2731 } 2732 2733 gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState) 2734 { 2735 const gl::SwizzleState &swizzle = textureState.getSwizzleState(); 2736 if (textureState.isStencilMode()) 2737 { 2738 // Per GL semantics, the stencil value should be in the red channel, while D3D11 formats 2739 // leave stencil in the green channel. So copy the stencil value from green to all 2740 // components requesting red. Green and blue become zero; alpha becomes one. 2741 std::unordered_map<GLenum, GLenum> map = {{GL_RED, GL_GREEN}, {GL_GREEN, GL_ZERO}, 2742 {GL_BLUE, GL_ZERO}, {GL_ALPHA, GL_ONE}, 2743 {GL_ZERO, GL_ZERO}, {GL_ONE, GL_ONE}}; 2744 2745 return gl::SwizzleState(map[swizzle.swizzleRed], map[swizzle.swizzleGreen], 2746 map[swizzle.swizzleBlue], map[swizzle.swizzleAlpha]); 2747 } 2748 return swizzle; 2749 } 2750 2751 } // namespace rx