summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/include/platform
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /gfx/angle/checkout/include/platform
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/include/platform')
-rw-r--r--gfx/angle/checkout/include/platform/Feature.h200
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesD3D.h239
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesGL.h565
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesMtl.h90
-rw-r--r--gfx/angle/checkout/include/platform/FeaturesVk.h531
-rw-r--r--gfx/angle/checkout/include/platform/FrontendFeatures.h86
-rw-r--r--gfx/angle/checkout/include/platform/Platform.h10
-rw-r--r--gfx/angle/checkout/include/platform/PlatformMethods.h339
8 files changed, 2060 insertions, 0 deletions
diff --git a/gfx/angle/checkout/include/platform/Feature.h b/gfx/angle/checkout/include/platform/Feature.h
new file mode 100644
index 0000000000..3ac263d6ec
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/Feature.h
@@ -0,0 +1,200 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Feature.h: Definition of structs to hold feature/workaround information.
+//
+
+#ifndef ANGLE_PLATFORM_FEATURE_H_
+#define ANGLE_PLATFORM_FEATURE_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#define ANGLE_FEATURE_CONDITION(set, feature, cond) \
+ do \
+ { \
+ (set)->feature.enabled = cond; \
+ (set)->feature.condition = ANGLE_STRINGIFY(cond); \
+ } while (0)
+
+namespace angle
+{
+
+enum class FeatureCategory
+{
+ FrontendWorkarounds,
+ FrontendFeatures,
+ OpenGLWorkarounds,
+ D3DWorkarounds,
+ D3DCompilerWorkarounds,
+ VulkanWorkarounds,
+ VulkanFeatures,
+ MetalFeatures,
+};
+
+constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds";
+constexpr char kFeatureCategoryFrontendFeatures[] = "Frontend features";
+constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds";
+constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds";
+constexpr char kFeatureCategoryD3DCompilerWorkarounds[] = "D3D compiler workarounds";
+constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds";
+constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features";
+constexpr char kFeatureCategoryMetalFeatures[] = "Metal features";
+constexpr char kFeatureCategoryUnknown[] = "Unknown";
+
+inline const char *FeatureCategoryToString(const FeatureCategory &fc)
+{
+ switch (fc)
+ {
+ case FeatureCategory::FrontendWorkarounds:
+ return kFeatureCategoryFrontendWorkarounds;
+ break;
+
+ case FeatureCategory::FrontendFeatures:
+ return kFeatureCategoryFrontendFeatures;
+ break;
+
+ case FeatureCategory::OpenGLWorkarounds:
+ return kFeatureCategoryOpenGLWorkarounds;
+ break;
+
+ case FeatureCategory::D3DWorkarounds:
+ return kFeatureCategoryD3DWorkarounds;
+ break;
+
+ case FeatureCategory::D3DCompilerWorkarounds:
+ return kFeatureCategoryD3DCompilerWorkarounds;
+ break;
+
+ case FeatureCategory::VulkanWorkarounds:
+ return kFeatureCategoryVulkanWorkarounds;
+ break;
+
+ case FeatureCategory::VulkanFeatures:
+ return kFeatureCategoryVulkanFeatures;
+ break;
+
+ case FeatureCategory::MetalFeatures:
+ return kFeatureCategoryMetalFeatures;
+ break;
+
+ default:
+ return kFeatureCategoryUnknown;
+ break;
+ }
+}
+
+constexpr char kFeatureStatusEnabled[] = "enabled";
+constexpr char kFeatureStatusDisabled[] = "disabled";
+
+inline const char *FeatureStatusToString(const bool &status)
+{
+ if (status)
+ {
+ return kFeatureStatusEnabled;
+ }
+ return kFeatureStatusDisabled;
+}
+
+struct Feature;
+
+using FeatureMap = std::map<std::string, Feature *>;
+using FeatureList = std::vector<const Feature *>;
+
+struct Feature
+{
+ Feature(const Feature &other);
+ Feature(const char *name,
+ const FeatureCategory &category,
+ const char *description,
+ FeatureMap *const mapPtr,
+ const char *bug);
+ ~Feature();
+
+ // The name of the workaround, lowercase, camel_case
+ const char *const name;
+
+ // The category that the workaround belongs to. Eg. "Vulkan workarounds"
+ const FeatureCategory category;
+
+ // A short description to be read by the user.
+ const char *const description;
+
+ // A link to the bug, if any
+ const char *const bug;
+
+ // Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
+ // version, but may be overriden to any value.
+ bool enabled = false;
+
+ // A stingified version of the condition used to set 'enabled'. ie "IsNvidia() && IsApple()"
+ const char *condition;
+};
+
+inline Feature::Feature(const Feature &other) = default;
+inline Feature::Feature(const char *name,
+ const FeatureCategory &category,
+ const char *description,
+ FeatureMap *const mapPtr,
+ const char *bug = "")
+ : name(name),
+ category(category),
+ description(description),
+ bug(bug),
+ enabled(false),
+ condition("")
+{
+ if (mapPtr != nullptr)
+ {
+ (*mapPtr)[std::string(name)] = this;
+ }
+}
+
+inline Feature::~Feature() = default;
+
+struct FeatureSetBase
+{
+ public:
+ FeatureSetBase();
+ ~FeatureSetBase();
+
+ private:
+ // Non-copyable
+ FeatureSetBase(const FeatureSetBase &other) = delete;
+ FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
+
+ protected:
+ FeatureMap members = FeatureMap();
+
+ public:
+ void overrideFeatures(const std::vector<std::string> &featureNames, bool enabled)
+ {
+ for (const std::string &name : featureNames)
+ {
+ if (members.find(name) != members.end())
+ {
+ members[name]->enabled = enabled;
+ }
+ }
+ }
+
+ void populateFeatureList(FeatureList *features) const
+ {
+ for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
+ {
+ features->push_back(it->second);
+ }
+ }
+
+ const FeatureMap &getFeatures() const { return members; }
+};
+
+inline FeatureSetBase::FeatureSetBase() = default;
+inline FeatureSetBase::~FeatureSetBase() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_WORKAROUND_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesD3D.h b/gfx/angle/checkout/include/platform/FeaturesD3D.h
new file mode 100644
index 0000000000..bbceb49a73
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesD3D.h
@@ -0,0 +1,239 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FeaturesD3D.h: Features and workarounds for D3D driver bugs and other issues.
+
+#ifndef ANGLE_PLATFORM_FEATURESD3D_H_
+#define ANGLE_PLATFORM_FEATURESD3D_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+// Workarounds attached to each shader. Do not need to expose information about these workarounds so
+// a simple bool struct suffices.
+struct CompilerWorkaroundsD3D
+{
+ bool skipOptimization = false;
+
+ bool useMaxOptimization = false;
+
+ // IEEE strictness needs to be enabled for NANs to work.
+ bool enableIEEEStrictness = false;
+};
+
+struct FeaturesD3D : FeatureSetBase
+{
+ FeaturesD3D();
+ ~FeaturesD3D();
+
+ // On some systems, having extra rendertargets than necessary slows down the shader.
+ // We can fix this by optimizing those out of the shader. At the same time, we can
+ // work around a bug on some nVidia drivers that they ignore "null" render targets
+ // in D3D11, by compacting the active color attachments list to omit null entries.
+ Feature mrtPerfWorkaround = {"mrt_perf_workaround", FeatureCategory::D3DWorkarounds,
+ "Some drivers have a bug where they ignore null render targets",
+ &members};
+
+ Feature setDataFasterThanImageUpload = {"set_data_faster_than_image_upload",
+ FeatureCategory::D3DWorkarounds,
+ "Set data faster than image upload", &members};
+
+ Feature setDataFasterThanImageUploadOn128bitFormats = {
+ "set_data_faster_than_image_upload_on_128bit_formats", FeatureCategory::D3DWorkarounds,
+ "Set data faster than image upload on 128bit formats", &members};
+
+ // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level
+ // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to
+ // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no
+ // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an
+ // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST
+ // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the
+ // texture. The textures' level zeros are identical, but only one texture has mips.
+ Feature zeroMaxLodWorkaround = {"zero_max_lod", FeatureCategory::D3DWorkarounds,
+ "Missing an option to disable mipmaps on a mipmapped texture",
+ &members};
+
+ // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite
+ // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite
+ // emulation that is implemented using instanced quads.
+ Feature useInstancedPointSpriteEmulation = {
+ "use_instanced_point_sprite_emulation", FeatureCategory::D3DWorkarounds,
+ "Some D3D11 renderers do not support geometry shaders for pointsprite emulation", &members};
+
+ // A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using
+ // CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround
+ // is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer
+ // NVIDIA driver versions because of a second driver bug present with the workaround enabled.
+ // (See: http://anglebug.com/1452)
+ Feature depthStencilBlitExtraCopy = {
+ "depth_stencil_blit_extra_copy", FeatureCategory::D3DWorkarounds,
+ "Bug in some drivers triggers a TDR when using CopySubresourceRegion from a staging "
+ "texture to a depth/stencil",
+ &members, "http://anglebug.com/1452"};
+
+ // The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions.
+ // We can work around this by expanding the pow into a series of multiplies if we're running
+ // under the affected compiler.
+ Feature expandIntegerPowExpressions = {
+ "expand_integer_pow_expressions", FeatureCategory::D3DWorkarounds,
+ "The HLSL optimizer has a bug with optimizing 'pow' in certain integer-valued expressions",
+ &members};
+
+ // NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform
+ // feedback is used to repeatedly write to the same buffer positions.
+ Feature flushAfterEndingTransformFeedback = {
+ "flush_after_ending_transform_feedback", FeatureCategory::D3DWorkarounds,
+ "Some drivers sometimes write out-of-order results to StreamOut buffers when transform "
+ "feedback is used to repeatedly write to the same buffer positions",
+ &members};
+
+ // Some drivers (NVIDIA) do not take into account the base level of the texture in the results
+ // of the HLSL GetDimensions builtin.
+ Feature getDimensionsIgnoresBaseLevel = {
+ "get_dimensions_ignores_base_level", FeatureCategory::D3DWorkarounds,
+ "Some drivers do not take into account the base level of the "
+ "texture in the results of the HLSL GetDimensions builtin",
+ &members};
+
+ // On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location
+ // is negative, even if the sum of Offset and Location is in range. This may cause errors when
+ // translating GLSL's function texelFetchOffset into texture.Load, as it is valid for
+ // texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P
+ // and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch
+ // by adding Offset directly to Location before reading the texture.
+ Feature preAddTexelFetchOffsets = {
+ "pre_add_texel_fetch_offsets", FeatureCategory::D3DWorkarounds,
+ "HLSL's function texture.Load returns 0 when the parameter Location is negative, even if "
+ "the sum of Offset and Location is in range",
+ &members};
+
+ // On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly.
+ // We can work around this bug by doing an internal blit to a temporary single-channel texture
+ // before we sample.
+ Feature emulateTinyStencilTextures = {
+ "emulate_tiny_stencil_textures", FeatureCategory::D3DWorkarounds,
+ "1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly", &members};
+
+ // In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly.
+ // This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use
+ // R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers.
+ // On older AMD drivers, the data in DXGI_FORMAT_B5G6R5_UNORM becomes corrupted for unknown
+ // reasons.
+ Feature disableB5G6R5Support = {"disable_b5g6r5_support", FeatureCategory::D3DWorkarounds,
+ "Textures with the format "
+ "DXGI_FORMAT_B5G6R5_UNORM have incorrect data",
+ &members};
+
+ // On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in
+ // vertex shaders. To work around this bug, we translate -(int) into ~(int)+1.
+ // This driver bug is fixed in 20.19.15.4624.
+ Feature rewriteUnaryMinusOperator = {
+ "rewrite_unary_minus_operator", FeatureCategory::D3DWorkarounds,
+ "Evaluating unary minus operator on integer may get wrong answer in vertex shaders",
+ &members};
+
+ // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
+ // this bug, we use an expression to emulate function isnan().
+ // Tracking bug: https://crbug.com/650547
+ // This driver bug is fixed in 21.20.16.4542.
+ Feature emulateIsnanFloat = {"emulate_isnan_float", FeatureCategory::D3DWorkarounds,
+ "Using isnan() on highp float will get wrong answer", &members,
+ "https://crbug.com/650547"};
+
+ // On some Intel drivers, using clear() may not take effect. To work around this bug, we call
+ // clear() twice on these platforms.
+ // Tracking bug: https://crbug.com/655534
+ Feature callClearTwice = {"call_clear_twice", FeatureCategory::D3DWorkarounds,
+ "Using clear() may not take effect", &members,
+ "https://crbug.com/655534"};
+
+ // On Sandybridge, calling ClearView after using dual source blending causes the hardware to
+ // hang. See: https://bugzilla.mozilla.org/show_bug.cgi?id=1633628
+ Feature emulateClearViewAfterDualSourceBlending = {
+ "emulate_clear_view_after_dual_source_blending", FeatureCategory::D3DWorkarounds,
+ "On Sandybridge, calling ClearView after using dual source blending causes "
+ "the hardware to hang",
+ &members, "https://bugzilla.mozilla.org/show_bug.cgi?id=1633628"};
+
+ // On some Intel drivers, copying from staging storage to constant buffer storage does not
+ // seem to work. Work around this by keeping system memory storage as a canonical reference
+ // for buffer data.
+ // D3D11-only workaround. See http://crbug.com/593024.
+ Feature useSystemMemoryForConstantBuffers = {"use_system_memory_for_constant_buffers",
+ FeatureCategory::D3DWorkarounds,
+ "Copying from staging storage to constant buffer "
+ "storage does not work",
+ &members, "https://crbug.com/593024"};
+
+ // This workaround is for the ANGLE_multiview extension. If enabled the viewport or render
+ // target slice will be selected in the geometry shader stage. The workaround flag is added to
+ // make it possible to select the code path in end2end and performance tests.
+ Feature selectViewInGeometryShader = {
+ "select_view_in_geometry_shader", FeatureCategory::D3DWorkarounds,
+ "The viewport or render target slice will be selected in the geometry shader stage for "
+ "the ANGLE_multiview extension",
+ &members};
+
+ // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
+ // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
+ // shader.
+ // 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'.
+ // When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even
+ // if they should be discard by 'discard' statements.
+ // 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set,
+ // then rendering samples also pass neglecting discard statements in pixel shader.
+ // So we add a mock texture as render target in such case. See http://anglebug.com/2152
+ Feature addMockTextureNoRenderTarget = {
+ "add_mock_texture_no_render_target", FeatureCategory::D3DWorkarounds,
+ "On some drivers when rendering with no render target, two bugs lead to incorrect behavior",
+ &members, "http://anglebug.com/2152"};
+
+ // Don't use D3D constant register zero when allocating space for uniforms in the vertex shader.
+ // This is targeted to work around a bug in NVIDIA D3D driver version 388.59 where in very
+ // specific cases the driver would not handle constant register zero correctly.
+ Feature skipVSConstantRegisterZero = {
+ "skip_vs_constant_register_zero", FeatureCategory::D3DWorkarounds,
+ "In specific cases the driver doesn't handle constant register zero correctly", &members};
+
+ // Forces the value returned from an atomic operations to be always be resolved. This is
+ // targeted to workaround a bug in NVIDIA D3D driver where the return value from
+ // RWByteAddressBuffer.InterlockedAdd does not get resolved when used in the .yzw components of
+ // a RWByteAddressBuffer.Store operation. Only has an effect on HLSL translation.
+ // http://anglebug.com/3246
+ Feature forceAtomicValueResolution = {
+ "force_atomic_value_resolution", FeatureCategory::D3DWorkarounds,
+ "On some drivers the return value from RWByteAddressBuffer.InterlockedAdd does not resolve "
+ "when used in the .yzw components of a RWByteAddressBuffer.Store operation",
+ &members, "http://anglebug.com/3246"};
+
+ // Match chromium's robust resource init behaviour by always prefering to upload texture data
+ // instead of clearing. Clear calls have been observed to cause texture corruption for some
+ // formats.
+ Feature allowClearForRobustResourceInit = {
+ "allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds,
+ "Some drivers corrupt texture data when clearing for robust resource initialization.",
+ &members, "http://crbug.com/941620"};
+
+ // Allow translating uniform block to StructuredBuffer. This is targeted to work around a slow
+ // fxc compile performance issue with dynamic uniform indexing. http://anglebug.com/3682
+ Feature allowTranslateUniformBlockToStructuredBuffer = {
+ "allow_translate_uniform_block_to_structured_buffer", FeatureCategory::D3DWorkarounds,
+ "There is a slow fxc compile performance issue with dynamic uniform indexing if "
+ "translating a uniform block with a large array member to cbuffer.",
+ &members, "http://anglebug.com/3682"};
+
+ Feature allowES3OnFL10_0 = {"allowES3OnFL10_0", FeatureCategory::D3DWorkarounds,
+ "Allow ES3 on 10.0 devices", &members};
+};
+
+inline FeaturesD3D::FeaturesD3D() = default;
+inline FeaturesD3D::~FeaturesD3D() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESD3D_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesGL.h b/gfx/angle/checkout/include/platform/FeaturesGL.h
new file mode 100644
index 0000000000..064cda64e4
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesGL.h
@@ -0,0 +1,565 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FeaturesGL.h: Features and workarounds for GL driver bugs and other issues.
+
+#ifndef ANGLE_PLATFORM_FEATURESGL_H_
+#define ANGLE_PLATFORM_FEATURESGL_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesGL : FeatureSetBase
+{
+ FeaturesGL();
+ ~FeaturesGL();
+
+ // When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write
+ // one of the two closest normalized integer representations (although round to nearest is
+ // preferred) (see section 2.3.5.2 of the GL 4.5 core specification). OpenGL ES requires that
+ // round-to-nearest is used (see "Conversion from Floating-Point to Framebuffer Fixed-Point" in
+ // section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on AMD drivers on
+ // framebuffer formats that have 1-bit alpha, work around this by using higher precision formats
+ // instead.
+ Feature avoid1BitAlphaTextureFormats = {"avoid_1_bit_alpha_texture_formats",
+ FeatureCategory::OpenGLWorkarounds,
+ "Issue with 1-bit alpha framebuffer formats", &members};
+
+ // On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus
+ // returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable
+ // format.
+ Feature rgba4IsNotSupportedForColorRendering = {"rgba4_is_not_supported_for_color_rendering",
+ FeatureCategory::OpenGLWorkarounds,
+ "GL_RGBA4 is not color renderable", &members};
+
+ // Newer Intel GPUs natively support ETC2/EAC compressed texture formats.
+ Feature allowEtcFormats = {"allow_etc_formats", FeatureCategory::OpenGLWorkarounds,
+ "Enable ETC2/EAC on desktop OpenGL", &members};
+
+ // When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the
+ // driver clears to the linearized clear color despite the framebuffer not supporting SRGB
+ // blending. It only seems to do this when the framebuffer has only linear attachments, mixed
+ // attachments appear to get the correct clear color.
+ Feature doesSRGBClearsOnLinearFramebufferAttachments = {
+ "does_srgb_clears_on_linear_framebuffer_attachments", FeatureCategory::OpenGLWorkarounds,
+ "Issue clearing framebuffers with linear attachments when GL_FRAMEBUFFER_SRGB is enabled",
+ &members};
+
+ // On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following:
+ // int i = 1;
+ // do {
+ // i --;
+ // continue;
+ // } while (i > 0)
+ // Work around this by rewriting the do-while to use another GLSL construct (block + while)
+ Feature doWhileGLSLCausesGPUHang = {
+ "do_while_glsl_causes_gpu_hang", FeatureCategory::OpenGLWorkarounds,
+ "Some GLSL constructs involving do-while loops cause GPU hangs", &members,
+ "http://crbug.com/644669"};
+
+ // On Mac AMD GPU gl_VertexID in GLSL vertex shader doesn't include base vertex value,
+ // Work aronud this by replace gl_VertexID with (gl_VertexID - angle_BaseVertex) when
+ // angle_BaseVertex is present.
+ Feature addBaseVertexToVertexID = {
+ "vertex_id_does_not_include_base_vertex", FeatureCategory::OpenGLWorkarounds,
+ "gl_VertexID in GLSL vertex shader doesn't include base vertex value", &members};
+
+ // Calling glFinish doesn't cause all queries to report that the result is available on some
+ // (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish
+ // causes it to fully finish.
+ Feature finishDoesNotCauseQueriesToBeAvailable = {
+ "finish_does_not_cause_queries_to_be_available", FeatureCategory::OpenGLWorkarounds,
+ "glFinish doesn't cause all queries to report available result", &members};
+
+ // Always call useProgram after a successful link to avoid a driver bug.
+ // This workaround is meant to reproduce the use_current_program_after_successful_link
+ // workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is
+ // not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b).
+ Feature alwaysCallUseProgramAfterLink = {
+ "always_call_use_program_after_link", FeatureCategory::OpenGLWorkarounds,
+ "Always call useProgram after a successful link to avoid a driver bug", &members,
+ "http://crbug.com/110263"};
+
+ // On NVIDIA, in the case of unpacking from a pixel unpack buffer, unpack overlapping rows row
+ // by row.
+ Feature unpackOverlappingRowsSeparatelyUnpackBuffer = {
+ "unpack_overlapping_rows_separately_unpack_buffer", FeatureCategory::OpenGLWorkarounds,
+ "In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row",
+ &members};
+
+ // On NVIDIA, in the case of packing to a pixel pack buffer, pack overlapping rows row by row.
+ Feature packOverlappingRowsSeparatelyPackBuffer = {
+ "pack_overlapping_rows_separately_pack_buffer", FeatureCategory::OpenGLWorkarounds,
+ "In the case of packing to a pixel pack buffer, pack overlapping rows row by row",
+ &members};
+
+ // On NVIDIA, during initialization, assign the current vertex attributes to the spec-mandated
+ // defaults.
+ Feature initializeCurrentVertexAttributes = {
+ "initialize_current_vertex_attributes", FeatureCategory::OpenGLWorkarounds,
+ "During initialization, assign the current vertex attributes to the spec-mandated defaults",
+ &members};
+
+ // abs(i) where i is an integer returns unexpected result on Intel Mac.
+ // Emulate abs(i) with i * sign(i).
+ Feature emulateAbsIntFunction = {"emulate_abs_int_function", FeatureCategory::OpenGLWorkarounds,
+ "abs(i) where i is an integer returns unexpected result",
+ &members, "http://crbug.com/642227"};
+
+ // On Intel Mac, calculation of loop conditions in for and while loop has bug.
+ // Add "&& true" to the end of the condition expression to work around the bug.
+ Feature addAndTrueToLoopCondition = {
+ "add_and_true_to_loop_condition", FeatureCategory::OpenGLWorkarounds,
+ "Calculation of loop conditions in for and while loop has bug", &members};
+
+ // When uploading textures from an unpack buffer, some drivers count an extra row padding when
+ // checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512
+ // For example considering the pixel buffer below where in memory, each row data (D) of the
+ // texture is followed by some unused data (the dots):
+ // +-------+--+
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // |DDDDDDD|..|
+ // +-------A--B
+ // The last pixel read will be A, but the driver will think it is B, causing it to generate an
+ // error when the pixel buffer is just big enough.
+ Feature unpackLastRowSeparatelyForPaddingInclusion = {
+ "unpack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds,
+ "When uploading textures from an unpack buffer, some drivers count an extra row padding",
+ &members, "http://anglebug.com/1512"};
+
+ // Equivalent workaround when uploading data from a pixel pack buffer.
+ Feature packLastRowSeparatelyForPaddingInclusion = {
+ "pack_last_row_separately_for_padding_inclusion", FeatureCategory::OpenGLWorkarounds,
+ "When uploading textures from an pack buffer, some drivers count an extra row padding",
+ &members, "http://anglebug.com/1512"};
+
+ // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
+ // this bug, we use an expression to emulate function isnan().
+ // Tracking bug: http://crbug.com/650547
+ Feature emulateIsnanFloat = {"emulate_isnan_float", FeatureCategory::OpenGLWorkarounds,
+ "Using isnan() on highp float will get wrong answer", &members,
+ "http://crbug.com/650547"};
+
+ // On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be
+ // treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a
+ // unused std140 or shared uniform block at the beginning of main to work around it.
+ // Also used on Linux AMD.
+ Feature useUnusedBlocksWithStandardOrSharedLayout = {
+ "use_unused_blocks_with_standard_or_shared_layout", FeatureCategory::OpenGLWorkarounds,
+ "Unused std140 or shared uniform blocks will be treated as inactive", &members};
+
+ // This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3.
+ Feature removeInvariantAndCentroidForESSL3 = {
+ "remove_invarient_and_centroid_for_essl3", FeatureCategory::OpenGLWorkarounds,
+ "Fix spec difference between GLSL 4.1 or lower and ESSL3", &members};
+
+ // On Intel Mac OSX 10.11 driver, using "-float" will get wrong answer. Use "0.0 - float" to
+ // replace "-float".
+ // Tracking bug: http://crbug.com/308366
+ Feature rewriteFloatUnaryMinusOperator = {
+ "rewrite_float_unary_minus_operator", FeatureCategory::OpenGLWorkarounds,
+ "Using '-<float>' will get wrong answer", &members, "http://crbug.com/308366"};
+
+ // On NVIDIA drivers, atan(y, x) may return a wrong answer.
+ // Tracking bug: http://crbug.com/672380
+ Feature emulateAtan2Float = {"emulate_atan_2_float", FeatureCategory::OpenGLWorkarounds,
+ "atan(y, x) may return a wrong answer", &members,
+ "http://crbug.com/672380"};
+
+ // Some drivers seem to forget about UBO bindings when using program binaries. Work around
+ // this by re-applying the bindings after the program binary is loaded or saved.
+ // This only seems to affect AMD OpenGL drivers, and some Android devices.
+ // http://anglebug.com/1637
+ Feature reapplyUBOBindingsAfterUsingBinaryProgram = {
+ "reapply_ubo_bindings_after_using_binary_program", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers forget about UBO bindings when using program binaries", &members,
+ "http://anglebug.com/1637"};
+
+ // Some Linux OpenGL drivers return 0 when we query MAX_VERTEX_ATTRIB_STRIDE in an OpenGL 4.4 or
+ // higher context.
+ // This only seems to affect AMD OpenGL drivers.
+ // Tracking bug: http://anglebug.com/1936
+ Feature emulateMaxVertexAttribStride = {
+ "emulate_max_vertex_attrib_stride", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers return 0 when MAX_VERTEX_ATTRIB_STRIED queried", &members,
+ "http://anglebug.com/1936"};
+
+ // Initializing uninitialized locals caused odd behavior on Android Qualcomm in a few WebGL 2
+ // tests. Tracking bug: http://anglebug.com/2046
+ Feature dontInitializeUninitializedLocals = {
+ "dont_initialize_uninitialized_locals", FeatureCategory::OpenGLWorkarounds,
+ "Initializing uninitialized locals caused odd behavior in a few WebGL 2 tests", &members,
+ "http://anglebug.com/2046"};
+
+ // On some NVIDIA drivers the point size range reported from the API is inconsistent with the
+ // actual behavior. Clamp the point size to the value from the API to fix this.
+ Feature clampPointSize = {
+ "clamp_point_size", FeatureCategory::OpenGLWorkarounds,
+ "The point size range reported from the API is inconsistent with the actual behavior",
+ &members};
+
+ // On some NVIDIA drivers certain types of GLSL arithmetic ops mixing vectors and scalars may be
+ // executed incorrectly. Change them in the shader translator. Tracking bug:
+ // http://crbug.com/772651
+ Feature rewriteVectorScalarArithmetic = {"rewrite_vector_scalar_arithmetic",
+ FeatureCategory::OpenGLWorkarounds,
+ "Certain types of GLSL arithmetic ops mixing vectors "
+ "and scalars may be executed incorrectly",
+ &members, "http://crbug.com/772651"};
+
+ // On some Android devices for loops used to initialize variables hit native GLSL compiler bugs.
+ Feature dontUseLoopsToInitializeVariables = {
+ "dont_use_loops_to_initialize_variables", FeatureCategory::OpenGLWorkarounds,
+ "For loops used to initialize variables hit native GLSL compiler bugs", &members,
+ "http://crbug.com/809422"};
+
+ // On some NVIDIA drivers gl_FragDepth is not clamped correctly when rendering to a floating
+ // point depth buffer. Clamp it in the translated shader to fix this.
+ Feature clampFragDepth = {
+ "clamp_frag_depth", FeatureCategory::OpenGLWorkarounds,
+ "gl_FragDepth is not clamped correctly when rendering to a floating point depth buffer",
+ &members};
+
+ // On some NVIDIA drivers before version 397.31 repeated assignment to swizzled values inside a
+ // GLSL user-defined function have incorrect results. Rewrite this type of statements to fix
+ // this.
+ Feature rewriteRepeatedAssignToSwizzled = {"rewrite_repeated_assign_to_swizzled",
+ FeatureCategory::OpenGLWorkarounds,
+ "Repeated assignment to swizzled values inside a "
+ "GLSL user-defined function have incorrect results",
+ &members};
+
+ // On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests.
+ // It might be possible to work around the Intel bug by rewriting *FragData to *FragColor
+ // instead of disabling the functionality entirely. The AMD bug looked like incorrect blending,
+ // not sure if a workaround is feasible. http://anglebug.com/1085
+ Feature disableBlendFuncExtended = {
+ "disable_blend_func_extended", FeatureCategory::OpenGLWorkarounds,
+ "ARB_blend_func_extended does not pass the tests", &members, "http://anglebug.com/1085"};
+
+ // Qualcomm drivers returns raw sRGB values instead of linearized values when calling
+ // glReadPixels on unsized sRGB texture formats. http://crbug.com/550292 and
+ // http://crbug.com/565179
+ Feature unsizedsRGBReadPixelsDoesntTransform = {
+ "unsized_srgb_read_pixels_doesnt_transform", FeatureCategory::OpenGLWorkarounds,
+ "Drivers returning raw sRGB values instead of linearized values when calling glReadPixels "
+ "on unsized sRGB texture formats",
+ &members, "http://crbug.com/565179"};
+
+ // Older Qualcomm drivers generate errors when querying the number of bits in timer queries, ex:
+ // GetQueryivEXT(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS). http://anglebug.com/3027
+ Feature queryCounterBitsGeneratesErrors = {
+ "query_counter_bits_generates_errors", FeatureCategory::OpenGLWorkarounds,
+ "Drivers generate errors when querying the number of bits in timer queries", &members,
+ "http://anglebug.com/3027"};
+
+ // Re-linking a program in parallel is buggy on some Intel Windows OpenGL drivers and Android
+ // platforms.
+ // http://anglebug.com/3045
+ Feature dontRelinkProgramsInParallel = {
+ "dont_relink_programs_in_parallel", FeatureCategory::OpenGLWorkarounds,
+ "Relinking a program in parallel is buggy", &members, "http://anglebug.com/3045"};
+
+ // Some tests have been seen to fail using worker contexts, this switch allows worker contexts
+ // to be disabled for some platforms. http://crbug.com/849576
+ Feature disableWorkerContexts = {"disable_worker_contexts", FeatureCategory::OpenGLWorkarounds,
+ "Some tests have been seen to fail using worker contexts",
+ &members, "http://crbug.com/849576"};
+
+ // Most Android devices fail to allocate a texture that is larger than 4096. Limit the caps
+ // instead of generating GL_OUT_OF_MEMORY errors. Also causes system to hang on some older
+ // intel mesa drivers on Linux.
+ Feature limitMaxTextureSizeTo4096 = {"max_texture_size_limit_4096",
+ FeatureCategory::OpenGLWorkarounds,
+ "Limit max texture size to 4096 to avoid frequent "
+ "out-of-memory errors",
+ &members, "http://crbug.com/927470"};
+
+ // Prevent excessive MSAA allocations on Android devices, various rendering bugs have been
+ // observed and they tend to be high DPI anyways. http://crbug.com/797243
+ Feature limitMaxMSAASamplesTo4 = {
+ "max_msaa_sample_count_4", FeatureCategory::OpenGLWorkarounds,
+ "Various rendering bugs have been observed when using higher MSAA counts", &members,
+ "http://crbug.com/797243"};
+
+ // Prefer to do the robust resource init clear using a glClear. Calls to TexSubImage2D on large
+ // textures can take hundreds of milliseconds because of slow uploads on macOS. Do this only on
+ // macOS because clears are buggy on other drivers.
+ // https://crbug.com/848952 (slow uploads on macOS)
+ // https://crbug.com/883276 (buggy clears on Android)
+ Feature allowClearForRobustResourceInit = {
+ "allow_clear_for_robust_resource_init", FeatureCategory::OpenGLWorkarounds,
+ "Using glClear for robust resource initialization is buggy on some drivers and leads to "
+ "texture corruption. Default to data uploads except on MacOS where it is very slow.",
+ &members, "http://crbug.com/883276"};
+
+ // Some drivers automatically handle out-of-bounds uniform array access but others need manual
+ // clamping to satisfy the WebGL requirements.
+ Feature clampArrayAccess = {"clamp_array_access", FeatureCategory::OpenGLWorkarounds,
+ "Clamp uniform array access to avoid reading invalid memory.",
+ &members, "http://anglebug.com/2978"};
+
+ // Reset glTexImage2D base level to workaround pixel comparison failure above Mac OS 10.12.4 on
+ // Intel Mac.
+ Feature resetTexImage2DBaseLevel = {"reset_teximage2d_base_level",
+ FeatureCategory::OpenGLWorkarounds,
+ "Reset texture base level before calling glTexImage2D to "
+ "work around pixel comparison failure.",
+ &members, "https://crbug.com/705865"};
+
+ // glClearColor does not always work on Intel 6xxx Mac drivers when the clear color made up of
+ // all zeros and ones.
+ Feature clearToZeroOrOneBroken = {
+ "clear_to_zero_or_one_broken", FeatureCategory::OpenGLWorkarounds,
+ "Clears when the clear color is all zeros or ones do not work.", &members,
+ "https://crbug.com/710443"};
+
+ // Some older Linux Intel mesa drivers will hang the system when allocating large textures. Fix
+ // this by capping the max texture size.
+ Feature limitMax3dArrayTextureSizeTo1024 = {
+ "max_3d_array_texture_size_1024", FeatureCategory::OpenGLWorkarounds,
+ "Limit max 3d texture size and max array texture layers to 1024 to avoid system hang",
+ &members, "http://crbug.com/927470"};
+
+ // BlitFramebuffer has issues on some platforms with large source/dest texture sizes. This
+ // workaround adjusts the destination rectangle source and dest rectangle to fit within maximum
+ // twice the size of the framebuffer.
+ Feature adjustSrcDstRegionBlitFramebuffer = {
+ "adjust_src_dst_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds,
+ "Many platforms have issues with blitFramebuffer when the parameters are large.", &members,
+ "http://crbug.com/830046"};
+
+ // BlitFramebuffer has issues on Mac when the source bounds aren't enclosed by the framebuffer.
+ // This workaround clips the source region and adjust the dest region proportionally.
+ Feature clipSrcRegionBlitFramebuffer = {
+ "clip_src_region_for_blitframebuffer", FeatureCategory::OpenGLWorkarounds,
+ "Issues with blitFramebuffer when the parameters don't match the framebuffer size.",
+ &members, "http://crbug.com/830046"};
+
+ // Calling glTexImage2D with zero size generates GL errors
+ Feature resettingTexturesGeneratesErrors = {
+ "reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds,
+ "Calling glTexImage2D with zero size generates errors.", &members,
+ "http://anglebug.com/3859"};
+
+ // Mac Intel samples transparent black from GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+ Feature rgbDXT1TexturesSampleZeroAlpha = {
+ "rgb_dxt1_textures_sample_zero_alpha", FeatureCategory::OpenGLWorkarounds,
+ "Sampling BLACK texels from RGB DXT1 textures returns transparent black on Mac.", &members,
+ "http://anglebug.com/3729"};
+
+ // Mac incorrectly executes both sides of && and || expressions when they should short-circuit.
+ Feature unfoldShortCircuits = {
+ "unfold_short_circuits", FeatureCategory::OpenGLWorkarounds,
+ "Mac incorrectly executes both sides of && and || expressions when they should "
+ "short-circuit.",
+ &members, "http://anglebug.com/482"};
+
+ Feature emulatePrimitiveRestartFixedIndex = {
+ "emulate_primitive_restart_fixed_index", FeatureCategory::OpenGLWorkarounds,
+ "When GL_PRIMITIVE_RESTART_FIXED_INDEX is not available, emulate it with "
+ "GL_PRIMITIVE_RESTART and glPrimitiveRestartIndex.",
+ &members, "http://anglebug.com/3997"};
+
+ Feature setPrimitiveRestartFixedIndexForDrawArrays = {
+ "set_primitive_restart_fixed_index_for_draw_arrays", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers discard vertex data in DrawArrays calls when the fixed primitive restart "
+ "index is within the number of primitives being drawn.",
+ &members, "http://anglebug.com/3997"};
+
+ // Dynamic indexing of swizzled l-values doesn't work correctly on various platforms.
+ Feature removeDynamicIndexingOfSwizzledVector = {
+ "remove_dynamic_indexing_of_swizzled_vector", FeatureCategory::OpenGLWorkarounds,
+ "Dynamic indexing of swizzled l-values doesn't work correctly on various platforms.",
+ &members, "http://crbug.com/709351"};
+
+ // Intel Mac drivers does not treat texelFetchOffset() correctly.
+ Feature preAddTexelFetchOffsets = {
+ "pre_add_texel_fetch_offsets", FeatureCategory::OpenGLWorkarounds,
+ "Intel Mac drivers mistakenly consider the parameter position of nagative vaule as invalid "
+ "even if the sum of position and offset is in range, so we need to add workarounds by "
+ "rewriting texelFetchOffset(sampler, position, lod, offset) into texelFetch(sampler, "
+ "position + offset, lod).",
+ &members, "http://crbug.com/642605"};
+
+ // All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct
+ // name with a unique prefix
+ Feature regenerateStructNames = {
+ "regenerate_struct_names", FeatureCategory::OpenGLWorkarounds,
+ "All Mac drivers do not handle struct scopes correctly. This workaround overwrites a struct"
+ "name with a unique prefix.",
+ &members, "http://crbug.com/403957"};
+
+ // Quite some OpenGL ES drivers don't implement readPixels for RGBA/UNSIGNED_SHORT from
+ // EXT_texture_norm16 correctly
+ Feature readPixelsUsingImplementationColorReadFormatForNorm16 = {
+ "read_pixels_using_implementation_color_read_format", FeatureCategory::OpenGLWorkarounds,
+ "Quite some OpenGL ES drivers don't implement readPixels for RGBA/UNSIGNED_SHORT from "
+ "EXT_texture_norm16 correctly",
+ &members, "http://anglebug.com/4214"};
+
+ // Bugs exist in some Intel drivers where dependencies are incorrectly
+ // tracked for textures which are copy destinations (via CopyTexImage2D, for
+ // example). Flush before DeleteTexture if these entry points have been
+ // called recently.
+ Feature flushBeforeDeleteTextureIfCopiedTo = {
+ "flush_before_delete_texture_if_copied_to", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers track CopyTex{Sub}Image texture dependencies incorrectly. Flush"
+ " before glDeleteTextures in this case",
+ &members, "http://anglebug.com/4267"};
+
+ // Rewrite row-major matrices as column-major as a driver bug workaround if
+ // necessary.
+ Feature rewriteRowMajorMatrices = {
+ "rewrite_row_major_matrices", FeatureCategory::OpenGLWorkarounds,
+ "Rewrite row major matrices in shaders as column major as a driver bug workaround",
+ &members, "http://anglebug.com/2273"};
+
+ // Bugs exist in various OpenGL Intel drivers on Windows that produce incorrect
+ // values for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT format. Replace it with
+ // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT as it's the closest option allowed by
+ // the WebGL extension spec.
+ Feature avoidDXT1sRGBTextureFormat = {
+ "avoid_dxt1_srgb_texture_format", FeatureCategory::OpenGLWorkarounds,
+ "Replaces DXT1 sRGB with DXT1 sRGB Alpha as a driver bug workaround.", &members};
+
+ // Bugs exist in OpenGL AMD drivers on Windows that produce incorrect pipeline state for
+ // colorMaski calls.
+ Feature disableDrawBuffersIndexed = {"disable_draw_buffers_indexed",
+ FeatureCategory::OpenGLWorkarounds,
+ "Disable OES_draw_buffers_indexed extension.", &members};
+
+ // GL_EXT_semaphore_fd doesn't work properly with Mesa 19.3.4 and earlier versions.
+ Feature disableSemaphoreFd = {"disable_semaphore_fd", FeatureCategory::OpenGLWorkarounds,
+ "Disable GL_EXT_semaphore_fd extension", &members,
+ "https://crbug.com/1046462"};
+
+ // GL_EXT_disjoint_timer_query doesn't work properly with Linux VMWare drivers.
+ Feature disableTimestampQueries = {
+ "disable_timestamp_queries", FeatureCategory::OpenGLWorkarounds,
+ "Disable GL_EXT_disjoint_timer_query extension", &members, "https://crbug.com/811661"};
+
+ // Some drivers use linear blending when generating mipmaps for sRGB textures. Work around this
+ // by generating mipmaps in a linear texture and copying back to sRGB.
+ Feature encodeAndDecodeSRGBForGenerateMipmap = {
+ "decode_encode_srgb_for_generatemipmap", FeatureCategory::OpenGLWorkarounds,
+ "Decode and encode before generateMipmap for srgb format textures.", &members,
+ "http://anglebug.com/4646"};
+
+ Feature emulateCopyTexImage2DFromRenderbuffers = {
+ "emulate_copyteximage2d_from_renderbuffers", FeatureCategory::OpenGLWorkarounds,
+ "CopyTexImage2D spuriously returns errors on iOS when copying from renderbuffers.",
+ &members, "https://anglebug.com/4674"};
+
+ Feature disableGPUSwitchingSupport = {
+ "disable_gpu_switching_support", FeatureCategory::OpenGLWorkarounds,
+ "Disable GPU switching support (use only the low-power GPU) on older MacBook Pros.",
+ &members, "https://crbug.com/1091824"};
+
+ // KHR_parallel_shader_compile fails TSAN on Linux, so we avoid using it with this workaround.
+ Feature disableNativeParallelCompile = {
+ "disable_native_parallel_compile", FeatureCategory::OpenGLWorkarounds,
+ "Do not use native KHR_parallel_shader_compile even when available.", &members,
+ "http://crbug.com/1094869"};
+
+ Feature emulatePackSkipRowsAndPackSkipPixels = {
+ "emulate_pack_skip_rows_and_pack_skip_pixels", FeatureCategory::OpenGLWorkarounds,
+ "GL_PACK_SKIP_ROWS and GL_PACK_SKIP_PIXELS are ignored in Apple's OpenGL driver.", &members,
+ "https://anglebug.com/4849"};
+
+ // Some drivers return bogus/1hz values for GetMscRate, which we may want to clamp
+ Feature clampMscRate = {
+ "clamp_msc_rate", FeatureCategory::OpenGLWorkarounds,
+ "Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members,
+ "https://crbug.com/1042393"};
+
+ // Mac drivers generate GL_INVALID_VALUE when binding a transform feedback buffer with
+ // glBindBufferRange before first binding it to some generic binding point.
+ Feature bindTransformFeedbackBufferBeforeBindBufferRange = {
+ "bind_transform_feedback_buffer_before_bind_buffer_range",
+ FeatureCategory::OpenGLWorkarounds,
+ "Bind transform feedback buffers to the generic binding point before calling "
+ "glBindBufferBase or glBindBufferRange.",
+ &members, "https://anglebug.com/5140"};
+
+ // Speculative fix for issues on Linux/Wayland where exposing GLX_OML_sync_control renders
+ // Chrome unusable
+ Feature disableSyncControlSupport = {
+ "disable_sync_control_support", FeatureCategory::OpenGLWorkarounds,
+ "Speculative fix for issues on Linux/Wayland where exposing GLX_OML_sync_control renders "
+ "Chrome unusable",
+ &members, "https://crbug.com/1137851"};
+
+ // Buffers need to maintain a shadow copy of data when buffer data readback is not possible
+ // through the GL API
+ Feature keepBufferShadowCopy = {
+ "keep_buffer_shadow_copy", FeatureCategory::OpenGLWorkarounds,
+ "Maintain a shadow copy of buffer data when the GL API does not permit reading data back.",
+ &members};
+
+ // glGenerateMipmap fails if the zero texture level is not set on some Mac drivers
+ Feature setZeroLevelBeforeGenerateMipmap = {
+ "set_zero_level_before_generating_mipmap", FeatureCategory::OpenGLWorkarounds,
+ "glGenerateMipmap fails if the zero texture level is not set on some Mac drivers.",
+ &members};
+
+ // On macOS with AMD GPUs, packed color formats like RGB565 and RGBA4444 are buggy. Promote them
+ // to 8 bit per channel formats.
+ Feature promotePackedFormatsTo8BitPerChannel = {
+ "promote_packed_formats_to_8_bit_per_channel", FeatureCategory::OpenGLWorkarounds,
+ "Packed color formats are buggy on Macs with AMD GPUs", &members,
+ "http://anglebug.com/5469"};
+
+ // If gl_FragColor is not written by fragment shader, it may cause context lost with Adreno 42x
+ // and 3xx.
+ Feature initFragmentOutputVariables = {
+ "init_fragment_output_variables", FeatureCategory::OpenGLWorkarounds,
+ "No init gl_FragColor causes context lost", &members, "http://crbug.com/1171371"};
+
+ // On macOS with Intel GPUs, instanced array with divisor > 0 is buggy when first > 0 in
+ // drawArraysInstanced. Shift the attributes with extra offset to workaround.
+ Feature shiftInstancedArrayDataWithExtraOffset = {
+ "shift_instanced_array_data_with_offset", FeatureCategory::OpenGLWorkarounds,
+ "glDrawArraysInstanced is buggy on certain new Mac Intel GPUs", &members,
+ "http://crbug.com/1144207"};
+
+ // ANGLE needs to support devices that have no native VAOs. Sync everything to the default VAO.
+ Feature syncVertexArraysToDefault = {
+ "sync_vertex_arrays_to_default", FeatureCategory::OpenGLWorkarounds,
+ "Only use the default VAO because of missing support or driver bugs", &members,
+ "http://anglebug.com/5577"};
+
+ // On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
+ // leaked via GL_RENDERER. We workaround this to improve user privacy.
+ Feature sanitizeAmdGpuRendererString = {
+ "sanitize_amdgpu_renderer_string", FeatureCategory::OpenGLWorkarounds,
+ "Strip precise kernel and DRM version information from amdgpu renderer strings.", &members,
+ "http://crbug.com/1181193"};
+
+ // Imagination GL drivers are buggy with context switching. We need to ubind fbo to workaround a
+ // crash in the driver.
+ Feature unbindFBOOnContextSwitch = {"unbind_fbo_before_switching_context",
+ FeatureCategory::OpenGLWorkarounds,
+ "Imagination GL drivers are buggy with context switching.",
+ &members, "http://crbug.com/1181193"};
+
+ Feature flushOnFramebufferChange = {"flush_on_framebuffer_change",
+ FeatureCategory::OpenGLWorkarounds,
+ "Switching framebuffers without a flush can lead to "
+ "crashes on Intel 9th Generation GPU Macs.",
+ &members, "http://crbug.com/1181068"};
+};
+
+inline FeaturesGL::FeaturesGL() = default;
+inline FeaturesGL::~FeaturesGL() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESGL_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesMtl.h b/gfx/angle/checkout/include/platform/FeaturesMtl.h
new file mode 100644
index 0000000000..fe5e8abdf0
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesMtl.h
@@ -0,0 +1,90 @@
+//
+// Copyright 2019 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FeaturesMtl.h: Optional features for the Metal renderer.
+//
+
+#ifndef ANGLE_PLATFORM_FEATURESMTL_H_
+#define ANGLE_PLATFORM_FEATURESMTL_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FeaturesMtl : FeatureSetBase
+{
+ // BaseVertex/Instanced draw support:
+ Feature hasBaseVertexInstancedDraw = {
+ "has_base_vertex_instanced_draw", FeatureCategory::MetalFeatures,
+ "The renderer supports base vertex instanced draw", &members};
+
+ // Support depth texture filtering
+ Feature hasDepthTextureFiltering = {
+ "has_depth_texture_filtering", FeatureCategory::MetalFeatures,
+ "The renderer supports depth texture's filtering other than nearest", &members};
+
+ // Support explicit memory barrier
+ Feature hasExplicitMemBarrier = {"has_explicit_mem_barrier_mtl", FeatureCategory::MetalFeatures,
+ "The renderer supports explicit memory barrier", &members};
+
+ // Some renderer can break render pass cheaply, i.e. desktop class GPUs.
+ Feature hasCheapRenderPass = {"has_cheap_render_pass_mtl", FeatureCategory::MetalFeatures,
+ "The renderer can cheaply break a render pass.", &members};
+
+ // Non-uniform compute shader dispatch support, i.e. Group size is not necessarily to be fixed:
+ Feature hasNonUniformDispatch = {
+ "has_non_uniform_dispatch", FeatureCategory::MetalFeatures,
+ "The renderer supports non uniform compute shader dispatch's group size", &members};
+
+ // fragment stencil output support
+ Feature hasStencilOutput = {"has_shader_stencil_output", FeatureCategory::MetalFeatures,
+ "The renderer supports stencil output from fragment shader",
+ &members};
+
+ // Texture swizzle support:
+ Feature hasTextureSwizzle = {"has_texture_swizzle", FeatureCategory::MetalFeatures,
+ "The renderer supports texture swizzle", &members};
+
+ Feature hasDepthAutoResolve = {
+ "has_msaa_depth_auto_resolve", FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA depth auto resolve at the end of render pass", &members};
+
+ Feature hasStencilAutoResolve = {
+ "has_msaa_stencil_auto_resolve", FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA stencil auto resolve at the end of render pass", &members};
+
+ Feature hasEvents = {"has_mtl_events", FeatureCategory::MetalFeatures,
+ "The renderer supports MTL(Shared)Event", &members};
+
+ // On macos, separate depth & stencil buffers are not supproted. However, on iOS devices,
+ // they are supproted:
+ Feature allowSeparatedDepthStencilBuffers = {
+ "allow_separate_depth_stencil_buffers", FeatureCategory::MetalFeatures,
+ "Some Apple platforms such as iOS allows separate depth & stencil buffers, "
+ "whereas others such as macOS don't",
+ &members};
+
+ Feature allowMultisampleStoreAndResolve = {
+ "allow_msaa_store_and_resolve", FeatureCategory::MetalFeatures,
+ "The renderer supports MSAA store and resolve in the same pass", &members};
+
+ Feature allowGenMultipleMipsPerPass = {
+ "gen_multiple_mips_per_pass", FeatureCategory::MetalFeatures,
+ "The renderer supports generating multiple mipmaps per pass", &members};
+
+ Feature forceBufferGPUStorage = {
+ "force_buffer_gpu_storage_mtl", FeatureCategory::MetalFeatures,
+ "On systems that support both buffer's memory allocation on GPU and shared memory (such as "
+ "macOS), force using GPU memory allocation for buffers.",
+ &members};
+
+ Feature forceD24S8AsUnsupported = {"force_d24s8_as_unsupported", FeatureCategory::MetalFeatures,
+ "Force Depth24Stencil8 format as unsupported.", &members};
+};
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESMTL_H_
diff --git a/gfx/angle/checkout/include/platform/FeaturesVk.h b/gfx/angle/checkout/include/platform/FeaturesVk.h
new file mode 100644
index 0000000000..0c4454e7d7
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FeaturesVk.h
@@ -0,0 +1,531 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// FeaturesVk.h: Optional features for the Vulkan renderer.
+//
+
+#ifndef ANGLE_PLATFORM_FEATURESVK_H_
+#define ANGLE_PLATFORM_FEATURESVK_H_
+
+#include "platform/Feature.h"
+
+#include <array>
+
+namespace angle
+{
+
+struct FeaturesVk : FeatureSetBase
+{
+ FeaturesVk();
+ ~FeaturesVk();
+
+ // Line segment rasterization must follow OpenGL rules. This means using an algorithm similar
+ // to Bresenham's. Vulkan uses a different algorithm. This feature enables the use of pixel
+ // shader patching to implement OpenGL basic line rasterization rules. This feature will
+ // normally always be enabled. Exposing it as an option enables performance testing.
+ Feature basicGLLineRasterization = {
+ "basicGLLineRasterization", FeatureCategory::VulkanFeatures,
+ "Enable the use of pixel shader patching to implement OpenGL basic line "
+ "rasterization rules",
+ &members};
+
+ // If the VK_EXT_line_rasterization extension is available we'll use it to get
+ // Bresenham line rasterization.
+ Feature bresenhamLineRasterization = {
+ "bresenhamLineRasterization", FeatureCategory::VulkanFeatures,
+ "Enable Bresenham line rasterization via VK_EXT_line_rasterization extension", &members};
+
+ // If the VK_EXT_provoking_vertex extension is available, we'll use it to set
+ // the provoking vertex mode
+ Feature provokingVertex = {"provokingVertex", FeatureCategory::VulkanFeatures,
+ "Enable provoking vertex mode via VK_EXT_provoking_vertex extension",
+ &members};
+
+ // Add an extra copy region when using vkCmdCopyBuffer as the Windows Intel driver seems
+ // to have a bug where the last region is ignored.
+ Feature extraCopyBufferRegion = {
+ "extraCopyBufferRegion", FeatureCategory::VulkanWorkarounds,
+ "Some drivers seem to have a bug where the last copy region in vkCmdCopyBuffer is ignored",
+ &members};
+
+ // This flag is added for the sole purpose of end2end tests, to test the correctness
+ // of various algorithms when a fallback format is used, such as using a packed format to
+ // emulate a depth- or stencil-only format.
+ Feature forceFallbackFormat = {"forceFallbackFormat", FeatureCategory::VulkanWorkarounds,
+ "Force a fallback format for angle_end2end_tests", &members};
+
+ // On some NVIDIA drivers the point size range reported from the API is inconsistent with the
+ // actual behavior. Clamp the point size to the value from the API to fix this.
+ // Tracked in http://anglebug.com/2970.
+ Feature clampPointSize = {
+ "clampPointSize", FeatureCategory::VulkanWorkarounds,
+ "The point size range reported from the API is inconsistent with the actual behavior",
+ &members, "http://anglebug.com/2970"};
+
+ // On some NVIDIA drivers the depth value is not clamped to [0,1] for floating point depth
+ // buffers. This is NVIDIA bug 3171019, see http://anglebug.com/3970 for details.
+ Feature depthClamping = {
+ "depth_clamping", FeatureCategory::VulkanWorkarounds,
+ "The depth value is not clamped to [0,1] for floating point depth buffers.", &members,
+ "http://anglebug.com/3970"};
+
+ // On some android devices, the memory barrier between the compute shader that converts vertex
+ // attributes and the vertex shader that reads from it is ineffective. Only known workaround is
+ // to perform a flush after the conversion. http://anglebug.com/3016
+ Feature flushAfterVertexConversion = {
+ "flushAfterVertexConversion", FeatureCategory::VulkanWorkarounds,
+ "The memory barrier between the compute shader that converts vertex attributes and the "
+ "vertex shader that reads from it is ineffective",
+ &members, "http://anglebug.com/3016"};
+
+ Feature supportsRenderpass2 = {"supportsRenderpass2", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_create_renderpass2 extension",
+ &members};
+
+ // Whether the VkDevice supports the VK_KHR_incremental_present extension, on which the
+ // EGL_KHR_swap_buffers_with_damage extension can be layered.
+ Feature supportsIncrementalPresent = {
+ "supportsIncrementalPresent", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_incremental_present extension", &members};
+
+ // Whether texture copies on cube map targets should be done on GPU. This is a workaround for
+ // Intel drivers on windows that have an issue with creating single-layer views on cube map
+ // textures.
+ Feature forceCPUPathForCubeMapCopy = {
+ "forceCPUPathForCubeMapCopy", FeatureCategory::VulkanWorkarounds,
+ "Some drivers have an issue with creating single-layer views on cube map textures",
+ &members};
+
+ // Whether the VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer
+ // extension, on which the EGL_ANDROID_image_native_buffer extension can be layered.
+ Feature supportsAndroidHardwareBuffer = {
+ "supportsAndroidHardwareBuffer", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer extension",
+ &members};
+
+ // Whether the VkDevice supports the VK_GGP_frame_token extension, on which
+ // the EGL_ANGLE_swap_with_frame_token extension can be layered.
+ Feature supportsGGPFrameToken = {"supportsGGPFrameToken", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_GGP_frame_token extension",
+ &members};
+
+ // Whether the VkDevice supports the VK_KHR_external_memory_fd extension, on which the
+ // GL_EXT_memory_object_fd extension can be layered.
+ Feature supportsExternalMemoryFd = {"supportsExternalMemoryFd", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_memory_fd extension",
+ &members};
+
+ // Whether the VkDevice supports the VK_FUCHSIA_external_memory
+ // extension, on which the GL_ANGLE_memory_object_fuchsia extension can be layered.
+ Feature supportsExternalMemoryFuchsia = {
+ "supportsExternalMemoryFuchsia", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_FUCHSIA_external_memory extension", &members};
+
+ Feature supportsFilteringPrecision = {
+ "supportsFilteringPrecision", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_GOOGLE_sampler_filtering_precision extension", &members};
+
+ // Whether the VkDevice supports the VK_KHR_external_fence_capabilities extension.
+ Feature supportsExternalFenceCapabilities = {
+ "supportsExternalFenceCapabilities", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_fence_capabilities extension", &members};
+
+ // Whether the VkDevice supports the VK_KHR_external_semaphore_capabilities extension.
+ Feature supportsExternalSemaphoreCapabilities = {
+ "supportsExternalSemaphoreCapabilities", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_semaphore_capabilities extension", &members};
+
+ // Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the
+ // GL_EXT_semaphore_fd extension can be layered.
+ Feature supportsExternalSemaphoreFd = {
+ "supportsExternalSemaphoreFd", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_semaphore_fd extension", &members};
+
+ // Whether the VkDevice supports the VK_FUCHSIA_external_semaphore
+ // extension, on which the GL_ANGLE_semaphore_fuchsia extension can be layered.
+ angle::Feature supportsExternalSemaphoreFuchsia = {
+ "supportsExternalSemaphoreFuchsia", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_FUCHSIA_external_semaphore extension", &members};
+
+ // Whether the VkDevice supports the VK_KHR_external_fence_fd extension, on which the
+ // EGL_ANDROID_native_fence extension can be layered.
+ Feature supportsExternalFenceFd = {"supportsExternalFenceFd", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_external_fence_fd extension",
+ &members, "http://anglebug.com/2517"};
+
+ // Whether the VkDevice can support EGL_ANDROID_native_fence_sync extension.
+ Feature supportsAndroidNativeFenceSync = {
+ "supportsAndroidNativeFenceSync", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the EGL_ANDROID_native_fence_sync extension", &members,
+ "http://anglebug.com/2517"};
+
+ // Whether the VkDevice can support imageCubeArray feature properly.
+ Feature supportsImageCubeArray = {"supportsImageCubeArray", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the imageCubeArray feature properly",
+ &members, "http://anglebug.com/3584"};
+
+ // Whether the VkDevice supports the VK_EXT_shader_stencil_export extension, which is used to
+ // perform multisampled resolve of stencil buffer. A multi-step workaround is used instead if
+ // this extension is not available.
+ Feature supportsShaderStencilExport = {
+ "supportsShaderStencilExport", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_shader_stencil_export extension", &members};
+
+ // Whether the VkDevice supports the VK_KHR_sampler_ycbcr_conversion extension, which is needed
+ // to support Ycbcr conversion with external images.
+ Feature supportsYUVSamplerConversion = {
+ "supportsYUVSamplerConversion", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_sampler_ycbcr_conversion extension", &members};
+
+ // Where VK_EXT_transform_feedback is not support, an emulation path is used.
+ // http://anglebug.com/3205
+ Feature emulateTransformFeedback = {
+ "emulateTransformFeedback", FeatureCategory::VulkanFeatures,
+ "Emulate transform feedback as the VK_EXT_transform_feedback is not present.", &members,
+ "http://anglebug.com/3205"};
+
+ // Where VK_EXT_transform_feedback is supported, it's preferred over an emulation path.
+ // http://anglebug.com/3206
+ Feature supportsTransformFeedbackExtension = {
+ "supportsTransformFeedbackExtension", FeatureCategory::VulkanFeatures,
+ "Transform feedback uses the VK_EXT_transform_feedback extension.", &members,
+ "http://anglebug.com/3206"};
+
+ // Whether the VkDevice supports the VK_EXT_index_type_uint8 extension
+ // http://anglebug.com/4405
+ Feature supportsIndexTypeUint8 = {"supportsIndexTypeUint8", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_index_type_uint8 extension",
+ &members, "http://anglebug.com/4405"};
+
+ // Whether the VkDevice supports the VK_KHR_depth_stencil_resolve extension with the
+ // independentResolveNone feature.
+ // http://anglebug.com/4836
+ Feature supportsDepthStencilResolve = {"supportsDepthStencilResolve",
+ FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_depth_stencil_resolve "
+ "extension with the independentResolveNone feature",
+ &members, "http://anglebug.com/4836"};
+
+ // Whether the VkDevice supports the VK_EXT_multisampled_render_to_single_sampled extension.
+ // http://anglebug.com/4836
+ Feature supportsMultisampledRenderToSingleSampled = {
+ "supportsMultisampledRenderToSingleSampled", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_multisampled_render_to_single_sampled extension", &members,
+ "http://anglebug.com/4836"};
+
+ // VK_PRESENT_MODE_FIFO_KHR causes random timeouts on Linux Intel. http://anglebug.com/3153
+ Feature disableFifoPresentMode = {"disableFifoPresentMode", FeatureCategory::VulkanWorkarounds,
+ "VK_PRESENT_MODE_FIFO_KHR causes random timeouts", &members,
+ "http://anglebug.com/3153"};
+
+ // On Qualcomm, gaps in bound descriptor set indices causes the post-gap sets to misbehave.
+ // For example, binding only descriptor set 3 results in zero being read from a uniform buffer
+ // object within that set. This flag results in empty descriptor sets being bound for any
+ // unused descriptor set to work around this issue. http://anglebug.com/2727
+ Feature bindEmptyForUnusedDescriptorSets = {
+ "bindEmptyForUnusedDescriptorSets", FeatureCategory::VulkanWorkarounds,
+ "Gaps in bound descriptor set indices causes the post-gap sets to misbehave", &members,
+ "http://anglebug.com/2727"};
+
+ // OES_depth_texture is a commonly expected feature on Android. However it
+ // requires that D16_UNORM support texture filtering
+ // (e.g. VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) and some devices
+ // do not. Work-around this by setting saying D16_UNORM supports filtering
+ // anyway.
+ Feature forceD16TexFilter = {
+ "forceD16TexFilter", FeatureCategory::VulkanWorkarounds,
+ "VK_FORMAT_D16_UNORM does not support VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, "
+ "which prevents OES_depth_texture from being supported.",
+ &members, "http://anglebug.com/3452"};
+
+ // On some android devices, vkCmdBlitImage with flipped coordinates blits incorrectly. This
+ // workaround makes sure this path is avoided. http://anglebug.com/3498
+ Feature disableFlippingBlitWithCommand = {
+ "disableFlippingBlitWithCommand", FeatureCategory::VulkanWorkarounds,
+ "vkCmdBlitImage with flipped coordinates blits incorrectly.", &members,
+ "http://anglebug.com/3498"};
+
+ // On platform with Intel or AMD GPU, a window resizing would not trigger the vulkan driver to
+ // return VK_ERROR_OUT_OF_DATE on swapchain present. Work-around by query current window extent
+ // every frame to detect a window resizing.
+ // http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625
+ Feature perFrameWindowSizeQuery = {
+ "perFrameWindowSizeQuery", FeatureCategory::VulkanWorkarounds,
+ "Vulkan swapchain is not returning VK_ERROR_OUT_OF_DATE when window resizing", &members,
+ "http://anglebug.com/3623, http://anglebug.com/3624, http://anglebug.com/3625"};
+
+ // Seamful cube map emulation misbehaves on the AMD windows driver, so it's disallowed.
+ Feature disallowSeamfulCubeMapEmulation = {
+ "disallowSeamfulCubeMapEmulation", FeatureCategory::VulkanWorkarounds,
+ "Seamful cube map emulation misbehaves on some drivers, so it's disallowed", &members,
+ "http://anglebug.com/3243"};
+
+ // Vulkan considers vertex attribute accesses to count up to the last multiple of the stride.
+ // This additional access supports AMD's robust buffer access implementation.
+ // AMDVLK in particular will return incorrect values when the vertex access extends into the
+ // range that would be the stride padding and the buffer is too small.
+ // This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a reasonable value and pads out
+ // every buffer allocation size to be large enough to support a maximum vertex stride.
+ // http://anglebug.com/4428
+ Feature padBuffersToMaxVertexAttribStride = {
+ "padBuffersToMaxVertexAttribStride", FeatureCategory::VulkanWorkarounds,
+ "Vulkan considers vertex attribute accesses to count up to the last multiple of the "
+ "stride. This additional access supports AMD's robust buffer access implementation. "
+ "AMDVLK in particular will return incorrect values when the vertex access extends into "
+ "the range that would be the stride padding and the buffer is too small. "
+ "This workaround limits GL_MAX_VERTEX_ATTRIB_STRIDE to a maximum value and "
+ "pads up every buffer allocation size to be a multiple of the maximum stride.",
+ &members, "http://anglebug.com/4428"};
+
+ // Whether the VkDevice supports the VK_EXT_swapchain_colorspace extension
+ // http://anglebug.com/2514
+ Feature supportsSwapchainColorspace = {
+ "supportsSwapchainColorspace", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_swapchain_colorspace extension", &members,
+ "http://anglebug.com/2514"};
+
+ // Whether the VkDevice supports the VK_EXT_external_memory_host extension, on which the
+ // ANGLE_iosurface_client_buffer extension can be layered.
+ Feature supportsExternalMemoryHost = {
+ "supportsExternalMemoryHost", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_EXT_external_memory_host extension", &members};
+
+ // Whether to fill new buffers and textures with nonzero data to sanitize robust resource
+ // initialization and flush out assumptions about zero init.
+ Feature allocateNonZeroMemory = {
+ "allocateNonZeroMemory", FeatureCategory::VulkanFeatures,
+ "Fill new allocations with non-zero values to flush out errors.", &members,
+ "http://anglebug.com/4384"};
+
+ // Whether to log each callback from the VK_EXT_device_memory_report extension. This feature is
+ // used for trying to debug GPU memory leaks.
+ Feature logMemoryReportCallbacks = {"logMemoryReportCallbacks", FeatureCategory::VulkanFeatures,
+ "Log each callback from VK_EXT_device_memory_report",
+ &members};
+
+ // Whether to log statistics from the VK_EXT_device_memory_report extension each eglSwapBuffer.
+ Feature logMemoryReportStats = {"logMemoryReportStats", FeatureCategory::VulkanFeatures,
+ "Log stats from VK_EXT_device_memory_report each swap",
+ &members};
+
+ // Allocate a "shadow" buffer for GL buffer objects. For GPU-read only buffers
+ // glMap* latency can be reduced by maintaining a copy of the buffer which is
+ // writeable only by the CPU. We then return this shadow buffer on glMap* calls.
+ Feature shadowBuffers = {
+ "shadowBuffers", FeatureCategory::VulkanFeatures,
+ "Allocate a shadow buffer for GL buffer objects to reduce glMap* latency.", &members,
+ "http://anglebug.com/4339"};
+
+ // Persistently map buffer memory until destroy, saves on map/unmap IOCTL overhead
+ // for buffers that are updated frequently.
+ Feature persistentlyMappedBuffers = {
+ "persistentlyMappedBuffers", FeatureCategory::VulkanFeatures,
+ "Persistently map buffer memory to reduce map/unmap IOCTL overhead.", &members,
+ "http://anglebug.com/2162"};
+
+ // Android needs to pre-rotate surfaces that are not oriented per the native device's
+ // orientation (e.g. a landscape application on a Pixel phone). This feature works for
+ // full-screen applications. http://anglebug.com/3502
+ Feature enablePreRotateSurfaces = {"enablePreRotateSurfaces", FeatureCategory::VulkanFeatures,
+ "Enable Android pre-rotation for landscape applications",
+ &members, "http://anglebug.com/3502"};
+
+ // Enable precision qualifiers for shaders generated by Vulkan backend http://anglebug.com/3078
+ Feature enablePrecisionQualifiers = {
+ "enablePrecisionQualifiers", FeatureCategory::VulkanFeatures,
+ "Enable precision qualifiers in shaders", &members, "http://anglebug.com/3078"};
+
+ // Desktop (at least NVIDIA) drivers prefer combining barriers into one vkCmdPipelineBarrier
+ // call over issuing multiple barrier calls with fine grained dependency information to have
+ // better performance. http://anglebug.com/4633
+ Feature preferAggregateBarrierCalls = {
+ "preferAggregateBarrierCalls", FeatureCategory::VulkanWorkarounds,
+ "Single barrier call is preferred over multiple calls with "
+ "fine grained pipeline stage dependency information",
+ &members, "http://anglebug.com/4633"};
+
+ // Tell the Vulkan back-end to use the async command queue to dispatch work to the GPU. Command
+ // buffer work will happened in a worker thread. Otherwise use Renderer::CommandQueue directly.
+ Feature asyncCommandQueue = {"asyncCommandQueue", FeatureCategory::VulkanFeatures,
+ "Use CommandQueue worker thread to dispatch work to GPU.",
+ &members, "http://anglebug.com/4324"};
+
+ // Whether the VkDevice supports the VK_KHR_shader_float16_int8 extension and has the
+ // shaderFloat16 feature.
+ Feature supportsShaderFloat16 = {"supportsShaderFloat16", FeatureCategory::VulkanFeatures,
+ "VkDevice supports the VK_KHR_shader_float16_int8 extension "
+ "and has the shaderFloat16 feature",
+ &members, "http://anglebug.com/4551"};
+
+ // Some devices don't meet the limits required to perform mipmap generation using the built-in
+ // compute shader. On some other devices, VK_IMAGE_USAGE_STORAGE_BIT is detrimental to
+ // performance, making this solution impractical.
+ Feature allowGenerateMipmapWithCompute = {
+ "allowGenerateMipmapWithCompute", FeatureCategory::VulkanFeatures,
+ "Use the compute path to generate mipmaps on devices that meet the minimum requirements, "
+ "and the performance is better.",
+ &members, "http://anglebug.com/4551"};
+
+ // Whether the VkDevice supports the VK_QCOM_render_pass_store_ops extension
+ // http://anglebug.com/5505
+ Feature supportsRenderPassStoreOpNoneQCOM = {
+ "supportsRenderPassStoreOpNoneQCOM", FeatureCategory::VulkanFeatures,
+ "VkDevice supports VK_QCOM_render_pass_store_ops extension.", &members,
+ "http://anglebug.com/5055"};
+
+ // Force maxUniformBufferSize to 16K on Qualcomm's Adreno 540. Pixel2's Adreno540 reports
+ // maxUniformBufferSize 64k but various tests failed with that size. For that specific
+ // device, we set to 16k for now which is known to pass all tests.
+ // https://issuetracker.google.com/161903006
+ Feature forceMaxUniformBufferSize16KB = {
+ "forceMaxUniformBufferSize16KB", FeatureCategory::VulkanWorkarounds,
+ "Force max uniform buffer size to 16K on some device due to bug", &members,
+ "https://issuetracker.google.com/161903006"};
+
+ // Enable mutable bit by default for ICD's that support VK_KHR_image_format_list.
+ // http://anglebug.com/5281
+ Feature supportsImageFormatList = {
+ "supportsImageFormatList", FeatureCategory::VulkanFeatures,
+ "Enable VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT by default for ICDs "
+ "that support VK_KHR_image_format_list",
+ &members, "http://anglebug.com/5281"};
+
+ // Swiftshader on mac fails to initialize WebGL context when EXT_multisampled_render_to_texture
+ // is used by Chromium.
+ // http://anglebug.com/4937
+ Feature enableMultisampledRenderToTexture = {
+ "enableMultisampledRenderToTexture", FeatureCategory::VulkanWorkarounds,
+ "Expose EXT_multisampled_render_to_texture", &members, "http://anglebug.com/4937"};
+
+ // Qualcomm fails some tests when reducing the preferred block size to 4M.
+ // http://anglebug.com/4995
+ Feature preferredLargeHeapBlockSize4MB = {
+ "preferredLargeHeapBlockSize4MB", FeatureCategory::VulkanWorkarounds,
+ "Use 4 MB preferred large heap block size with AMD allocator", &members,
+ "http://anglebug.com/4995"};
+
+ // Manhattan is calling glFlush in the middle of renderpass which breaks renderpass and hurts
+ // performance on tile based GPU. When this is enabled, we will defer the glFlush call made in
+ // the middle of renderpass to the end of renderpass.
+ // https://issuetracker.google.com/issues/166475273
+ Feature deferFlushUntilEndRenderPass = {
+ "deferFlushUntilEndRenderPass", FeatureCategory::VulkanWorkarounds,
+ "Allow glFlush to be deferred until renderpass ends", &members,
+ "https://issuetracker.google.com/issues/166475273"};
+
+ // Android mistakenly destroys oldSwapchain passed to vkCreateSwapchainKHR, causing crashes on
+ // certain drivers. http://anglebug.com/5061
+ Feature waitIdleBeforeSwapchainRecreation = {
+ "waitIdleBeforeSwapchainRecreation", FeatureCategory::VulkanWorkarounds,
+ "Before passing an oldSwapchain to VkSwapchainCreateInfoKHR, wait for queue to be idle. "
+ "Works around a bug on platforms which destroy oldSwapchain in vkCreateSwapchainKHR.",
+ &members, "http://anglebug.com/5061"};
+
+ // Allow forcing an LOD offset on all sampling operations for performance comparisons. ANGLE is
+ // non-conformant if this feature is enabled.
+ std::array<angle::Feature, 4> forceTextureLODOffset = {
+ angle::Feature{"force_texture_lod_offset_1", angle::FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 1 when sampling.",
+ &members},
+ angle::Feature{"force_texture_lod_offset_2", angle::FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 2 when sampling.",
+ &members},
+ angle::Feature{"force_texture_lod_offset_3", angle::FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 3 when sampling.",
+ &members},
+ angle::Feature{"force_texture_lod_offset_4", angle::FeatureCategory::VulkanWorkarounds,
+ "Increase the minimum texture level-of-detail by 4 when sampling.",
+ &members},
+ };
+
+ // Translate non-nearest filtering modes to nearest for all samplers for performance
+ // comparisons. ANGLE is non-conformant if this feature is enabled.
+ Feature forceNearestFiltering = {"force_nearest_filtering", FeatureCategory::VulkanWorkarounds,
+ "Force nearest filtering when sampling.", &members};
+
+ // Translate non-nearest mip filtering modes to nearest mip for all samplers for performance
+ // comparisons. ANGLE is non-conformant if this feature is enabled.
+ Feature forceNearestMipFiltering = {"forceNearestMipFiltering",
+ FeatureCategory::VulkanWorkarounds,
+ "Force nearest mip filtering when sampling.", &members};
+
+ // Compress float32 vertices in static buffers to float16 at draw time. ANGLE is non-conformant
+ // if this feature is enabled.
+ angle::Feature compressVertexData = {"compress_vertex_data",
+ angle::FeatureCategory::VulkanWorkarounds,
+ "Compress vertex data to smaller data types when "
+ "possible. Using this feature makes ANGLE non-conformant.",
+ &members};
+
+ // Qualcomm missynchronizes vkCmdClearAttachments in the middle of render pass.
+ // https://issuetracker.google.com/166809097
+ Feature preferDrawClearOverVkCmdClearAttachments = {
+ "preferDrawClearOverVkCmdClearAttachments", FeatureCategory::VulkanWorkarounds,
+ "On some hardware, clear using a draw call instead of vkCmdClearAttachments in the middle "
+ "of render pass due to bugs",
+ &members, "https://issuetracker.google.com/166809097"};
+
+ // Whether prerotation is being emulated for testing. 90 degree rotation.
+ Feature emulatedPrerotation90 = {"emulatedPrerotation90", FeatureCategory::VulkanFeatures,
+ "Emulate 90-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ // Whether prerotation is being emulated for testing. 180 degree rotation.
+ Feature emulatedPrerotation180 = {"emulatedPrerotation180", FeatureCategory::VulkanFeatures,
+ "Emulate 180-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ // Whether prerotation is being emulated for testing. 270 degree rotation.
+ Feature emulatedPrerotation270 = {"emulatedPrerotation270", FeatureCategory::VulkanFeatures,
+ "Emulate 270-degree prerotation.", &members,
+ "http://anglebug.com/4901"};
+
+ // Whether we should use driver uniforms over specialization constants for some shader
+ // modifications like yflip and rotation.
+ Feature forceDriverUniformOverSpecConst = {
+ "forceDriverUniformOverSpecConst", FeatureCategory::VulkanWorkarounds,
+ "Forces using driver uniforms instead of specialization constants.", &members,
+ "http://issuetracker.google.com/173636783"};
+
+ // Whether non-conformant configurations and extensions should be exposed. When an extension is
+ // in development, or a GLES version is not supported on a device, we may still want to expose
+ // them for partial testing. This feature is enabled by our test harness.
+ Feature exposeNonConformantExtensionsAndVersions = {
+ "exposeNonConformantExtensionsAndVersions", FeatureCategory::VulkanWorkarounds,
+ "Expose GLES versions and extensions that are not conformant.", &members,
+ "http://anglebug.com/5375"};
+
+ // imageAtomicExchange is expected to work for r32f formats, but support for atomic operations
+ // for VK_FORMAT_R32_SFLOAT is rare. This support is emulated by using an r32ui format for such
+ // images instead.
+ Feature emulateR32fImageAtomicExchange = {
+ "emulateR32fImageAtomicExchange", FeatureCategory::VulkanWorkarounds,
+ "Emulate r32f images with r32ui to support imageAtomicExchange.", &members,
+ "http://anglebug.com/5535"};
+
+ Feature supportsNegativeViewport = {
+ "supportsNegativeViewport", FeatureCategory::VulkanFeatures,
+ "The driver supports inverting the viewport with a negative height.", &members};
+
+ // Whether we should force any highp precision in the fragment shader to mediump.
+ // ANGLE is non-conformant if this feature is enabled.
+ Feature forceFragmentShaderPrecisionHighpToMediump = {
+ "forceFragmentShaderPrecisionHighpToMediump", FeatureCategory::VulkanWorkarounds,
+ "Forces highp precision in fragment shader to mediump.", &members,
+ "https://issuetracker.google.com/184850002"};
+
+ // Whether we should submit at each FBO boundary.
+ Feature preferSubmitAtFBOBoundary = {
+ "preferSubmitAtFBOBoundary", FeatureCategory::VulkanWorkarounds,
+ "Submit commands to driver at each FBO boundary for performance improvements.", &members,
+ "https://issuetracker.google.com/187425444"};
+};
+
+inline FeaturesVk::FeaturesVk() = default;
+inline FeaturesVk::~FeaturesVk() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FEATURESVK_H_
diff --git a/gfx/angle/checkout/include/platform/FrontendFeatures.h b/gfx/angle/checkout/include/platform/FrontendFeatures.h
new file mode 100644
index 0000000000..a5d596a10e
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/FrontendFeatures.h
@@ -0,0 +1,86 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FrontendFeatures.h: Features/workarounds for driver bugs and other behaviors seen
+// on all platforms.
+
+#ifndef ANGLE_PLATFORM_FRONTENDFEATURES_H_
+#define ANGLE_PLATFORM_FRONTENDFEATURES_H_
+
+#include "platform/Feature.h"
+
+namespace angle
+{
+
+struct FrontendFeatures : angle::FeatureSetBase
+{
+ FrontendFeatures();
+ ~FrontendFeatures();
+
+ // Force the context to be lost (via KHR_robustness) if a GL_OUT_OF_MEMORY error occurs. The
+ // driver may be in an inconsistent state if this happens, and some users of ANGLE rely on this
+ // notification to prevent further execution.
+ angle::Feature loseContextOnOutOfMemory = {
+ "lose_context_on_out_of_memory", angle::FeatureCategory::FrontendWorkarounds,
+ "Some users rely on a lost context notification if a GL_OUT_OF_MEMORY "
+ "error occurs",
+ &members};
+
+ // Program binaries don't contain transform feedback varyings on Qualcomm GPUs.
+ // Work around this by disabling the program cache for programs with transform feedback.
+ angle::Feature disableProgramCachingForTransformFeedback = {
+ "disable_program_caching_for_transform_feedback",
+ angle::FeatureCategory::FrontendWorkarounds,
+ "On some GPUs, program binaries don't contain transform feedback varyings", &members};
+
+ // On Windows Intel OpenGL drivers TexImage sometimes seems to interact with the Framebuffer.
+ // Flaky crashes can occur unless we sync the Framebuffer bindings. The workaround is to add
+ // Framebuffer binding dirty bits to TexImage updates. See http://anglebug.com/2906
+ angle::Feature syncFramebufferBindingsOnTexImage = {
+ "sync_framebuffer_bindings_on_tex_image", angle::FeatureCategory::FrontendWorkarounds,
+ "On some drivers TexImage sometimes seems to interact "
+ "with the Framebuffer",
+ &members};
+
+ angle::Feature scalarizeVecAndMatConstructorArgs = {
+ "scalarize_vec_and_mat_constructor_args", angle::FeatureCategory::FrontendWorkarounds,
+ "Always rewrite vec/mat constructors to be consistent", &members,
+ "http://crbug.com/1165751"};
+
+ // Disable support for GL_OES_get_program_binary
+ angle::Feature disableProgramBinary = {
+ "disable_program_binary", angle::FeatureCategory::FrontendFeatures,
+ "Disable support for GL_OES_get_program_binary", &members, "http://anglebug.com/5007"};
+
+ // Allow disabling of GL_EXT_texture_filter_anisotropic through a runtime feature for
+ // performance comparisons.
+ angle::Feature disableAnisotropicFiltering = {
+ "disable_anisotropic_filtering", angle::FeatureCategory::FrontendWorkarounds,
+ "Disable support for anisotropic filtering", &members};
+
+ // We can use this feature to override compressed format support for portability.
+ angle::Feature allowCompressedFormats = {"allow_compressed_formats",
+ angle::FeatureCategory::FrontendWorkarounds,
+ "Allow compressed formats", &members};
+
+ angle::Feature captureLimits = {"enable_capture_limits",
+ angle::FeatureCategory::FrontendFeatures,
+ "Set the context limits like frame capturing was enabled",
+ &members, "http://anglebug.com/5750"};
+
+ // Whether we should compress pipeline cache in thread pool before it's stored in blob cache.
+ // http://anglebug.com/4722
+ angle::Feature enableCompressingPipelineCacheInThreadPool = {
+ "enableCompressingPipelineCacheInThreadPool", angle::FeatureCategory::FrontendWorkarounds,
+ "Enable compressing pipeline cache in thread pool.", &members, "http://anglebug.com/4722"};
+};
+
+inline FrontendFeatures::FrontendFeatures() = default;
+inline FrontendFeatures::~FrontendFeatures() = default;
+
+} // namespace angle
+
+#endif // ANGLE_PLATFORM_FRONTENDFEATURES_H_
diff --git a/gfx/angle/checkout/include/platform/Platform.h b/gfx/angle/checkout/include/platform/Platform.h
new file mode 100644
index 0000000000..2c9537ed46
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/Platform.h
@@ -0,0 +1,10 @@
+//
+// Copyright 2020 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Platform.h: Simple forwarding header to PlatformMethods.h.
+// Ideally we can remove this file at some point since "Platform.h" is overloaded.
+//
+
+#include "PlatformMethods.h"
diff --git a/gfx/angle/checkout/include/platform/PlatformMethods.h b/gfx/angle/checkout/include/platform/PlatformMethods.h
new file mode 100644
index 0000000000..4697a87e45
--- /dev/null
+++ b/gfx/angle/checkout/include/platform/PlatformMethods.h
@@ -0,0 +1,339 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// PlatformMethods.h: The public interface ANGLE exposes to the API layer, for
+// doing platform-specific tasks like gathering data, or for tracing.
+
+#ifndef ANGLE_PLATFORMMETHODS_H
+#define ANGLE_PLATFORMMETHODS_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <array>
+
+#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x3482
+
+#if !defined(ANGLE_PLATFORM_EXPORT)
+# if defined(_WIN32)
+# if !defined(LIBANGLE_IMPLEMENTATION)
+# define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
+# else
+# define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
+# endif
+# elif defined(__GNUC__) || defined(__clang__)
+# define ANGLE_PLATFORM_EXPORT __attribute__((visibility("default")))
+# endif
+#endif
+#if !defined(ANGLE_PLATFORM_EXPORT)
+# define ANGLE_PLATFORM_EXPORT
+#endif
+
+#if defined(_WIN32)
+# define ANGLE_APIENTRY __stdcall
+#else
+# define ANGLE_APIENTRY
+#endif
+
+namespace angle
+{
+struct FeaturesD3D;
+struct FeaturesVk;
+struct FeaturesMtl;
+using TraceEventHandle = uint64_t;
+using EGLDisplayType = void *;
+struct PlatformMethods;
+
+// Use a C-like API to not trigger undefined calling behaviour.
+// Avoid using decltype here to work around sanitizer limitations.
+// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
+
+// System --------------------------------------------------------------
+
+// Wall clock time in seconds since the epoch.
+// TODO(jmadill): investigate using an ANGLE internal time library
+using CurrentTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultCurrentTime(PlatformMethods *platform)
+{
+ return 0.0;
+}
+
+// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
+// This function is expected to return at least millisecond-precision values. For this reason,
+// it is recommended that the fixed point be no further in the past than the epoch.
+using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
+inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
+{
+ return 0.0;
+}
+
+// Logging ------------------------------------------------------------
+
+// Log an error message within the platform implementation.
+using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
+inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage) {}
+
+// Log a warning message within the platform implementation.
+using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
+inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage) {}
+
+// Log an info message within the platform implementation.
+using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
+inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage) {}
+
+// Tracing --------
+
+// Get a pointer to the enabled state of the given trace category. The
+// embedder can dynamically change the enabled state as trace event
+// recording is started and stopped by the application. Only long-lived
+// literal strings should be given as the category name. The implementation
+// expects the returned pointer to be held permanently in a local static. If
+// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
+// addTraceEvent is expected to be called by the trace event macros.
+using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
+ const char *categoryName);
+inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
+ const char *categoryName)
+{
+ return nullptr;
+}
+
+//
+// Add a trace event to the platform tracing system. Depending on the actual
+// enabled state, this event may be recorded or dropped.
+// - phase specifies the type of event:
+// - BEGIN ('B'): Marks the beginning of a scoped event.
+// - END ('E'): Marks the end of a scoped event.
+// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
+// need a matching END event. Instead, at the end of the scope,
+// updateTraceEventDuration() must be called with the TraceEventHandle
+// returned from addTraceEvent().
+// - INSTANT ('I'): Standalone, instantaneous event.
+// - START ('S'): Marks the beginning of an asynchronous event (the end
+// event can occur in a different scope or thread). The id parameter is
+// used to match START/FINISH pairs.
+// - FINISH ('F'): Marks the end of an asynchronous event.
+// - COUNTER ('C'): Used to trace integer quantities that change over
+// time. The argument values are expected to be of type int.
+// - METADATA ('M'): Reserved for internal use.
+// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
+// - name is the name of the event. Also used to match BEGIN/END and
+// START/FINISH pairs.
+// - id optionally allows events of the same name to be distinguished from
+// each other. For example, to trace the construction and destruction of
+// objects, specify the pointer as the id parameter.
+// - timestamp should be a time value returned from monotonicallyIncreasingTime.
+// - numArgs specifies the number of elements in argNames, argTypes, and
+// argValues.
+// - argNames is the array of argument names. Use long-lived literal strings
+// or specify the COPY flag.
+// - argTypes is the array of argument types:
+// - BOOL (1): bool
+// - UINT (2): unsigned long long
+// - INT (3): long long
+// - DOUBLE (4): double
+// - POINTER (5): void*
+// - STRING (6): char* (long-lived null-terminated char* string)
+// - COPY_STRING (7): char* (temporary null-terminated char* string)
+// - CONVERTABLE (8): WebConvertableToTraceFormat
+// - argValues is the array of argument values. Each value is the unsigned
+// long long member of a union of all supported types.
+// - flags can be 0 or one or more of the following, ORed together:
+// - COPY (0x1): treat all strings (name, argNames and argValues of type
+// string) as temporary so that they will be copied by addTraceEvent.
+// - HAS_ID (0x2): use the id argument to uniquely identify the event for
+// matching with other events of the same name.
+// - MANGLE_ID (0x4): specify this flag if the id parameter is the value
+// of a pointer.
+using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ unsigned long long id,
+ double timestamp,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags);
+inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ unsigned long long id,
+ double timestamp,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags)
+{
+ return 0;
+}
+
+// Set the duration field of a COMPLETE trace event.
+using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ angle::TraceEventHandle eventHandle);
+inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
+ const unsigned char *categoryEnabledFlag,
+ const char *name,
+ angle::TraceEventHandle eventHandle)
+{}
+
+// Callbacks for reporting histogram data.
+// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
+// would do.
+using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int min,
+ int max,
+ int bucketCount);
+inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int min,
+ int max,
+ int bucketCount)
+{}
+// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
+// value.
+using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int boundaryValue);
+inline void DefaultHistogramEnumeration(PlatformMethods *platform,
+ const char *name,
+ int sample,
+ int boundaryValue)
+{}
+// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
+using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
+inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample) {}
+// Boolean histograms track two-state variables.
+using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
+inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample) {}
+
+// Allows us to programatically override ANGLE's default workarounds for testing purposes.
+using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,
+ angle::FeaturesD3D *featuresD3D);
+inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,
+ angle::FeaturesD3D *featuresD3D)
+{}
+
+using OverrideFeaturesVkFunc = void (*)(PlatformMethods *platform,
+ angle::FeaturesVk *featuresVulkan);
+inline void DefaultOverrideFeaturesVk(PlatformMethods *platform, angle::FeaturesVk *featuresVulkan)
+{}
+
+using OverrideFeaturesMtlFunc = void (*)(PlatformMethods *platform,
+ angle::FeaturesMtl *featuresMetal);
+inline void DefaultOverrideFeaturesMtl(PlatformMethods *platform, angle::FeaturesMtl *featuresMetal)
+{}
+
+// Callback on a successful program link with the program binary. Can be used to store
+// shaders to disk. Keys are a 160-bit SHA-1 hash.
+using ProgramKeyType = std::array<uint8_t, 20>;
+using CacheProgramFunc = void (*)(PlatformMethods *platform,
+ const ProgramKeyType &key,
+ size_t programSize,
+ const uint8_t *programBytes);
+inline void DefaultCacheProgram(PlatformMethods *platform,
+ const ProgramKeyType &key,
+ size_t programSize,
+ const uint8_t *programBytes)
+{}
+
+using PostWorkerTaskCallback = void (*)(void *userData);
+using PostWorkerTaskFunc = void (*)(PlatformMethods *platform,
+ PostWorkerTaskCallback callback,
+ void *userData);
+constexpr PostWorkerTaskFunc DefaultPostWorkerTask = nullptr;
+
+// Platform methods are enumerated here once.
+#define ANGLE_PLATFORM_OP(OP) \
+ OP(currentTime, CurrentTime) \
+ OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
+ OP(logError, LogError) \
+ OP(logWarning, LogWarning) \
+ OP(logInfo, LogInfo) \
+ OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
+ OP(addTraceEvent, AddTraceEvent) \
+ OP(updateTraceEventDuration, UpdateTraceEventDuration) \
+ OP(histogramCustomCounts, HistogramCustomCounts) \
+ OP(histogramEnumeration, HistogramEnumeration) \
+ OP(histogramSparse, HistogramSparse) \
+ OP(histogramBoolean, HistogramBoolean) \
+ OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \
+ OP(overrideFeaturesVk, OverrideFeaturesVk) \
+ OP(cacheProgram, CacheProgram) \
+ OP(overrideFeaturesMtl, OverrideFeaturesMtl) \
+ OP(postWorkerTask, PostWorkerTask)
+
+#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
+
+struct ANGLE_PLATFORM_EXPORT PlatformMethods
+{
+ inline PlatformMethods();
+
+ // User data pointer for any implementation specific members. Put it at the start of the
+ // platform structure so it doesn't become overwritten if one version of the platform
+ // adds or removes new members.
+ void *context = 0;
+
+ ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF)
+};
+
+inline PlatformMethods::PlatformMethods() = default;
+
+#undef ANGLE_PLATFORM_METHOD_DEF
+
+// Subtract one to account for the context pointer.
+constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
+
+#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
+#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
+
+constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
+ ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
+
+#undef ANGLE_PLATFORM_METHOD_STRING2
+#undef ANGLE_PLATFORM_METHOD_STRING
+
+} // namespace angle
+
+extern "C" {
+
+// Gets the platform methods on the passed-in EGL display. If the method name signature does not
+// match the compiled signature for this ANGLE, false is returned. On success true is returned.
+// The application should set any platform methods it cares about on the returned pointer.
+// If display is not valid, behaviour is undefined.
+
+ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
+ const char *const methodNames[],
+ unsigned int methodNameCount,
+ void *context,
+ void *platformMethodsOut);
+
+// Sets the platform methods back to their defaults.
+// If display is not valid, behaviour is undefined.
+ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
+} // extern "C"
+
+namespace angle
+{
+typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
+ const char *const *,
+ unsigned int,
+ void *,
+ void *);
+typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
+} // namespace angle
+
+// This function is not exported
+angle::PlatformMethods *ANGLEPlatformCurrent();
+
+#endif // ANGLE_PLATFORMMETHODS_H