OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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/gl_utils.h" | 5 #include "gpu/command_buffer/service/gl_utils.h" |
6 | 6 |
7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "gpu/command_buffer/common/capabilities.h" |
| 9 #include "gpu/command_buffer/service/feature_info.h" |
| 10 #include "ui/gl/gl_version_info.h" |
8 | 11 |
9 namespace gpu { | 12 namespace gpu { |
10 namespace gles2 { | 13 namespace gles2 { |
11 | 14 |
12 std::vector<int> GetAllGLErrors() { | 15 std::vector<int> GetAllGLErrors() { |
13 int gl_errors[] = { | 16 int gl_errors[] = { |
14 GL_NO_ERROR, | 17 GL_NO_ERROR, |
15 GL_INVALID_ENUM, | 18 GL_INVALID_ENUM, |
16 GL_INVALID_VALUE, | 19 GL_INVALID_VALUE, |
17 GL_INVALID_OPERATION, | 20 GL_INVALID_OPERATION, |
18 GL_INVALID_FRAMEBUFFER_OPERATION, | 21 GL_INVALID_FRAMEBUFFER_OPERATION, |
19 GL_OUT_OF_MEMORY, | 22 GL_OUT_OF_MEMORY, |
20 }; | 23 }; |
21 return base::CustomHistogram::ArrayToCustomRanges(gl_errors, | 24 return base::CustomHistogram::ArrayToCustomRanges(gl_errors, |
22 arraysize(gl_errors)); | 25 arraysize(gl_errors)); |
23 } | 26 } |
24 | 27 |
| 28 bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, |
| 29 GLint rangeMax, |
| 30 GLint precision) { |
| 31 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16); |
| 32 } |
| 33 |
| 34 void QueryShaderPrecisionFormat(const gl::GLVersionInfo& gl_version_info, |
| 35 GLenum shader_type, |
| 36 GLenum precision_type, |
| 37 GLint* range, |
| 38 GLint* precision) { |
| 39 switch (precision_type) { |
| 40 case GL_LOW_INT: |
| 41 case GL_MEDIUM_INT: |
| 42 case GL_HIGH_INT: |
| 43 // These values are for a 32-bit twos-complement integer format. |
| 44 range[0] = 31; |
| 45 range[1] = 30; |
| 46 *precision = 0; |
| 47 break; |
| 48 case GL_LOW_FLOAT: |
| 49 case GL_MEDIUM_FLOAT: |
| 50 case GL_HIGH_FLOAT: |
| 51 // These values are for an IEEE single-precision floating-point format. |
| 52 range[0] = 127; |
| 53 range[1] = 127; |
| 54 *precision = 23; |
| 55 break; |
| 56 default: |
| 57 NOTREACHED(); |
| 58 break; |
| 59 } |
| 60 |
| 61 if (gl_version_info.is_es) { |
| 62 // This function is sometimes defined even though it's really just |
| 63 // a stub, so we need to set range and precision as if it weren't |
| 64 // defined before calling it. |
| 65 // On Mac OS with some GPUs, calling this generates a |
| 66 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2 |
| 67 // platforms. |
| 68 glGetShaderPrecisionFormat(shader_type, precision_type, range, precision); |
| 69 |
| 70 // TODO(brianderson): Make the following official workarounds. |
| 71 |
| 72 // Some drivers have bugs where they report the ranges as a negative number. |
| 73 // Taking the absolute value here shouldn't hurt because negative numbers |
| 74 // aren't expected anyway. |
| 75 range[0] = abs(range[0]); |
| 76 range[1] = abs(range[1]); |
| 77 |
| 78 // If the driver reports a precision for highp float that isn't actually |
| 79 // highp, don't pretend like it's supported because shader compilation will |
| 80 // fail anyway. |
| 81 if (precision_type == GL_HIGH_FLOAT && |
| 82 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) { |
| 83 range[0] = 0; |
| 84 range[1] = 0; |
| 85 *precision = 0; |
| 86 } |
| 87 } |
| 88 } |
| 89 |
| 90 void PopulateNumericCapabilities(Capabilities* caps, |
| 91 const FeatureInfo* feature_info) { |
| 92 DCHECK(caps != nullptr); |
| 93 |
| 94 const gl::GLVersionInfo& version_info = feature_info->gl_version_info(); |
| 95 caps->VisitPrecisions([&version_info]( |
| 96 GLenum shader, GLenum type, |
| 97 Capabilities::ShaderPrecision* shader_precision) { |
| 98 GLint range[2] = {0, 0}; |
| 99 GLint precision = 0; |
| 100 QueryShaderPrecisionFormat(version_info, shader, type, range, &precision); |
| 101 shader_precision->min_range = range[0]; |
| 102 shader_precision->max_range = range[1]; |
| 103 shader_precision->precision = precision; |
| 104 }); |
| 105 |
| 106 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, |
| 107 &caps->max_combined_texture_image_units); |
| 108 glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps->max_cube_map_texture_size); |
| 109 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, |
| 110 &caps->max_fragment_uniform_vectors); |
| 111 glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps->max_renderbuffer_size); |
| 112 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps->max_texture_image_units); |
| 113 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps->max_texture_size); |
| 114 glGetIntegerv(GL_MAX_VARYING_VECTORS, &caps->max_varying_vectors); |
| 115 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->max_vertex_attribs); |
| 116 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, |
| 117 &caps->max_vertex_texture_image_units); |
| 118 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, |
| 119 &caps->max_vertex_uniform_vectors); |
| 120 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, |
| 121 &caps->num_compressed_texture_formats); |
| 122 glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps->num_shader_binary_formats); |
| 123 |
| 124 if (feature_info->IsES3Enabled()) { |
| 125 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &caps->max_3d_texture_size); |
| 126 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &caps->max_array_texture_layers); |
| 127 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &caps->max_color_attachments); |
| 128 glGetInteger64v(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, |
| 129 &caps->max_combined_fragment_uniform_components); |
| 130 glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, |
| 131 &caps->max_combined_uniform_blocks); |
| 132 glGetInteger64v(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, |
| 133 &caps->max_combined_vertex_uniform_components); |
| 134 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &caps->max_draw_buffers); |
| 135 glGetInteger64v(GL_MAX_ELEMENT_INDEX, &caps->max_element_index); |
| 136 glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &caps->max_elements_indices); |
| 137 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &caps->max_elements_vertices); |
| 138 glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, |
| 139 &caps->max_fragment_input_components); |
| 140 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, |
| 141 &caps->max_fragment_uniform_blocks); |
| 142 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, |
| 143 &caps->max_fragment_uniform_components); |
| 144 glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->max_program_texel_offset); |
| 145 glGetInteger64v(GL_MAX_SERVER_WAIT_TIMEOUT, &caps->max_server_wait_timeout); |
| 146 glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->max_texture_lod_bias); |
| 147 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, |
| 148 &caps->max_transform_feedback_interleaved_components); |
| 149 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, |
| 150 &caps->max_transform_feedback_separate_attribs); |
| 151 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, |
| 152 &caps->max_transform_feedback_separate_components); |
| 153 glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &caps->max_uniform_block_size); |
| 154 glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, |
| 155 &caps->max_uniform_buffer_bindings); |
| 156 glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &caps->max_varying_components); |
| 157 glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, |
| 158 &caps->max_vertex_output_components); |
| 159 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, |
| 160 &caps->max_vertex_uniform_blocks); |
| 161 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, |
| 162 &caps->max_vertex_uniform_components); |
| 163 glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->min_program_texel_offset); |
| 164 glGetIntegerv(GL_NUM_EXTENSIONS, &caps->num_extensions); |
| 165 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, |
| 166 &caps->num_program_binary_formats); |
| 167 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, |
| 168 &caps->uniform_buffer_offset_alignment); |
| 169 caps->major_version = 3; |
| 170 caps->minor_version = 0; |
| 171 } |
| 172 if (feature_info->feature_flags().multisampled_render_to_texture || |
| 173 feature_info->feature_flags().chromium_framebuffer_multisample || |
| 174 feature_info->IsES3Enabled()) { |
| 175 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples); |
| 176 } |
| 177 } |
| 178 |
25 } // namespace gles2 | 179 } // namespace gles2 |
26 } // namespace gpu | 180 } // namespace gpu |
OLD | NEW |