OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "GrGLCaps.h" | 9 #include "GrGLCaps.h" |
10 | 10 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 this->init(contextOptions, ctxInfo, glInterface); | 58 this->init(contextOptions, ctxInfo, glInterface); |
59 } | 59 } |
60 | 60 |
61 void GrGLCaps::init(const GrContextOptions& contextOptions, | 61 void GrGLCaps::init(const GrContextOptions& contextOptions, |
62 const GrGLContextInfo& ctxInfo, | 62 const GrGLContextInfo& ctxInfo, |
63 const GrGLInterface* gli) { | 63 const GrGLInterface* gli) { |
64 GrGLStandard standard = ctxInfo.standard(); | 64 GrGLStandard standard = ctxInfo.standard(); |
65 GrGLVersion version = ctxInfo.version(); | 65 GrGLVersion version = ctxInfo.version(); |
66 | 66 |
67 /************************************************************************** | 67 /************************************************************************** |
68 * Caps specific to GrGLSLCaps | |
69 **************************************************************************/ | |
70 | |
71 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); | |
72 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration(); | |
73 | |
74 if (kGLES_GrGLStandard == standard) { | |
75 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) { | |
76 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0)); | |
77 glslCaps->fFBFetchSupport = true; | |
78 glslCaps->fFBFetchColorName = "gl_LastFragData[0]"; | |
79 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch
"; | |
80 } | |
81 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) { | |
82 // Actually, we haven't seen an ES3.0 device with this extension yet
, so we don't know | |
83 glslCaps->fFBFetchNeedsCustomOutput = false; | |
84 glslCaps->fFBFetchSupport = true; | |
85 glslCaps->fFBFetchColorName = "gl_LastFragData[0]"; | |
86 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch"
; | |
87 } | |
88 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) { | |
89 // The arm extension also requires an additional flag which we will
set onResetContext | |
90 glslCaps->fFBFetchNeedsCustomOutput = false; | |
91 glslCaps->fFBFetchSupport = true; | |
92 glslCaps->fFBFetchColorName = "gl_LastFragColorARM"; | |
93 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch
"; | |
94 } | |
95 glslCaps->fUsesPrecisionModifiers = true; | |
96 } | |
97 | |
98 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_tex
ture"); | |
99 | |
100 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero
in a shader | |
101 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor(); | |
102 | |
103 /************************************************************************** | |
104 * Caps specific to GrGLCaps | 68 * Caps specific to GrGLCaps |
105 **************************************************************************/ | 69 **************************************************************************/ |
106 | 70 |
107 if (kGLES_GrGLStandard == standard) { | 71 if (kGLES_GrGLStandard == standard) { |
108 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS, | 72 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS, |
109 &fMaxFragmentUniformVectors); | 73 &fMaxFragmentUniformVectors); |
110 } else { | 74 } else { |
111 SkASSERT(kGL_GrGLStandard == standard); | 75 SkASSERT(kGL_GrGLStandard == standard); |
112 GrGLint max; | 76 GrGLint max; |
113 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max); | 77 GR_GL_GetIntegerv(gli, GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() || | 276 bool isANGLE = kANGLE_GrGLDriver == ctxInfo.driver() || |
313 kChromium_GrGLDriver == ctxInfo.driver(); | 277 kChromium_GrGLDriver == ctxInfo.driver(); |
314 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
| 278 // Angle has slow read/write pixel paths for 32bit RGBA (but fast for BGRA).
|
315 fRGBA8888PixelsOpsAreSlow = isANGLE; | 279 fRGBA8888PixelsOpsAreSlow = isANGLE; |
316 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is s
till true and | 280 // On DX9 ANGLE reading a partial FBO is slow. TODO: Check whether this is s
till true and |
317 // check DX11 ANGLE. | 281 // check DX11 ANGLE. |
318 fPartialFBOReadIsSlow = isANGLE; | 282 fPartialFBOReadIsSlow = isANGLE; |
319 #endif | 283 #endif |
320 | 284 |
321 /************************************************************************** | 285 /************************************************************************** |
322 * GrShaderCaps fields | |
323 **************************************************************************/ | |
324 | |
325 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli
); | |
326 | |
327 // For now these two are equivalent but we could have dst read in shader via
some other method | |
328 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport; | |
329 | |
330 // Enable supported shader-related caps | |
331 if (kGL_GrGLStandard == standard) { | |
332 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3
, 3) || | |
333 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) && | |
334 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration()); | |
335 glslCaps->fShaderDerivativeSupport = true; | |
336 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS | |
337 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2)
&& | |
338 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration; | |
339 } | |
340 else { | |
341 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blen
d_func_extended"); | |
342 | |
343 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0
) || | |
344 ctxInfo.hasExtension("GL_OES_standard_derivatives"); | |
345 } | |
346 | |
347 // We need dual source blending and the ability to disable multisample in or
der to support mixed | |
348 // samples in every corner case. | |
349 if (fMultisampleDisableSupport && glslCaps->fDualSourceBlendingSupport) { | |
350 // We understand "mixed samples" to mean the collective capability of 3
different extensions | |
351 glslCaps->fMixedSamplesSupport = | |
352 ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") && | |
353 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage") && | |
354 ctxInfo.hasExtension("GL_EXT_raster_multisample"); | |
355 } | |
356 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed sample
s. | |
357 if (kNVIDIA_GrGLDriver == ctxInfo.driver() && fShaderCaps->mixedSamplesSuppo
rt()) { | |
358 fDiscardRenderTargetSupport = false; | |
359 fInvalidateFBType = kNone_InvalidateFBType; | |
360 } | |
361 glslCaps->fProgrammableSampleLocationsSupport = | |
362 ctxInfo.hasExtension("GL_NV_sample_locations") || | |
363 ctxInfo.hasExtension("GL_ARB_sample_locations"); | |
364 | |
365 | |
366 /************************************************************************** | |
367 * GrCaps fields | 286 * GrCaps fields |
368 **************************************************************************/ | 287 **************************************************************************/ |
369 | 288 |
370 this->initFSAASupport(ctxInfo, gli); | 289 this->initFSAASupport(ctxInfo, gli); |
371 this->initBlendEqationSupport(ctxInfo); | 290 this->initBlendEqationSupport(ctxInfo); |
372 this->initStencilFormats(ctxInfo); | 291 this->initStencilFormats(ctxInfo); |
373 | 292 |
374 if (kGL_GrGLStandard == standard) { | 293 if (kGL_GrGLStandard == standard) { |
375 // we could also look for GL_ATI_separate_stencil extension or | 294 // we could also look for GL_ATI_separate_stencil extension or |
376 // GL_EXT_stencil_two_side but they use different function signatures | 295 // GL_EXT_stencil_two_side but they use different function signatures |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 version >= GR_GL_VER(3, 2) || | 425 version >= GR_GL_VER(3, 2) || |
507 (ctxInfo.hasExtension("GL_ARB_draw_instanced") && | 426 (ctxInfo.hasExtension("GL_ARB_draw_instanced") && |
508 ctxInfo.hasExtension("GL_ARB_instanced_arrays")); | 427 ctxInfo.hasExtension("GL_ARB_instanced_arrays")); |
509 } else { | 428 } else { |
510 fSupportsInstancedDraws = | 429 fSupportsInstancedDraws = |
511 version >= GR_GL_VER(3, 0) || | 430 version >= GR_GL_VER(3, 0) || |
512 (ctxInfo.hasExtension("GL_EXT_draw_instanced") && | 431 (ctxInfo.hasExtension("GL_EXT_draw_instanced") && |
513 ctxInfo.hasExtension("GL_EXT_instanced_arrays")); | 432 ctxInfo.hasExtension("GL_EXT_instanced_arrays")); |
514 } | 433 } |
515 | 434 |
| 435 // Must init GLSLCaps after setting GLCaps |
| 436 this->initGLSL(contextOptions, ctxInfo, gli); |
| 437 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); |
| 438 |
516 this->initConfigTexturableTable(ctxInfo, gli, srgbSupport); | 439 this->initConfigTexturableTable(ctxInfo, gli, srgbSupport); |
517 this->initConfigRenderableTable(ctxInfo, srgbSupport); | 440 this->initConfigRenderableTable(ctxInfo, srgbSupport); |
518 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps); | 441 this->initShaderPrecisionTable(ctxInfo, gli, glslCaps); |
519 | 442 |
520 this->applyOptionsOverrides(contextOptions); | 443 this->applyOptionsOverrides(contextOptions); |
521 glslCaps->applyOptionsOverrides(contextOptions); | 444 glslCaps->applyOptionsOverrides(contextOptions); |
522 } | 445 } |
523 | 446 |
| 447 const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration
generation, |
| 448 bool isCoreProfile) { |
| 449 switch (generation) { |
| 450 case k110_GrGLSLGeneration: |
| 451 if (kGLES_GrGLStandard == standard) { |
| 452 // ES2s shader language is based on version 1.20 but is version |
| 453 // 1.00 of the ES language. |
| 454 return "#version 100\n"; |
| 455 } else { |
| 456 SkASSERT(kGL_GrGLStandard == standard); |
| 457 return "#version 110\n"; |
| 458 } |
| 459 case k130_GrGLSLGeneration: |
| 460 SkASSERT(kGL_GrGLStandard == standard); |
| 461 return "#version 130\n"; |
| 462 case k140_GrGLSLGeneration: |
| 463 SkASSERT(kGL_GrGLStandard == standard); |
| 464 return "#version 140\n"; |
| 465 case k150_GrGLSLGeneration: |
| 466 SkASSERT(kGL_GrGLStandard == standard); |
| 467 if (isCoreProfile) { |
| 468 return "#version 150\n"; |
| 469 } else { |
| 470 return "#version 150 compatibility\n"; |
| 471 } |
| 472 case k330_GrGLSLGeneration: |
| 473 if (kGLES_GrGLStandard == standard) { |
| 474 return "#version 300 es\n"; |
| 475 } else { |
| 476 SkASSERT(kGL_GrGLStandard == standard); |
| 477 if (isCoreProfile) { |
| 478 return "#version 330\n"; |
| 479 } else { |
| 480 return "#version 330 compatibility\n"; |
| 481 } |
| 482 } |
| 483 case k310es_GrGLSLGeneration: |
| 484 SkASSERT(kGLES_GrGLStandard == standard); |
| 485 return "#version 310 es\n"; |
| 486 } |
| 487 return "<no version>"; |
| 488 } |
| 489 |
| 490 void GrGLCaps::initGLSL(const GrContextOptions& contextOptions, |
| 491 const GrGLContextInfo& ctxInfo, |
| 492 const GrGLInterface* gli) { |
| 493 GrGLStandard standard = ctxInfo.standard(); |
| 494 GrGLVersion version = ctxInfo.version(); |
| 495 |
| 496 /************************************************************************** |
| 497 * Caps specific to GrGLSLCaps |
| 498 **************************************************************************/ |
| 499 |
| 500 GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); |
| 501 glslCaps->fGLSLGeneration = ctxInfo.glslGeneration(); |
| 502 |
| 503 if (kGLES_GrGLStandard == standard) { |
| 504 if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) { |
| 505 glslCaps->fFBFetchNeedsCustomOutput = (version >= GR_GL_VER(3, 0)); |
| 506 glslCaps->fFBFetchSupport = true; |
| 507 glslCaps->fFBFetchColorName = "gl_LastFragData[0]"; |
| 508 glslCaps->fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch
"; |
| 509 } |
| 510 else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) { |
| 511 // Actually, we haven't seen an ES3.0 device with this extension yet
, so we don't know |
| 512 glslCaps->fFBFetchNeedsCustomOutput = false; |
| 513 glslCaps->fFBFetchSupport = true; |
| 514 glslCaps->fFBFetchColorName = "gl_LastFragData[0]"; |
| 515 glslCaps->fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch"
; |
| 516 } |
| 517 else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) { |
| 518 // The arm extension also requires an additional flag which we will
set onResetContext |
| 519 glslCaps->fFBFetchNeedsCustomOutput = false; |
| 520 glslCaps->fFBFetchSupport = true; |
| 521 glslCaps->fFBFetchColorName = "gl_LastFragColorARM"; |
| 522 glslCaps->fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch
"; |
| 523 } |
| 524 glslCaps->fUsesPrecisionModifiers = true; |
| 525 } |
| 526 |
| 527 glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_tex
ture"); |
| 528 |
| 529 // Adreno GPUs have a tendency to drop tiles when there is a divide-by-zero
in a shader |
| 530 glslCaps->fDropsTileOnZeroDivide = kQualcomm_GrGLVendor == ctxInfo.vendor(); |
| 531 |
| 532 // On the NexusS and GalaxyNexus, the use of 'any' causes the compilation er
ror "Calls to any |
| 533 // function that may require a gradient calculation inside a conditional blo
ck may return |
| 534 // undefined results". This appears to be an issue with the 'any' call since
even the simple |
| 535 // "result=black; if (any()) result=white;" code fails to compile. This issu
e comes into play |
| 536 // from our GrTextureDomain processor. |
| 537 glslCaps->fCanUseAnyFunctionInShader = kImagination_GrGLVendor != ctxInfo.ve
ndor(); |
| 538 |
| 539 glslCaps->fForceHighPrecisionNDSTransform = kARM_GrGLVendor != ctxInfo.vendo
r(); |
| 540 |
| 541 glslCaps->fVersionDeclString = get_glsl_version_decl_string(standard, glslCa
ps->fGLSLGeneration, |
| 542 fIsCoreProfile); |
| 543 |
| 544 /************************************************************************** |
| 545 * GrShaderCaps fields |
| 546 **************************************************************************/ |
| 547 |
| 548 glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli
); |
| 549 |
| 550 // For now these two are equivalent but we could have dst read in shader via
some other method |
| 551 glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport; |
| 552 |
| 553 // Enable supported shader-related caps |
| 554 if (kGL_GrGLStandard == standard) { |
| 555 glslCaps->fDualSourceBlendingSupport = (ctxInfo.version() >= GR_GL_VER(3
, 3) || |
| 556 ctxInfo.hasExtension("GL_ARB_blend_func_extended")) && |
| 557 GrGLSLSupportsNamedFragmentShaderOutputs(ctxInfo.glslGeneration()); |
| 558 glslCaps->fShaderDerivativeSupport = true; |
| 559 // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS |
| 560 glslCaps->fGeometryShaderSupport = ctxInfo.version() >= GR_GL_VER(3, 2)
&& |
| 561 ctxInfo.glslGeneration() >= k150_GrGLSLGeneration; |
| 562 } |
| 563 else { |
| 564 glslCaps->fDualSourceBlendingSupport = ctxInfo.hasExtension("GL_EXT_blen
d_func_extended"); |
| 565 |
| 566 glslCaps->fShaderDerivativeSupport = ctxInfo.version() >= GR_GL_VER(3, 0
) || |
| 567 ctxInfo.hasExtension("GL_OES_standard_derivatives"); |
| 568 } |
| 569 |
| 570 // We need dual source blending and the ability to disable multisample in or
der to support mixed |
| 571 // samples in every corner case. |
| 572 if (fMultisampleDisableSupport && glslCaps->fDualSourceBlendingSupport) { |
| 573 // We understand "mixed samples" to mean the collective capability of 3
different extensions |
| 574 glslCaps->fMixedSamplesSupport = |
| 575 ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") && |
| 576 ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage") && |
| 577 ctxInfo.hasExtension("GL_EXT_raster_multisample"); |
| 578 } |
| 579 // Workaround NVIDIA bug related to glInvalidateFramebuffer and mixed sample
s. |
| 580 if (kNVIDIA_GrGLDriver == ctxInfo.driver() && fShaderCaps->mixedSamplesSuppo
rt()) { |
| 581 fDiscardRenderTargetSupport = false; |
| 582 fInvalidateFBType = kNone_InvalidateFBType; |
| 583 } |
| 584 glslCaps->fProgrammableSampleLocationsSupport = |
| 585 ctxInfo.hasExtension("GL_NV_sample_locations") || |
| 586 ctxInfo.hasExtension("GL_ARB_sample_locations"); |
| 587 } |
| 588 |
524 bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrG
LInterface* gli) { | 589 bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrG
LInterface* gli) { |
525 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rende
ring"); | 590 bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rende
ring"); |
526 | 591 |
527 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRenderi
ng)) { | 592 if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRenderi
ng)) { |
528 return false; | 593 return false; |
529 } | 594 } |
530 | 595 |
531 if (kGL_GrGLStandard == ctxInfo.standard()) { | 596 if (kGL_GrGLStandard == ctxInfo.standard()) { |
532 if (ctxInfo.version() < GR_GL_VER(4, 3) && | 597 if (ctxInfo.version() < GR_GL_VER(4, 3) && |
533 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) { | 598 !ctxInfo.hasExtension("GL_ARB_program_interface_query")) { |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 for (int p = 0; p < kGrSLPrecisionCount; ++p) { | 1265 for (int p = 0; p < kGrSLPrecisionCount; ++p) { |
1201 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] = | 1266 glslCaps->fFloatPrecisions[kGeometry_GrShaderType][p] = |
1202 glslCaps->fFloatPrecisions[kVerte
x_GrShaderType][p]; | 1267 glslCaps->fFloatPrecisions[kVerte
x_GrShaderType][p]; |
1203 } | 1268 } |
1204 } | 1269 } |
1205 } | 1270 } |
1206 | 1271 |
1207 | 1272 |
1208 | 1273 |
1209 | 1274 |
OLD | NEW |