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.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:
DXGISupportHelper(ID3D11Device * device,D3D_FEATURE_LEVEL featureLevel)49 DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
50 : mDevice(device), mFeatureLevel(featureLevel)
51 {}
52
query(DXGI_FORMAT dxgiFormat,UINT supportMask)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
GenerateTextureFormatCaps(gl::Version maxClientVersion,GLenum internalFormat,ID3D11Device * device,const Renderer11DeviceCaps & renderer11DeviceCaps)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
GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)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
GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)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
GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)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
GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)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
GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)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
GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)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
GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)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
GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)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
GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)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
GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)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
GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel)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
GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel)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
GetMaxComputeSharedMemorySize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel)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
SetUAVRelatedResourceLimits(D3D_FEATURE_LEVEL featureLevel,gl::Caps * caps)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
GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)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
GetMinimumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)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
GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel)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
GetIntelDriverVersion(const Optional<LARGE_INTEGER> driverVersion)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
GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)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
GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel)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 3;
1283
1284 default:
1285 UNREACHABLE();
1286 return 0;
1287 }
1288 }
1289
GetMaximumClientVersion(const Renderer11DeviceCaps & caps)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
GetMinimumFeatureLevelForES31()1320 D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31()
1321 {
1322 return kMinimumFeatureLevelForES31;
1323 }
1324
GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel)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
IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel)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
GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel)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
GenerateCaps(ID3D11Device * device,ID3D11DeviceContext * deviceContext,const Renderer11DeviceCaps & renderer11DeviceCaps,const angle::FeaturesD3D & features,const char * description,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Limitations * limitations)1377 void GenerateCaps(ID3D11Device *device,
1378 ID3D11DeviceContext *deviceContext,
1379 const Renderer11DeviceCaps &renderer11DeviceCaps,
1380 const angle::FeaturesD3D &features,
1381 const char *description,
1382 gl::Caps *caps,
1383 gl::TextureCapsMap *textureCapsMap,
1384 gl::Extensions *extensions,
1385 gl::Limitations *limitations)
1386 {
1387 D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel;
1388 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
1389 for (GLenum internalFormat : allFormats)
1390 {
1391 gl::TextureCaps textureCaps =
1392 GenerateTextureFormatCaps(GetMaximumClientVersion(renderer11DeviceCaps), internalFormat,
1393 device, renderer11DeviceCaps);
1394 textureCapsMap->insert(internalFormat, textureCaps);
1395
1396 if (gl::GetSizedInternalFormatInfo(internalFormat).compressed)
1397 {
1398 caps->compressedTextureFormats.push_back(internalFormat);
1399 }
1400 }
1401
1402 // GL core feature limits
1403 // Reserve MAX_UINT for D3D11's primitive restart.
1404 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max() - 1);
1405 caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
1406 caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
1407 caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
1408 caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
1409
1410 // Unimplemented, set to minimum required
1411 caps->maxLODBias = 2.0f;
1412
1413 // No specific limits on render target size, maximum 2D texture size is equivalent
1414 caps->maxRenderbufferSize = caps->max2DTextureSize;
1415
1416 // Maximum draw buffers and color attachments are the same, max color attachments could
1417 // eventually be increased to 16
1418 caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
1419 caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
1420
1421 // D3D11 has the same limit for viewport width and height
1422 caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
1423 caps->maxViewportHeight = caps->maxViewportWidth;
1424
1425 // Choose a reasonable maximum, enforced in the shader.
1426 caps->minAliasedPointSize = 1.0f;
1427 caps->maxAliasedPointSize = 1024.0f;
1428
1429 // Wide lines not supported
1430 caps->minAliasedLineWidth = 1.0f;
1431 caps->maxAliasedLineWidth = 1.0f;
1432
1433 // Primitive count limits
1434 caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
1435 caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
1436
1437 // Program and shader binary formats (no supported shader binary formats)
1438 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
1439
1440 caps->vertexHighpFloat.setIEEEFloat();
1441 caps->vertexMediumpFloat.setIEEEFloat();
1442 caps->vertexLowpFloat.setIEEEFloat();
1443 caps->fragmentHighpFloat.setIEEEFloat();
1444 caps->fragmentMediumpFloat.setIEEEFloat();
1445 caps->fragmentLowpFloat.setIEEEFloat();
1446
1447 // 32-bit integers are natively supported
1448 caps->vertexHighpInt.setTwosComplementInt(32);
1449 caps->vertexMediumpInt.setTwosComplementInt(32);
1450 caps->vertexLowpInt.setTwosComplementInt(32);
1451 caps->fragmentHighpInt.setTwosComplementInt(32);
1452 caps->fragmentMediumpInt.setTwosComplementInt(32);
1453 caps->fragmentLowpInt.setTwosComplementInt(32);
1454
1455 // We do not wait for server fence objects internally, so report a max timeout of zero.
1456 caps->maxServerWaitTimeout = 0;
1457
1458 // Vertex shader limits
1459 caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
1460 caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
1461 if (features.skipVSConstantRegisterZero.enabled)
1462 {
1463 caps->maxVertexUniformVectors -= 1;
1464 }
1465 caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4;
1466 caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
1467 GetMaximumVertexUniformBlocks(featureLevel);
1468 caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
1469 caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
1470 GetMaximumVertexTextureUnits(featureLevel);
1471
1472 // Vertex Attribute Bindings are emulated on D3D11.
1473 caps->maxVertexAttribBindings = caps->maxVertexAttributes;
1474 // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11.
1475 caps->maxVertexAttribRelativeOffset = std::numeric_limits<GLint>::max();
1476 // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all
1477 // platforms.
1478 caps->maxVertexAttribStride = 2048;
1479
1480 // Fragment shader limits
1481 caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
1482 caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1483 caps->maxFragmentUniformVectors * 4;
1484 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
1485 GetMaximumPixelUniformBlocks(featureLevel);
1486 caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
1487 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
1488 GetMaximumPixelTextureUnits(featureLevel);
1489 caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
1490 caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
1491
1492 // Compute shader limits
1493 caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel);
1494 caps->maxComputeWorkGroupSize = GetMaxComputeWorkGroupSize(featureLevel);
1495 caps->maxComputeWorkGroupInvocations = GetMaxComputeWorkGroupInvocations(featureLevel);
1496 caps->maxComputeSharedMemorySize = GetMaxComputeSharedMemorySize(featureLevel);
1497 caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
1498 GetMaximumComputeUniformVectors(featureLevel) * 4;
1499 caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
1500 GetMaximumComputeUniformBlocks(featureLevel);
1501 caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
1502 GetMaximumComputeTextureUnits(featureLevel);
1503
1504 SetUAVRelatedResourceLimits(featureLevel, caps);
1505
1506 // Aggregate shader limits
1507 caps->maxUniformBufferBindings = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
1508 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
1509 caps->maxUniformBlockSize = static_cast<GLuint64>(GetMaximumConstantBufferSize(featureLevel));
1510
1511 // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1.
1512 caps->maxUniformLocations = 1024;
1513
1514 // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16
1515 // bytes each.
1516 // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
1517 // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however
1518 // we still keep the same alignment as 11.1 for consistency.
1519 caps->uniformBufferOffsetAlignment = 256;
1520
1521 caps->maxCombinedUniformBlocks = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
1522 caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
1523
1524 // A shader storage block will be translated to a structure in HLSL. So We reference the HLSL
1525 // structure packing rules
1526 // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx. The
1527 // resulting size of any structure will always be evenly divisible by sizeof(four-component
1528 // vector).
1529 caps->shaderStorageBufferOffsetAlignment = 16;
1530
1531 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1532 {
1533 caps->maxCombinedShaderUniformComponents[shaderType] =
1534 static_cast<GLint64>(caps->maxShaderUniformBlocks[shaderType]) *
1535 static_cast<GLint64>(caps->maxUniformBlockSize / 4) +
1536 static_cast<GLint64>(caps->maxShaderUniformComponents[shaderType]);
1537 }
1538
1539 caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
1540 caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
1541 caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] +
1542 caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment];
1543
1544 // Transform feedback limits
1545 caps->maxTransformFeedbackInterleavedComponents =
1546 GetMaximumStreamOutputInterleavedComponents(featureLevel);
1547 caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
1548 caps->maxTransformFeedbackSeparateComponents =
1549 GetMaximumStreamOutputSeparateComponents(featureLevel);
1550
1551 // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values
1552 // are determined according to available sample counts for each individual format.
1553 caps->maxSamples = std::numeric_limits<GLint>::max();
1554 caps->maxColorTextureSamples = std::numeric_limits<GLint>::max();
1555 caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max();
1556 caps->maxIntegerSamples = std::numeric_limits<GLint>::max();
1557
1558 // Sample mask words limits
1559 caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel);
1560
1561 // Framebuffer limits
1562 caps->maxFramebufferSamples = std::numeric_limits<GLint>::max();
1563 caps->maxFramebufferWidth = GetMaximumRenderToBufferWindowSize(featureLevel);
1564 caps->maxFramebufferHeight = caps->maxFramebufferWidth;
1565
1566 // Texture gather offset limits
1567 caps->minProgramTextureGatherOffset = GetMinimumTextureGatherOffset(featureLevel);
1568 caps->maxProgramTextureGatherOffset = GetMaximumTextureGatherOffset(featureLevel);
1569
1570 caps->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
1571 caps->queryCounterBitsTimeElapsed = 64;
1572 caps->queryCounterBitsTimestamp = 0; // Timestamps cannot be supported due to D3D11 limitations
1573 caps->maxDualSourceDrawBuffers = 1;
1574
1575 // GL extension support
1576 extensions->setTextureExtensionSupport(*textureCapsMap);
1577
1578 // Explicitly disable GL_OES_compressed_ETC1_RGB8_texture because it's emulated and never
1579 // becomes core. WebGL doesn't want to expose it unless there is native support.
1580 extensions->compressedETC1RGB8TextureOES = false;
1581 extensions->compressedETC1RGB8SubTextureEXT = false;
1582
1583 extensions->elementIndexUintOES = true;
1584 extensions->getProgramBinaryOES = true;
1585 extensions->rgb8Rgba8OES = true;
1586 extensions->readFormatBgraEXT = true;
1587 extensions->pixelBufferObjectNV = true;
1588 extensions->mapbufferOES = true;
1589 extensions->mapBufferRangeEXT = true;
1590 extensions->textureNpotOES = GetNPOTTextureSupport(featureLevel);
1591 extensions->drawBuffersEXT = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
1592 extensions->drawBuffersIndexedEXT =
1593 (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_1);
1594 extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT;
1595 extensions->textureStorageEXT = true;
1596 extensions->textureFilterAnisotropicEXT = true;
1597 extensions->occlusionQueryBooleanEXT = GetOcclusionQuerySupport(featureLevel);
1598 extensions->fenceNV = GetEventQuerySupport(featureLevel);
1599 extensions->disjointTimerQueryEXT = true;
1600 extensions->robustnessEXT = true;
1601 // Direct3D guarantees to return zero for any resource that is accessed out of bounds.
1602 // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx
1603 // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx
1604 extensions->robustBufferAccessBehaviorKHR = true;
1605 extensions->blendMinmaxEXT = true;
1606 // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware
1607 extensions->floatBlendEXT = true;
1608 extensions->framebufferBlitANGLE = GetFramebufferBlitSupport(featureLevel);
1609 extensions->framebufferBlitNV = extensions->framebufferBlitANGLE;
1610 extensions->framebufferMultisampleANGLE = GetFramebufferMultisampleSupport(featureLevel);
1611 extensions->instancedArraysANGLE = GetInstancingSupport(featureLevel);
1612 extensions->instancedArraysEXT = GetInstancingSupport(featureLevel);
1613 extensions->packReverseRowOrderANGLE = true;
1614 extensions->standardDerivativesOES = GetDerivativeInstructionSupport(featureLevel);
1615 extensions->shaderTextureLodEXT = GetShaderTextureLODSupport(featureLevel);
1616 extensions->fragDepthEXT = true;
1617 extensions->multiviewOVR = IsMultiviewSupported(featureLevel);
1618 extensions->multiview2OVR = IsMultiviewSupported(featureLevel);
1619 if (extensions->multiviewOVR || extensions->multiview2OVR)
1620 {
1621 caps->maxViews = std::min(static_cast<GLuint>(GetMaximum2DTextureArraySize(featureLevel)),
1622 GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel));
1623 }
1624 extensions->textureUsageANGLE = true; // This could be false since it has no effect in D3D11
1625 extensions->discardFramebufferEXT = true;
1626 extensions->translatedShaderSourceANGLE = true;
1627 extensions->fboRenderMipmapOES = true;
1628 extensions->debugMarkerEXT = true;
1629 extensions->EGLImageOES = true;
1630 extensions->EGLImageExternalOES = true;
1631 extensions->EGLImageExternalWrapModesEXT = true;
1632 extensions->EGLImageExternalEssl3OES = true;
1633 extensions->EGLStreamConsumerExternalNV = true;
1634 extensions->unpackSubimageEXT = true;
1635 extensions->packSubimageNV = true;
1636 extensions->lossyEtcDecodeANGLE = true;
1637 extensions->syncQueryCHROMIUM = GetEventQuerySupport(featureLevel);
1638 extensions->copyTextureCHROMIUM = true;
1639 extensions->copyCompressedTextureCHROMIUM = true;
1640 extensions->textureStorageMultisample2dArrayOES = true;
1641 extensions->multiviewMultisampleANGLE =
1642 ((extensions->multiviewOVR || extensions->multiview2OVR) &&
1643 extensions->textureStorageMultisample2dArrayOES);
1644 extensions->copyTexture3dANGLE = true;
1645 extensions->textureBorderClampOES = true;
1646 extensions->multiDrawIndirectEXT = true;
1647 extensions->textureMultisampleANGLE = true;
1648 extensions->provokingVertexANGLE = true;
1649 extensions->blendFuncExtendedEXT = true;
1650 // http://anglebug.com/4926
1651 extensions->texture3DOES = false;
1652 extensions->baseVertexBaseInstanceANGLE = true;
1653 extensions->baseVertexBaseInstanceShaderBuiltinANGLE = true;
1654 extensions->drawElementsBaseVertexOES = true;
1655 extensions->drawElementsBaseVertexEXT = true;
1656 if (!strstr(description, "Adreno"))
1657 {
1658 extensions->multisampledRenderToTextureEXT = true;
1659 }
1660 extensions->videoTextureWEBGL = true;
1661
1662 // D3D11 cannot support reading depth texture as a luminance texture.
1663 // It treats it as a red-channel-only texture.
1664 extensions->depthTextureOES = false;
1665
1666 // readPixels on depth & stencil not working with D3D11 backend.
1667 extensions->readDepthNV = false;
1668 extensions->readStencilNV = false;
1669 extensions->depthBufferFloat2NV = false;
1670
1671 // GL_EXT_clip_control
1672 extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3);
1673
1674 // GL_KHR_parallel_shader_compile
1675 extensions->parallelShaderCompileKHR = true;
1676
1677 // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing.
1678 // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't
1679 // support gl_FrontFacing.
1680 limitations->noFrontFacingSupport =
1681 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
1682
1683 // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage
1684 limitations->noSampleAlphaToCoverageSupport =
1685 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
1686
1687 // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require
1688 // additional
1689 // pre-validation of the shader at compile time to produce a better error message.
1690 limitations->shadersRequireIndexedLoopValidation =
1691 (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
1692
1693 // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil
1694 // state.
1695 limitations->noSeparateStencilRefsAndMasks = true;
1696
1697 // D3D11 cannot support constant color and alpha blend funcs together
1698 limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;
1699
1700 // D3D11 does not support multiple transform feedback outputs writing to the same buffer.
1701 limitations->noDoubleBoundTransformFeedbackBuffers = true;
1702
1703 // D3D11 does not support vertex attribute aliasing
1704 limitations->noVertexAttributeAliasing = true;
1705
1706 // D3D11 does not support compressed textures where the base mip level is not a multiple of 4
1707 limitations->compressedBaseMipLevelMultipleOfFour = true;
1708
1709 #ifdef ANGLE_ENABLE_WINDOWS_UWP
1710 // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era
1711 // devices. We should prevent developers from doing this on ALL Windows Store devices. This will
1712 // maintain consistency across all Windows devices. We allow non-zero divisors on attribute zero
1713 // if the Client Version >= 3, since devices affected by this issue don't support ES3+.
1714 limitations->attributeZeroRequiresZeroDivisorInEXT = true;
1715 #endif
1716 }
1717
1718 } // namespace d3d11_gl
1719
1720 namespace gl_d3d11
1721 {
1722
ConvertBlendFunc(GLenum glBlend,bool isAlpha)1723 D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
1724 {
1725 D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
1726
1727 switch (glBlend)
1728 {
1729 case GL_ZERO:
1730 d3dBlend = D3D11_BLEND_ZERO;
1731 break;
1732 case GL_ONE:
1733 d3dBlend = D3D11_BLEND_ONE;
1734 break;
1735 case GL_SRC_COLOR:
1736 d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);
1737 break;
1738 case GL_ONE_MINUS_SRC_COLOR:
1739 d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);
1740 break;
1741 case GL_DST_COLOR:
1742 d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);
1743 break;
1744 case GL_ONE_MINUS_DST_COLOR:
1745 d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR);
1746 break;
1747 case GL_SRC_ALPHA:
1748 d3dBlend = D3D11_BLEND_SRC_ALPHA;
1749 break;
1750 case GL_ONE_MINUS_SRC_ALPHA:
1751 d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;
1752 break;
1753 case GL_DST_ALPHA:
1754 d3dBlend = D3D11_BLEND_DEST_ALPHA;
1755 break;
1756 case GL_ONE_MINUS_DST_ALPHA:
1757 d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;
1758 break;
1759 case GL_CONSTANT_COLOR:
1760 d3dBlend = D3D11_BLEND_BLEND_FACTOR;
1761 break;
1762 case GL_ONE_MINUS_CONSTANT_COLOR:
1763 d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
1764 break;
1765 case GL_CONSTANT_ALPHA:
1766 d3dBlend = D3D11_BLEND_BLEND_FACTOR;
1767 break;
1768 case GL_ONE_MINUS_CONSTANT_ALPHA:
1769 d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
1770 break;
1771 case GL_SRC_ALPHA_SATURATE:
1772 d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;
1773 break;
1774 case GL_SRC1_COLOR_EXT:
1775 d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR);
1776 break;
1777 case GL_SRC1_ALPHA_EXT:
1778 d3dBlend = D3D11_BLEND_SRC1_ALPHA;
1779 break;
1780 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1781 d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR);
1782 break;
1783 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1784 d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA;
1785 break;
1786 default:
1787 UNREACHABLE();
1788 }
1789
1790 return d3dBlend;
1791 }
1792
ConvertBlendOp(GLenum glBlendOp)1793 D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
1794 {
1795 D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
1796
1797 switch (glBlendOp)
1798 {
1799 case GL_FUNC_ADD:
1800 d3dBlendOp = D3D11_BLEND_OP_ADD;
1801 break;
1802 case GL_FUNC_SUBTRACT:
1803 d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;
1804 break;
1805 case GL_FUNC_REVERSE_SUBTRACT:
1806 d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
1807 break;
1808 case GL_MIN:
1809 d3dBlendOp = D3D11_BLEND_OP_MIN;
1810 break;
1811 case GL_MAX:
1812 d3dBlendOp = D3D11_BLEND_OP_MAX;
1813 break;
1814 default:
1815 UNREACHABLE();
1816 }
1817
1818 return d3dBlendOp;
1819 }
1820
ConvertColorMask(bool red,bool green,bool blue,bool alpha)1821 UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
1822 {
1823 UINT8 mask = 0;
1824 if (red)
1825 {
1826 mask |= D3D11_COLOR_WRITE_ENABLE_RED;
1827 }
1828 if (green)
1829 {
1830 mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
1831 }
1832 if (blue)
1833 {
1834 mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
1835 }
1836 if (alpha)
1837 {
1838 mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
1839 }
1840 return mask;
1841 }
1842
ConvertCullMode(bool cullEnabled,gl::CullFaceMode cullMode)1843 D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode)
1844 {
1845 D3D11_CULL_MODE cull = D3D11_CULL_NONE;
1846
1847 if (cullEnabled)
1848 {
1849 switch (cullMode)
1850 {
1851 case gl::CullFaceMode::Front:
1852 cull = D3D11_CULL_FRONT;
1853 break;
1854 case gl::CullFaceMode::Back:
1855 cull = D3D11_CULL_BACK;
1856 break;
1857 case gl::CullFaceMode::FrontAndBack:
1858 cull = D3D11_CULL_NONE;
1859 break;
1860 default:
1861 UNREACHABLE();
1862 }
1863 }
1864 else
1865 {
1866 cull = D3D11_CULL_NONE;
1867 }
1868
1869 return cull;
1870 }
1871
ConvertComparison(GLenum comparison)1872 D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
1873 {
1874 D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
1875 switch (comparison)
1876 {
1877 case GL_NEVER:
1878 d3dComp = D3D11_COMPARISON_NEVER;
1879 break;
1880 case GL_ALWAYS:
1881 d3dComp = D3D11_COMPARISON_ALWAYS;
1882 break;
1883 case GL_LESS:
1884 d3dComp = D3D11_COMPARISON_LESS;
1885 break;
1886 case GL_LEQUAL:
1887 d3dComp = D3D11_COMPARISON_LESS_EQUAL;
1888 break;
1889 case GL_EQUAL:
1890 d3dComp = D3D11_COMPARISON_EQUAL;
1891 break;
1892 case GL_GREATER:
1893 d3dComp = D3D11_COMPARISON_GREATER;
1894 break;
1895 case GL_GEQUAL:
1896 d3dComp = D3D11_COMPARISON_GREATER_EQUAL;
1897 break;
1898 case GL_NOTEQUAL:
1899 d3dComp = D3D11_COMPARISON_NOT_EQUAL;
1900 break;
1901 default:
1902 UNREACHABLE();
1903 }
1904
1905 return d3dComp;
1906 }
1907
ConvertDepthMask(bool depthWriteEnabled)1908 D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
1909 {
1910 return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
1911 }
1912
ConvertStencilMask(GLuint stencilmask)1913 UINT8 ConvertStencilMask(GLuint stencilmask)
1914 {
1915 return static_cast<UINT8>(stencilmask);
1916 }
1917
ConvertStencilOp(GLenum stencilOp)1918 D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
1919 {
1920 D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
1921
1922 switch (stencilOp)
1923 {
1924 case GL_ZERO:
1925 d3dStencilOp = D3D11_STENCIL_OP_ZERO;
1926 break;
1927 case GL_KEEP:
1928 d3dStencilOp = D3D11_STENCIL_OP_KEEP;
1929 break;
1930 case GL_REPLACE:
1931 d3dStencilOp = D3D11_STENCIL_OP_REPLACE;
1932 break;
1933 case GL_INCR:
1934 d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;
1935 break;
1936 case GL_DECR:
1937 d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;
1938 break;
1939 case GL_INVERT:
1940 d3dStencilOp = D3D11_STENCIL_OP_INVERT;
1941 break;
1942 case GL_INCR_WRAP:
1943 d3dStencilOp = D3D11_STENCIL_OP_INCR;
1944 break;
1945 case GL_DECR_WRAP:
1946 d3dStencilOp = D3D11_STENCIL_OP_DECR;
1947 break;
1948 default:
1949 UNREACHABLE();
1950 }
1951
1952 return d3dStencilOp;
1953 }
1954
ConvertFilter(GLenum minFilter,GLenum magFilter,float maxAnisotropy,GLenum comparisonMode)1955 D3D11_FILTER ConvertFilter(GLenum minFilter,
1956 GLenum magFilter,
1957 float maxAnisotropy,
1958 GLenum comparisonMode)
1959 {
1960 bool comparison = comparisonMode != GL_NONE;
1961
1962 if (maxAnisotropy > 1.0f)
1963 {
1964 return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
1965 }
1966 else
1967 {
1968 D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
1969 D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
1970 switch (minFilter)
1971 {
1972 case GL_NEAREST:
1973 dxMin = D3D11_FILTER_TYPE_POINT;
1974 dxMip = D3D11_FILTER_TYPE_POINT;
1975 break;
1976 case GL_LINEAR:
1977 dxMin = D3D11_FILTER_TYPE_LINEAR;
1978 dxMip = D3D11_FILTER_TYPE_POINT;
1979 break;
1980 case GL_NEAREST_MIPMAP_NEAREST:
1981 dxMin = D3D11_FILTER_TYPE_POINT;
1982 dxMip = D3D11_FILTER_TYPE_POINT;
1983 break;
1984 case GL_LINEAR_MIPMAP_NEAREST:
1985 dxMin = D3D11_FILTER_TYPE_LINEAR;
1986 dxMip = D3D11_FILTER_TYPE_POINT;
1987 break;
1988 case GL_NEAREST_MIPMAP_LINEAR:
1989 dxMin = D3D11_FILTER_TYPE_POINT;
1990 dxMip = D3D11_FILTER_TYPE_LINEAR;
1991 break;
1992 case GL_LINEAR_MIPMAP_LINEAR:
1993 dxMin = D3D11_FILTER_TYPE_LINEAR;
1994 dxMip = D3D11_FILTER_TYPE_LINEAR;
1995 break;
1996 default:
1997 UNREACHABLE();
1998 }
1999
2000 D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
2001 switch (magFilter)
2002 {
2003 case GL_NEAREST:
2004 dxMag = D3D11_FILTER_TYPE_POINT;
2005 break;
2006 case GL_LINEAR:
2007 dxMag = D3D11_FILTER_TYPE_LINEAR;
2008 break;
2009 default:
2010 UNREACHABLE();
2011 }
2012
2013 return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip,
2014 static_cast<D3D11_COMPARISON_FUNC>(comparison));
2015 }
2016 }
2017
ConvertTextureWrap(GLenum wrap)2018 D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
2019 {
2020 switch (wrap)
2021 {
2022 case GL_REPEAT:
2023 return D3D11_TEXTURE_ADDRESS_WRAP;
2024 case GL_CLAMP_TO_EDGE:
2025 return D3D11_TEXTURE_ADDRESS_CLAMP;
2026 case GL_CLAMP_TO_BORDER:
2027 return D3D11_TEXTURE_ADDRESS_BORDER;
2028 case GL_MIRRORED_REPEAT:
2029 return D3D11_TEXTURE_ADDRESS_MIRROR;
2030 default:
2031 UNREACHABLE();
2032 }
2033
2034 return D3D11_TEXTURE_ADDRESS_WRAP;
2035 }
2036
ConvertMaxAnisotropy(float maxAnisotropy,D3D_FEATURE_LEVEL featureLevel)2037 UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel)
2038 {
2039 return static_cast<UINT>(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel)));
2040 }
2041
ConvertQueryType(gl::QueryType type)2042 D3D11_QUERY ConvertQueryType(gl::QueryType type)
2043 {
2044 switch (type)
2045 {
2046 case gl::QueryType::AnySamples:
2047 case gl::QueryType::AnySamplesConservative:
2048 return D3D11_QUERY_OCCLUSION;
2049 case gl::QueryType::TransformFeedbackPrimitivesWritten:
2050 return D3D11_QUERY_SO_STATISTICS;
2051 case gl::QueryType::TimeElapsed:
2052 // Two internal queries are also created for begin/end timestamps
2053 return D3D11_QUERY_TIMESTAMP_DISJOINT;
2054 case gl::QueryType::CommandsCompleted:
2055 return D3D11_QUERY_EVENT;
2056 default:
2057 UNREACHABLE();
2058 return D3D11_QUERY_EVENT;
2059 }
2060 }
2061
2062 // Get the D3D11 write mask covering all color channels of a given format
GetColorMask(const gl::InternalFormat & format)2063 UINT8 GetColorMask(const gl::InternalFormat &format)
2064 {
2065 return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0,
2066 format.alphaBits > 0);
2067 }
2068
2069 } // namespace gl_d3d11
2070
2071 namespace d3d11
2072 {
2073
GetDeviceType(ID3D11Device * device)2074 ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device)
2075 {
2076 // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value,
2077 // since it is difficult to tell Software and Reference devices apart
2078
2079 IDXGIDevice *dxgiDevice = nullptr;
2080 IDXGIAdapter *dxgiAdapter = nullptr;
2081 IDXGIAdapter2 *dxgiAdapter2 = nullptr;
2082
2083 ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN;
2084
2085 HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
2086 if (SUCCEEDED(hr))
2087 {
2088 hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
2089 if (SUCCEEDED(hr))
2090 {
2091 std::wstring adapterString;
2092 HRESULT adapter2hr =
2093 dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2);
2094 if (SUCCEEDED(adapter2hr))
2095 {
2096 // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter"
2097 // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the
2098 // actual hardware values if possible.
2099 DXGI_ADAPTER_DESC2 adapterDesc2;
2100 dxgiAdapter2->GetDesc2(&adapterDesc2);
2101 adapterString = std::wstring(adapterDesc2.Description);
2102 }
2103 else
2104 {
2105 DXGI_ADAPTER_DESC adapterDesc;
2106 dxgiAdapter->GetDesc(&adapterDesc);
2107 adapterString = std::wstring(adapterDesc.Description);
2108 }
2109
2110 // Both Reference and Software adapters will be 'Software Adapter'
2111 const bool isSoftwareDevice =
2112 (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos);
2113 const bool isNullDevice = (adapterString == L"");
2114 const bool isWARPDevice =
2115 (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos);
2116
2117 if (isSoftwareDevice || isNullDevice)
2118 {
2119 ASSERT(!isWARPDevice);
2120 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
2121 }
2122 else if (isWARPDevice)
2123 {
2124 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP;
2125 }
2126 else
2127 {
2128 retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
2129 }
2130 }
2131 }
2132
2133 SafeRelease(dxgiDevice);
2134 SafeRelease(dxgiAdapter);
2135 SafeRelease(dxgiAdapter2);
2136
2137 return retDeviceType;
2138 }
2139
MakeValidSize(bool isImage,DXGI_FORMAT format,GLsizei * requestWidth,GLsizei * requestHeight,int * levelOffset)2140 void MakeValidSize(bool isImage,
2141 DXGI_FORMAT format,
2142 GLsizei *requestWidth,
2143 GLsizei *requestHeight,
2144 int *levelOffset)
2145 {
2146 const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format);
2147 bool validFormat = format != DXGI_FORMAT_UNKNOWN;
2148 bool validImage = isImage && validFormat;
2149
2150 int upsampleCount = 0;
2151 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
2152 if (validImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
2153 *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
2154 {
2155 while (*requestWidth % dxgiFormatInfo.blockWidth != 0 ||
2156 *requestHeight % dxgiFormatInfo.blockHeight != 0)
2157 {
2158 *requestWidth <<= 1;
2159 *requestHeight <<= 1;
2160 upsampleCount++;
2161 }
2162 }
2163 else if (validFormat)
2164 {
2165 if (*requestWidth % dxgiFormatInfo.blockWidth != 0)
2166 {
2167 *requestWidth = roundUp(*requestWidth, static_cast<GLsizei>(dxgiFormatInfo.blockWidth));
2168 }
2169
2170 if (*requestHeight % dxgiFormatInfo.blockHeight != 0)
2171 {
2172 *requestHeight =
2173 roundUp(*requestHeight, static_cast<GLsizei>(dxgiFormatInfo.blockHeight));
2174 }
2175 }
2176
2177 if (levelOffset)
2178 {
2179 *levelOffset = upsampleCount;
2180 }
2181 }
2182
GenerateInitialTextureData(const gl::Context * context,GLint internalFormat,const Renderer11DeviceCaps & renderer11DeviceCaps,GLuint width,GLuint height,GLuint depth,GLuint mipLevels,gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> * outSubresourceData)2183 angle::Result GenerateInitialTextureData(
2184 const gl::Context *context,
2185 GLint internalFormat,
2186 const Renderer11DeviceCaps &renderer11DeviceCaps,
2187 GLuint width,
2188 GLuint height,
2189 GLuint depth,
2190 GLuint mipLevels,
2191 gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData)
2192 {
2193 const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
2194 ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr);
2195
2196 const d3d11::DXGIFormatSize &dxgiFormatInfo =
2197 d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat);
2198
2199 using CheckedSize = angle::CheckedNumeric<size_t>;
2200 CheckedSize rowPitch = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width);
2201 CheckedSize depthPitch = rowPitch * CheckedSize(height);
2202 CheckedSize maxImageSize = depthPitch * CheckedSize(depth);
2203
2204 Context11 *context11 = GetImplAs<Context11>(context);
2205 ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid());
2206
2207 angle::MemoryBuffer *scratchBuffer = nullptr;
2208 ANGLE_CHECK_GL_ALLOC(context11,
2209 context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer));
2210
2211 d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(),
2212 rowPitch.ValueOrDie(), depthPitch.ValueOrDie());
2213
2214 for (unsigned int i = 0; i < mipLevels; i++)
2215 {
2216 unsigned int mipWidth = std::max(width >> i, 1U);
2217 unsigned int mipHeight = std::max(height >> i, 1U);
2218
2219 using CheckedUINT = angle::CheckedNumeric<UINT>;
2220 CheckedUINT mipRowPitch = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth);
2221 CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight);
2222
2223 ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid());
2224
2225 outSubresourceData->at(i).pSysMem = scratchBuffer->data();
2226 outSubresourceData->at(i).SysMemPitch = mipRowPitch.ValueOrDie();
2227 outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie();
2228 }
2229
2230 return angle::Result::Continue;
2231 }
2232
GetPrimitiveRestartIndex()2233 UINT GetPrimitiveRestartIndex()
2234 {
2235 return std::numeric_limits<UINT>::max();
2236 }
2237
SetPositionTexCoordVertex(PositionTexCoordVertex * vertex,float x,float y,float u,float v)2238 void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v)
2239 {
2240 vertex->x = x;
2241 vertex->y = y;
2242 vertex->u = u;
2243 vertex->v = v;
2244 }
2245
SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex * vertex,float x,float y,unsigned int layer,float u,float v,float s)2246 void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
2247 float x,
2248 float y,
2249 unsigned int layer,
2250 float u,
2251 float v,
2252 float s)
2253 {
2254 vertex->x = x;
2255 vertex->y = y;
2256 vertex->l = layer;
2257 vertex->u = u;
2258 vertex->v = v;
2259 vertex->s = s;
2260 }
2261
BlendStateKey()2262 BlendStateKey::BlendStateKey()
2263 {
2264 memset(this, 0, sizeof(BlendStateKey));
2265 blendStateExt = gl::BlendStateExt();
2266 }
2267
BlendStateKey(const BlendStateKey & other)2268 BlendStateKey::BlendStateKey(const BlendStateKey &other)
2269 {
2270 memcpy(this, &other, sizeof(BlendStateKey));
2271 }
2272
operator ==(const BlendStateKey & a,const BlendStateKey & b)2273 bool operator==(const BlendStateKey &a, const BlendStateKey &b)
2274 {
2275 return memcmp(&a, &b, sizeof(BlendStateKey)) == 0;
2276 }
2277
operator !=(const BlendStateKey & a,const BlendStateKey & b)2278 bool operator!=(const BlendStateKey &a, const BlendStateKey &b)
2279 {
2280 return !(a == b);
2281 }
2282
RasterizerStateKey()2283 RasterizerStateKey::RasterizerStateKey()
2284 {
2285 memset(this, 0, sizeof(RasterizerStateKey));
2286 }
2287
operator ==(const RasterizerStateKey & a,const RasterizerStateKey & b)2288 bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b)
2289 {
2290 return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
2291 }
2292
operator !=(const RasterizerStateKey & a,const RasterizerStateKey & b)2293 bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b)
2294 {
2295 return !(a == b);
2296 }
2297
SetDebugName(ID3D11DeviceChild * resource,const char * internalName,const std::string * khrDebugName)2298 HRESULT SetDebugName(ID3D11DeviceChild *resource,
2299 const char *internalName,
2300 const std::string *khrDebugName)
2301 {
2302 // Prepend ANGLE to separate names from other components in the same process.
2303 std::string d3dName = "ANGLE";
2304 bool sendNameToD3D = false;
2305 if (internalName && internalName[0] != '\0')
2306 {
2307 d3dName += std::string("_") + internalName;
2308 sendNameToD3D = true;
2309 }
2310 if (khrDebugName && !khrDebugName->empty())
2311 {
2312 d3dName += std::string("_") + *khrDebugName;
2313 sendNameToD3D = true;
2314 }
2315 // If both internalName and khrDebugName are empty, avoid sending the string to d3d.
2316 if (sendNameToD3D)
2317 {
2318 return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
2319 static_cast<UINT>(d3dName.size()), d3dName.c_str());
2320 }
2321 return S_OK;
2322 }
2323
2324 // Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling
2325 // allocateResource is only compatible with Clang and MSVS, which support calling a
2326 // method on a forward declared class in a template.
2327 template <ResourceType ResourceT>
resolveImpl(d3d::Context * context,Renderer11 * renderer,const GetDescType<ResourceT> & desc,GetInitDataType<ResourceT> * initData,const char * name)2328 angle::Result LazyResource<ResourceT>::resolveImpl(d3d::Context *context,
2329 Renderer11 *renderer,
2330 const GetDescType<ResourceT> &desc,
2331 GetInitDataType<ResourceT> *initData,
2332 const char *name)
2333 {
2334 if (!mResource.valid())
2335 {
2336 ANGLE_TRY(renderer->allocateResource(context, desc, initData, &mResource));
2337 mResource.setInternalName(name);
2338 }
2339 return angle::Result::Continue;
2340 }
2341
2342 template angle::Result LazyResource<ResourceType::BlendState>::resolveImpl(
2343 d3d::Context *context,
2344 Renderer11 *renderer,
2345 const D3D11_BLEND_DESC &desc,
2346 void *initData,
2347 const char *name);
2348 template angle::Result LazyResource<ResourceType::ComputeShader>::resolveImpl(
2349 d3d::Context *context,
2350 Renderer11 *renderer,
2351 const ShaderData &desc,
2352 void *initData,
2353 const char *name);
2354 template angle::Result LazyResource<ResourceType::GeometryShader>::resolveImpl(
2355 d3d::Context *context,
2356 Renderer11 *renderer,
2357 const ShaderData &desc,
2358 const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
2359 const char *name);
2360 template angle::Result LazyResource<ResourceType::InputLayout>::resolveImpl(
2361 d3d::Context *context,
2362 Renderer11 *renderer,
2363 const InputElementArray &desc,
2364 const ShaderData *initData,
2365 const char *name);
2366 template angle::Result LazyResource<ResourceType::PixelShader>::resolveImpl(d3d::Context *context,
2367 Renderer11 *renderer,
2368 const ShaderData &desc,
2369 void *initData,
2370 const char *name);
2371 template angle::Result LazyResource<ResourceType::VertexShader>::resolveImpl(d3d::Context *context,
2372 Renderer11 *renderer,
2373 const ShaderData &desc,
2374 void *initData,
2375 const char *name);
2376
LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC * inputDesc,size_t inputDescLen,const BYTE * byteCode,size_t byteCodeLen,const char * debugName)2377 LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
2378 size_t inputDescLen,
2379 const BYTE *byteCode,
2380 size_t byteCodeLen,
2381 const char *debugName)
2382 : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName)
2383 {}
2384
~LazyInputLayout()2385 LazyInputLayout::~LazyInputLayout() {}
2386
resolve(d3d::Context * context,Renderer11 * renderer)2387 angle::Result LazyInputLayout::resolve(d3d::Context *context, Renderer11 *renderer)
2388 {
2389 return resolveImpl(context, renderer, mInputDesc, &mByteCode, mDebugName);
2390 }
2391
LazyBlendState(const D3D11_BLEND_DESC & desc,const char * debugName)2392 LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
2393 : mDesc(desc), mDebugName(debugName)
2394 {}
2395
resolve(d3d::Context * context,Renderer11 * renderer)2396 angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *renderer)
2397 {
2398 return resolveImpl(context, renderer, mDesc, nullptr, mDebugName);
2399 }
2400
InitializeFeatures(const Renderer11DeviceCaps & deviceCaps,const DXGI_ADAPTER_DESC & adapterDesc,angle::FeaturesD3D * features)2401 void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
2402 const DXGI_ADAPTER_DESC &adapterDesc,
2403 angle::FeaturesD3D *features)
2404 {
2405 bool isNvidia = IsNvidia(adapterDesc.VendorId);
2406 bool isIntel = IsIntel(adapterDesc.VendorId);
2407 bool isSkylake = false;
2408 bool isBroadwell = false;
2409 bool isHaswell = false;
2410 bool isIvyBridge = false;
2411 bool isAMD = IsAMD(adapterDesc.VendorId);
2412 bool isFeatureLevel9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
2413
2414 IntelDriverVersion capsVersion = IntelDriverVersion(0);
2415 if (isIntel)
2416 {
2417 capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion);
2418
2419 isSkylake = IsSkylake(adapterDesc.DeviceId);
2420 isBroadwell = IsBroadwell(adapterDesc.DeviceId);
2421 isHaswell = IsHaswell(adapterDesc.DeviceId);
2422 isIvyBridge = IsIvyBridge(adapterDesc.DeviceId);
2423 }
2424
2425 if (isNvidia)
2426 {
2427 // TODO(jmadill): Narrow problematic driver range.
2428 bool driverVersionValid = deviceCaps.driverVersion.valid();
2429 if (driverVersionValid)
2430 {
2431 WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart);
2432 WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart);
2433
2434 // Disable the workaround to fix a second driver bug on newer NVIDIA.
2435 ANGLE_FEATURE_CONDITION(
2436 features, depthStencilBlitExtraCopy,
2437 (part1 <= 13u && part2 < 6881) && isNvidia && driverVersionValid);
2438 }
2439 else
2440 {
2441 ANGLE_FEATURE_CONDITION(features, depthStencilBlitExtraCopy,
2442 isNvidia && !driverVersionValid);
2443 }
2444 }
2445
2446 ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true);
2447 ANGLE_FEATURE_CONDITION(features, zeroMaxLodWorkaround, isFeatureLevel9_3);
2448 ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, isFeatureLevel9_3);
2449 ANGLE_FEATURE_CONDITION(features, allowES3OnFL100, false);
2450
2451 // TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
2452 ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true);
2453
2454 ANGLE_FEATURE_CONDITION(features, flushAfterEndingTransformFeedback, isNvidia);
2455 ANGLE_FEATURE_CONDITION(features, getDimensionsIgnoresBaseLevel, isNvidia);
2456 ANGLE_FEATURE_CONDITION(features, skipVSConstantRegisterZero, isNvidia);
2457 ANGLE_FEATURE_CONDITION(features, forceAtomicValueResolution, isNvidia);
2458
2459 ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, isIntel);
2460 ANGLE_FEATURE_CONDITION(features, useSystemMemoryForConstantBuffers, isIntel);
2461
2462 ANGLE_FEATURE_CONDITION(features, callClearTwice,
2463 isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
2464 capsVersion < IntelDriverVersion(164771));
2465 ANGLE_FEATURE_CONDITION(features, emulateIsnanFloat,
2466 isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
2467 capsVersion < IntelDriverVersion(164542));
2468 ANGLE_FEATURE_CONDITION(features, rewriteUnaryMinusOperator,
2469 isIntel && (isBroadwell || isHaswell) &&
2470 capsVersion >= IntelDriverVersion(150000) &&
2471 capsVersion < IntelDriverVersion(154624));
2472
2473 ANGLE_FEATURE_CONDITION(features, addMockTextureNoRenderTarget,
2474 isIntel && capsVersion >= IntelDriverVersion(160000) &&
2475 capsVersion < IntelDriverVersion(164815));
2476
2477 // Haswell/Ivybridge drivers occasionally corrupt (small?) (vertex?) texture data uploads.
2478 ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload,
2479 !(isIvyBridge || isBroadwell || isHaswell));
2480
2481 ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support,
2482 (isIntel && capsVersion >= IntelDriverVersion(150000) &&
2483 capsVersion < IntelDriverVersion(154539)) ||
2484 isAMD);
2485
2486 // TODO(jmadill): Disable when we have a fixed driver version.
2487 // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a
2488 // depth stencil texture. This is not allowed until feature level 10.1 but since it is not
2489 // possible to support ES3 on these devices, there is no need for the workaround to begin with
2490 // (anglebug.com/1572).
2491 ANGLE_FEATURE_CONDITION(features, emulateTinyStencilTextures,
2492 isAMD && !(deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1));
2493
2494 // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to
2495 // select the viewport / RT array index in the geometry shader.
2496 ANGLE_FEATURE_CONDITION(features, selectViewInGeometryShader,
2497 !deviceCaps.supportsVpRtIndexWriteFromVertexShader);
2498
2499 // NVidia drivers have no trouble clearing textures without showing corruption.
2500 // Intel and AMD drivers that have trouble have been blocklisted by Chromium. In the case of
2501 // Intel, they've been blocklisted to the DX9 runtime.
2502 ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true);
2503
2504 // Allow translating uniform block to StructuredBuffer on Windows 10. This is targeted
2505 // to work around a slow fxc compile performance issue with dynamic uniform indexing.
2506 ANGLE_FEATURE_CONDITION(features, allowTranslateUniformBlockToStructuredBuffer,
2507 IsWin10OrGreater());
2508 }
2509
InitConstantBufferDesc(D3D11_BUFFER_DESC * constantBufferDescription,size_t byteWidth)2510 void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth)
2511 {
2512 constantBufferDescription->ByteWidth = static_cast<UINT>(byteWidth);
2513 constantBufferDescription->Usage = D3D11_USAGE_DYNAMIC;
2514 constantBufferDescription->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2515 constantBufferDescription->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2516 constantBufferDescription->MiscFlags = 0;
2517 constantBufferDescription->StructureByteStride = 0;
2518 }
2519
2520 } // namespace d3d11
2521
2522 // TextureHelper11 implementation.
TextureHelper11()2523 TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) {}
2524
TextureHelper11(TextureHelper11 && toCopy)2525 TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11()
2526 {
2527 *this = std::move(toCopy);
2528 }
2529
TextureHelper11(const TextureHelper11 & other)2530 TextureHelper11::TextureHelper11(const TextureHelper11 &other)
2531 : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount)
2532 {
2533 mData = other.mData;
2534 }
2535
~TextureHelper11()2536 TextureHelper11::~TextureHelper11() {}
2537
getDesc(D3D11_TEXTURE2D_DESC * desc) const2538 void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const
2539 {
2540 static_cast<ID3D11Texture2D *>(mData->object)->GetDesc(desc);
2541 }
2542
getDesc(D3D11_TEXTURE3D_DESC * desc) const2543 void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const
2544 {
2545 static_cast<ID3D11Texture3D *>(mData->object)->GetDesc(desc);
2546 }
2547
initDesc(const D3D11_TEXTURE2D_DESC & desc2D)2548 void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D)
2549 {
2550 mData->resourceType = ResourceType::Texture2D;
2551 mExtents.width = static_cast<int>(desc2D.Width);
2552 mExtents.height = static_cast<int>(desc2D.Height);
2553 mExtents.depth = 1;
2554 mSampleCount = desc2D.SampleDesc.Count;
2555 }
2556
initDesc(const D3D11_TEXTURE3D_DESC & desc3D)2557 void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D)
2558 {
2559 mData->resourceType = ResourceType::Texture3D;
2560 mExtents.width = static_cast<int>(desc3D.Width);
2561 mExtents.height = static_cast<int>(desc3D.Height);
2562 mExtents.depth = static_cast<int>(desc3D.Depth);
2563 mSampleCount = 1;
2564 }
2565
operator =(TextureHelper11 && other)2566 TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other)
2567 {
2568 std::swap(mData, other.mData);
2569 std::swap(mExtents, other.mExtents);
2570 std::swap(mFormatSet, other.mFormatSet);
2571 std::swap(mSampleCount, other.mSampleCount);
2572 return *this;
2573 }
2574
operator =(const TextureHelper11 & other)2575 TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other)
2576 {
2577 mData = other.mData;
2578 mExtents = other.mExtents;
2579 mFormatSet = other.mFormatSet;
2580 mSampleCount = other.mSampleCount;
2581 return *this;
2582 }
2583
operator ==(const TextureHelper11 & other) const2584 bool TextureHelper11::operator==(const TextureHelper11 &other) const
2585 {
2586 return mData->object == other.mData->object;
2587 }
2588
operator !=(const TextureHelper11 & other) const2589 bool TextureHelper11::operator!=(const TextureHelper11 &other) const
2590 {
2591 return mData->object != other.mData->object;
2592 }
2593
UsePresentPathFast(const Renderer11 * renderer,const gl::FramebufferAttachment * framebufferAttachment)2594 bool UsePresentPathFast(const Renderer11 *renderer,
2595 const gl::FramebufferAttachment *framebufferAttachment)
2596 {
2597 if (framebufferAttachment == nullptr)
2598 {
2599 return false;
2600 }
2601
2602 return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT &&
2603 renderer->presentPathFastEnabled());
2604 }
2605
UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,gl::DrawElementsType type)2606 bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
2607 gl::DrawElementsType type)
2608 {
2609 // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT
2610 // indices, since we restrict it via MAX_ELEMENT_INDEX.
2611 return (!primitiveRestartFixedIndexEnabled && type == gl::DrawElementsType::UnsignedShort);
2612 }
2613
ClassifyIndexStorage(const gl::State & glState,const gl::Buffer * elementArrayBuffer,gl::DrawElementsType elementType,gl::DrawElementsType destElementType,unsigned int offset)2614 IndexStorageType ClassifyIndexStorage(const gl::State &glState,
2615 const gl::Buffer *elementArrayBuffer,
2616 gl::DrawElementsType elementType,
2617 gl::DrawElementsType destElementType,
2618 unsigned int offset)
2619 {
2620 // No buffer bound means we are streaming from a client pointer.
2621 if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset))
2622 {
2623 return IndexStorageType::Dynamic;
2624 }
2625
2626 // The buffer can be used directly if the storage supports it and no translation needed.
2627 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
2628 if (bufferD3D->supportsDirectBinding() && destElementType == elementType)
2629 {
2630 return IndexStorageType::Direct;
2631 }
2632
2633 // Use a static copy when available.
2634 StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
2635 if (staticBuffer != nullptr)
2636 {
2637 return IndexStorageType::Static;
2638 }
2639
2640 // Static buffer not available, fall back to streaming.
2641 return IndexStorageType::Dynamic;
2642 }
2643 } // namespace rx
2644