Commit 82654e5d by John Plate Committed by Angle LUCI CQ

CL: Add program build commands

Add program build commands to front end and pass-through back end. Bug: angleproject:6015 Change-Id: I1175646d35ff050796b718d7f0e269520292b319 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2940839 Commit-Queue: John Plate <jplate@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent 5fd72bd3
......@@ -29,6 +29,8 @@ using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo,
size_t cb,
void *user_data);
using ProgramCB = void(CL_CALLBACK *)(cl_program program, void *user_data);
using EventCB = void(CL_CALLBACK *)(cl_event event, cl_int event_command_status, void *user_data);
template <typename T = void>
......
......@@ -258,16 +258,12 @@ cl_program Context::createProgramWithBinary(cl_uint numDevices,
cl_int &errorCode)
{
DevicePtrs devs;
Binaries bins;
devs.reserve(numDevices);
bins.reserve(numDevices);
while (numDevices-- != 0u)
{
devs.emplace_back(&(*devices++)->cast<Device>());
bins.emplace_back(*lengths++);
std::memcpy(bins.back().data(), *binaries++, bins.back().size());
}
return Object::Create<Program>(errorCode, *this, std::move(devs), std::move(bins),
return Object::Create<Program>(errorCode, *this, std::move(devs), lengths, binaries,
binaryStatus);
}
......@@ -285,6 +281,31 @@ cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices,
return Object::Create<Program>(errorCode, *this, std::move(devs), kernelNames);
}
cl_program Context::linkProgram(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
cl_uint numInputPrograms,
const cl_program *inputPrograms,
ProgramCB pfnNotify,
void *userData,
cl_int &errorCode)
{
DevicePtrs devices;
devices.reserve(numDevices);
while (numDevices-- != 0u)
{
devices.emplace_back(&(*deviceList++)->cast<Device>());
}
ProgramPtrs programs;
programs.reserve(numInputPrograms);
while (numInputPrograms-- != 0u)
{
programs.emplace_back(&(*inputPrograms++)->cast<Program>());
}
return Object::Create<Program>(errorCode, *this, devices, options, programs, pfnNotify,
userData);
}
cl_event Context::createUserEvent(cl_int &errorCode)
{
return Object::Create<Event>(errorCode, *this);
......
......@@ -89,6 +89,15 @@ class Context final : public _cl_context, public Object
const char *kernelNames,
cl_int &errorCode);
cl_program linkProgram(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
cl_uint numInputPrograms,
const cl_program *inputPrograms,
ProgramCB pfnNotify,
void *userData,
cl_int &errorCode);
cl_event createUserEvent(cl_int &errorCode);
cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
......
......@@ -205,16 +205,23 @@ cl_int Kernel::getArgInfo(cl_uint argIndex,
return CL_SUCCESS;
}
Kernel::~Kernel() = default;
Kernel::~Kernel()
{
--mProgram->mNumAttachedKernels;
}
Kernel::Kernel(Program &program, const char *name, cl_int &errorCode)
: mProgram(&program),
mImpl(program.getImpl().createKernel(*this, name, errorCode)),
mInfo(mImpl ? mImpl->createInfo(errorCode) : rx::CLKernelImpl::Info{})
{}
{
++mProgram->mNumAttachedKernels;
}
Kernel::Kernel(Program &program, const rx::CLKernelImpl::CreateFunc &createFunc, cl_int &errorCode)
: mProgram(&program), mImpl(createFunc(*this)), mInfo(mImpl->createInfo(errorCode))
{}
{
++mProgram->mNumAttachedKernels;
}
} // namespace cl
......@@ -252,6 +252,11 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti
userData, userSync);
}
cl_int Platform::unloadCompiler()
{
return mImpl->unloadCompiler();
}
Platform::~Platform() = default;
Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc)
......
......@@ -53,6 +53,8 @@ class Platform final : public _cl_platform_id, public Object
void *userData,
cl_int &errorCode);
cl_int unloadCompiler();
public:
~Platform() override;
......
......@@ -15,16 +15,66 @@
namespace cl
{
cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
cl_int Program::build(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
ProgramCB pfnNotify,
void *userData)
{
static_assert(std::is_same<cl_uint, cl_bool>::value &&
std::is_same<cl_uint, cl_addressing_mode>::value &&
std::is_same<cl_uint, cl_filter_mode>::value,
"OpenCL type mismatch");
DevicePtrs devices;
devices.reserve(numDevices);
while (numDevices-- != 0u)
{
devices.emplace_back(&(*deviceList++)->cast<Device>());
}
Program *notify = nullptr;
if (pfnNotify != nullptr)
{
// This program has to be retained until the notify callback is called.
retain();
mCallback = pfnNotify;
mUserData = userData;
notify = this;
}
return mImpl->build(devices, options, notify);
}
cl_int Program::compile(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
cl_uint numInputHeaders,
const cl_program *inputHeaders,
const char **headerIncludeNames,
ProgramCB pfnNotify,
void *userData)
{
DevicePtrs devices;
devices.reserve(numDevices);
while (numDevices-- != 0u)
{
devices.emplace_back(&(*deviceList++)->cast<Device>());
}
ProgramPtrs programs;
programs.reserve(numInputHeaders);
while (numInputHeaders-- != 0u)
{
programs.emplace_back(&(*inputHeaders++)->cast<Program>());
}
Program *notify = nullptr;
if (pfnNotify != nullptr)
{
// This program has to be retained until the notify callback is called.
retain();
mCallback = pfnNotify;
mUserData = userData;
notify = this;
}
return mImpl->compile(devices, options, programs, headerIncludeNames, notify);
}
cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const
{
std::vector<cl_device_id> devices;
std::vector<size_t> binarySizes;
std::vector<const unsigned char *> binaries;
cl_uint valUInt = 0u;
void *valPointer = nullptr;
const void *copyValue = nullptr;
......@@ -65,43 +115,12 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t
copySize = mIL.length() + 1u;
break;
case ProgramInfo::BinarySizes:
binarySizes.resize(mDevices.size(), 0u);
for (size_t index = 0u; index < binarySizes.size(); ++index)
{
binarySizes[index] = index < mBinaries.size() ? mBinaries[index].size() : 0u;
}
copyValue = binarySizes.data();
copySize = binarySizes.size() * sizeof(decltype(binarySizes)::value_type);
break;
case ProgramInfo::Binaries:
binaries.resize(mDevices.size(), nullptr);
for (size_t index = 0u; index < binaries.size(); ++index)
{
binaries[index] = index < mBinaries.size() && mBinaries[index].empty()
? mBinaries[index].data()
: nullptr;
}
copyValue = binaries.data();
copySize = binaries.size() * sizeof(decltype(binaries)::value_type);
break;
case ProgramInfo::NumKernels:
copyValue = &mNumKernels;
copySize = sizeof(mNumKernels);
break;
case ProgramInfo::KernelNames:
copyValue = mKernelNames.c_str();
copySize = mKernelNames.length() + 1u;
break;
case ProgramInfo::ScopeGlobalCtorsPresent:
valUInt = CL_FALSE;
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
case ProgramInfo::ScopeGlobalDtorsPresent:
valUInt = CL_FALSE;
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
return mImpl->getInfo(name, valueSize, value, valueSizeRet);
default:
return CL_INVALID_VALUE;
}
......@@ -126,6 +145,15 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t
return CL_SUCCESS;
}
cl_int Program::getBuildInfo(cl_device_id device,
ProgramBuildInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const
{
return mImpl->getBuildInfo(device->cast<Device>(), name, valueSize, value, valueSizeRet);
}
cl_kernel Program::createKernel(const char *kernel_name, cl_int &errorCode)
{
return Object::Create<Kernel>(errorCode, *this, kernel_name);
......@@ -162,11 +190,27 @@ cl_int Program::createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *n
Program::~Program() = default;
void Program::callback()
{
ASSERT(mCallback != nullptr);
const ProgramCB callback = mCallback;
void *const userData = mUserData;
mCallback = nullptr;
mUserData = nullptr;
callback(this, userData);
// This program can be released after the callback was called.
if (release())
{
delete this;
}
}
Program::Program(Context &context, std::string &&source, cl_int &errorCode)
: mContext(&context),
mDevices(context.getDevices()),
mImpl(context.getImpl().createProgramWithSource(*this, source, errorCode)),
mSource(std::move(source))
mSource(std::move(source)),
mNumAttachedKernels(0u)
{}
Program::Program(Context &context, const void *il, size_t length, cl_int &errorCode)
......@@ -174,26 +218,57 @@ Program::Program(Context &context, const void *il, size_t length, cl_int &errorC
mDevices(context.getDevices()),
mIL(static_cast<const char *>(il), length),
mImpl(context.getImpl().createProgramWithIL(*this, il, length, errorCode)),
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{})
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{}),
mNumAttachedKernels(0u)
{}
Program::Program(Context &context,
DevicePtrs &&devices,
Binaries &&binaries,
const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus,
cl_int &errorCode)
: mContext(&context),
mDevices(std::move(devices)),
mImpl(context.getImpl().createProgramWithBinary(*this, binaries, binaryStatus, errorCode)),
mImpl(context.getImpl()
.createProgramWithBinary(*this, lengths, binaries, binaryStatus, errorCode)),
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{}),
mBinaries(std::move(binaries))
mNumAttachedKernels(0u)
{}
Program::Program(Context &context, DevicePtrs &&devices, const char *kernelNames, cl_int &errorCode)
: mContext(&context),
mDevices(std::move(devices)),
mImpl(context.getImpl().createProgramWithBuiltInKernels(*this, kernelNames, errorCode)),
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{})
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{}),
mNumAttachedKernels(0u)
{}
Program::Program(Context &context,
const DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputPrograms,
ProgramCB pfnNotify,
void *userData,
cl_int &errorCode)
: mContext(&context),
mDevices(!devices.empty() ? devices : context.getDevices()),
mImpl(context.getImpl().linkProgram(*this,
devices,
options,
inputPrograms,
pfnNotify != nullptr ? this : nullptr,
errorCode)),
mSource(mImpl ? mImpl->getSource(errorCode) : std::string{}),
mCallback(pfnNotify),
mUserData(userData),
mNumAttachedKernels(0u)
{
if (mCallback != nullptr)
{
// This program has to be retained until the notify callback is called.
retain();
}
}
} // namespace cl
......@@ -8,9 +8,12 @@
#ifndef LIBANGLE_CLPROGRAM_H_
#define LIBANGLE_CLPROGRAM_H_
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLKernel.h"
#include "libANGLE/renderer/CLProgramImpl.h"
#include <atomic>
namespace cl
{
......@@ -19,8 +22,29 @@ class Program final : public _cl_program, public Object
public:
// Front end entry functions, only called from OpenCL entry points
cl_int build(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
ProgramCB pfnNotify,
void *userData);
cl_int compile(cl_uint numDevices,
const cl_device_id *deviceList,
const char *options,
cl_uint numInputHeaders,
const cl_program *inputHeaders,
const char **headerIncludeNames,
ProgramCB pfnNotify,
void *userData);
cl_int getInfo(ProgramInfo name, size_t valueSize, void *value, size_t *valueSizeRet) const;
cl_int getBuildInfo(cl_device_id device,
ProgramBuildInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const;
cl_kernel createKernel(const char *kernel_name, cl_int &errorCode);
cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
......@@ -31,32 +55,49 @@ class Program final : public _cl_program, public Object
Context &getContext();
const Context &getContext() const;
const DevicePtrs &getDevices() const;
bool hasDevice(const _cl_device_id *device) const;
bool isBuilding() const;
bool hasAttachedKernels() const;
template <typename T = rx::CLProgramImpl>
T &getImpl() const;
void callback();
private:
Program(Context &context, std::string &&source, cl_int &errorCode);
Program(Context &context, const void *il, size_t length, cl_int &errorCode);
Program(Context &context,
DevicePtrs &&devices,
Binaries &&binaries,
const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus,
cl_int &errorCode);
Program(Context &context, DevicePtrs &&devices, const char *kernelNames, cl_int &errorCode);
Program(Context &context,
const DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputPrograms,
ProgramCB pfnNotify,
void *userData,
cl_int &errorCode);
const ContextPtr mContext;
const DevicePtrs mDevices;
const std::string mIL;
const rx::CLProgramImpl::Ptr mImpl;
const std::string mSource;
Binaries mBinaries;
size_t mNumKernels;
std::string mKernelNames;
ProgramCB mCallback = nullptr;
void *mUserData = nullptr;
std::atomic<cl_uint> mNumAttachedKernels;
friend class Kernel;
friend class Object;
};
......@@ -75,6 +116,23 @@ inline const DevicePtrs &Program::getDevices() const
return mDevices;
}
inline bool Program::hasDevice(const _cl_device_id *device) const
{
return std::find_if(mDevices.cbegin(), mDevices.cend(), [=](const DevicePtr &ptr) {
return ptr.get() == device;
}) != mDevices.cend();
}
inline bool Program::isBuilding() const
{
return mCallback != nullptr;
}
inline bool Program::hasAttachedKernels() const
{
return mNumAttachedKernels != 0u;
}
template <typename T>
inline T &Program::getImpl() const
{
......
......@@ -54,9 +54,7 @@ using DevicePtrs = std::vector<DevicePtr>;
using EventPtrs = std::vector<EventPtr>;
using KernelPtrs = std::vector<KernelPtr>;
using PlatformPtrs = std::vector<PlatformPtr>;
using Binary = std::vector<unsigned char>;
using Binaries = std::vector<Binary>;
using ProgramPtrs = std::vector<ProgramPtr>;
struct ImageDescriptor
{
......
......@@ -53,7 +53,8 @@ class CLContextImpl : angle::NonCopyable
cl_int &errorCode) = 0;
virtual CLProgramImpl::Ptr createProgramWithBinary(const cl::Program &program,
const cl::Binaries &binaries,
const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus,
cl_int &errorCode) = 0;
......@@ -61,6 +62,13 @@ class CLContextImpl : angle::NonCopyable
const char *kernel_names,
cl_int &errorCode) = 0;
virtual CLProgramImpl::Ptr linkProgram(const cl::Program &program,
const cl::DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputPrograms,
cl::Program *notify,
cl_int &errorCode) = 0;
virtual CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) = 0;
virtual cl_int waitForEvents(const cl::EventPtrs &events) = 0;
......
......@@ -60,6 +60,8 @@ class CLPlatformImpl : angle::NonCopyable
bool userSync,
cl_int &errorCode) = 0;
virtual cl_int unloadCompiler() = 0;
protected:
const cl::Platform &mPlatform;
};
......
......@@ -23,6 +23,27 @@ class CLProgramImpl : angle::NonCopyable
virtual std::string getSource(cl_int &errorCode) const = 0;
virtual cl_int build(const cl::DevicePtrs &devices,
const char *options,
cl::Program *notify) = 0;
virtual cl_int compile(const cl::DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputHeaders,
const char **headerIncludeNames,
cl::Program *notify) = 0;
virtual cl_int getInfo(cl::ProgramInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const = 0;
virtual cl_int getBuildInfo(const cl::Device &device,
cl::ProgramBuildInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const = 0;
virtual CLKernelImpl::Ptr createKernel(const cl::Kernel &kernel,
const char *name,
cl_int &errorCode) = 0;
......
......@@ -232,26 +232,21 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithIL(const cl::Program &program,
}
CLProgramImpl::Ptr CLContextCL::createProgramWithBinary(const cl::Program &program,
const cl::Binaries &binaries,
const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus,
cl_int &errorCode)
{
ASSERT(program.getDevices().size() == binaries.size());
std::vector<cl_device_id> nativeDevices;
for (const cl::DevicePtr &device : program.getDevices())
{
nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
}
std::vector<size_t> lengths;
std::vector<const unsigned char *> nativeBinaries;
for (const cl::Binary &binary : binaries)
{
lengths.emplace_back(binary.size());
nativeBinaries.emplace_back(binary.data());
}
const cl_program nativeProgram = mNative->getDispatch().clCreateProgramWithBinary(
mNative, static_cast<cl_uint>(nativeDevices.size()), nativeDevices.data(), lengths.data(),
nativeBinaries.data(), binaryStatus, &errorCode);
cl_program nativeProgram = mNative->getDispatch().clCreateProgramWithBinary(
mNative, static_cast<cl_uint>(nativeDevices.size()), nativeDevices.data(), lengths,
binaries, binaryStatus, &errorCode);
return CLProgramImpl::Ptr(nativeProgram != nullptr ? new CLProgramCL(program, nativeProgram)
: nullptr);
}
......@@ -272,6 +267,37 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithBuiltInKernels(const cl::Progra
: nullptr);
}
CLProgramImpl::Ptr CLContextCL::linkProgram(const cl::Program &program,
const cl::DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputPrograms,
cl::Program *notify,
cl_int &errorCode)
{
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 : inputPrograms)
{
nativePrograms.emplace_back(program->getImpl<CLProgramCL>().getNative());
}
const cl_uint numInputHeaders = static_cast<cl_uint>(nativePrograms.size());
const cl::ProgramCB callback = notify != nullptr ? CLProgramCL::Callback : nullptr;
const cl_program nativeProgram = mNative->getDispatch().clLinkProgram(
mNative, numDevices, nativeDevicesPtr, options, numInputHeaders, nativePrograms.data(),
callback, notify, &errorCode);
return CLProgramImpl::Ptr(nativeProgram != nullptr ? new CLProgramCL(program, nativeProgram)
: nullptr);
}
CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &errorCode)
{
const cl_event nativeEvent = mNative->getDispatch().clCreateUserEvent(mNative, &errorCode);
......
......@@ -47,7 +47,8 @@ class CLContextCL : public CLContextImpl
cl_int &errorCode) override;
CLProgramImpl::Ptr createProgramWithBinary(const cl::Program &program,
const cl::Binaries &binaries,
const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus,
cl_int &errorCode) override;
......@@ -55,6 +56,13 @@ class CLContextCL : public CLContextImpl
const char *kernel_names,
cl_int &errorCode) override;
CLProgramImpl::Ptr linkProgram(const cl::Program &program,
const cl::DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputPrograms,
cl::Program *notify,
cl_int &errorCode) override;
CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) override;
cl_int waitForEvents(const cl::EventPtrs &events) override;
......
......@@ -18,7 +18,7 @@ class CLDeviceCL : public CLDeviceImpl
public:
~CLDeviceCL() override;
cl_device_id getNative();
cl_device_id getNative() const;
Info createInfo(cl::DeviceType type) const override;
......@@ -41,7 +41,7 @@ class CLDeviceCL : public CLDeviceImpl
friend class CLPlatformCL;
};
inline cl_device_id CLDeviceCL::getNative()
inline cl_device_id CLDeviceCL::getNative() const
{
return mNative;
}
......
......@@ -21,7 +21,7 @@ class CLEventCL : public CLEventImpl
CLEventCL(const cl::Event &event, cl_event native);
~CLEventCL() override;
cl_event getNative();
cl_event getNative() const;
cl_int getCommandExecutionStatus(cl_int &executionStatus) override;
......@@ -37,7 +37,7 @@ class CLEventCL : public CLEventImpl
const cl_event mNative;
};
inline cl_event CLEventCL::getNative()
inline cl_event CLEventCL::getNative() const
{
return mNative;
}
......
......@@ -21,7 +21,7 @@ class CLKernelCL : public CLKernelImpl
CLKernelCL(const cl::Kernel &kernel, cl_kernel native);
~CLKernelCL() override;
cl_kernel getNative();
cl_kernel getNative() const;
Info createInfo(cl_int &errorCode) const override;
......@@ -29,7 +29,7 @@ class CLKernelCL : public CLKernelImpl
const cl_kernel mNative;
};
inline cl_kernel CLKernelCL::getNative()
inline cl_kernel CLKernelCL::getNative() const
{
return mNative;
}
......
......@@ -19,7 +19,7 @@ class CLMemoryCL : public CLMemoryImpl
CLMemoryCL(const cl::Memory &memory, cl_mem native);
~CLMemoryCL() override;
cl_mem getNative();
cl_mem getNative() const;
size_t getSize(cl_int &errorCode) const override;
......@@ -31,7 +31,7 @@ class CLMemoryCL : public CLMemoryImpl
const cl_mem mNative;
};
inline cl_mem CLMemoryCL::getNative()
inline cl_mem CLMemoryCL::getNative() const
{
return mNative;
}
......
......@@ -401,6 +401,11 @@ CLContextImpl::Ptr CLPlatformCL::createContextFromType(cl::Context &context,
: nullptr);
}
cl_int CLPlatformCL::unloadCompiler()
{
return mNative->getDispatch().clUnloadPlatformCompiler(mNative);
}
void CLPlatformCL::Initialize(CreateFuncs &createFuncs, bool isIcd)
{
// Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to
......
......@@ -18,7 +18,7 @@ class CLPlatformCL : public CLPlatformImpl
public:
~CLPlatformCL() override;
cl_platform_id getNative();
cl_platform_id getNative() const;
Info createInfo() const override;
CLDeviceImpl::CreateDatas createDevices() const override;
......@@ -33,6 +33,8 @@ class CLPlatformCL : public CLPlatformImpl
bool userSync,
cl_int &errorCode) override;
cl_int unloadCompiler() override;
static void Initialize(CreateFuncs &createFuncs, bool isIcd);
private:
......@@ -43,7 +45,7 @@ class CLPlatformCL : public CLPlatformImpl
friend class CLContextCL;
};
inline cl_platform_id CLPlatformCL::getNative()
inline cl_platform_id CLPlatformCL::getNative() const
{
return mNative;
}
......
......@@ -7,8 +7,12 @@
#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
{
......@@ -45,6 +49,71 @@ std::string CLProgramCL::getSource(cl_int &errorCode) const
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)
......@@ -78,4 +147,9 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels,
return errorCode;
}
void CLProgramCL::Callback(cl_program program, void *userData)
{
static_cast<cl::Program *>(userData)->callback();
}
} // namespace rx
......@@ -21,8 +21,29 @@ class CLProgramCL : public CLProgramImpl
CLProgramCL(const cl::Program &program, cl_program native);
~CLProgramCL() override;
cl_program getNative() const;
std::string getSource(cl_int &errorCode) const override;
cl_int build(const cl::DevicePtrs &devices, const char *options, cl::Program *notify) override;
cl_int compile(const cl::DevicePtrs &devices,
const char *options,
const cl::ProgramPtrs &inputHeaders,
const char **headerIncludeNames,
cl::Program *notify) override;
cl_int getInfo(cl::ProgramInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const override;
cl_int getBuildInfo(const cl::Device &device,
cl::ProgramBuildInfo name,
size_t valueSize,
void *value,
size_t *valueSizeRet) const override;
CLKernelImpl::Ptr createKernel(const cl::Kernel &kernel,
const char *name,
cl_int &errorCode) override;
......@@ -32,9 +53,18 @@ class CLProgramCL : public CLProgramImpl
cl_uint *numKernelsRet) override;
private:
static void CL_CALLBACK Callback(cl_program program, void *userData);
const cl_program mNative;
friend class CLContextCL;
};
inline cl_program CLProgramCL::getNative() const
{
return mNative;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLPROGRAMCL_H_
......@@ -83,6 +83,11 @@ CLContextImpl::Ptr CLPlatformVk::createContextFromType(cl::Context &context,
return contextImpl;
}
cl_int CLPlatformVk::unloadCompiler()
{
return CL_SUCCESS;
}
void CLPlatformVk::Initialize(CreateFuncs &createFuncs)
{
createFuncs.emplace_back(
......
......@@ -31,6 +31,8 @@ class CLPlatformVk : public CLPlatformImpl
bool userSync,
cl_int &errorCode) override;
cl_int unloadCompiler() override;
static void Initialize(CreateFuncs &createFuncs);
static constexpr cl_version GetVersion();
......
......@@ -1155,6 +1155,49 @@ cl_int ValidateBuildProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const void *user_data)
{
// CL_INVALID_PROGRAM if program is not a valid program object.
if (!Program::IsValid(program))
{
return CL_INVALID_PROGRAM;
}
const Program &prog = program->cast<Program>();
// CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero,
// or if device_list is not NULL and num_devices is zero.
if ((device_list != nullptr) != (num_devices != 0u))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_DEVICE if any device in device_list
// is not in the list of devices associated with program.
while (num_devices-- != 0u)
{
if (!prog.hasDevice(*device_list++))
{
return CL_INVALID_DEVICE;
}
}
// CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
if (pfn_notify == nullptr && user_data != nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_OPERATION if the build of a program executable for any of the devices listed
// in device_list by a previous call to clBuildProgram for program has not completed.
if (prog.isBuilding())
{
return CL_INVALID_OPERATION;
}
// CL_INVALID_OPERATION if there are kernel objects attached to program.
if (prog.hasAttachedKernels())
{
return CL_INVALID_OPERATION;
}
return CL_SUCCESS;
}
......@@ -1164,14 +1207,15 @@ cl_int ValidateGetProgramInfo(cl_program program,
const void *param_value,
const size_t *param_value_size_ret)
{
// CL_INVALID_PROGRAM if program is a not a valid program object.
// CL_INVALID_PROGRAM if program is not a valid program object.
if (!Program::IsValid(program))
{
return CL_INVALID_PROGRAM;
}
const Program &prog = program->cast<Program>();
// CL_INVALID_VALUE if param_name is not valid.
const cl_version version = program->cast<Program>().getContext().getPlatform().getVersion();
const cl_version version = prog.getContext().getPlatform().getVersion();
switch (param_name)
{
case ProgramInfo::NumKernels:
......@@ -1202,6 +1246,36 @@ cl_int ValidateGetProgramBuildInfo(cl_program program,
const void *param_value,
const size_t *param_value_size_ret)
{
// CL_INVALID_PROGRAM if program is not a valid program object.
if (!Program::IsValid(program))
{
return CL_INVALID_PROGRAM;
}
const Program &prog = program->cast<Program>();
// CL_INVALID_DEVICE if device is not in the list of devices associated with program.
if (!prog.hasDevice(device))
{
return CL_INVALID_DEVICE;
}
// CL_INVALID_VALUE if param_name is not valid.
const cl_version version = prog.getContext().getPlatform().getVersion();
switch (param_name)
{
case ProgramBuildInfo::BinaryType:
ANGLE_VALIDATE_VERSION(version, 1, 2);
break;
case ProgramBuildInfo::GlobalVariableTotalSize:
ANGLE_VALIDATE_VERSION(version, 2, 0);
break;
case ProgramBuildInfo::InvalidEnum:
return CL_INVALID_VALUE;
default:
// All remaining possible values for param_name are valid for all versions.
break;
}
return CL_SUCCESS;
}
......@@ -2534,6 +2608,62 @@ cl_int ValidateCompileProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const void *user_data)
{
// CL_INVALID_PROGRAM if program is not a valid program object.
if (!Program::IsValid(program))
{
return CL_INVALID_PROGRAM;
}
const Program &prog = program->cast<Program>();
if (!prog.getContext().getPlatform().isVersionOrNewer(1u, 2u))
{
return CL_INVALID_PROGRAM;
}
// CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero,
// or if device_list is not NULL and num_devices is zero.
if ((device_list != nullptr) != (num_devices != 0u))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_DEVICE if any device in device_list
// is not in the list of devices associated with program.
while (num_devices-- != 0u)
{
if (!prog.hasDevice(*device_list++))
{
return CL_INVALID_DEVICE;
}
}
// CL_INVALID_VALUE if num_input_headers is zero and header_include_names
// or input_headers are not NULL
// or if num_input_headers is not zero and header_include_names or input_headers are NULL.
if ((num_input_headers != 0u) != (header_include_names != nullptr) ||
(num_input_headers != 0u) != (input_headers != nullptr))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
if (pfn_notify == nullptr && user_data != nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_OPERATION if the build of a program executable for any of the devices listed
// in device_list by a previous call to clBuildProgram for program has not completed.
if (prog.isBuilding())
{
return CL_INVALID_OPERATION;
}
// CL_INVALID_OPERATION if there are kernel objects attached to program.
if (prog.hasAttachedKernels())
{
return CL_INVALID_OPERATION;
}
return CL_SUCCESS;
}
......@@ -2546,11 +2676,61 @@ cl_int ValidateLinkProgram(cl_context context,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const void *user_data)
{
// CL_INVALID_CONTEXT if context is not a valid context.
if (!Context::IsValidAndVersionOrNewer(context, 1u, 2u))
{
return CL_INVALID_CONTEXT;
}
const Context &ctx = context->cast<Context>();
// CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero,
// or if device_list is not NULL and num_devices is zero.
if ((device_list != nullptr) != (num_devices != 0u))
{
return CL_INVALID_VALUE;
}
// CL_INVALID_DEVICE if any device in device_list
// is not in the list of devices associated with context.
while (num_devices-- != 0u)
{
if (!ctx.hasDevice(*device_list++))
{
return CL_INVALID_DEVICE;
}
}
// CL_INVALID_VALUE if num_input_programs is zero or input_programs is NULL.
if (num_input_programs == 0u || input_programs == nullptr)
{
return CL_INVALID_VALUE;
}
// CL_INVALID_PROGRAM if programs specified in input_programs are not valid program objects.
while (num_input_programs-- != 0u)
{
if (!Program::IsValid(*input_programs++))
{
return CL_INVALID_PROGRAM;
}
}
// CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
if (pfn_notify == nullptr && user_data != nullptr)
{
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
cl_int ValidateUnloadPlatformCompiler(cl_platform_id platform)
{
// CL_INVALID_PLATFORM if platform is not a valid platform.
if (!Platform::IsValid(platform) || !platform->cast<Platform>().isVersionOrNewer(1u, 2u))
{
return CL_INVALID_PLATFORM;
}
return CL_SUCCESS;
}
......
......@@ -454,8 +454,7 @@ cl_int BuildProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
void *user_data)
{
WARN_NOT_SUPPORTED(BuildProgram);
return 0;
return program->cast<Program>().build(num_devices, device_list, options, pfn_notify, user_data);
}
cl_int CompileProgram(cl_program program,
......@@ -468,8 +467,9 @@ cl_int CompileProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
void *user_data)
{
WARN_NOT_SUPPORTED(CompileProgram);
return 0;
return program->cast<Program>().compile(num_devices, device_list, options, num_input_headers,
input_headers, header_include_names, pfn_notify,
user_data);
}
cl_program LinkProgram(cl_context context,
......@@ -482,8 +482,9 @@ cl_program LinkProgram(cl_context context,
void *user_data,
cl_int &errorCode)
{
WARN_NOT_SUPPORTED(LinkProgram);
return 0;
return context->cast<Context>().linkProgram(num_devices, device_list, options,
num_input_programs, input_programs, pfn_notify,
user_data, errorCode);
}
cl_int SetProgramReleaseCallback(cl_program program,
......@@ -505,8 +506,7 @@ cl_int SetProgramSpecializationConstant(cl_program program,
cl_int UnloadPlatformCompiler(cl_platform_id platform)
{
WARN_NOT_SUPPORTED(UnloadPlatformCompiler);
return 0;
return platform->cast<Platform>().unloadCompiler();
}
cl_int GetProgramInfo(cl_program program,
......@@ -526,8 +526,8 @@ cl_int GetProgramBuildInfo(cl_program program,
void *param_value,
size_t *param_value_size_ret)
{
WARN_NOT_SUPPORTED(GetProgramBuildInfo);
return 0;
return program->cast<Program>().getBuildInfo(device, param_name, param_value_size, param_value,
param_value_size_ret);
}
cl_kernel CreateKernel(cl_program program, const char *kernel_name, cl_int &errorCode)
......@@ -1161,8 +1161,8 @@ cl_int EnqueueBarrier(cl_command_queue command_queue)
cl_int UnloadCompiler()
{
WARN_NOT_SUPPORTED(UnloadCompiler);
return 0;
Platform *const platform = Platform::GetDefault();
return platform != nullptr ? platform->unloadCompiler() : CL_SUCCESS;
}
void *GetExtensionFunctionAddress(const char *func_name)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment