From AI Studio analysis of https://github.com/google/angle/blob/6a04a50f98cac71b25464d10289ce7a013841caf/src/libANGLE/renderer/vulkan/vk_renderer.cpp#L4879
These workarounds apply to GPUs designed by ARM (Mali), found in chipsets like Samsung Exynos, Google Tensor, and MediaTek Dimensity.
Feature / Workaround | mFeatures Flag |
Condition / Driver Version | Reason & Impact |
---|---|---|---|
Protected Memory Restriction | supportsProtectedMemory |
Blocked if: isARM && !pipelineProtectedAccess |
Bug: On older ARM platforms, enabling VK_KHR_protected_memory causes excessive, unnecessary load/store unit activity. Workaround: Only enabled on ARM if the newer VK_EXT_pipeline_protected_access extension is also present, indicating a fixed driver. (b/208458772) |
Mixed Load Op Restriction | disallowMixedDepthStencilLoadOpNoneAndLoad |
Enabled if: isARM && driverVersion < r38.1.0 |
Bug: ARM drivers older than r38p1 are buggy when a render pass uses LOAD_OP_NONE for one attachment (e.g., depth) and LOAD_OP_LOAD for another (e.g., stencil) simultaneously. Workaround: ANGLE avoids this combination on affected drivers. |
Forced Host Copy for Luma | forceHostImageCopyForLuma |
Enabled if: isARM |
Performance: For luminance/alpha texture formats, using a CPU-based host copy is faster than a GPU copy on ARM. This outweighs the benefit of framebuffer compression (which is disabled by the host copy path). |
CPU Preference for Buffer Copies | preferCPUForBufferSubData |
Enabled if: isARM |
Performance: On ARM GPUs, especially older "Job Manager" based architectures, performing buffer copies on the CPU can prevent a GPU pipeline bubble, allowing vertex and fragment shaders to overlap more effectively. |
Disabled Async Command Buffer Resets | asyncCommandBufferReset |
Blocked if: isARM |
Bug/Stall: On ARM, calling vkResetCommandPool in a background thread can stall, as the call blocks on a mutex inside the driver. Workaround: ANGLE performs command buffer resets synchronously on the main thread for ARM. |
Disabled MSRTT Emulation | allowMultisampledRenderToTextureEmulation |
Blocked if: isARM |
Bug: Emulating GL_EXT_multisampled_render_to_texture (when the native Vulkan MSRTSS extension is not available) fails multiple tests on older ARM drivers. Workaround: The emulation path is disabled on all ARM devices. |
Idle Wait on Swapchain Recreation | waitIdleBeforeSwapchainRecreation |
Enabled if: IsAndroid() && isARM |
Bug: On Android, ARM drivers can mistakenly destroy the old swapchain while creating a new one. Workaround: ANGLE calls vkDeviceWaitIdle before swapchain recreation to prevent this race condition. |
SPIR-V 1.4 Disabled on Old Drivers | supportsSPIRV14 |
Blocked if: isARM && driverVersion < r47.0.0 |
Bug: ARM drivers older than r47 fail tests when OpSelect uses a scalar to select between vectors in SPIR-V 1.4 shaders. Workaround: ANGLE generates SPIR-V 1.3 on these older drivers. (anglebug/343218491) |
Buggy Extended Dynamic State | supportsExtendedDynamicState |
Blocked if: `(isARM && driverVersion < r44.1.0) | |
Buggy Vertex Input Dynamic State | supportsVertexInputDynamicState |
Blocked if: isARM && driverVersion < r48.0.0 |
Bug: ARM drivers < r48 have a bug in vkCmdBindVertexBuffers2 where strides are applied to the wrong binding index. Workaround: The feature is disabled on affected drivers. (ARM Errata) |
Buggy Cull Mode Dynamic State | useCullModeDynamicState |
Blocked if: isARM && driverVersion < r52.0.0 |
Bug: ARM drivers < r52 incorrectly cull non-triangle topologies when vkCmdSetCullMode is used. Workaround: The feature is disabled on affected drivers. (ARM Errata) |
Buggy Imageless Framebuffers | supportsImagelessFramebuffer |
Blocked if: isARM && driverVersion >= r38.0.0 && driverVersion < r38.2.0 |
Bug: ARM drivers r38.0 and r38.1 crash when creating imageless framebuffers. Workaround: The feature is disabled on these specific driver versions. |
Disabled Graphics Pipeline Library | supportsGraphicsPipelineLibrary |
Blocked if: isARM |
Performance: "Unacceptable performance degradation" was observed on ARM GPUs when using the Graphics Pipeline Library (GPL) extension. Workaround: GPL is disabled on all ARM devices. (anglebug/404581992) |
Ineffective Pipeline Cache Warm-up | warmUpPipelineCacheAtLink |
Blocked if: isARM |
Performance: ARM drivers key their pipeline cache blobs in a way that includes vertex/fragment state, making pre-warmed caches miss at draw time if that state changes. Workaround: ANGLE disables pipeline cache warm-up at link time. |
Non-Zero Stencil Write Mask | useNonZeroStencilWriteMaskStaticState |
Enabled if: isARM && driverVersion < r43.0.0 |
Bug: ARM drivers < r43 have a bug where dynamic stencil write masks don't work correctly if the pipeline was created with a static mask of 0 , especially when discard or alpha-to-coverage is used. Workaround: ANGLE uses a non-zero static state. |
Mediump Float to 16-bit Cast | explicitlyCastMediumpFloatTo16Bit |
Enabled if: isARM |
Compiler Quirk: Forces an explicit cast of mediump float to 16-bit types in the shader source. This likely ensures the ARM shader compiler uses the intended 16-bit hardware path. |
Forced Wait for Query Results | forceWaitForSubmissionToCompleteForQueryResult |
Enabled if: isARM |
Bug: On ARM, calling vkGetQueryPoolResults with the VK_QUERY_RESULT_WAIT_BIT flag can incorrectly return VK_NOT_READY . Workaround: ANGLE forces a full CPU wait for the command buffer to complete before retrieving query results. (issuetracker.google.com/253522366) |
Command Pool Memory Leak Fix | useResetCommandBufferBitForSecondaryPools |
Enabled if: isARM |
Bug: Some ARM drivers may not free memory from vkFreeCommandBuffers correctly unless the command pool was created with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag. Workaround: ANGLE always uses this flag for secondary command pools on ARM. |
VkEvent Recycling Disabled | recycleVkEvent |
Blocked if: isARM |
Performance: On ARM, vkCmdResetEvent has significant GPU overhead. Workaround: It's faster to destroy and re-create VkEvent objects on the CPU than to reset and reuse them on the GPU. |
Buggy Dynamic Rendering | preferDynamicRendering |
Blocked if: isARM && driverVersion < r52.0.0 |
Bug: ARM drivers < r52 have various bugs with dynamic rendering. Workaround: Dynamic rendering is disabled on affected drivers. (issuetracker.google.com/356051947) |
ASTC 3D Sliced Texture Support | supportsAstcSliced3d |
Enabled if: isARM |
Quirk: Enables a special path or acknowledges support for sliced 3D ASTC textures, which may be a non-standard or vendor-specific implementation detail on ARM. |
These workarounds apply to Qualcomm's Adreno GPUs, found in Snapdragon chipsets (e.g., Google Pixel phones).
Feature / Workaround | mFeatures Flag |
Condition / Driver Version | Reason & Impact |
---|---|---|---|
Buggy Multisampled-to-Single-Sampled | supportsMultisampledRenderToSingleSampled |
Blocked if: isQualcommProprietary && driverVersion < 512.822.0 |
Bug: Proprietary Qualcomm drivers < 512.822 have rendering bugs with the MSRTSS extension. Workaround: The feature is disabled on affected drivers. (crbug/413427770) |
Stencil Border Color Quirk | usesSecondComponentForStencilBorderColor |
Enabled if: isQualcommProprietary |
Quirk: Qualcomm drivers read custom stencil border colors from the second component (.y ) of the borderColor vector. Workaround: ANGLE places the stencil value in the correct component for Qualcomm. |
Disabled Precision Qualifiers on Pixel | enablePrecisionQualifiers |
Blocked if: IsPixel2(...) && driverVersion < 512.490.0 OR IsPixel4(...) |
Bug: Precision qualifiers are buggy on Pixel 2 (with old drivers) and all Pixel 4 devices. Workaround: They are disabled entirely on these devices to prevent shader compilation errors or incorrect rendering. (anglebug/42261756) |
Draw Calls for Clears | preferDrawClearOverVkCmdClearAttachments |
Enabled if: isQualcommProprietary && driverVersion < 512.762.12 |
Bug: On Qualcomm drivers < 512.762.12 , vkCmdClearAttachments can race with subsequent draw calls. Workaround: ANGLE uses a full-screen draw call to perform clears instead, which is safer. (issuetracker.google.com/166809097) |
Dithering Precision Workaround | roundOutputAfterDithering |
Enabled if: isQualcomm |
Bug: A workaround for an unspecified imprecision issue related to dithering on Qualcomm hardware. |
Disabled SPIR-V 1.4 | supportsSPIRV14 |
Blocked if: isQualcommProprietary |
Bug: Proprietary Qualcomm drivers crash when compiling SPIR-V 1.4 shaders that use OpCopyLogical with certain types. Workaround: ANGLE disables SPIR-V 1.4 on all proprietary Qualcomm drivers. (anglebug/343218484) |
Buggy Vertex Input Dynamic State | supportsVertexInputDynamicState |
Blocked if: isQualcommProprietary && driverVersion < 512.777.0 |
Bug: Qualcomm drivers < 512.777 have a bug in this feature. Workaround: The feature is disabled on affected drivers. (anglebug/381384988) |
Buggy Imageless Framebuffers | supportsImagelessFramebuffer |
Blocked if: isQualcommProprietary && driverVersion < 512.806.0 |
Bug: Qualcomm drivers < 512.806 can infinite-loop or crash when using imageless framebuffers. Workaround: The feature is disabled on affected drivers. (issuetracker.google.com/369693310) |
Buggy Dynamic Rendering | preferDynamicRendering |
Blocked if: isQualcommProprietary && driverVersion < 512.801.0 |
Bug: Qualcomm drivers < 512.801 have bugs with dynamic rendering. Workaround: The feature is disabled on affected drivers. (crbug/415738891) |
Disabled Rasterization Order Access | supportsRasterizationOrderAttachmentAccess |
Blocked if: isQualcomm |
Bug: Enabling this extension (used for coherent framebuffer fetch) causes issues on Qualcomm GPUs. Workaround: The feature is disabled on all Qualcomm devices. (issuetracker.google.com/255837430) |
Force 16KB Max UBO Size on Adreno 540 | forceMaxUniformBufferSize16KB |
Enabled if: isQualcommProprietary && isAdreno540 |
Hardware Limitation/Bug: A specific workaround for the Adreno 540 GPU (Pixel 2 / Snapdragon 835) that limits the uniform buffer object (UBO) size to 16KB to avoid a driver bug or hardware limit. |
These workarounds apply to GPUs developed by Samsung (Xclipse), found in their Exynos chipsets (e.g., Galaxy S22/S23 series).
Feature / Workaround | mFeatures Flag |
Condition / Driver Version | Reason & Impact |
---|---|---|---|
Mismatched Varying Precision | varyingsRequireMatchingPrecisionInSpirv |
Enabled if: isSamsung |
Bug: Samsung drivers require that precision qualifiers for varying variables match exactly between the vertex and fragment shaders. |
Buggy Dynamic Logic Op on S23 | supportsLogicOpDynamicState |
Blocked if: isGalaxyS23 |
Bug: Dynamic state for logical operations is buggy on Galaxy S23 devices. Workaround: This feature is disabled on the S23. |
Buggy Imageless Framebuffers | supportsImagelessFramebuffer |
Blocked if: isSamsung && driverVersion < 24.0.0 |
Bug: Samsung drivers < 24.0.0 have a bug in imageless framebuffer support. Workaround: The feature is disabled on affected drivers. |
Buggy Dynamic Rendering | supportsDynamicRendering |
Blocked if: isSamsung |
Bug: Dynamic rendering is completely disabled on all Samsung devices due to unspecified driver bugs. (anglebug/386749841#comment21) |
Disabled Extensions | supportsAngleRgbxInternalFormat , supportsAppleClipDistance |
Blocked if: isSamsung |
Bug: These two extensions are explicitly disabled on Samsung devices, likely due to driver bugs or lack of support. |
Enable Native CL Kernels | usesNativeBuiltinClKernel |
Enabled if: isSamsung |
Performance: Enables the use of specific, vendor-provided OpenCL kernels for certain operations, which are likely more optimized than a generic shader-based implementation. |
Force Sample Usage for AHB | forceSampleUsageForAhbBackedImages |
Enabled if: isSamsung |
Bug: Forces the VK_IMAGE_USAGE_SAMPLED_BIT to be set for all Android Hardware Buffer (AHB) backed images, likely to work around a driver issue. |
Dual Pipeline Blob Cache | useDualPipelineBlobCacheSlots |
Enabled if: isSamsung |
Performance: Enables the use of two slots in the blob cache for pipelines. The comment notes this is beneficial on Samsung because it has a "big blob cache", suggesting this helps manage it more effectively. |
Feature / Workaround | mFeatures Flag |
Condition / Driver Version | Reason & Impact |
---|---|---|---|
Mismatched Varying Precision | varyingsRequireMatchingPrecisionInSpirv |
Enabled if: isPowerVR |
Bug: PowerVR drivers require that precision qualifiers for varying variables match exactly between the vertex and fragment shaders. |
Buggy/Slow Imageless Framebuffers | supportsImagelessFramebuffer |
Blocked if: isPowerVR |
Performance: Using imageless framebuffers on PowerVR causes "enormous amounts of time" to be spent in framebuffer creation and destruction. Workaround: The feature is disabled. (issuetracker.google.com/372273294) |
Ineffective Pipeline Cache Warm-up | warmUpPipelineCacheAtLink |
Blocked if: isPowerVR |
Performance: Like ARM, PowerVR drivers do not benefit from pipeline cache warm-up for monolithic pipelines. Workaround: ANGLE disables this warm-up to avoid wasted work. |
Slow Dynamic Rendering | preferDynamicRendering |
Blocked if: isPowerVR |
Performance: Dynamic rendering is disabled on PowerVR devices for performance reasons. (issuetracker.google.com/372273294) |
These apply to the general class of Tile-Based Rendering (TBR) GPUs (which includes ARM, Qualcomm, and PowerVR) or are specific to the Android platform.
Feature / Workaround | mFeatures Flag |
Condition / Driver Version | Reason & Impact |
---|---|---|---|
CPU Data Copy Preference | mMaxCopyBytesUsingCPUWhenPreservingBufferData |
UINT32_MAX if IsAndroid() (else 0 ) |
Performance: On Android, ANGLE defaults to using the CPU for most buffer data copies to offload work from the often-limited GPU. (issuetracker.google.com/201826021) |
Submit at FBO Boundary | preferSubmitAtFBOBoundary |
Enabled if: isTileBasedRenderer |
Performance: On all TBRs, submitting command buffers at the end of a render pass allows the GPU to fully process and flush its tile memory, avoiding stalls. isTileBasedRenderer is true for ARM, PowerVR, Qualcomm, Broadcom, and Apple. |
Permanent Framebuffer Fetch Mode | permanentlySwitchToFramebufferFetchMode |
Enabled if: isTileBasedRenderer && !preferDynamicRendering |
Performance: On TBRs using legacy render passes, switching in and out of framebuffer fetch mode is very expensive. Workaround: Once FBF is used, ANGLE keeps the render pass in that mode permanently. |
Single Buffer Swap Behavior | swapbuffersOnFlushOrFinishWithSingleBuffer |
Enabled if: IsAndroid() |
Quirk: On Android, eglSwapBuffers is required to present an image to the display, even in single-buffered scenarios where it might otherwise be a no-op. |
Bottom-Left Present Regions | bottomLeftOriginPresentRegionRectangles |
Enabled if: IsAndroid() |
Bug: The Android presentation engine expects rectangles for partial updates to have a bottom-left origin, which contradicts the Vulkan spec (top-left). ANGLE flips the rectangles. (anglebug/42265410) |
Flush on Query Change | preferSubmitOnAnySamplesPassedQueryEnd |
Enabled if: isTileBasedRenderer |
Performance: On TBRs, query results may not be available until the entire render pass is finished. Workaround: ANGLE issues an immediate flush when switching from a draw with an active query to one without. (issuetracker.google.com/250706693) |
Use VkEvents for Barriers | useVkEventForImageBarrier , useVkEventForBufferBarrier |
Enabled if: isTileBasedRenderer |
Performance: VkEvent objects have lower overhead for synchronization than full pipeline barriers on TBR GPUs. Using them can reduce bubbles and improve performance. |