diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /gfx/angle/checkout/include/platform | |
parent | Initial commit. (diff) | |
download | firefox-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.h | 200 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/FeaturesD3D.h | 239 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/FeaturesGL.h | 565 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/FeaturesMtl.h | 90 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/FeaturesVk.h | 531 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/FrontendFeatures.h | 86 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/Platform.h | 10 | ||||
-rw-r--r-- | gfx/angle/checkout/include/platform/PlatformMethods.h | 339 |
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 |