// // Copyright 2021 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // CLProgramCL.cpp: Implements the class methods for CLProgramCL. #include "libANGLE/renderer/cl/CLProgramCL.h" #include "libANGLE/renderer/cl/CLDeviceCL.h" #include "libANGLE/renderer/cl/CLKernelCL.h" #include "libANGLE/CLDevice.h" #include "libANGLE/CLProgram.h" namespace rx { CLProgramCL::CLProgramCL(const cl::Program &program, cl_program native) : CLProgramImpl(program), mNative(native) {} CLProgramCL::~CLProgramCL() { if (mNative->getDispatch().clReleaseProgram(mNative) != CL_SUCCESS) { ERR() << "Error while releasing CL program"; } } std::string CLProgramCL::getSource(cl_int &errorCode) const { size_t size = 0u; errorCode = mNative->getDispatch().clGetProgramInfo(mNative, CL_PROGRAM_SOURCE, 0u, nullptr, &size); if (errorCode == CL_SUCCESS) { if (size != 0u) { std::vector valString(size, '\0'); errorCode = mNative->getDispatch().clGetProgramInfo(mNative, CL_PROGRAM_SOURCE, size, valString.data(), nullptr); if (errorCode == CL_SUCCESS) { return std::string(valString.data(), valString.size() - 1u); } } } return std::string{}; } cl_int CLProgramCL::build(const cl::DevicePtrs &devices, const char *options, cl::Program *notify) { std::vector nativeDevices; for (const cl::DevicePtr &device : devices) { nativeDevices.emplace_back(device->getImpl().getNative()); } const cl_uint numDevices = static_cast(nativeDevices.size()); const cl_device_id *const nativeDevicesPtr = !nativeDevices.empty() ? nativeDevices.data() : nullptr; const cl::ProgramCB callback = notify != nullptr ? Callback : nullptr; return mNative->getDispatch().clBuildProgram(mNative, numDevices, nativeDevicesPtr, options, callback, notify); } cl_int CLProgramCL::compile(const cl::DevicePtrs &devices, const char *options, const cl::ProgramPtrs &inputHeaders, const char **headerIncludeNames, cl::Program *notify) { std::vector nativeDevices; for (const cl::DevicePtr &device : devices) { nativeDevices.emplace_back(device->getImpl().getNative()); } const cl_uint numDevices = static_cast(nativeDevices.size()); const cl_device_id *const nativeDevicesPtr = !nativeDevices.empty() ? nativeDevices.data() : nullptr; std::vector nativePrograms; for (const cl::ProgramPtr &program : inputHeaders) { nativePrograms.emplace_back(program->getImpl().getNative()); } const cl_uint numInputHeaders = static_cast(nativePrograms.size()); const cl_program *const inputHeadersPtr = !nativePrograms.empty() ? nativePrograms.data() : nullptr; const cl::ProgramCB callback = notify != nullptr ? Callback : nullptr; return mNative->getDispatch().clCompileProgram(mNative, numDevices, nativeDevicesPtr, options, numInputHeaders, inputHeadersPtr, headerIncludeNames, callback, notify); } cl_int CLProgramCL::getInfo(cl::ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const { return mNative->getDispatch().clGetProgramInfo(mNative, cl::ToCLenum(name), valueSize, value, valueSizeRet); } cl_int CLProgramCL::getBuildInfo(const cl::Device &device, cl::ProgramBuildInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const { return mNative->getDispatch().clGetProgramBuildInfo( mNative, device.getImpl().getNative(), cl::ToCLenum(name), valueSize, value, valueSizeRet); } CLKernelImpl::Ptr CLProgramCL::createKernel(const cl::Kernel &kernel, const char *name, cl_int &errorCode) { const cl_kernel nativeKernel = mNative->getDispatch().clCreateKernel(mNative, name, &errorCode); return CLKernelImpl::Ptr(nativeKernel != nullptr ? new CLKernelCL(kernel, nativeKernel) : nullptr); } cl_int CLProgramCL::createKernels(cl_uint numKernels, CLKernelImpl::CreateFuncs &createFuncs, cl_uint *numKernelsRet) { if (numKernels == 0u) { return mNative->getDispatch().clCreateKernelsInProgram(mNative, 0u, nullptr, numKernelsRet); } std::vector nativeKernels(numKernels, nullptr); const cl_int errorCode = mNative->getDispatch().clCreateKernelsInProgram( mNative, numKernels, nativeKernels.data(), numKernelsRet); if (errorCode == CL_SUCCESS) { for (cl_kernel nativeKernel : nativeKernels) { createFuncs.emplace_back([nativeKernel](const cl::Kernel &kernel) { return CLKernelImpl::Ptr(new CLKernelCL(kernel, nativeKernel)); }); } } return errorCode; } void CLProgramCL::Callback(cl_program program, void *userData) { static_cast(userData)->callback(); } } // namespace rx