1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // CLProgramCL.cpp: Implements the class methods for CLProgramCL.
7
8 #include "libANGLE/renderer/cl/CLProgramCL.h"
9
10 #include "libANGLE/renderer/cl/CLDeviceCL.h"
11 #include "libANGLE/renderer/cl/CLKernelCL.h"
12
13 #include "libANGLE/CLDevice.h"
14 #include "libANGLE/CLProgram.h"
15
16 namespace rx
17 {
18
CLProgramCL(const cl::Program & program,cl_program native)19 CLProgramCL::CLProgramCL(const cl::Program &program, cl_program native)
20 : CLProgramImpl(program), mNative(native)
21 {}
22
~CLProgramCL()23 CLProgramCL::~CLProgramCL()
24 {
25 if (mNative->getDispatch().clReleaseProgram(mNative) != CL_SUCCESS)
26 {
27 ERR() << "Error while releasing CL program";
28 }
29 }
30
getSource(cl_int & errorCode) const31 std::string CLProgramCL::getSource(cl_int &errorCode) const
32 {
33 size_t size = 0u;
34 errorCode =
35 mNative->getDispatch().clGetProgramInfo(mNative, CL_PROGRAM_SOURCE, 0u, nullptr, &size);
36 if (errorCode == CL_SUCCESS)
37 {
38 if (size != 0u)
39 {
40 std::vector<char> valString(size, '\0');
41 errorCode = mNative->getDispatch().clGetProgramInfo(mNative, CL_PROGRAM_SOURCE, size,
42 valString.data(), nullptr);
43 if (errorCode == CL_SUCCESS)
44 {
45 return std::string(valString.data(), valString.size() - 1u);
46 }
47 }
48 }
49 return std::string{};
50 }
51
build(const cl::DevicePtrs & devices,const char * options,cl::Program * notify)52 cl_int CLProgramCL::build(const cl::DevicePtrs &devices, const char *options, cl::Program *notify)
53 {
54 std::vector<cl_device_id> nativeDevices;
55 for (const cl::DevicePtr &device : devices)
56 {
57 nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
58 }
59 const cl_uint numDevices = static_cast<cl_uint>(nativeDevices.size());
60 const cl_device_id *const nativeDevicesPtr =
61 !nativeDevices.empty() ? nativeDevices.data() : nullptr;
62 const cl::ProgramCB callback = notify != nullptr ? Callback : nullptr;
63 return mNative->getDispatch().clBuildProgram(mNative, numDevices, nativeDevicesPtr, options,
64 callback, notify);
65 }
66
compile(const cl::DevicePtrs & devices,const char * options,const cl::ProgramPtrs & inputHeaders,const char ** headerIncludeNames,cl::Program * notify)67 cl_int CLProgramCL::compile(const cl::DevicePtrs &devices,
68 const char *options,
69 const cl::ProgramPtrs &inputHeaders,
70 const char **headerIncludeNames,
71 cl::Program *notify)
72 {
73 std::vector<cl_device_id> nativeDevices;
74 for (const cl::DevicePtr &device : devices)
75 {
76 nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
77 }
78 const cl_uint numDevices = static_cast<cl_uint>(nativeDevices.size());
79 const cl_device_id *const nativeDevicesPtr =
80 !nativeDevices.empty() ? nativeDevices.data() : nullptr;
81
82 std::vector<cl_program> nativePrograms;
83 for (const cl::ProgramPtr &program : inputHeaders)
84 {
85 nativePrograms.emplace_back(program->getImpl<CLProgramCL>().getNative());
86 }
87 const cl_uint numInputHeaders = static_cast<cl_uint>(nativePrograms.size());
88 const cl_program *const inputHeadersPtr =
89 !nativePrograms.empty() ? nativePrograms.data() : nullptr;
90
91 const cl::ProgramCB callback = notify != nullptr ? Callback : nullptr;
92 return mNative->getDispatch().clCompileProgram(mNative, numDevices, nativeDevicesPtr, options,
93 numInputHeaders, inputHeadersPtr,
94 headerIncludeNames, callback, notify);
95 }
96
getInfo(cl::ProgramInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const97 cl_int CLProgramCL::getInfo(cl::ProgramInfo name,
98 size_t valueSize,
99 void *value,
100 size_t *valueSizeRet) const
101 {
102 return mNative->getDispatch().clGetProgramInfo(mNative, cl::ToCLenum(name), valueSize, value,
103 valueSizeRet);
104 }
105
getBuildInfo(const cl::Device & device,cl::ProgramBuildInfo name,size_t valueSize,void * value,size_t * valueSizeRet) const106 cl_int CLProgramCL::getBuildInfo(const cl::Device &device,
107 cl::ProgramBuildInfo name,
108 size_t valueSize,
109 void *value,
110 size_t *valueSizeRet) const
111 {
112 return mNative->getDispatch().clGetProgramBuildInfo(
113 mNative, device.getImpl<CLDeviceCL>().getNative(), cl::ToCLenum(name), valueSize, value,
114 valueSizeRet);
115 }
116
createKernel(const cl::Kernel & kernel,const char * name,cl_int & errorCode)117 CLKernelImpl::Ptr CLProgramCL::createKernel(const cl::Kernel &kernel,
118 const char *name,
119 cl_int &errorCode)
120 {
121 const cl_kernel nativeKernel = mNative->getDispatch().clCreateKernel(mNative, name, &errorCode);
122 return CLKernelImpl::Ptr(nativeKernel != nullptr ? new CLKernelCL(kernel, nativeKernel)
123 : nullptr);
124 }
125
createKernels(cl_uint numKernels,CLKernelImpl::CreateFuncs & createFuncs,cl_uint * numKernelsRet)126 cl_int CLProgramCL::createKernels(cl_uint numKernels,
127 CLKernelImpl::CreateFuncs &createFuncs,
128 cl_uint *numKernelsRet)
129 {
130 if (numKernels == 0u)
131 {
132 return mNative->getDispatch().clCreateKernelsInProgram(mNative, 0u, nullptr, numKernelsRet);
133 }
134
135 std::vector<cl_kernel> nativeKernels(numKernels, nullptr);
136 const cl_int errorCode = mNative->getDispatch().clCreateKernelsInProgram(
137 mNative, numKernels, nativeKernels.data(), numKernelsRet);
138 if (errorCode == CL_SUCCESS)
139 {
140 for (cl_kernel nativeKernel : nativeKernels)
141 {
142 createFuncs.emplace_back([nativeKernel](const cl::Kernel &kernel) {
143 return CLKernelImpl::Ptr(new CLKernelCL(kernel, nativeKernel));
144 });
145 }
146 }
147 return errorCode;
148 }
149
Callback(cl_program program,void * userData)150 void CLProgramCL::Callback(cl_program program, void *userData)
151 {
152 static_cast<cl::Program *>(userData)->callback();
153 }
154
155 } // namespace rx
156