eedeb4b803
This method takes an input assembly buffer and selects which OpenCL kernels need to be executed on that buffer to transform the input data into the eventual output StimulusFrame for the current timeslice period.
190 lines
4.8 KiB
C++
190 lines
4.8 KiB
C++
#ifndef _LIVOX_GEN1_OPENCL_COLLATING_AND_MESHING_ENGINE_H
|
|
#define _LIVOX_GEN1_OPENCL_COLLATING_AND_MESHING_ENGINE_H
|
|
|
|
#include <boostAsioLinkageFix.h>
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#define CL_TARGET_OPENCL_VERSION 300
|
|
#include <CL/cl.h>
|
|
#include <asynchronousLoop.h>
|
|
#include <callback.h>
|
|
#include <user/stimulusFrame.h>
|
|
#include "stagingBuffer.h"
|
|
#include "frameAssemblyDesc.h"
|
|
|
|
namespace smo {
|
|
namespace stim_buff {
|
|
|
|
class PcloudStimulusBuffer;
|
|
|
|
class OpenClCollatingAndMeshingEngine
|
|
{
|
|
public:
|
|
explicit OpenClCollatingAndMeshingEngine(PcloudStimulusBuffer& parent);
|
|
~OpenClCollatingAndMeshingEngine();
|
|
|
|
// Non-copyable, movable
|
|
OpenClCollatingAndMeshingEngine(
|
|
const OpenClCollatingAndMeshingEngine&) = delete;
|
|
OpenClCollatingAndMeshingEngine& operator=(
|
|
const OpenClCollatingAndMeshingEngine&) = delete;
|
|
OpenClCollatingAndMeshingEngine(
|
|
OpenClCollatingAndMeshingEngine&&) = default;
|
|
OpenClCollatingAndMeshingEngine& operator=(
|
|
OpenClCollatingAndMeshingEngine&&) = default;
|
|
|
|
bool setup();
|
|
void finalize();
|
|
|
|
// Callback function types
|
|
typedef std::function<void(cl_int)> compactKernelCbFn;
|
|
typedef std::function<void(cl_int)> collateKernelCbFn;
|
|
typedef std::function<void(bool, StimulusFrame&)>
|
|
compactCollateAndMeshFrameReqCbFn;
|
|
|
|
bool startCompactKernel(
|
|
StagingBuffer& assemblyBuff, uint32_t nSucceeded,
|
|
compactKernelCbFn callback);
|
|
bool startCollateKernel(
|
|
StagingBuffer& assemblyBuff, StagingBuffer& collationBuff,
|
|
collateKernelCbFn callback);
|
|
|
|
void stopCompactKernel();
|
|
void stopCollateKernel();
|
|
void stop();
|
|
|
|
void compactCollateAndMeshFrameReq(
|
|
AsynchronousLoop& asyncLoop, StimulusFrame& stimulusFrame,
|
|
Callback<compactCollateAndMeshFrameReqCbFn> callback);
|
|
|
|
private:
|
|
PcloudStimulusBuffer& parent;
|
|
|
|
// OpenCL infrastructure
|
|
cl_platform_id platform;
|
|
cl_device_id device;
|
|
cl_context context;
|
|
cl_command_queue commandQueue;
|
|
cl_program slotCompactorProgram;
|
|
cl_program collateProgram;
|
|
cl_kernel slotCompactorKernel;
|
|
cl_kernel collateKernel;
|
|
bool isSetup;
|
|
|
|
// OpenCL buffers
|
|
cl_mem clAssemblyBuffer;
|
|
cl_mem clCollationBuffer;
|
|
|
|
// State tracking
|
|
bool compactIsSetup;
|
|
bool compactIsRunning;
|
|
bool collateIsSetup;
|
|
bool collateIsRunning;
|
|
cl_event currentCompactKernelEvent;
|
|
cl_event currentCollateKernelEvent;
|
|
|
|
// Memory tracking
|
|
void* assemblyBufferPtr;
|
|
size_t assemblyBufferSize;
|
|
void* collationBufferPtr;
|
|
size_t collationBufferSize;
|
|
|
|
// Frame descriptor (cached from setup)
|
|
std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc;
|
|
|
|
// Callback storage
|
|
compactKernelCbFn compactKernelCb;
|
|
collateKernelCbFn collateKernelCb;
|
|
|
|
// Static callbacks for OpenCL events
|
|
static void CL_CALLBACK compactKernelEventCallback(
|
|
cl_event event, cl_int event_command_exec_status, void* user_data);
|
|
static void CL_CALLBACK collateKernelEventCallback(
|
|
cl_event event, cl_int event_command_exec_status, void* user_data);
|
|
|
|
// Private helper methods
|
|
bool compileAndPrepareKernel(
|
|
const char* kernelSource, size_t kernelSourceLen,
|
|
const char* kernelName, cl_program& program, cl_kernel& kernel);
|
|
bool compileAndPrepareKernels();
|
|
bool setupSlotCompactorsArgs(
|
|
StagingBuffer& assemblyBuff, uint32_t nSucceeded);
|
|
bool setupCollateDgramsArgs(StagingBuffer& assemblyBuff);
|
|
|
|
// Forward declaration for continuation class
|
|
class CompactCollateAndMeshFrameReq;
|
|
|
|
// Unified kernel start function
|
|
template<typename SetupArgsFn, typename ValidateBuffersFn>
|
|
bool startKernel(
|
|
cl_kernel kernel,
|
|
cl_event* eventPtr,
|
|
SetupArgsFn setupArgsFn,
|
|
ValidateBuffersFn validateBuffersFn,
|
|
size_t globalWorkSize,
|
|
void (CL_CALLBACK *eventCallback)(cl_event, cl_int, void*),
|
|
const char* kernelName,
|
|
bool& isSetup,
|
|
bool& isRunning)
|
|
{
|
|
if (!isSetup)
|
|
{
|
|
std::cerr << __func__ << ": engine not set up" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
if (isRunning)
|
|
{
|
|
std::cerr << __func__ << ": already running, call stop() first"
|
|
<< std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Validate buffers
|
|
validateBuffersFn();
|
|
|
|
// Set up kernel arguments
|
|
if (!setupArgsFn()) {
|
|
return false;
|
|
}
|
|
|
|
// Enqueue kernel execution
|
|
cl_int err = clEnqueueNDRangeKernel(
|
|
commandQueue, kernel, 1, nullptr, &globalWorkSize, nullptr,
|
|
0, nullptr, eventPtr);
|
|
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
std::cerr << __func__ << ": failed to enqueue " << kernelName
|
|
<< " kernel: " << err << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// Set up callback using static member function
|
|
err = clSetEventCallback(
|
|
*eventPtr, CL_COMPLETE, eventCallback, this);
|
|
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
std::cerr << __func__ << ": failed to set event callback: " << err
|
|
<< std::endl;
|
|
clReleaseEvent(*eventPtr);
|
|
*eventPtr = nullptr;
|
|
return false;
|
|
}
|
|
|
|
isRunning = true;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
} // namespace stim_buff
|
|
} // namespace smo
|
|
|
|
#endif // _LIVOX_GEN1_OPENCL_COLLATING_AND_MESHING_ENGINE_H
|
|
|