| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/feature_info.h" | 5 #include "gpu/command_buffer/service/feature_info.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 namespace gles2 { | 30 namespace gles2 { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 struct FormatInfo { | 34 struct FormatInfo { |
| 35 GLenum format; | 35 GLenum format; |
| 36 const GLenum* types; | 36 const GLenum* types; |
| 37 size_t count; | 37 size_t count; |
| 38 }; | 38 }; |
| 39 | 39 |
| 40 class StringSet { | 40 } // anonymous namespace. |
| 41 |
| 42 class FeatureInfo::StringSet { |
| 41 public: | 43 public: |
| 42 StringSet() {} | 44 StringSet() {} |
| 43 | 45 |
| 44 StringSet(const char* s) { | 46 StringSet(const char* s) { |
| 45 Init(s); | 47 Init(s); |
| 46 } | 48 } |
| 47 | 49 |
| 48 StringSet(const std::string& str) { | 50 StringSet(const std::string& str) { |
| 49 Init(str); | 51 Init(str); |
| 50 } | 52 } |
| 51 | 53 |
| 52 StringSet(const std::vector<std::string>& strs) { | 54 StringSet(const std::vector<std::string>& strs) { |
| 53 string_set_.insert(strs.begin(), strs.end()); | 55 string_set_.insert(strs.begin(), strs.end()); |
| 54 } | 56 } |
| 55 | 57 |
| 56 void Init(const char* s) { | 58 void Init(const char* s) { |
| 57 std::string str(s ? s : ""); | 59 std::string str(s ? s : ""); |
| 58 Init(str); | 60 Init(str); |
| 59 } | 61 } |
| 60 | 62 |
| 61 void Init(const std::string& str) { | 63 void Init(const std::string& str) { |
| 62 std::vector<std::string> tokens = base::SplitString( | 64 std::vector<std::string> tokens = base::SplitString( |
| 63 str, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 65 str, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 64 string_set_.insert(tokens.begin(), tokens.end()); | 66 string_set_.insert(tokens.begin(), tokens.end()); |
| 65 } | 67 } |
| 66 | 68 |
| 67 bool Contains(const char* s) { | 69 bool Contains(const char* s) const { |
| 68 return string_set_.find(s) != string_set_.end(); | 70 return string_set_.find(s) != string_set_.end(); |
| 69 } | 71 } |
| 70 | 72 |
| 71 bool Contains(const std::string& s) { | 73 bool Contains(const std::string& s) const { |
| 72 return string_set_.find(s) != string_set_.end(); | 74 return string_set_.find(s) != string_set_.end(); |
| 73 } | 75 } |
| 74 | 76 |
| 75 const std::set<std::string>& GetImpl() { | 77 const std::set<std::string>& GetImpl() { |
| 76 return string_set_; | 78 return string_set_; |
| 77 } | 79 } |
| 78 | 80 |
| 79 private: | 81 private: |
| 80 std::set<std::string> string_set_; | 82 std::set<std::string> string_set_; |
| 81 }; | 83 }; |
| 82 | 84 |
| 85 namespace { |
| 86 |
| 83 class ScopedPixelUnpackBufferOverride { | 87 class ScopedPixelUnpackBufferOverride { |
| 84 public: | 88 public: |
| 85 explicit ScopedPixelUnpackBufferOverride( | 89 explicit ScopedPixelUnpackBufferOverride( |
| 86 bool enable_es3, | 90 bool enable_es3, |
| 87 GLuint binding_override) | 91 GLuint binding_override) |
| 88 : orig_binding_(-1) { | 92 : orig_binding_(-1) { |
| 89 if (enable_es3) { | 93 if (enable_es3) { |
| 90 GLint orig_binding; | 94 GLint orig_binding; |
| 91 glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &orig_binding); | 95 glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &orig_binding); |
| 92 if (static_cast<GLuint>(orig_binding) != binding_override) { | 96 if (static_cast<GLuint>(orig_binding) != binding_override) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 GL_RGBA16F); | 233 GL_RGBA16F); |
| 230 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_R32F); | 234 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_R32F); |
| 231 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_RG32F); | 235 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_RG32F); |
| 232 validators_.texture_sized_color_renderable_internal_format.AddValue( | 236 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 233 GL_RGBA32F); | 237 GL_RGBA32F); |
| 234 validators_.texture_sized_color_renderable_internal_format.AddValue( | 238 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 235 GL_R11F_G11F_B10F); | 239 GL_R11F_G11F_B10F); |
| 236 feature_flags_.enable_color_buffer_float = true; | 240 feature_flags_.enable_color_buffer_float = true; |
| 237 } | 241 } |
| 238 | 242 |
| 243 void FeatureInfo::EnableEXTColorBufferHalfFloat() { |
| 244 AddExtensionString("GL_EXT_color_buffer_half_float"); |
| 245 validators_.render_buffer_format.AddValue(GL_R16F); |
| 246 validators_.render_buffer_format.AddValue(GL_RG16F); |
| 247 validators_.render_buffer_format.AddValue(GL_RGB16F); |
| 248 validators_.render_buffer_format.AddValue(GL_RGBA16F); |
| 249 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_R16F); |
| 250 validators_.texture_sized_color_renderable_internal_format.AddValue(GL_RG16F); |
| 251 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 252 GL_RGB16F); |
| 253 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 254 GL_RGBA16F); |
| 255 feature_flags_.enable_color_buffer_half_float = true; |
| 256 } |
| 257 |
| 239 void FeatureInfo::EnableCHROMIUMColorBufferFloatRGBA() { | 258 void FeatureInfo::EnableCHROMIUMColorBufferFloatRGBA() { |
| 240 if (!feature_flags_.chromium_color_buffer_float_rgba) | 259 if (!feature_flags_.chromium_color_buffer_float_rgba) |
| 241 return; | 260 return; |
| 242 validators_.texture_internal_format.AddValue(GL_RGBA32F); | 261 validators_.texture_internal_format.AddValue(GL_RGBA32F); |
| 243 validators_.texture_sized_color_renderable_internal_format.AddValue( | 262 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 244 GL_RGBA32F); | 263 GL_RGBA32F); |
| 245 AddExtensionString("GL_CHROMIUM_color_buffer_float_rgba"); | 264 AddExtensionString("GL_CHROMIUM_color_buffer_float_rgba"); |
| 246 } | 265 } |
| 247 | 266 |
| 248 void FeatureInfo::EnableCHROMIUMColorBufferFloatRGB() { | 267 void FeatureInfo::EnableCHROMIUMColorBufferFloatRGB() { |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 enable_texture_storage = false; | 667 enable_texture_storage = false; |
| 649 break; | 668 break; |
| 650 case CONTEXT_TYPE_OPENGLES3: | 669 case CONTEXT_TYPE_OPENGLES3: |
| 651 case CONTEXT_TYPE_WEBGL1: | 670 case CONTEXT_TYPE_WEBGL1: |
| 652 case CONTEXT_TYPE_WEBGL2: | 671 case CONTEXT_TYPE_WEBGL2: |
| 653 enable_texture_format_bgra8888 = false; | 672 enable_texture_format_bgra8888 = false; |
| 654 break; | 673 break; |
| 655 } | 674 } |
| 656 } | 675 } |
| 657 | 676 |
| 677 if (enable_texture_storage) { |
| 678 feature_flags_.ext_texture_storage = true; |
| 679 AddExtensionString("GL_EXT_texture_storage"); |
| 680 validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT); |
| 681 if (enable_texture_format_bgra8888) { |
| 682 validators_.texture_internal_format_storage.AddValue(GL_BGRA8_EXT); |
| 683 validators_.texture_sized_color_renderable_internal_format.AddValue( |
| 684 GL_BGRA8_EXT); |
| 685 validators_.texture_sized_texture_filterable_internal_format.AddValue( |
| 686 GL_BGRA8_EXT); |
| 687 } |
| 688 } |
| 689 |
| 658 if (enable_texture_format_bgra8888) { | 690 if (enable_texture_format_bgra8888) { |
| 659 feature_flags_.ext_texture_format_bgra8888 = true; | 691 feature_flags_.ext_texture_format_bgra8888 = true; |
| 660 AddExtensionString("GL_EXT_texture_format_BGRA8888"); | 692 AddExtensionString("GL_EXT_texture_format_BGRA8888"); |
| 661 validators_.texture_internal_format.AddValue(GL_BGRA_EXT); | 693 validators_.texture_internal_format.AddValue(GL_BGRA_EXT); |
| 662 validators_.texture_format.AddValue(GL_BGRA_EXT); | 694 validators_.texture_format.AddValue(GL_BGRA_EXT); |
| 663 validators_.texture_unsized_internal_format.AddValue(GL_BGRA_EXT); | 695 validators_.texture_unsized_internal_format.AddValue(GL_BGRA_EXT); |
| 664 } | 696 } |
| 665 | 697 |
| 666 // On desktop, all devices support BGRA render buffers (note that on desktop | 698 // On desktop, all devices support BGRA render buffers (note that on desktop |
| 667 // BGRA internal formats are converted to RGBA in the API implementation). | 699 // BGRA internal formats are converted to RGBA in the API implementation). |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 // Check if we should allow GL_OES_texture_npot | 750 // Check if we should allow GL_OES_texture_npot |
| 719 if (!disallowed_features_.npot_support && | 751 if (!disallowed_features_.npot_support && |
| 720 (gl_version_info_->is_es3 || | 752 (gl_version_info_->is_es3 || |
| 721 gl_version_info_->is_desktop_core_profile || | 753 gl_version_info_->is_desktop_core_profile || |
| 722 extensions.Contains("GL_ARB_texture_non_power_of_two") || | 754 extensions.Contains("GL_ARB_texture_non_power_of_two") || |
| 723 extensions.Contains("GL_OES_texture_npot"))) { | 755 extensions.Contains("GL_OES_texture_npot"))) { |
| 724 AddExtensionString("GL_OES_texture_npot"); | 756 AddExtensionString("GL_OES_texture_npot"); |
| 725 feature_flags_.npot_ok = true; | 757 feature_flags_.npot_ok = true; |
| 726 } | 758 } |
| 727 | 759 |
| 728 // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float, | 760 InitializeFloatAndHalfFloatFeatures(extensions); |
| 729 // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear | |
| 730 bool enable_texture_float = false; | |
| 731 bool enable_texture_float_linear = false; | |
| 732 bool enable_texture_half_float = false; | |
| 733 bool enable_texture_half_float_linear = false; | |
| 734 bool enable_ext_color_buffer_float = false; | |
| 735 | |
| 736 bool may_enable_chromium_color_buffer_float = false; | |
| 737 | |
| 738 // This extension allows a variety of floating point formats to be | |
| 739 // rendered to via framebuffer objects. | |
| 740 if (extensions.Contains("GL_EXT_color_buffer_float")) { | |
| 741 enable_ext_color_buffer_float = true; | |
| 742 } | |
| 743 | |
| 744 if (extensions.Contains("GL_ARB_texture_float") || | |
| 745 gl_version_info_->is_desktop_core_profile) { | |
| 746 enable_texture_float = true; | |
| 747 enable_texture_float_linear = true; | |
| 748 enable_texture_half_float = true; | |
| 749 enable_texture_half_float_linear = true; | |
| 750 may_enable_chromium_color_buffer_float = true; | |
| 751 } else { | |
| 752 // GLES3 adds support for Float type by default but it doesn't support all | |
| 753 // formats as GL_OES_texture_float(i.e.LUMINANCE_ALPHA,LUMINANCE and Alpha) | |
| 754 if (extensions.Contains("GL_OES_texture_float")) { | |
| 755 enable_texture_float = true; | |
| 756 if (extensions.Contains("GL_OES_texture_float_linear")) { | |
| 757 enable_texture_float_linear = true; | |
| 758 } | |
| 759 | |
| 760 if (enable_ext_color_buffer_float || gl_version_info_->is_angle) { | |
| 761 may_enable_chromium_color_buffer_float = true; | |
| 762 } | |
| 763 } | |
| 764 | |
| 765 // TODO(dshwang): GLES3 supports half float by default but GL_HALF_FLOAT_OES | |
| 766 // isn't equal to GL_HALF_FLOAT. | |
| 767 if (extensions.Contains("GL_OES_texture_half_float")) { | |
| 768 enable_texture_half_float = true; | |
| 769 if (extensions.Contains("GL_OES_texture_half_float_linear")) { | |
| 770 enable_texture_half_float_linear = true; | |
| 771 } | |
| 772 } | |
| 773 } | |
| 774 | |
| 775 if (enable_texture_float) { | |
| 776 validators_.pixel_type.AddValue(GL_FLOAT); | |
| 777 validators_.read_pixel_type.AddValue(GL_FLOAT); | |
| 778 AddExtensionString("GL_OES_texture_float"); | |
| 779 if (enable_texture_float_linear) { | |
| 780 oes_texture_float_linear_available_ = true; | |
| 781 if (!disallowed_features_.oes_texture_float_linear) | |
| 782 EnableOESTextureFloatLinear(); | |
| 783 } | |
| 784 } | |
| 785 | |
| 786 if (enable_texture_half_float) { | |
| 787 validators_.pixel_type.AddValue(GL_HALF_FLOAT_OES); | |
| 788 validators_.read_pixel_type.AddValue(GL_HALF_FLOAT_OES); | |
| 789 AddExtensionString("GL_OES_texture_half_float"); | |
| 790 if (enable_texture_half_float_linear) { | |
| 791 oes_texture_half_float_linear_available_ = true; | |
| 792 if (!disallowed_features_.oes_texture_half_float_linear) | |
| 793 EnableOESTextureHalfFloatLinear(); | |
| 794 } | |
| 795 } | |
| 796 | |
| 797 if (may_enable_chromium_color_buffer_float) { | |
| 798 static_assert(GL_RGBA32F_ARB == GL_RGBA32F && | |
| 799 GL_RGBA32F_EXT == GL_RGBA32F && | |
| 800 GL_RGB32F_ARB == GL_RGB32F && | |
| 801 GL_RGB32F_EXT == GL_RGB32F, | |
| 802 "sized float internal format variations must match"); | |
| 803 // We don't check extension support beyond ARB_texture_float on desktop GL, | |
| 804 // and format support varies between GL configurations. For example, spec | |
| 805 // prior to OpenGL 3.0 mandates framebuffer support only for one | |
| 806 // implementation-chosen format, and ES3.0 EXT_color_buffer_float does not | |
| 807 // support rendering to RGB32F. Check for framebuffer completeness with | |
| 808 // formats that the extensions expose, and only enable an extension when a | |
| 809 // framebuffer created with its texture format is reported as complete. | |
| 810 GLint fb_binding = 0; | |
| 811 GLint tex_binding = 0; | |
| 812 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding); | |
| 813 glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding); | |
| 814 | |
| 815 GLuint tex_id = 0; | |
| 816 GLuint fb_id = 0; | |
| 817 GLsizei width = 16; | |
| 818 | |
| 819 glGenTextures(1, &tex_id); | |
| 820 glGenFramebuffersEXT(1, &fb_id); | |
| 821 glBindTexture(GL_TEXTURE_2D, tex_id); | |
| 822 // Nearest filter needed for framebuffer completeness on some drivers. | |
| 823 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 824 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0, GL_RGBA, | |
| 825 GL_FLOAT, NULL); | |
| 826 glBindFramebufferEXT(GL_FRAMEBUFFER, fb_id); | |
| 827 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 828 GL_TEXTURE_2D, tex_id, 0); | |
| 829 GLenum status_rgba = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | |
| 830 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0, GL_RGB, | |
| 831 GL_FLOAT, NULL); | |
| 832 GLenum status_rgb = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | |
| 833 | |
| 834 // For desktop systems, check to see if we support rendering to the full | |
| 835 // range of formats supported by EXT_color_buffer_float | |
| 836 if (status_rgba == GL_FRAMEBUFFER_COMPLETE && enable_es3) { | |
| 837 bool full_float_support = true; | |
| 838 | |
| 839 glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, width, width, 0, GL_RED, | |
| 840 GL_FLOAT, NULL); | |
| 841 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 842 GL_FRAMEBUFFER_COMPLETE; | |
| 843 glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16F, width, width, 0, GL_RG, | |
| 844 GL_FLOAT, NULL); | |
| 845 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 846 GL_FRAMEBUFFER_COMPLETE; | |
| 847 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, width, 0, GL_RGBA, | |
| 848 GL_FLOAT, NULL); | |
| 849 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 850 GL_FRAMEBUFFER_COMPLETE; | |
| 851 glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, width, 0, GL_RED, | |
| 852 GL_FLOAT, NULL); | |
| 853 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 854 GL_FRAMEBUFFER_COMPLETE; | |
| 855 glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, width, width, 0, GL_RG, | |
| 856 GL_FLOAT, NULL); | |
| 857 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 858 GL_FRAMEBUFFER_COMPLETE; | |
| 859 glTexImage2D(GL_TEXTURE_2D, 0, GL_R11F_G11F_B10F, width, width, 0, GL_RGB, | |
| 860 GL_FLOAT, NULL); | |
| 861 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == | |
| 862 GL_FRAMEBUFFER_COMPLETE; | |
| 863 | |
| 864 enable_ext_color_buffer_float = full_float_support; | |
| 865 } | |
| 866 | |
| 867 glDeleteFramebuffersEXT(1, &fb_id); | |
| 868 glDeleteTextures(1, &tex_id); | |
| 869 | |
| 870 glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding)); | |
| 871 glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding)); | |
| 872 | |
| 873 DCHECK(glGetError() == GL_NO_ERROR); | |
| 874 | |
| 875 if (status_rgba == GL_FRAMEBUFFER_COMPLETE) { | |
| 876 feature_flags_.chromium_color_buffer_float_rgba = true; | |
| 877 if (!disallowed_features_.chromium_color_buffer_float_rgba) | |
| 878 EnableCHROMIUMColorBufferFloatRGBA(); | |
| 879 } | |
| 880 if (status_rgb == GL_FRAMEBUFFER_COMPLETE) { | |
| 881 feature_flags_.chromium_color_buffer_float_rgb = true; | |
| 882 if (!disallowed_features_.chromium_color_buffer_float_rgb) | |
| 883 EnableCHROMIUMColorBufferFloatRGB(); | |
| 884 } | |
| 885 } | |
| 886 | |
| 887 // Enable the GL_EXT_color_buffer_float extension for WebGL 2.0 | |
| 888 if (enable_ext_color_buffer_float && enable_es3) { | |
| 889 ext_color_buffer_float_available_ = true; | |
| 890 if (!disallowed_features_.ext_color_buffer_float) | |
| 891 EnableEXTColorBufferFloat(); | |
| 892 } | |
| 893 | 761 |
| 894 // Check for multisample support | 762 // Check for multisample support |
| 895 if (!workarounds_.disable_chromium_framebuffer_multisample) { | 763 if (!workarounds_.disable_chromium_framebuffer_multisample) { |
| 896 bool ext_has_multisample = | 764 bool ext_has_multisample = |
| 897 extensions.Contains("GL_EXT_framebuffer_multisample") || | 765 extensions.Contains("GL_EXT_framebuffer_multisample") || |
| 898 gl_version_info_->is_es3 || | 766 gl_version_info_->is_es3 || |
| 899 gl_version_info_->is_desktop_core_profile; | 767 gl_version_info_->is_desktop_core_profile; |
| 900 if (gl_version_info_->is_angle) { | 768 if (gl_version_info_->is_angle) { |
| 901 feature_flags_.angle_framebuffer_multisample = | 769 feature_flags_.angle_framebuffer_multisample = |
| 902 extensions.Contains("GL_ANGLE_framebuffer_multisample"); | 770 extensions.Contains("GL_ANGLE_framebuffer_multisample"); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 | 944 |
| 1077 // TODO(gman): Add support for these extensions. | 945 // TODO(gman): Add support for these extensions. |
| 1078 // GL_OES_depth32 | 946 // GL_OES_depth32 |
| 1079 | 947 |
| 1080 if (extensions.Contains("GL_ANGLE_texture_usage")) { | 948 if (extensions.Contains("GL_ANGLE_texture_usage")) { |
| 1081 feature_flags_.angle_texture_usage = true; | 949 feature_flags_.angle_texture_usage = true; |
| 1082 AddExtensionString("GL_ANGLE_texture_usage"); | 950 AddExtensionString("GL_ANGLE_texture_usage"); |
| 1083 validators_.texture_parameter.AddValue(GL_TEXTURE_USAGE_ANGLE); | 951 validators_.texture_parameter.AddValue(GL_TEXTURE_USAGE_ANGLE); |
| 1084 } | 952 } |
| 1085 | 953 |
| 1086 if (enable_texture_storage) { | |
| 1087 feature_flags_.ext_texture_storage = true; | |
| 1088 AddExtensionString("GL_EXT_texture_storage"); | |
| 1089 validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT); | |
| 1090 if (enable_texture_format_bgra8888) { | |
| 1091 validators_.texture_internal_format_storage.AddValue(GL_BGRA8_EXT); | |
| 1092 validators_.texture_sized_color_renderable_internal_format.AddValue( | |
| 1093 GL_BGRA8_EXT); | |
| 1094 validators_.texture_sized_texture_filterable_internal_format.AddValue( | |
| 1095 GL_BGRA8_EXT); | |
| 1096 } | |
| 1097 if (enable_texture_float) { | |
| 1098 validators_.texture_internal_format_storage.AddValue(GL_RGBA32F_EXT); | |
| 1099 validators_.texture_internal_format_storage.AddValue(GL_RGB32F_EXT); | |
| 1100 validators_.texture_internal_format_storage.AddValue(GL_ALPHA32F_EXT); | |
| 1101 validators_.texture_internal_format_storage.AddValue( | |
| 1102 GL_LUMINANCE32F_EXT); | |
| 1103 validators_.texture_internal_format_storage.AddValue( | |
| 1104 GL_LUMINANCE_ALPHA32F_EXT); | |
| 1105 } | |
| 1106 if (enable_texture_half_float) { | |
| 1107 validators_.texture_internal_format_storage.AddValue(GL_RGBA16F_EXT); | |
| 1108 validators_.texture_internal_format_storage.AddValue(GL_RGB16F_EXT); | |
| 1109 validators_.texture_internal_format_storage.AddValue(GL_ALPHA16F_EXT); | |
| 1110 validators_.texture_internal_format_storage.AddValue( | |
| 1111 GL_LUMINANCE16F_EXT); | |
| 1112 validators_.texture_internal_format_storage.AddValue( | |
| 1113 GL_LUMINANCE_ALPHA16F_EXT); | |
| 1114 } | |
| 1115 } | |
| 1116 | |
| 1117 bool have_occlusion_query = | 954 bool have_occlusion_query = |
| 1118 gl_version_info_->IsAtLeastGLES(3, 0) || | 955 gl_version_info_->IsAtLeastGLES(3, 0) || |
| 1119 gl_version_info_->IsAtLeastGL(3, 3); | 956 gl_version_info_->IsAtLeastGL(3, 3); |
| 1120 bool have_ext_occlusion_query_boolean = | 957 bool have_ext_occlusion_query_boolean = |
| 1121 extensions.Contains("GL_EXT_occlusion_query_boolean"); | 958 extensions.Contains("GL_EXT_occlusion_query_boolean"); |
| 1122 bool have_arb_occlusion_query2 = | 959 bool have_arb_occlusion_query2 = |
| 1123 extensions.Contains("GL_ARB_occlusion_query2"); | 960 extensions.Contains("GL_ARB_occlusion_query2"); |
| 1124 bool have_arb_occlusion_query = | 961 bool have_arb_occlusion_query = |
| 1125 (gl_version_info_->is_desktop_core_profile && | 962 (gl_version_info_->is_desktop_core_profile && |
| 1126 gl_version_info_->IsAtLeastGL(1, 5)) || | 963 gl_version_info_->IsAtLeastGL(1, 5)) || |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 feature_flags_.angle_webgl_compatibility = | 1248 feature_flags_.angle_webgl_compatibility = |
| 1412 extensions.Contains("GL_ANGLE_webgl_compatibility"); | 1249 extensions.Contains("GL_ANGLE_webgl_compatibility"); |
| 1413 feature_flags_.chromium_copy_texture = | 1250 feature_flags_.chromium_copy_texture = |
| 1414 extensions.Contains("GL_CHROMIUM_copy_texture"); | 1251 extensions.Contains("GL_CHROMIUM_copy_texture"); |
| 1415 feature_flags_.chromium_copy_compressed_texture = | 1252 feature_flags_.chromium_copy_compressed_texture = |
| 1416 extensions.Contains("GL_CHROMIUM_copy_compressed_texture"); | 1253 extensions.Contains("GL_CHROMIUM_copy_compressed_texture"); |
| 1417 feature_flags_.angle_client_arrays = | 1254 feature_flags_.angle_client_arrays = |
| 1418 extensions.Contains("GL_ANGLE_client_arrays"); | 1255 extensions.Contains("GL_ANGLE_client_arrays"); |
| 1419 } | 1256 } |
| 1420 | 1257 |
| 1258 void FeatureInfo::InitializeFloatAndHalfFloatFeatures( |
| 1259 const StringSet& extensions) { |
| 1260 // Check if we should allow GL_OES_texture_float, GL_OES_texture_half_float, |
| 1261 // GL_OES_texture_float_linear, GL_OES_texture_half_float_linear |
| 1262 bool enable_texture_float = false; |
| 1263 bool enable_texture_float_linear = false; |
| 1264 bool enable_texture_half_float = false; |
| 1265 bool enable_texture_half_float_linear = false; |
| 1266 bool enable_ext_color_buffer_float = false; |
| 1267 bool enable_ext_color_buffer_half_float = false; |
| 1268 |
| 1269 bool may_enable_chromium_color_buffer_float = false; |
| 1270 |
| 1271 bool enable_es3 = IsWebGL2OrES3Context(); |
| 1272 |
| 1273 // These extensions allow a variety of floating point formats to be |
| 1274 // rendered to via framebuffer objects. |
| 1275 if (extensions.Contains("GL_EXT_color_buffer_float")) |
| 1276 enable_ext_color_buffer_float = true; |
| 1277 if (extensions.Contains("GL_EXT_color_buffer_half_float")) |
| 1278 enable_ext_color_buffer_half_float = true; |
| 1279 |
| 1280 if (extensions.Contains("GL_ARB_texture_float") || |
| 1281 gl_version_info_->is_desktop_core_profile) { |
| 1282 enable_texture_float = true; |
| 1283 enable_texture_float_linear = true; |
| 1284 enable_texture_half_float = true; |
| 1285 enable_texture_half_float_linear = true; |
| 1286 may_enable_chromium_color_buffer_float = true; |
| 1287 } else { |
| 1288 // GLES3 adds support for Float type by default but it doesn't support all |
| 1289 // formats as GL_OES_texture_float(i.e.LUMINANCE_ALPHA,LUMINANCE and Alpha) |
| 1290 if (extensions.Contains("GL_OES_texture_float")) { |
| 1291 enable_texture_float = true; |
| 1292 if (extensions.Contains("GL_OES_texture_float_linear")) { |
| 1293 enable_texture_float_linear = true; |
| 1294 } |
| 1295 |
| 1296 if (enable_ext_color_buffer_float || gl_version_info_->is_angle) { |
| 1297 may_enable_chromium_color_buffer_float = true; |
| 1298 } |
| 1299 } |
| 1300 |
| 1301 // TODO(dshwang): GLES3 supports half float by default but GL_HALF_FLOAT_OES |
| 1302 // isn't equal to GL_HALF_FLOAT. |
| 1303 if (extensions.Contains("GL_OES_texture_half_float")) { |
| 1304 enable_texture_half_float = true; |
| 1305 if (extensions.Contains("GL_OES_texture_half_float_linear")) { |
| 1306 enable_texture_half_float_linear = true; |
| 1307 } |
| 1308 } |
| 1309 } |
| 1310 |
| 1311 if (enable_texture_float) { |
| 1312 validators_.pixel_type.AddValue(GL_FLOAT); |
| 1313 validators_.read_pixel_type.AddValue(GL_FLOAT); |
| 1314 AddExtensionString("GL_OES_texture_float"); |
| 1315 if (enable_texture_float_linear) { |
| 1316 oes_texture_float_linear_available_ = true; |
| 1317 if (!disallowed_features_.oes_texture_float_linear) |
| 1318 EnableOESTextureFloatLinear(); |
| 1319 } |
| 1320 } |
| 1321 |
| 1322 if (enable_texture_half_float) { |
| 1323 validators_.pixel_type.AddValue(GL_HALF_FLOAT_OES); |
| 1324 validators_.read_pixel_type.AddValue(GL_HALF_FLOAT_OES); |
| 1325 AddExtensionString("GL_OES_texture_half_float"); |
| 1326 if (enable_texture_half_float_linear) { |
| 1327 oes_texture_half_float_linear_available_ = true; |
| 1328 if (!disallowed_features_.oes_texture_half_float_linear) |
| 1329 EnableOESTextureHalfFloatLinear(); |
| 1330 } |
| 1331 } |
| 1332 |
| 1333 if (may_enable_chromium_color_buffer_float) { |
| 1334 static_assert(GL_RGBA32F_ARB == GL_RGBA32F && |
| 1335 GL_RGBA32F_EXT == GL_RGBA32F && |
| 1336 GL_RGB32F_ARB == GL_RGB32F && GL_RGB32F_EXT == GL_RGB32F, |
| 1337 "sized float internal format variations must match"); |
| 1338 // We don't check extension support beyond ARB_texture_float on desktop GL, |
| 1339 // and format support varies between GL configurations. For example, spec |
| 1340 // prior to OpenGL 3.0 mandates framebuffer support only for one |
| 1341 // implementation-chosen format, and ES3.0 EXT_color_buffer_float does not |
| 1342 // support rendering to RGB32F. Check for framebuffer completeness with |
| 1343 // formats that the extensions expose, and only enable an extension when a |
| 1344 // framebuffer created with its texture format is reported as complete. |
| 1345 GLint fb_binding = 0; |
| 1346 GLint tex_binding = 0; |
| 1347 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding); |
| 1348 glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding); |
| 1349 |
| 1350 GLuint tex_id = 0; |
| 1351 GLuint fb_id = 0; |
| 1352 GLsizei width = 16; |
| 1353 |
| 1354 glGenTextures(1, &tex_id); |
| 1355 glGenFramebuffersEXT(1, &fb_id); |
| 1356 glBindTexture(GL_TEXTURE_2D, tex_id); |
| 1357 // Nearest filter needed for framebuffer completeness on some drivers. |
| 1358 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 1359 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0, GL_RGBA, |
| 1360 GL_FLOAT, NULL); |
| 1361 glBindFramebufferEXT(GL_FRAMEBUFFER, fb_id); |
| 1362 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 1363 GL_TEXTURE_2D, tex_id, 0); |
| 1364 GLenum status_rgba = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 1365 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0, GL_RGB, GL_FLOAT, |
| 1366 NULL); |
| 1367 GLenum status_rgb = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 1368 |
| 1369 // For desktop systems, check to see if we support rendering to the full |
| 1370 // range of formats supported by EXT_color_buffer_float |
| 1371 if (status_rgba == GL_FRAMEBUFFER_COMPLETE && enable_es3) { |
| 1372 bool full_float_support = true; |
| 1373 GLenum internal_formats[] = { |
| 1374 GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_R11F_G11F_B10F, |
| 1375 }; |
| 1376 GLenum formats[] = { |
| 1377 GL_RED, GL_RG, GL_RGBA, GL_RED, GL_RG, GL_RGB, |
| 1378 }; |
| 1379 DCHECK_EQ(arraysize(internal_formats), arraysize(formats)); |
| 1380 for (size_t i = 0; i < arraysize(formats); ++i) { |
| 1381 glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], width, width, 0, |
| 1382 formats[i], GL_FLOAT, NULL); |
| 1383 full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == |
| 1384 GL_FRAMEBUFFER_COMPLETE; |
| 1385 } |
| 1386 enable_ext_color_buffer_float = full_float_support; |
| 1387 } |
| 1388 // Likewise for EXT_color_buffer_half_float on ES2 contexts. |
| 1389 if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float) { |
| 1390 bool full_half_float_support = true; |
| 1391 GLenum internal_formats[] = { |
| 1392 GL_R16F, GL_RG16F, GL_RGBA16F, |
| 1393 }; |
| 1394 GLenum formats[] = { |
| 1395 GL_RED, GL_RG, GL_RGBA, |
| 1396 }; |
| 1397 GLenum data_type = GL_FLOAT; |
| 1398 if (gl_version_info_->is_es2) |
| 1399 data_type = GL_HALF_FLOAT_OES; |
| 1400 if (gl_version_info_->is_es3) |
| 1401 data_type = GL_HALF_FLOAT; |
| 1402 DCHECK_EQ(arraysize(internal_formats), arraysize(formats)); |
| 1403 for (size_t i = 0; i < arraysize(formats); ++i) { |
| 1404 glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], width, width, 0, |
| 1405 formats[i], data_type, NULL); |
| 1406 full_half_float_support &= |
| 1407 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) == |
| 1408 GL_FRAMEBUFFER_COMPLETE; |
| 1409 } |
| 1410 enable_ext_color_buffer_half_float = full_half_float_support; |
| 1411 } |
| 1412 |
| 1413 glDeleteFramebuffersEXT(1, &fb_id); |
| 1414 glDeleteTextures(1, &tex_id); |
| 1415 |
| 1416 glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding)); |
| 1417 glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding)); |
| 1418 |
| 1419 DCHECK_EQ(glGetError(), static_cast<GLuint>(GL_NO_ERROR)); |
| 1420 |
| 1421 if (status_rgba == GL_FRAMEBUFFER_COMPLETE) { |
| 1422 feature_flags_.chromium_color_buffer_float_rgba = true; |
| 1423 if (!disallowed_features_.chromium_color_buffer_float_rgba) |
| 1424 EnableCHROMIUMColorBufferFloatRGBA(); |
| 1425 } |
| 1426 if (status_rgb == GL_FRAMEBUFFER_COMPLETE) { |
| 1427 feature_flags_.chromium_color_buffer_float_rgb = true; |
| 1428 if (!disallowed_features_.chromium_color_buffer_float_rgb) |
| 1429 EnableCHROMIUMColorBufferFloatRGB(); |
| 1430 } |
| 1431 } |
| 1432 |
| 1433 // Enable the GL_EXT_color_buffer_float extension for WebGL 2.0 |
| 1434 if (enable_ext_color_buffer_float && enable_es3) { |
| 1435 ext_color_buffer_float_available_ = true; |
| 1436 if (!disallowed_features_.ext_color_buffer_float) |
| 1437 EnableEXTColorBufferFloat(); |
| 1438 } |
| 1439 |
| 1440 // Enable GL_EXT_color_buffer_half_float if we have found the capability. |
| 1441 if (enable_ext_color_buffer_half_float && |
| 1442 !disallowed_features_.ext_color_buffer_half_float) { |
| 1443 EnableEXTColorBufferHalfFloat(); |
| 1444 } |
| 1445 |
| 1446 if (feature_flags_.ext_texture_storage) { |
| 1447 if (enable_texture_float) { |
| 1448 validators_.texture_internal_format_storage.AddValue(GL_RGBA32F_EXT); |
| 1449 validators_.texture_internal_format_storage.AddValue(GL_RGB32F_EXT); |
| 1450 validators_.texture_internal_format_storage.AddValue(GL_ALPHA32F_EXT); |
| 1451 validators_.texture_internal_format_storage.AddValue(GL_LUMINANCE32F_EXT); |
| 1452 validators_.texture_internal_format_storage.AddValue( |
| 1453 GL_LUMINANCE_ALPHA32F_EXT); |
| 1454 } |
| 1455 if (enable_texture_half_float) { |
| 1456 validators_.texture_internal_format_storage.AddValue(GL_RGBA16F_EXT); |
| 1457 validators_.texture_internal_format_storage.AddValue(GL_RGB16F_EXT); |
| 1458 validators_.texture_internal_format_storage.AddValue(GL_ALPHA16F_EXT); |
| 1459 validators_.texture_internal_format_storage.AddValue(GL_LUMINANCE16F_EXT); |
| 1460 validators_.texture_internal_format_storage.AddValue( |
| 1461 GL_LUMINANCE_ALPHA16F_EXT); |
| 1462 } |
| 1463 } |
| 1464 } |
| 1465 |
| 1421 bool FeatureInfo::IsES3Capable() const { | 1466 bool FeatureInfo::IsES3Capable() const { |
| 1422 if (workarounds_.disable_texture_storage) | 1467 if (workarounds_.disable_texture_storage) |
| 1423 return false; | 1468 return false; |
| 1424 if (gl_version_info_) | 1469 if (gl_version_info_) |
| 1425 return gl_version_info_->is_es3_capable; | 1470 return gl_version_info_->is_es3_capable; |
| 1426 return false; | 1471 return false; |
| 1427 } | 1472 } |
| 1428 | 1473 |
| 1429 void FeatureInfo::EnableES3Validators() { | 1474 void FeatureInfo::EnableES3Validators() { |
| 1430 DCHECK(IsES3Capable()); | 1475 DCHECK(IsES3Capable()); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 if (pos == std::string::npos) { | 1575 if (pos == std::string::npos) { |
| 1531 extensions_ += (extensions_.empty() ? "" : " ") + str; | 1576 extensions_ += (extensions_.empty() ? "" : " ") + str; |
| 1532 } | 1577 } |
| 1533 } | 1578 } |
| 1534 | 1579 |
| 1535 FeatureInfo::~FeatureInfo() { | 1580 FeatureInfo::~FeatureInfo() { |
| 1536 } | 1581 } |
| 1537 | 1582 |
| 1538 } // namespace gles2 | 1583 } // namespace gles2 |
| 1539 } // namespace gpu | 1584 } // namespace gpu |
| OLD | NEW |