Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_cache_cl.c File Reference

Pixelpipe cache ↔ OpenCL buffer lifecycle helpers. More...

#include "common/atomic.h"
#include "common/darktable.h"
#include "common/opencl.h"
#include "develop/pixelpipe.h"
#include "develop/pixelpipe_cache.h"
#include <stddef.h>
+ Include dependency graph for pixelpipe_cache_cl.c:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static void _gpu_clear_buffer (void **cl_mem_buffer, dt_pixel_cache_entry_t *cache_entry, void *host_ptr, int cst, const gboolean cache_device)
 No-OpenCL stub for _gpu_clear_buffer().
 

Detailed Description

Pixelpipe cache ↔ OpenCL buffer lifecycle helpers.

This file contains the "plumbing" between:

  • the pixelpipe cache (host/RAM buffers, lifetime + locks handled by pixelpipe_cache.[ch]), and
  • OpenCL images (device-side objects, optionally backed by host memory via CL_MEM_USE_HOST_PTR).

Why this exists

The pixelpipe is mostly written as a classic CPU pipeline: each module consumes a packed host buffer and produces a packed host buffer. When OpenCL is enabled, some modules can run GPU kernels using process_cl().

The performance goal is to avoid unnecessary copies between RAM and vRAM:

  • If we can keep buffers on the device between GPU modules, we do so.
  • If a CPU module needs the buffer, we synchronize device → host.

However, correctness has strict requirements:

  • The pixelpipe cache can evict entries (LRU + fragmentation mitigation).
  • The pixelpipe cache can auto-destroy entries when their refcount drops.
  • Host buffers can be reused for other images/ROIs once unlocked.

When using CL_MEM_USE_HOST_PTR, OpenCL may:

  • truly run zero-copy, reading host memory directly (best case), or
  • allocate a device-side staging copy (still legal), requiring explicit transfers for correctness.

Therefore we must:

  1. Detect when a CL_MEM_USE_HOST_PTR image is really zero-copy for a given driver/device.
  2. Keep the cache entry appropriately locked while the GPU may still read from host memory.
  3. Provide robust sync primitives (map/unmap or explicit transfers) for device ↔ host transitions.
  4. Avoid leaving stale cl_mem pointers in our cache-side bookkeeping when we release a buffer.

Where these helpers are used

The high-level OpenCL control-flow lives in pixelpipe_hb.c (whether to run on GPU, tiling decisions, CPU fallbacks, etc.). This file focuses on the mechanics of OpenCL buffers:

  • allocating and reusing pinned buffers,
  • caching cl_mem objects inside cache entries for later reuse,
  • clearing/releasing/caching cl_mem objects in a safe way,
  • synchronizing contents between device and host.

Threading / locking model

  • Pixelpipe cache entries have their own locks (read/write) and reference counting.
  • When OpenCL uses true zero-copy pinned buffers, the GPU may read host memory asynchronously. In that case we must keep a read lock on the cache entry until all queued GPU work is finished, otherwise another code path could overwrite the host buffer while the GPU is still reading it.

Important warning

You can't "just" call a CPU fallback when a GPU module fails: the CPU code expects a host buffer. In OpenCL mode, the host buffer can legitimately be NULL (GPU-only intermediate), while the correct data exists only in cl_mem. The fallback path must allocate the host buffer and synchronize it before CPU code can proceed.

Function Documentation

◆ _gpu_clear_buffer()

static void _gpu_clear_buffer ( void **  cl_mem_buffer,
dt_pixel_cache_entry_t cache_entry,
void host_ptr,
int  cst,
const gboolean  cache_device 
)
inlinestatic

No-OpenCL stub for _gpu_clear_buffer().

The pixelpipe code keeps cl_mem pointers around even when OpenCL is not compiled in, because the control flow is shared. In non-OpenCL builds those pointers must be treated as "always NULL".

This stub keeps the caller code simple and avoids littering the pixelpipe with preprocessor conditionals.

References void().

Referenced by _abort_module_shutdown_cleanup(), and dt_dev_pixelpipe_process().