blob: 0cf54ab46c2022c5afc15826275aa245af274d24 [file] [log] [blame]
//
// 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<char> 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<cl_device_id> nativeDevices;
for (const cl::DevicePtr &device : devices)
{
nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
}
const cl_uint numDevices = static_cast<cl_uint>(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<cl_device_id> nativeDevices;
for (const cl::DevicePtr &device : devices)
{
nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
}
const cl_uint numDevices = static_cast<cl_uint>(nativeDevices.size());
const cl_device_id *const nativeDevicesPtr =
!nativeDevices.empty() ? nativeDevices.data() : nullptr;
std::vector<cl_program> nativePrograms;
for (const cl::ProgramPtr &program : inputHeaders)
{
nativePrograms.emplace_back(program->getImpl<CLProgramCL>().getNative());
}
const cl_uint numInputHeaders = static_cast<cl_uint>(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<CLDeviceCL>().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<cl_kernel> 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<cl::Program *>(userData)->callback();
}
} // namespace rx