1 // 2 // Copyright 2015 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // FeaturesGL.h: Features and workarounds for GL driver bugs and other issues. 8 9 #ifndef ANGLE_PLATFORM_FEATURESGL_H_ 10 #define ANGLE_PLATFORM_FEATURESGL_H_ 11 12 #include "platform/Feature.h" 13 14 namespace angle 15 { 16 17 struct FeaturesGL : FeatureSetBase 18 { 19 FeaturesGL(); 20 ~FeaturesGL(); 21 22 // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write 23 // one of the two closest normalized integer representations (although round to nearest is 24 // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that 25 // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in 26 // section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on Intel and AMD 27 // drivers on framebuffer formats that have 1-bit alpha, work around this by using higher 28 // precision formats instead. 29 Feature avoid1BitAlphaTextureFormats = { 30 "avoid_1_bit_alpha_texture_formats", FeatureCategory::OpenGLWorkarounds, 31 "Issue on Intel and AMD drivers with 1-bit alpha framebuffer formats", &members}; 32 33 // On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus 34 // returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable 35 // format. 36 Feature rgba4IsNotSupportedForColorRendering = { 37 "rgba4_is_not_supported_for_color_rendering", FeatureCategory::OpenGLWorkarounds, 38 "Issue on older Intel drivers, GL_RGBA4 is not color renderable", &members}; 39 40 // When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the 41 // driver clears to the linearized clear color despite the framebuffer not supporting SRGB 42 // blending. It only seems to do this when the framebuffer has only linear attachments, mixed 43 // attachments appear to get the correct clear color. 44 Feature doesSRGBClearsOnLinearFramebufferAttachments = { 45 "does_srgb_clears_on_linear_framebuffer_attachments", FeatureCategory::OpenGLWorkarounds, 46 "Issue clearing framebuffers with linear attachments on Intel or AMD " 47 "drivers when GL_FRAMEBUFFER_SRGB is enabled", 48 &members}; 49 50 // On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following: 51 // int i = 1; 52 // do { 53 // i --; 54 // continue; 55 // } while (i > 0) 56 // Work around this by rewriting the do-while to use another GLSL construct (block + while) 57 Feature doWhileGLSLCausesGPUHang = { 58 "do_while_glsl_causes_gpu_hang", FeatureCategory::OpenGLWorkarounds, 59 "On Mac, some GLSL constructs involving do-while loops cause GPU hangs", &members}; 60 61 // Calling glFinish doesn't cause all queries to report that the result is available on some 62 // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish 63 // causes it to fully finish. 64 Feature finishDoesNotCauseQueriesToBeAvailable = { 65 "finish_does_not_cause_queries_to_be_available", FeatureCategory::OpenGLWorkarounds, 66 "On some NVIDIA drivers, glFinish doesn't cause all queries to report available result", 67 &members}; 68 69 // Always call useProgram after a successful link to avoid a driver bug. 70 // This workaround is meant to reproduce the use_current_program_after_successful_link 71 // workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is 72 // not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b). 73 Feature alwaysCallUseProgramAfterLink = { 74 "always_call_use_program_after_link", FeatureCategory::OpenGLWorkarounds, 75 "Always call useProgram after a successful link to avoid a driver bug", &members}; 76 77 // In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row. 78 Feature unpackOverlappingRowsSeparatelyUnpackBuffer = { 79 "unpack_overlapping_rows_separately_unpack_buffer", FeatureCategory::OpenGLWorkarounds, 80 "In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row", 81 &members}; 82 83 // In the case of packing to a pixel pack buffer, pack overlapping rows row by row. 84 Feature packOverlappingRowsSeparatelyPackBuffer = { 85 "pack_overlapping_rows_separately_pack_buffer", FeatureCategory::OpenGLWorkarounds, 86 "In the case of packing to a pixel pack buffer, pack overlapping rows row by row", 87 &members}; 88 89 // During initialization, assign the current vertex attributes to the spec-mandated defaults. 90 Feature initializeCurrentVertexAttributes = { 91 "initialize_current_vertex_attributes", FeatureCategory::OpenGLWorkarounds, 92 "During initialization, assign the current vertex attributes to the spec-mandated defaults", 93 &members}; 94 95 // abs(i) where i is an integer returns unexpected result on Intel Mac. 96 // Emulate abs(i) with i * sign(i). 97 Feature emulateAbsIntFunction = { 98 "emulate_abs_int_function", FeatureCategory::OpenGLWorkarounds, 99 "On Intel Mac, abs(i) where i is an integer returns unexpected result", &members}; 100 101 // On Intel Mac, calculation of loop conditions in for and while loop has bug. 102 // Add "&& true" to the end of the condition expression to work around the bug. 103 Feature addAndTrueToLoopCondition = { 104 "add_and_true_to_loop_condition", FeatureCategory::OpenGLWorkarounds, 105 "On Intel Mac, calculation of loop conditions in for and while loop has bug", &members}; 106 107 // When uploading textures from an unpack buffer, some drivers count an extra row padding when 108 // checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512 109 // For example considering the pixel buffer below where in memory, each row data (D) of the 110 // texture is followed by some unused data (the dots): 111 // +-------+--+ 112 // |DDDDDDD|..| 113 // |DDDDDDD|..| 114 // |DDDDDDD|..| 115 // |DDDDDDD|..| 116 // +-------A--B 117 // The last pixel read will be A, but the driver will think it is B, causing it to generate an 118 // error when the pixel buffer is just big enough. 119 Feature unpackLastRowSeparatelyForPaddingInclusion = { 120 "unpack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds, 121 "When uploading textures from an unpack buffer, some drivers count an extra row padding", 122 &members}; 123 124 // Equivalent workaround when uploading data from a pixel pack buffer. 125 Feature packLastRowSeparatelyForPaddingInclusion = { 126 "pack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds, 127 "When uploading textures from an pack buffer, some drivers count an extra row padding", 128 &members}; 129 130 // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around 131 // this bug, we use an expression to emulate function isnan(). 132 // Tracking bug: http://crbug.com/650547 133 Feature emulateIsnanFloat = { 134 "emulate_isnan_float", FeatureCategory::OpenGLWorkarounds, 135 "On some Intel drivers, using isnan() on highp float will get wrong answer", &members}; 136 137 // On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be 138 // treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a 139 // unused std140 or shared uniform block at the beginning of main to work around it. 140 // Also used on Linux AMD. 141 Feature useUnusedBlocksWithStandardOrSharedLayout = { 142 "use_unused_blocks_with_standard_or_shared_layout", FeatureCategory::OpenGLWorkarounds, 143 "On Mac with OpenGL version 4.1 and Linux AMD, unused std140 or shared uniform blocks " 144 "will be treated as inactive", 145 &members}; 146 147 // This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3. 148 Feature removeInvariantAndCentroidForESSL3 = { 149 "remove_invarient_and_centroid_for_essl3", FeatureCategory::OpenGLWorkarounds, 150 "Fix spec difference between GLSL 4.1 or lower and ESSL3", &members}; 151 152 // On Intel Mac OSX 10.11 driver, using "-float" will get wrong answer. Use "0.0 - float" to 153 // replace "-float". 154 // Tracking bug: http://crbug.com/308366 155 Feature rewriteFloatUnaryMinusOperator = { 156 "rewrite_float_unary_minus_operator", FeatureCategory::OpenGLWorkarounds, 157 "On Intel Mac OSX 10.11 driver, using '-<float>' will get wrong answer", &members, 158 "http://crbug.com/308366"}; 159 160 // On NVIDIA drivers, atan(y, x) may return a wrong answer. 161 // Tracking bug: http://crbug.com/672380 162 Feature emulateAtan2Float = {"emulate_atan_2_float", FeatureCategory::OpenGLWorkarounds, 163 "On NVIDIA drivers, atan(y, x) may return a wrong answer", 164 &members, "http://crbug.com/672380"}; 165 166 // Some drivers seem to forget about UBO bindings when using program binaries. Work around 167 // this by re-applying the bindings after the program binary is loaded or saved. 168 // This only seems to affect AMD OpenGL drivers, and some Android devices. 169 // http://anglebug.com/1637 170 Feature reapplyUBOBindingsAfterUsingBinaryProgram = { 171 "reapply_ubo_bindings_after_using_binary_program", FeatureCategory::OpenGLWorkarounds, 172 "Some AMD OpenGL drivers and Android devices forget about UBO bindings " 173 "when using program binaries", 174 &members, "http://anglebug.com/1637"}; 175 176 // Some OpenGL drivers return 0 when we query MAX_VERTEX_ATTRIB_STRIDE in an OpenGL 4.4 or 177 // higher context. 178 // This only seems to affect AMD OpenGL drivers. 179 // Tracking bug: http://anglebug.com/1936 180 Feature emulateMaxVertexAttribStride = { 181 "emulate_max_vertex_attrib_stride", FeatureCategory::OpenGLWorkarounds, 182 "Some AMD OpenGL >= 4.4 drivers return 0 when MAX_VERTEX_ATTRIB_STRIED queried", &members, 183 "http://anglebug.com/1936"}; 184 185 // Initializing uninitialized locals caused odd behavior on Mac in a few WebGL 2 tests. 186 // Tracking bug: http://anglebug/2041 187 Feature dontInitializeUninitializedLocals = { 188 "dont_initialize_uninitialized_locals", FeatureCategory::OpenGLWorkarounds, 189 "On Mac initializing uninitialized locals caused odd behavior in a few WebGL 2 tests", 190 &members, "http://anglebug.com/2041"}; 191 192 // On some NVIDIA drivers the point size range reported from the API is inconsistent with the 193 // actual behavior. Clamp the point size to the value from the API to fix this. 194 Feature clampPointSize = { 195 "clamp_point_size", FeatureCategory::OpenGLWorkarounds, 196 "On some NVIDIA drivers the point size range reported from the API is " 197 "inconsistent with the actual behavior", 198 &members}; 199 200 // On some NVIDIA drivers certain types of GLSL arithmetic ops mixing vectors and scalars may be 201 // executed incorrectly. Change them in the shader translator. Tracking bug: 202 // http://crbug.com/772651 203 Feature rewriteVectorScalarArithmetic = { 204 "rewrite_vector_scalar_arithmetic", FeatureCategory::OpenGLWorkarounds, 205 "On some NVIDIA drivers certain types of GLSL arithmetic ops mixing " 206 "vectors and scalars may be executed incorrectly", 207 &members, "http://crbug.com/772651"}; 208 209 // On some Android devices for loops used to initialize variables hit native GLSL compiler bugs. 210 Feature dontUseLoopsToInitializeVariables = { 211 "dont_use_loops_to_initialize_variables", FeatureCategory::OpenGLWorkarounds, 212 "On some Android devices for loops used to initialize variables hit " 213 "native GLSL compiler bugs", 214 &members}; 215 216 // On some NVIDIA drivers gl_FragDepth is not clamped correctly when rendering to a floating 217 // point depth buffer. Clamp it in the translated shader to fix this. 218 Feature clampFragDepth = {"clamp_frag_depth", FeatureCategory::OpenGLWorkarounds, 219 "On some NVIDIA drivers gl_FragDepth is not clamped correctly when " 220 "rendering to a floating point depth buffer", 221 &members}; 222 223 // On some NVIDIA drivers before version 397.31 repeated assignment to swizzled values inside a 224 // GLSL user-defined function have incorrect results. Rewrite this type of statements to fix 225 // this. 226 Feature rewriteRepeatedAssignToSwizzled = { 227 "rewrite_repeated_assign_to_swizzled", FeatureCategory::OpenGLWorkarounds, 228 "On some NVIDIA drivers < v397.31, repeated assignment to swizzled " 229 "values inside a GLSL user-defined function have incorrect results", 230 &members}; 231 // On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests. 232 // It might be possible to work around the Intel bug by rewriting *FragData to *FragColor 233 // instead of disabling the functionality entirely. The AMD bug looked like incorrect blending, 234 // not sure if a workaround is feasible. http://anglebug.com/1085 235 Feature disableBlendFuncExtended = { 236 "disable_blend_func_extended", FeatureCategory::OpenGLWorkarounds, 237 "On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests", 238 &members, "http://anglebug.com/1085"}; 239 240 // Qualcomm drivers returns raw sRGB values instead of linearized values when calling 241 // glReadPixels on unsized sRGB texture formats. http://crbug.com/550292 and 242 // http://crbug.com/565179 243 Feature unsizedsRGBReadPixelsDoesntTransform = { 244 "unsized_srgb_read_pixels_doesnt_transform", FeatureCategory::OpenGLWorkarounds, 245 "Qualcomm drivers returns raw sRGB values instead of linearized values " 246 "when calling glReadPixels on unsized sRGB texture formats", 247 &members, "http://crbug.com/565179"}; 248 249 // Older Qualcomm drivers generate errors when querying the number of bits in timer queries, ex: 250 // GetQueryivEXT(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS). http://anglebug.com/3027 251 Feature queryCounterBitsGeneratesErrors = { 252 "query_counter_bits_generates_errors", FeatureCategory::OpenGLWorkarounds, 253 "Older Qualcomm drivers generate errors when querying the number of bits in timer queries", 254 &members, "http://anglebug.com/3027"}; 255 256 // Re-linking a program in parallel is buggy on some Intel Windows OpenGL drivers and Android 257 // platforms. 258 // http://anglebug.com/3045 259 Feature dontRelinkProgramsInParallel = { 260 "dont_relink_programs_in_parallel", FeatureCategory::OpenGLWorkarounds, 261 "On some Intel Windows OpenGL drivers and Android, relinking a program " 262 "in parallel is buggy", 263 &members, "http://anglebug.com/3045"}; 264 265 // Some tests have been seen to fail using worker contexts, this switch allows worker contexts 266 // to be disabled for some platforms. http://crbug.com/849576 267 Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds, 268 "Some tests have been seen to fail using worker contexts", 269 &members, "http://crbug.com/849576"}; 270 271 // Most Android devices fail to allocate a texture that is larger than 4096. Limit the caps 272 // instead of generating GL_OUT_OF_MEMORY errors. Also causes system to hang on some older 273 // intel mesa drivers on Linux. 274 Feature limitMaxTextureSizeTo4096 = {"max_texture_size_limit_4096", 275 FeatureCategory::OpenGLWorkarounds, 276 "Limit max texture size to 4096 to avoid frequent " 277 "out-of-memory errors on Android or Intel Linux", 278 &members, "http://crbug.com/927470"}; 279 280 // Prevent excessive MSAA allocations on Android devices, various rendering bugs have been 281 // observed and they tend to be high DPI anyways. http://crbug.com/797243 282 Feature limitMaxMSAASamplesTo4 = { 283 "max_msaa_sample_count_4", FeatureCategory::OpenGLWorkarounds, 284 "Various rendering bugs have been observed when using higher MSAA counts on Android", 285 &members, "http://crbug.com/797243"}; 286 287 // Prefer to do the robust resource init clear using a glClear. Calls to TexSubImage2D on large 288 // textures can take hundreds of milliseconds because of slow uploads on macOS. Do this only on 289 // macOS because clears are buggy on other drivers. 290 // https://crbug.com/848952 (slow uploads on macOS) 291 // https://crbug.com/883276 (buggy clears on Android) 292 Feature allowClearForRobustResourceInit = { 293 "allow_clear_for_robust_resource_init", FeatureCategory::OpenGLWorkarounds, 294 "Using glClear for robust resource initialization is buggy on some drivers and leads to " 295 "texture corruption. Default to data uploads except on MacOS where it is very slow.", 296 &members, "http://crbug.com/883276"}; 297 298 // Some drivers automatically handle out-of-bounds uniform array access but others need manual 299 // clamping to satisfy the WebGL requirements. 300 Feature clampArrayAccess = {"clamp_array_access", FeatureCategory::OpenGLWorkarounds, 301 "Clamp uniform array access to avoid reading invalid memory.", 302 &members, "http://anglebug.com/2978"}; 303 304 // Reset glTexImage2D base level to workaround pixel comparison failure above Mac OS 10.12.4 on 305 // Intel Mac. 306 Feature resetTexImage2DBaseLevel = {"reset_teximage2d_base_level", 307 FeatureCategory::OpenGLWorkarounds, 308 "Reset texture base level before calling glTexImage2D to " 309 "work around pixel comparison failure.", 310 &members, "https://crbug.com/705865"}; 311 312 // glClearColor does not always work on Intel 6xxx Mac drivers when the clear color made up of 313 // all zeros and ones. 314 Feature clearToZeroOrOneBroken = { 315 "clear_to_zero_or_one_broken", FeatureCategory::OpenGLWorkarounds, 316 "Clears when the clear color is all zeros or ones do not work.", &members, 317 "https://crbug.com/710443"}; 318 319 // Some older Linux Intel mesa drivers will hang the system when allocating large textures. Fix 320 // this by capping the max texture size. 321 Feature limitMax3dArrayTextureSizeTo1024 = { 322 "max_3d_array_texture_size_1024", FeatureCategory::OpenGLWorkarounds, 323 "Limit max 3d texture size and max array texture layers to 1024 to avoid system hang on " 324 "older Intel Linux", 325 &members, "http://crbug.com/927470"}; 326 327 // BlitFramebuffer has issues on some platforms with large source/dest texture sizes. This 328 // workaround adjusts the destination rectangle source and dest rectangle to fit within maximum 329 // twice the size of the framebuffer. 330 Feature adjustSrcDstRegionBlitFramebuffer = { 331 "adjust_src_dst_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds, 332 "Many platforms have issues with blitFramebuffer when the parameters are large.", &members, 333 "http://crbug.com/830046"}; 334 335 // BlitFramebuffer has issues on Mac when the source bounds aren't enclosed by the framebuffer. 336 // This workaround clips the source region and adjust the dest region proportionally. 337 Feature clipSrcRegionBlitFramebuffer = { 338 "clip_src_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds, 339 "Mac has issues with blitFramebuffer when the parameters don't match the framebuffer size.", 340 &members, "http://crbug.com/830046"}; 341 }; 342 343 inline FeaturesGL::FeaturesGL() = default; 344 inline FeaturesGL::~FeaturesGL() = default; 345 346 } // namespace angle 347 348 #endif // ANGLE_PLATFORM_FEATURESGL_H_ 349