#1153873 i965-va-driver: vaExportSurfaceHandle fails on freshly created surfaces, so Chromium falls back to software decoding

Package:
i965-va-driver
Source:
i965-va-driver
Description:
VAAPI driver for Intel G45 & HD Graphics family
Submitter:
Luke Esau
Date:
2026-11-13 00:37:02 UTC
Severity:
normal
#1153873#5
Date:
2026-11-13 00:35:15 UTC
From:
To:
Dear Maintainer,

Chromium (and Google Chrome) cannot use VA-API hardware decoding with the
i965 driver, on any GPU it supports (Sandy Bridge through Cannon Lake).
The decoder initializes, then every frame export fails and Chromium
silently falls back to software decoding.  With --enable-logging=stderr
--v=1 the GPU process prints:

  ERROR:media/gpu/vaapi/vaapi_wrapper.cc:2756] vaExportSurfaceHandle
failed, VA error: invalid VASurfaceID
  VERBOSE2:media/gpu/vaapi/vaapi_video_decoder.cc:144] ~VaapiVideoDecoder():

Cause
-----
i965 allocates the buffer object backing a surface lazily, on the first
vaBeginPicture()/vaDeriveImage() that touches it
(i965_check_alloc_surface_bo).  i965_ExportSurfaceHandle() in
src/i965_drv_video.c returns VA_STATUS_ERROR_INVALID_SURFACE when
obj_surface->bo is NULL.  Chromium's VideoDecoderPipeline exports every
surface of its frame pool right after vaCreateSurfaces(), before any
decode, which causes exports to fail.

Fix
---
The attached DEP-3 patch
(debian/patches/0006-ExportSurfaceHandle-allocate-bo.patch)
allocates the storage on export for 8-bit 4:2:0 surfaces, as NV12 and
tiled where the hardware supports it, which is what the decoders
allocate in i965_decoder_utils.c, so the later decode finds a matching
buffer.  Other render-target formats keep the previous behavior
(INVALID_SURFACE, now with an i965_log_info message).  It applies on top
of the current series including
0004-fix-exporting-buffers-with-3-planes.patch.

Upstream (github.com/intel/intel-vaapi-driver) is archived,
so the patch cannot be forwarded; Forwarded: not-needed.

Testing
-------
Intel Core i5-2415M / HD 3000 (Sandy Bridge, Gen6), Ubuntu 24.04 with the
package rebuilt from 2.4.1+dfsg1-1ubuntu0.2 plus this patch, libva 2.20,
Mesa 25.2 (crocus), GNOME on Wayland, Google Chrome 156 started with
--enable-features=VaapiVideoDecodeLinuxGL:

  - the vaExportSurfaceHandle error is gone and VaapiVideoDecoder stays
alive;
  - CPU time of the whole Chrome process tree during 15 s of steady 1080p
    H.264 High playback: ~14 CPU-s before (software fallback), ~6 after;
  - decoded output verified visually (test pattern renders correctly);
  - Firefox, which exports surfaces only after decoding, is unaffected and
    still decodes via VA-API;
  - vainfo and GStreamer vaapih264dec unchanged.

Not tested on Gen7/8/9 hardware but the tiling choice follows
codec_info->has_tiled_surface exactly as the decoders do.

Retested 2026-11-09 after moving the same machine to Ubuntu 26.04.1
(kernel 7.0, libva 2.23, libdrm 2.4.131, Mesa 26.0): the patch was
rebuilt on top of the unmodified Debian 2.4.1+dfsg1-2 source.  A small
libva test that calls vaExportSurfaceHandle() immediately after
vaCreateSurfaces() fails with VA_STATUS_ERROR_INVALID_SURFACE on the
stock driver and succeeds with the patch (NV12, 1920x1080, 1 object,
2 layers).  vainfo is unchanged.