blob: 16ef4548cb6a991192c71935b8d5524af55fa764 [file] [log] [blame]
junov0cad1f42016-01-07 21:48:511// 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
3// found in the LICENSE file.
4
5#include "gpu/command_buffer/service/gl_utils.h"
6
7#include "base/metrics/histogram.h"
geofflang124fd552016-09-08 20:02:558#include "gpu/command_buffer/common/capabilities.h"
9#include "gpu/command_buffer/service/feature_info.h"
10#include "ui/gl/gl_version_info.h"
junov0cad1f42016-01-07 21:48:5111
12namespace gpu {
13namespace gles2 {
14
15std::vector<int> GetAllGLErrors() {
16 int gl_errors[] = {
17 GL_NO_ERROR,
18 GL_INVALID_ENUM,
19 GL_INVALID_VALUE,
20 GL_INVALID_OPERATION,
21 GL_INVALID_FRAMEBUFFER_OPERATION,
22 GL_OUT_OF_MEMORY,
23 };
24 return base::CustomHistogram::ArrayToCustomRanges(gl_errors,
25 arraysize(gl_errors));
26}
27
geofflang124fd552016-09-08 20:02:5528bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
29 GLint rangeMax,
30 GLint precision) {
31 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
32}
33
34void 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
90void 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
kaininoe20d23ac2016-11-03 01:03:45124 if (feature_info->IsWebGL2OrES3Context()) {
geofflang124fd552016-09-08 20:02:55125 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 ||
kaininoe20d23ac2016-11-03 01:03:45174 feature_info->IsWebGL2OrES3Context()) {
geofflang124fd552016-09-08 20:02:55175 glGetIntegerv(GL_MAX_SAMPLES, &caps->max_samples);
176 }
177}
178
geofflang851a4812016-09-14 19:20:29179bool CheckUniqueAndNonNullIds(GLsizei n, const GLuint* client_ids) {
180 if (n <= 0)
181 return true;
182 std::unordered_set<uint32_t> unique_ids(client_ids, client_ids + n);
183 return (unique_ids.size() == static_cast<size_t>(n)) &&
184 (unique_ids.find(0) == unique_ids.end());
185}
186
junov0cad1f42016-01-07 21:48:51187} // namespace gles2
188} // namespace gpu