Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions src/opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
#include "opencl.h"

#include <sys/mman.h>

#include <utility>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
Expand Down Expand Up @@ -134,6 +136,11 @@ std::shared_ptr<RawImage> 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) {
Expand All @@ -142,8 +149,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;
Expand Down
5 changes: 5 additions & 0 deletions src/opencl.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,16 @@ class CLArray {
public:
explicit CLArray(int size);
CLArray(void* data, int size);
~CLArray();

template<typename T> CLMap<T> read() const { return CLMap<T>(buffer, size, CL_MAP_READ); }
template<typename T> CLMap<T> write() { return CLMap<T>(buffer, size, CL_MAP_WRITE_INVALIDATE_REGION); }
template<typename T> CLMap<T> readWrite() { return CLMap<T>(buffer, size, CL_MAP_WRITE); }

private:
const void* ptr;

public:
const cl::Buffer buffer;
const int size;
};
Expand Down
Loading