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_utils.cpp: Conversion functions and other utility routines 8 // specific to the D3D11 renderer. 9 10 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" 11 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" 12 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h" 13 #include "libGLESv2/ProgramBinary.h" 14 #include "libGLESv2/Framebuffer.h" 15 16 #include "common/debug.h" 17 18 #include <algorithm> 19 20 namespace rx 21 { 22 23 namespace gl_d3d11 24 { 25 26 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) 27 { 28 D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; 29 30 switch (glBlend) 31 { 32 case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; 33 case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; 34 case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; 35 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; 36 case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; 37 case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; 38 case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; 39 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; 40 case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; 41 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; 42 case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; 43 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; 44 case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; 45 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; 46 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; 47 default: UNREACHABLE(); 48 } 49 50 return d3dBlend; 51 } 52 53 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) 54 { 55 D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; 56 57 switch (glBlendOp) 58 { 59 case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; 60 case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; 61 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; 62 case GL_MIN: d3dBlendOp = D3D11_BLEND_OP_MIN; break; 63 case GL_MAX: d3dBlendOp = D3D11_BLEND_OP_MAX; break; 64 default: UNREACHABLE(); 65 } 66 67 return d3dBlendOp; 68 } 69 70 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) 71 { 72 UINT8 mask = 0; 73 if (red) 74 { 75 mask |= D3D11_COLOR_WRITE_ENABLE_RED; 76 } 77 if (green) 78 { 79 mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; 80 } 81 if (blue) 82 { 83 mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; 84 } 85 if (alpha) 86 { 87 mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; 88 } 89 return mask; 90 } 91 92 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) 93 { 94 D3D11_CULL_MODE cull = D3D11_CULL_NONE; 95 96 if (cullEnabled) 97 { 98 switch (cullMode) 99 { 100 case GL_FRONT: cull = D3D11_CULL_FRONT; break; 101 case GL_BACK: cull = D3D11_CULL_BACK; break; 102 case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; 103 default: UNREACHABLE(); 104 } 105 } 106 else 107 { 108 cull = D3D11_CULL_NONE; 109 } 110 111 return cull; 112 } 113 114 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) 115 { 116 D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; 117 switch (comparison) 118 { 119 case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; 120 case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; 121 case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; 122 case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; 123 case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; 124 case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; 125 case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; 126 case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; 127 default: UNREACHABLE(); 128 } 129 130 return d3dComp; 131 } 132 133 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) 134 { 135 return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; 136 } 137 138 UINT8 ConvertStencilMask(GLuint stencilmask) 139 { 140 return static_cast<UINT8>(stencilmask); 141 } 142 143 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) 144 { 145 D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; 146 147 switch (stencilOp) 148 { 149 case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; 150 case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; 151 case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; 152 case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; 153 case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; 154 case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; 155 case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; 156 case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; 157 default: UNREACHABLE(); 158 } 159 160 return d3dStencilOp; 161 } 162 163 D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode) 164 { 165 bool comparison = comparisonMode != GL_NONE; 166 167 if (maxAnisotropy > 1.0f) 168 { 169 return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison)); 170 } 171 else 172 { 173 D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; 174 D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; 175 switch (minFilter) 176 { 177 case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; 178 case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; 179 case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; 180 case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; 181 case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; 182 case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; 183 default: UNREACHABLE(); 184 } 185 186 D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; 187 switch (magFilter) 188 { 189 case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; 190 case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; 191 default: UNREACHABLE(); 192 } 193 194 return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison)); 195 } 196 } 197 198 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) 199 { 200 switch (wrap) 201 { 202 case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; 203 case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; 204 case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; 205 default: UNREACHABLE(); 206 } 207 208 return D3D11_TEXTURE_ADDRESS_WRAP; 209 } 210 211 D3D11_QUERY ConvertQueryType(GLenum queryType) 212 { 213 switch (queryType) 214 { 215 case GL_ANY_SAMPLES_PASSED_EXT: 216 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION; 217 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS; 218 default: UNREACHABLE(); return D3D11_QUERY_EVENT; 219 } 220 } 221 222 } 223 224 225 namespace d3d11_gl 226 { 227 228 static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11Device *device) 229 { 230 gl::TextureCaps textureCaps; 231 232 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat); 233 234 UINT formatSupport; 235 if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport))) 236 { 237 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); 238 if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) 239 { 240 textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0); 241 } 242 else 243 { 244 textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0) && 245 ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) != 0) && 246 ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) != 0); 247 } 248 } 249 250 if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) && 251 ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0)) 252 { 253 for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) 254 { 255 UINT qualityCount = 0; 256 if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) && 257 qualityCount > 0) 258 { 259 textureCaps.sampleCounts.insert(sampleCount); 260 } 261 } 262 } 263 264 textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) && 265 ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0; 266 textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) && 267 ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) || 268 (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) && 269 ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0)); 270 271 return textureCaps; 272 } 273 274 static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) 275 { 276 switch (featureLevel) 277 { 278 case D3D_FEATURE_LEVEL_11_1: 279 case D3D_FEATURE_LEVEL_11_0: 280 case D3D_FEATURE_LEVEL_10_1: 281 case D3D_FEATURE_LEVEL_10_0: return true; 282 283 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx 284 case D3D_FEATURE_LEVEL_9_3: 285 case D3D_FEATURE_LEVEL_9_2: 286 case D3D_FEATURE_LEVEL_9_1: return false; 287 288 default: UNREACHABLE(); return false; 289 } 290 } 291 292 static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) 293 { 294 switch (featureLevel) 295 { 296 case D3D_FEATURE_LEVEL_11_1: 297 case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY; 298 299 case D3D_FEATURE_LEVEL_10_1: 300 case D3D_FEATURE_LEVEL_10_0: return D3D10_MAX_MAXANISOTROPY; 301 302 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx 303 case D3D_FEATURE_LEVEL_9_3: 304 case D3D_FEATURE_LEVEL_9_2: return 16; 305 306 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; 307 308 default: UNREACHABLE(); return 0; 309 } 310 } 311 312 static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) 313 { 314 switch (featureLevel) 315 { 316 case D3D_FEATURE_LEVEL_11_1: 317 case D3D_FEATURE_LEVEL_11_0: 318 case D3D_FEATURE_LEVEL_10_1: 319 case D3D_FEATURE_LEVEL_10_0: return true; 320 321 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery 322 case D3D_FEATURE_LEVEL_9_3: 323 case D3D_FEATURE_LEVEL_9_2: return true; 324 case D3D_FEATURE_LEVEL_9_1: return false; 325 326 default: UNREACHABLE(); return false; 327 } 328 } 329 330 static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) 331 { 332 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery 333 334 switch (featureLevel) 335 { 336 case D3D_FEATURE_LEVEL_11_1: 337 case D3D_FEATURE_LEVEL_11_0: 338 case D3D_FEATURE_LEVEL_10_1: 339 case D3D_FEATURE_LEVEL_10_0: 340 case D3D_FEATURE_LEVEL_9_3: 341 case D3D_FEATURE_LEVEL_9_2: 342 case D3D_FEATURE_LEVEL_9_1: return true; 343 344 default: UNREACHABLE(); return false; 345 } 346 } 347 348 static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) 349 { 350 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout 351 352 switch (featureLevel) 353 { 354 case D3D_FEATURE_LEVEL_11_1: 355 case D3D_FEATURE_LEVEL_11_0: 356 case D3D_FEATURE_LEVEL_10_1: 357 case D3D_FEATURE_LEVEL_10_0: 358 case D3D_FEATURE_LEVEL_9_3: return true; 359 360 case D3D_FEATURE_LEVEL_9_2: 361 case D3D_FEATURE_LEVEL_9_1: return false; 362 363 default: UNREACHABLE(); return false; 364 } 365 } 366 367 static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) 368 { 369 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model 370 // ps_2_x is required for the ddx (and other derivative functions). 371 372 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that feature level 373 // 9.3 supports shader model ps_2_x. 374 375 switch (featureLevel) 376 { 377 case D3D_FEATURE_LEVEL_11_1: 378 case D3D_FEATURE_LEVEL_11_0: 379 case D3D_FEATURE_LEVEL_10_1: 380 case D3D_FEATURE_LEVEL_10_0: 381 case D3D_FEATURE_LEVEL_9_3: return true; 382 case D3D_FEATURE_LEVEL_9_2: 383 case D3D_FEATURE_LEVEL_9_1: return false; 384 385 default: UNREACHABLE(); return false; 386 } 387 } 388 389 static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel) 390 { 391 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout 392 393 switch (featureLevel) 394 { 395 case D3D_FEATURE_LEVEL_11_1: 396 case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; 397 398 case D3D_FEATURE_LEVEL_10_1: 399 case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; 400 401 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; 402 case D3D_FEATURE_LEVEL_9_2: 403 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; 404 405 default: UNREACHABLE(); return 0; 406 } 407 } 408 409 static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) 410 { 411 switch (featureLevel) 412 { 413 case D3D_FEATURE_LEVEL_11_1: 414 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; 415 416 case D3D_FEATURE_LEVEL_10_1: 417 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; 418 419 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; 420 case D3D_FEATURE_LEVEL_9_2: 421 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; 422 423 default: UNREACHABLE(); return 0; 424 } 425 } 426 427 static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) 428 { 429 switch (featureLevel) 430 { 431 case D3D_FEATURE_LEVEL_11_1: 432 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; 433 434 case D3D_FEATURE_LEVEL_10_1: 435 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURECUBE_DIMENSION; 436 437 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION; 438 case D3D_FEATURE_LEVEL_9_2: 439 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION; 440 441 default: UNREACHABLE(); return 0; 442 } 443 } 444 445 static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) 446 { 447 switch (featureLevel) 448 { 449 case D3D_FEATURE_LEVEL_11_1: 450 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; 451 452 case D3D_FEATURE_LEVEL_10_1: 453 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; 454 455 case D3D_FEATURE_LEVEL_9_3: 456 case D3D_FEATURE_LEVEL_9_2: 457 case D3D_FEATURE_LEVEL_9_1: return 0; 458 459 default: UNREACHABLE(); return 0; 460 } 461 } 462 463 static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) 464 { 465 switch (featureLevel) 466 { 467 case D3D_FEATURE_LEVEL_11_1: 468 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 469 470 case D3D_FEATURE_LEVEL_10_1: 471 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 472 473 case D3D_FEATURE_LEVEL_9_3: 474 case D3D_FEATURE_LEVEL_9_2: 475 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; 476 477 default: UNREACHABLE(); return 0; 478 } 479 } 480 481 static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) 482 { 483 switch (featureLevel) 484 { 485 case D3D_FEATURE_LEVEL_11_1: 486 case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX; 487 488 case D3D_FEATURE_LEVEL_10_1: 489 case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX; 490 491 // No constants for D3D9 viewport size limits, use the maximum texture sizes 492 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; 493 case D3D_FEATURE_LEVEL_9_2: 494 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; 495 496 default: UNREACHABLE(); return 0; 497 } 498 } 499 500 static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) 501 { 502 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's 503 // returned from glGetInteger 504 META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); 505 META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32); 506 507 switch (featureLevel) 508 { 509 case D3D_FEATURE_LEVEL_11_1: 510 case D3D_FEATURE_LEVEL_11_0: 511 case D3D_FEATURE_LEVEL_10_1: 512 case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max(); 513 514 case D3D_FEATURE_LEVEL_9_3: 515 case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; 516 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; 517 518 default: UNREACHABLE(); return 0; 519 } 520 } 521 522 static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) 523 { 524 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's 525 // returned from glGetInteger 526 META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); 527 META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32); 528 529 switch (featureLevel) 530 { 531 case D3D_FEATURE_LEVEL_11_1: 532 case D3D_FEATURE_LEVEL_11_0: 533 case D3D_FEATURE_LEVEL_10_1: 534 case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max(); 535 536 case D3D_FEATURE_LEVEL_9_3: 537 case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; 538 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; 539 540 default: UNREACHABLE(); return 0; 541 } 542 } 543 544 static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) 545 { 546 switch (featureLevel) 547 { 548 case D3D_FEATURE_LEVEL_11_1: 549 case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; 550 551 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; 552 case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; 553 554 // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots" 555 case D3D_FEATURE_LEVEL_9_3: 556 case D3D_FEATURE_LEVEL_9_2: 557 case D3D_FEATURE_LEVEL_9_1: return 16; 558 559 default: UNREACHABLE(); return 0; 560 } 561 } 562 563 static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) 564 { 565 // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass 566 switch (featureLevel) 567 { 568 case D3D_FEATURE_LEVEL_11_1: 569 case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 570 571 case D3D_FEATURE_LEVEL_10_1: 572 case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 573 574 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers 575 case D3D_FEATURE_LEVEL_9_3: 576 case D3D_FEATURE_LEVEL_9_2: 577 case D3D_FEATURE_LEVEL_9_1: return 255; 578 579 default: UNREACHABLE(); return 0; 580 } 581 } 582 583 static size_t GetReservedVertexUniformBuffers() 584 { 585 // Reserve one buffer for the application uniforms, and one for driver uniforms 586 return 2; 587 } 588 589 static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) 590 { 591 switch (featureLevel) 592 { 593 case D3D_FEATURE_LEVEL_11_1: 594 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); 595 596 case D3D_FEATURE_LEVEL_10_1: 597 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); 598 599 // Uniform blocks not supported in D3D9 feature levels 600 case D3D_FEATURE_LEVEL_9_3: 601 case D3D_FEATURE_LEVEL_9_2: 602 case D3D_FEATURE_LEVEL_9_1: return 0; 603 604 default: UNREACHABLE(); return 0; 605 } 606 } 607 608 static size_t GetReservedVertexOutputVectors() 609 { 610 // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize 611 return 4; 612 } 613 614 static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) 615 { 616 META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); 617 618 switch (featureLevel) 619 { 620 case D3D_FEATURE_LEVEL_11_1: 621 case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); 622 623 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); 624 case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); 625 626 // Use D3D9 SM3 and SM2 limits 627 case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); 628 case D3D_FEATURE_LEVEL_9_2: 629 case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); 630 631 default: UNREACHABLE(); return 0; 632 } 633 } 634 635 static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) 636 { 637 switch (featureLevel) 638 { 639 case D3D_FEATURE_LEVEL_11_1: 640 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; 641 642 case D3D_FEATURE_LEVEL_10_1: 643 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; 644 645 // Vertex textures not supported in D3D9 feature levels according to 646 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx 647 // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources 648 case D3D_FEATURE_LEVEL_9_3: 649 case D3D_FEATURE_LEVEL_9_2: 650 case D3D_FEATURE_LEVEL_9_1: return 0; 651 652 default: UNREACHABLE(); return 0; 653 } 654 } 655 656 static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) 657 { 658 // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass 659 switch (featureLevel) 660 { 661 case D3D_FEATURE_LEVEL_11_1: 662 case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 663 664 case D3D_FEATURE_LEVEL_10_1: 665 case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; 666 667 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers 668 case D3D_FEATURE_LEVEL_9_3: 669 case D3D_FEATURE_LEVEL_9_2: 670 case D3D_FEATURE_LEVEL_9_1: return 32; 671 672 default: UNREACHABLE(); return 0; 673 } 674 } 675 676 static size_t GetReservedPixelUniformBuffers() 677 { 678 // Reserve one buffer for the application uniforms, and one for driver uniforms 679 return 2; 680 } 681 682 static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) 683 { 684 switch (featureLevel) 685 { 686 case D3D_FEATURE_LEVEL_11_1: 687 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); 688 689 case D3D_FEATURE_LEVEL_10_1: 690 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); 691 692 // Uniform blocks not supported in D3D9 feature levels 693 case D3D_FEATURE_LEVEL_9_3: 694 case D3D_FEATURE_LEVEL_9_2: 695 case D3D_FEATURE_LEVEL_9_1: return 0; 696 697 default: UNREACHABLE(); return 0; 698 } 699 } 700 701 static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) 702 { 703 switch (featureLevel) 704 { 705 case D3D_FEATURE_LEVEL_11_1: 706 case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); 707 708 case D3D_FEATURE_LEVEL_10_1: 709 case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(); 710 711 // Use D3D9 SM3 and SM2 limits 712 case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors(); 713 case D3D_FEATURE_LEVEL_9_2: 714 case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(); 715 716 default: UNREACHABLE(); return 0; 717 } 718 } 719 720 static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) 721 { 722 switch (featureLevel) 723 { 724 case D3D_FEATURE_LEVEL_11_1: 725 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; 726 727 case D3D_FEATURE_LEVEL_10_1: 728 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; 729 730 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources 731 case D3D_FEATURE_LEVEL_9_3: 732 case D3D_FEATURE_LEVEL_9_2: 733 case D3D_FEATURE_LEVEL_9_1: return 16; 734 735 default: UNREACHABLE(); return 0; 736 } 737 } 738 739 static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) 740 { 741 switch (featureLevel) 742 { 743 case D3D_FEATURE_LEVEL_11_1: 744 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; 745 746 case D3D_FEATURE_LEVEL_10_1: 747 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; 748 749 // Sampling functions with offsets are not available below shader model 4.0. 750 case D3D_FEATURE_LEVEL_9_3: 751 case D3D_FEATURE_LEVEL_9_2: 752 case D3D_FEATURE_LEVEL_9_1: return 0; 753 754 default: UNREACHABLE(); return 0; 755 } 756 } 757 758 static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) 759 { 760 switch (featureLevel) 761 { 762 case D3D_FEATURE_LEVEL_11_1: 763 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; 764 case D3D_FEATURE_LEVEL_10_1: 765 case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; 766 767 // Sampling functions with offsets are not available below shader model 4.0. 768 case D3D_FEATURE_LEVEL_9_3: 769 case D3D_FEATURE_LEVEL_9_2: 770 case D3D_FEATURE_LEVEL_9_1: return 0; 771 772 default: UNREACHABLE(); return 0; 773 } 774 } 775 776 static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) 777 { 778 // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of 779 // any buffer that could be allocated. 780 781 const size_t bytesPerComponent = 4 * sizeof(float); 782 783 switch (featureLevel) 784 { 785 case D3D_FEATURE_LEVEL_11_1: 786 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; 787 788 case D3D_FEATURE_LEVEL_10_1: 789 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; 790 791 // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section 792 case D3D_FEATURE_LEVEL_9_3: 793 case D3D_FEATURE_LEVEL_9_2: 794 case D3D_FEATURE_LEVEL_9_1: return 4096 * bytesPerComponent; 795 796 default: UNREACHABLE(); return 0; 797 } 798 } 799 800 static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) 801 { 802 switch (featureLevel) 803 { 804 case D3D_FEATURE_LEVEL_11_1: 805 case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT; 806 807 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT; 808 case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT; 809 810 case D3D_FEATURE_LEVEL_9_3: 811 case D3D_FEATURE_LEVEL_9_2: 812 case D3D_FEATURE_LEVEL_9_1: return 0; 813 814 default: UNREACHABLE(); return 0; 815 } 816 } 817 818 static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel) 819 { 820 switch (featureLevel) 821 { 822 case D3D_FEATURE_LEVEL_11_1: 823 case D3D_FEATURE_LEVEL_11_0: 824 825 case D3D_FEATURE_LEVEL_10_1: 826 case D3D_FEATURE_LEVEL_10_0: return GetMaximumVertexOutputVectors(featureLevel) * 4; 827 828 case D3D_FEATURE_LEVEL_9_3: 829 case D3D_FEATURE_LEVEL_9_2: 830 case D3D_FEATURE_LEVEL_9_1: return 0; 831 832 default: UNREACHABLE(); return 0; 833 } 834 } 835 836 static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel) 837 { 838 switch (featureLevel) 839 { 840 case D3D_FEATURE_LEVEL_11_1: 841 case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) / 842 GetMaximumStreamOutputBuffers(featureLevel); 843 844 845 // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used. 846 case D3D_FEATURE_LEVEL_10_1: 847 case D3D_FEATURE_LEVEL_10_0: return 4; 848 849 case D3D_FEATURE_LEVEL_9_3: 850 case D3D_FEATURE_LEVEL_9_2: 851 case D3D_FEATURE_LEVEL_9_1: return 0; 852 853 default: UNREACHABLE(); return 0; 854 } 855 } 856 857 void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions) 858 { 859 GLuint maxSamples = 0; 860 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); 861 for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) 862 { 863 gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device); 864 textureCapsMap->insert(*internalFormat, textureCaps); 865 866 maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); 867 868 if (gl::GetInternalFormatInfo(*internalFormat).compressed) 869 { 870 caps->compressedTextureFormats.push_back(*internalFormat); 871 } 872 } 873 874 D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel(); 875 876 // GL core feature limits 877 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max()); 878 caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel); 879 caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel); 880 caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel); 881 caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel); 882 883 // Unimplemented, set to minimum required 884 caps->maxLODBias = 2.0f; 885 886 // No specific limits on render target size, maximum 2D texture size is equivalent 887 caps->maxRenderbufferSize = caps->max2DTextureSize; 888 889 // Maximum draw buffers and color attachments are the same, max color attachments could eventually be 890 // increased to 16 891 caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel); 892 caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel); 893 894 // D3D11 has the same limit for viewport width and height 895 caps->maxViewportWidth = GetMaximumViewportSize(featureLevel); 896 caps->maxViewportHeight = caps->maxViewportWidth; 897 898 // Choose a reasonable maximum, enforced in the shader. 899 caps->minAliasedPointSize = 1.0f; 900 caps->maxAliasedPointSize = 1024.0f; 901 902 // Wide lines not supported 903 caps->minAliasedLineWidth = 1.0f; 904 caps->maxAliasedLineWidth = 1.0f; 905 906 // Primitive count limits 907 caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel); 908 caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel); 909 910 // Program and shader binary formats (no supported shader binary formats) 911 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE); 912 913 // We do not wait for server fence objects internally, so report a max timeout of zero. 914 caps->maxServerWaitTimeout = 0; 915 916 // Vertex shader limits 917 caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel); 918 caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4; 919 caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel); 920 caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel); 921 caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; 922 caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel); 923 924 // Fragment shader limits 925 caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4; 926 caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel); 927 caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel); 928 caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4; 929 caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel); 930 caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); 931 caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); 932 933 // Aggregate shader limits 934 caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks; 935 caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel); 936 937 // Setting a large alignment forces uniform buffers to bind with zero offset 938 caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max()); 939 940 caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks; 941 caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) + 942 static_cast<GLint64>(caps->maxVertexUniformComponents); 943 caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) + 944 static_cast<GLint64>(caps->maxFragmentUniformComponents); 945 caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4; 946 caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel); 947 caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits; 948 949 // Transform feedback limits 950 caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel); 951 caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel); 952 caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel); 953 954 // GL extension support 955 extensions->setTextureExtensionSupport(*textureCapsMap); 956 extensions->elementIndexUint = true; 957 extensions->packedDepthStencil = true; 958 extensions->getProgramBinary = true; 959 extensions->rgb8rgba8 = true; 960 extensions->readFormatBGRA = true; 961 extensions->pixelBufferObject = true; 962 extensions->mapBuffer = true; 963 extensions->mapBufferRange = true; 964 extensions->textureNPOT = GetNPOTTextureSupport(featureLevel); 965 extensions->drawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel) > 1; 966 extensions->textureStorage = true; 967 extensions->textureFilterAnisotropic = true; 968 extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel); 969 extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel); 970 extensions->fence = GetEventQuerySupport(featureLevel); 971 extensions->timerQuery = false; // Unimplemented 972 extensions->robustness = true; 973 extensions->blendMinMax = true; 974 extensions->framebufferBlit = true; 975 extensions->framebufferMultisample = true; 976 extensions->maxSamples = maxSamples; 977 extensions->instancedArrays = GetInstancingSupport(featureLevel); 978 extensions->packReverseRowOrder = true; 979 extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel); 980 extensions->shaderTextureLOD = true; 981 extensions->fragDepth = true; 982 extensions->textureUsage = true; // This could be false since it has no effect in D3D11 983 extensions->translatedShaderSource = true; 984 } 985 986 } 987 988 namespace d3d11 989 { 990 991 void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) 992 { 993 const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); 994 995 int upsampleCount = 0; 996 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. 997 if (isImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) || 998 *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight)) 999 { 1000 while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0) 1001 { 1002 *requestWidth <<= 1; 1003 *requestHeight <<= 1; 1004 upsampleCount++; 1005 } 1006 } 1007 *levelOffset = upsampleCount; 1008 } 1009 1010 void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth, 1011 GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, 1012 std::vector< std::vector<BYTE> > *outData) 1013 { 1014 const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat); 1015 ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); 1016 1017 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat); 1018 1019 outSubresourceData->resize(mipLevels); 1020 outData->resize(mipLevels); 1021 1022 for (unsigned int i = 0; i < mipLevels; i++) 1023 { 1024 unsigned int mipWidth = std::max(width >> i, 1U); 1025 unsigned int mipHeight = std::max(height >> i, 1U); 1026 unsigned int mipDepth = std::max(depth >> i, 1U); 1027 1028 unsigned int rowWidth = dxgiFormatInfo.pixelBytes * mipWidth; 1029 unsigned int imageSize = rowWidth * height; 1030 1031 outData->at(i).resize(rowWidth * mipHeight * mipDepth); 1032 d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize); 1033 1034 outSubresourceData->at(i).pSysMem = outData->at(i).data(); 1035 outSubresourceData->at(i).SysMemPitch = rowWidth; 1036 outSubresourceData->at(i).SysMemSlicePitch = imageSize; 1037 } 1038 } 1039 1040 void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) 1041 { 1042 vertex->x = x; 1043 vertex->y = y; 1044 vertex->u = u; 1045 vertex->v = v; 1046 } 1047 1048 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y, 1049 unsigned int layer, float u, float v, float s) 1050 { 1051 vertex->x = x; 1052 vertex->y = y; 1053 vertex->l = layer; 1054 vertex->u = u; 1055 vertex->v = v; 1056 vertex->s = s; 1057 } 1058 1059 HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) 1060 { 1061 #if defined(_DEBUG) 1062 return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); 1063 #else 1064 return S_OK; 1065 #endif 1066 } 1067 1068 RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment) 1069 { 1070 RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment); 1071 return RenderTarget11::makeRenderTarget11(renderTarget); 1072 } 1073 1074 } 1075 1076 } 1077