Zero-copy DMA-BUF import and 2D BLT contract for Gen9 userspace

Abierto
#1,053 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
cpp, linux

Línea de trabajo

Start by reading the runtime's DMA-BUF and external memory support, then compare its existing buffer and synchronization APIs with the proposed contract. The issue points to chipmem.h, blit.h, docs/linux-equivalents.md, and docs/backends.md in the linked implementation as references. Done means the runtime exposes or documents a supported zero-copy import and coherency handoff for Gen9 userspace.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Type: Feature Request
Pre-submission Checklist
  • I have searched for similar feature requests and found none
  • This feature request includes a clear description of the proposed functionality
Feature Title

Zero-copy DMA-BUF import and 2D BLT contract for Gen9 userspace

Feature Category

Other

Other Category

Userspace memory contract / DMA-BUF interop

GPU Hardware

Intel Skylake-U GT2 (HD Graphics 520, Gen9)

Operating System

Other

Other Operating System

Linux, Fedora 43, kernel 7.2.13

API

OpenCL

Problem Statement

On Gen9 (Skylake), userspace can already do zero-copy GPU work, but the compute stack does not expose a small contract for it.

The kernel supports the full path: allocate a GEM object with DRM_IOCTL_I915_GEM_CREATE, export it as a DMA-BUF with DRM_IOCTL_PRIME_HANDLE_TO_FD, map it for CPU access, submit an XY_SRC_COPY_BLT to the BLT ring via DRM_IOCTL_I915_GEM_EXECBUFFER2 with softpin, and bracket the CPU read with DMA_BUF_IOCTL_SYNC. The GPU reads and writes the same physical pages the CPU wrote. No copy at the API boundary.

The compute-runtime does not expose this as a usable primitive. The alternatives are:

  • Rusticl/iris, which runs kernels on the GPU but copies at the boundary because it does not implement cl_khr_external_memory_dma_buf.
  • Hand-rolling the i915 ioctls, which is what my working implementation does, and which requires userspace to know the Gen9 batch encoding, the softpin rules, and the retired-vs-current domain ioctls.

The result is that a Gen9 iGPU, which shares memory with the CPU and can do zero-copy work, is treated by the software stack as if it were a discrete GPU that needs copies. That limitation prevents integrated GPUs from being used for GPU-side preprocessing without a copy tax, and it makes the coherency contract the application's problem to rediscover.

Proposed Solution

A small, documented userspace contract for zero-copy DMA-BUF import on Gen9, with an explicit coherency handoff. Two functions are the core of it:

  • an allocator that returns a buffer accessible to both CPU and GPU, exported as a DMA-BUF
  • a handoff call that brackets CPU access and blocks until the GPU is done

A working implementation exists and is measured. It is not a proposal for a new driver feature; it is a proposal that the runtime document or expose the pattern, so applications do not have to hand-roll it.

The implementation is at github.com/SimoesCTT/the-level. It builds and tests on Fedora 43 with make check and make check-coupling. The zero-copy path is verified: 0 mismatches out of 1024 elements on Skylake-U. The coherency handoff is proven load-bearing: skipping it produces 42–99% stale reads across batches (100 runs per case).

Expected Benefits
  • Makes Gen9 iGPUs usable for zero-copy GPU-side work without a discrete card.
  • Removes the copy at the API boundary for applications that already own their buffers.
  • Gives applications an explicit coherency contract instead of requiring them to rediscover the i915 softpin and batch rules.
  • Establishes a documented pattern that newer Intel generations can extend (fast copy, block copy, compute engines) without changing the application-facing contract.

Target users: developers doing GPU-side preprocessing (tiling, masking, layout conversion) on integrated GPUs; AI pipeline authors who currently either run this work on the CPU or pay for a copy to the GPU.

Use Case Scenarios

Use Case 1: An AI pipeline on a laptop with an integrated GPU needs to resize, mask, and re-layout image tensors before inference. Today this runs on the CPU (serial, slow) or through a GPU path that copies at the boundary. With a zero-copy contract, the data stays where it is and the GPU operates on it directly.

Use Case 2: A developer wants to chain several small 2D operations on the same buffer. The copy boundary makes chaining expensive; a zero-copy contract with an explicit handoff makes it cheap.

Use Case 3: A researcher on older Intel hardware (Gen8/Gen9) wants to use the GPU they already have, without buying a discrete card or renting cloud GPU time.

Code Examples / API Design

The working contract, from chipmem.h and blit.h in the repository:

chipmem_buffer_t *in  = chipmem_alloc(4096, NULL);
chipmem_buffer_t *out = chipmem_alloc(4096, NULL);

uint32_t *src = chipmem_cpu_ptr(in);
uint32_t *dst = chipmem_cpu_ptr(out);
fill(src);

chipmem_sync(in, CHIPMEM_ACCESS_CPU_WRITE);

blit_desc_t d = { .minterm = 0xF0, .src = src, .dst = dst,
                  .width = 1024, .height = 1, .bpp = 4 };
blit_op_t *op = blit(&d, BLIT_MODE_ASYNC);
blit_op_wait(op);

chipmem_sync(out, CHIPMEM_ACCESS_ACCEL_WRITE);
check(dst);

The point is the shape: one allocation, one handoff, one completion. The application does not manage the DMA-BUF import, the softpin addresses, or the sync ioctl.

### Alternatives & Workarounds

Alternative 1: Rusticl/iris via OpenCL. Limitation: copies at the boundary because cl_khr_external_memory_dma_buf is not implemented on this platform. The GPU does not touch the caller's memory.

Alternative 2: Hand-rolled i915 ioctls. Limitation: requires the application to know the Gen9 batch encoding (XY_SRC_COPY_BLT, MI_BATCH_BUFFER_END = 0x05000000), the softpin rules (EXEC_OBJECT_PINNED, EXEC_OBJECT_SUPPORTS_48B_ADDRESS, low addresses to avoid the display server's mappings), and that GEM_SET_DOMAIN is retired while mmap+munmap clears the write domain. This is what my working implementation does, and it is the thing a contract would remove.

Alternative 3: A discrete GPU. Limitation: cost. The point of the project is that the integrated GPU already present can do this work.

text

**Priority:** `High`
**Estimated Impact:** `Some users` (honest — Gen8/Gen9 is older hardware, but the pattern extends)

**References:**
Working implementation: https://github.com/SimoesCTT/the-level

Audit of the Linux equivalents and the coherency measurement: docs/linux-equivalents.md in the repository

Backend interface and the discrete-GPU extension: docs/backends.md in the repository

### Priority / Importance

Medium - Nice to have enhancement

### Estimated Impact

Unknown

### References


Working implementation: https://github.com/SimoesCTT/the-level

Audit of the Linux equivalents and the coherency measurement: docs/linux-equivalents.md in the repository

Backend interface and the discrete-GPU extension: docs/backends.md in the repository

### Additional Notes

The measurements are in the repository and reproducible with make check-coupling. The coherency handoff was measured over 100 runs per case, across multiple batches. The stale rate varies between batches (42–99% for "skip both syncs", 87–100% for "skip output sync only"), which is why the range is reported rather than a single number.

The implementation also has a capability query (blit_caps()) and three backends behind one contract, so a discrete-GPU zero-copy backend can be added without changing the application-facing API. That is the extension path if this is interesting to the runtime team.
Lenguaje dominante
C++
Estrellas
1.5k
Forks
306
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de intel/compute-runtime

Todos los issues de intel/compute-runtime

Issues similares

Más issues de C++

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.