Skip to content

Transparent2d particle draws never appear on Qualcomm Adreno 830/840 (Vulkan), despite effects reporting ready + active spawners #548

Description

@benp87

Summary

On two Qualcomm Adreno adapters (Adreno (TM) 830 and Adreno (TM) 840, Vulkan backend), bevy_hanabi 2D effects report fully ready/compiled with active spawners (CompiledParticleEffect::is_ready() == true, EffectSpawner::active == true), and the effect entities have both ViewVisibility and InheritedVisibility set, but no particles are ever visible on screen. No panic, no error, no warning -- the Transparent2d draw simply produces no pixels. The same effects render correctly on desktop (Linux, Vulkan/wgpu) and the app's own Mesh2d/sprite-based Transparent2d content (unrelated to Hanabi) renders correctly on the same Adreno devices, which suggests the issue is specific to Hanabi's render/draw path rather than the Transparent2d phase in general.

Environment

  • bevy_hanabi 0.19.0
  • bevy 0.19.0
  • wgpu 29.0.4 / naga 29.0.4
  • Backend: Vulkan
  • Platform: Android (native, android-game-activity feature), Rust stable toolchain
  • GPU adapters (from wgpu::AdapterInfo logged via RenderAdapterInfo), confirmed on two separate physical devices with the identical symptom:
    • adapter_name=Adreno (TM) 840 vendor_id=20803 (0x5143, Qualcomm) backend=Vulkan device_type=IntegratedGpu driver="Qualcomm Technologies Inc. Adreno Vulkan Driver"
    • adapter_name=Adreno (TM) 830 vendor_id=20803 (0x5143, Qualcomm) backend=Vulkan device_type=IntegratedGpu driver="Qualcomm Technologies Inc. Adreno Vulkan Driver"
  • Desktop reference: Linux, Vulkan backend -- effects render correctly with the same EffectAsset definitions.

Logcat evidence (Adreno 830 device)

INFO render_adapter: GPU adapter detected; render quality selected adapter_name=Adreno (TM) 830 vendor_id=20803 backend=Vulkan device_type=IntegratedGpu driver=Qualcomm Technologies Inc. Adreno Vulkan Driver fallback=Default preset=High effective=High
INFO render_adapter: Hanabi readiness probe total=3 ready=3 view_vis=1 inherited=1 spawn_active=3
INFO render_adapter: Hanabi readiness probe total=7 ready=7 view_vis=5 inherited=5 spawn_active=7
INFO render_adapter: Hanabi readiness probe total=7 ready=7 view_vis=5 inherited=5 spawn_active=7

Despite ready == total and spawn_active == total throughout, and the majority of effects reporting both view_vis and inherited visibility true, no particle pixels ever appeared on screen for the duration of the session.

Reproduction

  1. Register HanabiPlugin in a 2D Bevy app on Android (native activity, Vulkan backend, Adreno 830/840).
  2. Spawn a ParticleEffect referencing a simple EffectAsset (tested with both one-shot burst effects and continuous-rate ambient effects; both are affected).
  3. Observe via logging that:
    • CompiledParticleEffect::is_ready() returns true.
    • EffectSpawner::active is true.
    • ViewVisibility / InheritedVisibility are both visible.
  4. No particle pixels ever appear on screen, at any point in the effect's lifetime.

What we ruled out

  • Not a visibility/culling bug in our own code: we log ViewVisibility/InheritedVisibility/is_ready/spawner.active every ~2s and all report correctly "ready" throughout.
  • Not a general Transparent2d phase failure on this hardware: ordinary Mesh2d + MeshMaterial2d<ColorMaterial> sprites with alpha blending render correctly in the same scene on the same Adreno 830/840 devices, in the same Transparent2d phase.
  • Not desktop-reproducible: the identical EffectAssets render correctly on Linux/Vulkan.
  • We are aware of the historical Adreno bitflag/UBO-alignment issue affecting StandardMaterialFlags in Bevy core (Transparency doesnt work when on webgl adreno devices bevyengine/bevy#10066, #11472) on older Adreno 500/600-series GPUs, but that was a 3D StandardMaterial bug fixed years ago; our devices are newer-generation Adreno (830/840) and the failure is 2D/Hanabi-specific, so we don't believe it's the same root cause, but flagging in case it's relevant context (e.g. a related class of driver quirk around packed/indirect GPU data on Qualcomm hardware).

Suspicion

Hanabi's particle simulation and draw path is GPU-driven (compute-shader simulation + indirect draw), which is a different code path from a typical CPU-issued Transparent2d draw. Our working theory is a driver-specific issue with indirect draw calls or compute-shader-written buffers feeding the render pass on this Adreno driver, but we have not instrumented far enough (e.g. via a GPU capture tool) to pinpoint whether the compute pass writes are actually landing, or whether the indirect draw parameters are wrong/zeroed on this driver.

Workaround in our app

We've shipped an adapter-scoped Mesh2d CPU-particle fallback gated specifically to these two confirmed adapter strings + the Qualcomm PCI vendor ID, defaulting every other adapter to attempting Hanabi normally. Happy to share more logs, a minimal repro project, or run a GPU capture (RenderDoc/Vulkan validation layers) against a debug build if that would help track this down -- let us know what would be most useful.

Would help from us

  • Confirmation on whether this is a known Adreno-family issue with Hanabi's compute/indirect draw path.
  • Any diagnostic Hanabi already exposes (feature flags, debug dumps of indirect draw args, etc.) we could enable to gather more targeted evidence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    need-reproNeed a repro to be able to diagnose and fix

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions