From 99b49c2b6ca0c32ccad96e2d4ec7ae4bc4f99bda Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 18 Jul 2026 12:22:33 +0200 Subject: [PATCH] CL_MEM_USE_HOST_PTR for CLArrays instead of CL_MEM_ALLOC_HOST_PTR for alignment reasons --- src/opencl.cpp | 25 ++++++++++++++++++++++--- src/opencl.h | 5 +++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/opencl.cpp b/src/opencl.cpp index 980d407..512231c 100644 --- a/src/opencl.cpp +++ b/src/opencl.cpp @@ -14,7 +14,8 @@ limitations under the License. */ #include "opencl.h" -#include "cl_kernels.h" + +#include #include #include @@ -142,6 +143,11 @@ std::shared_ptr OpenCL::acquireNV12(int width, int height) { } static inline cl::Buffer clAlloc(cl_mem_flags type, cl::size_type size, void* data) { + if(type &= CL_MEM_USE_HOST_PTR) { + if(!mlock(data, size)) // Some OpenCL drivers (nvidia, AMD) require pinned memory for zero copy operations + std:: cerr << "[OpenCL] Could not lock memory, potential performance degradation" << std::endl; + } + int error; cl::Buffer buffer(type | CL_MEM_READ_WRITE, size, data, &error); if(error != CL_SUCCESS) { @@ -151,8 +157,21 @@ static inline cl::Buffer clAlloc(cl_mem_flags type, cl::size_type size, void* da return buffer; } -CLArray::CLArray(int size): buffer(clAlloc((cl_mem_flags) CL_MEM_ALLOC_HOST_PTR, (cl::size_type) size, nullptr)), size(size) {} -CLArray::CLArray(void* data, const int size): buffer(clAlloc((cl_mem_flags) CL_MEM_COPY_HOST_PTR, (cl::size_type) size, data)), size(size) {} +/* Manually align to 4KiB instead of using CL_MEM_ALLOC_HOST_PTR due to possible device constraints. +- Spinnaker USB requires 1024 byte alignment +- Nvidia, AMD, Intel require usually page boundary (4KiB on x86 and AMD64) alignment + https://www.intel.com/content/dam/develop/external/us/en/documents/opencl-zero-copy-in-opencl-1-2.pdf +*/ +#define MINIMUM_ALIGNMENT 4096 + +CLArray::CLArray(int size): ptr(aligned_alloc(MINIMUM_ALIGNMENT, size)), buffer(clAlloc((cl_mem_flags) CL_MEM_USE_HOST_PTR, (cl::size_type) size, (void*) ptr)), size(size) {} +CLArray::CLArray(void* data, const int size): ptr(nullptr), buffer(clAlloc((cl_mem_flags) CL_MEM_COPY_HOST_PTR, (cl::size_type) size, data)), size(size) {} +CLArray::~CLArray() { + if(ptr) { + munlock(ptr, size); + free((void*) ptr); + } +} static inline cl::Image2D allocImage(int width, int height, const PixelFormat* format) { int error; diff --git a/src/opencl.h b/src/opencl.h index 5fe9506..b075ed0 100644 --- a/src/opencl.h +++ b/src/opencl.h @@ -158,11 +158,16 @@ class CLArray { public: explicit CLArray(int size); CLArray(void* data, int size); + ~CLArray(); template CLMap read() const { return CLMap(buffer, size, CL_MAP_READ); } template CLMap write() { return CLMap(buffer, size, CL_MAP_WRITE_INVALIDATE_REGION); } template CLMap readWrite() { return CLMap(buffer, size, CL_MAP_WRITE); } +private: + const void* ptr; + +public: const cl::Buffer buffer; const int size; };