TerraForge3D  2.3.1
3D Terrain And Landscape Generator
ComputeKernel.cpp
1#include "Base/OpenCL/ComputeKernel.h"
2
3#include <iostream>
4
5static void OnError(std::string message)
6{
7 std::cout << "OpenCL Error : " << message << std::endl;
8}
9
10static void OnStatus(std::string message)
11{
12 std::cout << "OpenCL Status : " << message << std::endl;
13}
14
15ComputeKernel::ComputeKernel()
16 :ComputeKernel(OnError, OnStatus)
17{
18}
19
20ComputeKernel::~ComputeKernel()
21{
22}
23
24ComputeKernel::ComputeKernel(std::function<void(std::string)> errFunc, std::function<void(std::string)> statusFunc)
25{
26 onError = errFunc;
27 onStatus = statusFunc;
28 std::vector<cl::Platform> platforms;
29 cl::Platform::get(&platforms);
30
31 if (platforms.size() == 0)
32 {
33 onError("No Platform found supporting OpenCL!");
34 return;
35 }
36
37 platform = platforms[0];
38 onStatus("Using OpenCL Platform : " + platform.getInfo<CL_PLATFORM_NAME>() );
39 std::vector<cl::Device> devices;
40 platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
41
42 if (devices.size() == 0)
43 {
44 onError("No Device found supporting OpenCL!");
45 return;
46 }
47
48 bool tmp = false;
49
50 for (auto &d : devices)
51 {
52 tmp = (d.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU);
53
54 if (tmp)
55 {
56 device = d;
57 onStatus("Using GPU Device : " + device.getInfo<CL_DEVICE_NAME>());
58 break;
59 }
60 }
61
62 if (!tmp)
63 {
64 device = devices[0];
65 onStatus("Using CPU Device : " + device.getInfo<CL_DEVICE_NAME>());
66 }
67
68 context = cl::Context({device});
69 queue = cl::CommandQueue(context, device);
70}
71
72void ComputeKernel::AddSoruce(std::string source)
73{
74 sources.push_back({source.c_str(), source.size()});
75}
76
77void ComputeKernel::BuildProgram(std::string options)
78{
79 program = cl::Program(context, sources);
80
81 if (program.build({ device }, options.c_str()) != CL_SUCCESS)
82 {
83 onStatus("Error Building : " + program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device));
84 return;
85 }
86}
87
88void ComputeKernel::AddKernel(std::string name)
89{
90 kernels[name] = cl::Kernel(program, name.c_str());
91}
92
93void ComputeKernel::Clear()
94{
95 sources.clear();
96 kernels.clear();
97}
98
99void ComputeKernel::ExecuteKernel(std::string name, cl::NDRange local, cl::NDRange global)
100{
101 queue.enqueueNDRangeKernel(kernels[name], cl::NullRange, global, local);
102 queue.finish();
103}
104
105void ComputeKernel::CreateBuffer(std::string name, int type, size_t size)
106{
107 OpenCLBuffer buffer;
108 buffer.size = size;
109 buffer.buffer = cl::Buffer(context, type, size);
110 buffers[name] = buffer;
111}
112
113void ComputeKernel::SetKernelArg(std::string name, int arg, std::string buffer)
114{
115 kernels[name].setArg(arg, buffers[buffer].buffer);
116}
117
118void ComputeKernel::ReadBuffer(std::string buffer, bool blocking, size_t size, void *data)
119{
120 queue.enqueueReadBuffer(buffers[buffer].buffer, blocking ? CL_TRUE : CL_FALSE, 0, size, data);
121}
122
123void ComputeKernel::WriteBuffer(std::string buffer, bool blocking, size_t size, void *data)
124{
125 queue.enqueueWriteBuffer(buffers[buffer].buffer, blocking ? CL_TRUE : CL_FALSE, 0, size, data);
126}