• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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