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