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, ...@@ -29,6 +29,8 @@ using ContextErrorCB = void(CL_CALLBACK *)(const char *errinfo,
size_t cb, size_t cb,
void *user_data); 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); using EventCB = void(CL_CALLBACK *)(cl_event event, cl_int event_command_status, void *user_data);
template <typename T = void> template <typename T = void>
......
...@@ -258,16 +258,12 @@ cl_program Context::createProgramWithBinary(cl_uint numDevices, ...@@ -258,16 +258,12 @@ cl_program Context::createProgramWithBinary(cl_uint numDevices,
cl_int &errorCode) cl_int &errorCode)
{ {
DevicePtrs devs; DevicePtrs devs;
Binaries bins;
devs.reserve(numDevices); devs.reserve(numDevices);
bins.reserve(numDevices);
while (numDevices-- != 0u) while (numDevices-- != 0u)
{ {
devs.emplace_back(&(*devices++)->cast<Device>()); 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); binaryStatus);
} }
...@@ -285,6 +281,31 @@ cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices, ...@@ -285,6 +281,31 @@ cl_program Context::createProgramWithBuiltInKernels(cl_uint numDevices,
return Object::Create<Program>(errorCode, *this, std::move(devs), kernelNames); 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) cl_event Context::createUserEvent(cl_int &errorCode)
{ {
return Object::Create<Event>(errorCode, *this); return Object::Create<Event>(errorCode, *this);
......
...@@ -89,6 +89,15 @@ class Context final : public _cl_context, public Object ...@@ -89,6 +89,15 @@ class Context final : public _cl_context, public Object
const char *kernelNames, const char *kernelNames,
cl_int &errorCode); 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_event createUserEvent(cl_int &errorCode);
cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList); cl_int waitForEvents(cl_uint numEvents, const cl_event *eventList);
......
...@@ -205,16 +205,23 @@ cl_int Kernel::getArgInfo(cl_uint argIndex, ...@@ -205,16 +205,23 @@ cl_int Kernel::getArgInfo(cl_uint argIndex,
return CL_SUCCESS; return CL_SUCCESS;
} }
Kernel::~Kernel() = default; Kernel::~Kernel()
{
--mProgram->mNumAttachedKernels;
}
Kernel::Kernel(Program &program, const char *name, cl_int &errorCode) Kernel::Kernel(Program &program, const char *name, cl_int &errorCode)
: mProgram(&program), : mProgram(&program),
mImpl(program.getImpl().createKernel(*this, name, errorCode)), mImpl(program.getImpl().createKernel(*this, name, errorCode)),
mInfo(mImpl ? mImpl->createInfo(errorCode) : rx::CLKernelImpl::Info{}) mInfo(mImpl ? mImpl->createInfo(errorCode) : rx::CLKernelImpl::Info{})
{} {
++mProgram->mNumAttachedKernels;
}
Kernel::Kernel(Program &program, const rx::CLKernelImpl::CreateFunc &createFunc, cl_int &errorCode) Kernel::Kernel(Program &program, const rx::CLKernelImpl::CreateFunc &createFunc, cl_int &errorCode)
: mProgram(&program), mImpl(createFunc(*this)), mInfo(mImpl->createInfo(errorCode)) : mProgram(&program), mImpl(createFunc(*this)), mInfo(mImpl->createInfo(errorCode))
{} {
++mProgram->mNumAttachedKernels;
}
} // namespace cl } // namespace cl
...@@ -252,6 +252,11 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti ...@@ -252,6 +252,11 @@ cl_context Platform::CreateContextFromType(const cl_context_properties *properti
userData, userSync); userData, userSync);
} }
cl_int Platform::unloadCompiler()
{
return mImpl->unloadCompiler();
}
Platform::~Platform() = default; Platform::~Platform() = default;
Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc) Platform::Platform(const rx::CLPlatformImpl::CreateFunc &createFunc)
......
...@@ -53,6 +53,8 @@ class Platform final : public _cl_platform_id, public Object ...@@ -53,6 +53,8 @@ class Platform final : public _cl_platform_id, public Object
void *userData, void *userData,
cl_int &errorCode); cl_int &errorCode);
cl_int unloadCompiler();
public: public:
~Platform() override; ~Platform() override;
......
...@@ -15,16 +15,66 @@ ...@@ -15,16 +15,66 @@
namespace cl 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 && DevicePtrs devices;
std::is_same<cl_uint, cl_addressing_mode>::value && devices.reserve(numDevices);
std::is_same<cl_uint, cl_filter_mode>::value, while (numDevices-- != 0u)
"OpenCL type mismatch"); {
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<cl_device_id> devices;
std::vector<size_t> binarySizes;
std::vector<const unsigned char *> binaries;
cl_uint valUInt = 0u; cl_uint valUInt = 0u;
void *valPointer = nullptr; void *valPointer = nullptr;
const void *copyValue = nullptr; const void *copyValue = nullptr;
...@@ -65,43 +115,12 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t ...@@ -65,43 +115,12 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t
copySize = mIL.length() + 1u; copySize = mIL.length() + 1u;
break; break;
case ProgramInfo::BinarySizes: 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: 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: case ProgramInfo::NumKernels:
copyValue = &mNumKernels;
copySize = sizeof(mNumKernels);
break;
case ProgramInfo::KernelNames: case ProgramInfo::KernelNames:
copyValue = mKernelNames.c_str();
copySize = mKernelNames.length() + 1u;
break;
case ProgramInfo::ScopeGlobalCtorsPresent: case ProgramInfo::ScopeGlobalCtorsPresent:
valUInt = CL_FALSE;
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
case ProgramInfo::ScopeGlobalDtorsPresent: case ProgramInfo::ScopeGlobalDtorsPresent:
valUInt = CL_FALSE; return mImpl->getInfo(name, valueSize, value, valueSizeRet);
copyValue = &valUInt;
copySize = sizeof(valUInt);
break;
default: default:
return CL_INVALID_VALUE; return CL_INVALID_VALUE;
} }
...@@ -126,6 +145,15 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t ...@@ -126,6 +145,15 @@ cl_int Program::getInfo(ProgramInfo name, size_t valueSize, void *value, size_t
return CL_SUCCESS; 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) cl_kernel Program::createKernel(const char *kernel_name, cl_int &errorCode)
{ {
return Object::Create<Kernel>(errorCode, *this, kernel_name); 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 ...@@ -162,11 +190,27 @@ cl_int Program::createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *n
Program::~Program() = default; 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) Program::Program(Context &context, std::string &&source, cl_int &errorCode)
: mContext(&context), : mContext(&context),
mDevices(context.getDevices()), mDevices(context.getDevices()),
mImpl(context.getImpl().createProgramWithSource(*this, source, errorCode)), 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) 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 ...@@ -174,26 +218,57 @@ Program::Program(Context &context, const void *il, size_t length, cl_int &errorC
mDevices(context.getDevices()), mDevices(context.getDevices()),
mIL(static_cast<const char *>(il), length), mIL(static_cast<const char *>(il), length),
mImpl(context.getImpl().createProgramWithIL(*this, il, length, errorCode)), 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, Program::Program(Context &context,
DevicePtrs &&devices, DevicePtrs &&devices,
Binaries &&binaries, const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus, cl_int *binaryStatus,
cl_int &errorCode) cl_int &errorCode)
: mContext(&context), : mContext(&context),
mDevices(std::move(devices)), 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{}), 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) Program::Program(Context &context, DevicePtrs &&devices, const char *kernelNames, cl_int &errorCode)
: mContext(&context), : mContext(&context),
mDevices(std::move(devices)), mDevices(std::move(devices)),
mImpl(context.getImpl().createProgramWithBuiltInKernels(*this, kernelNames, errorCode)), 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 } // namespace cl
...@@ -8,9 +8,12 @@ ...@@ -8,9 +8,12 @@
#ifndef LIBANGLE_CLPROGRAM_H_ #ifndef LIBANGLE_CLPROGRAM_H_
#define LIBANGLE_CLPROGRAM_H_ #define LIBANGLE_CLPROGRAM_H_
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLKernel.h" #include "libANGLE/CLKernel.h"
#include "libANGLE/renderer/CLProgramImpl.h" #include "libANGLE/renderer/CLProgramImpl.h"
#include <atomic>
namespace cl namespace cl
{ {
...@@ -19,8 +22,29 @@ class Program final : public _cl_program, public Object ...@@ -19,8 +22,29 @@ class Program final : public _cl_program, public Object
public: public:
// Front end entry functions, only called from OpenCL entry points // 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 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_kernel createKernel(const char *kernel_name, cl_int &errorCode);
cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet); cl_int createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet);
...@@ -31,32 +55,49 @@ class Program final : public _cl_program, public Object ...@@ -31,32 +55,49 @@ class Program final : public _cl_program, public Object
Context &getContext(); Context &getContext();
const Context &getContext() const; const Context &getContext() const;
const DevicePtrs &getDevices() const; const DevicePtrs &getDevices() const;
bool hasDevice(const _cl_device_id *device) const;
bool isBuilding() const;
bool hasAttachedKernels() const;
template <typename T = rx::CLProgramImpl> template <typename T = rx::CLProgramImpl>
T &getImpl() const; T &getImpl() const;
void callback();
private: private:
Program(Context &context, std::string &&source, cl_int &errorCode); Program(Context &context, std::string &&source, cl_int &errorCode);
Program(Context &context, const void *il, size_t length, cl_int &errorCode); Program(Context &context, const void *il, size_t length, cl_int &errorCode);
Program(Context &context, Program(Context &context,
DevicePtrs &&devices, DevicePtrs &&devices,
Binaries &&binaries, const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus, cl_int *binaryStatus,
cl_int &errorCode); cl_int &errorCode);
Program(Context &context, DevicePtrs &&devices, const char *kernelNames, 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 ContextPtr mContext;
const DevicePtrs mDevices; const DevicePtrs mDevices;
const std::string mIL; const std::string mIL;
const rx::CLProgramImpl::Ptr mImpl; const rx::CLProgramImpl::Ptr mImpl;
const std::string mSource; const std::string mSource;
Binaries mBinaries; ProgramCB mCallback = nullptr;
size_t mNumKernels; void *mUserData = nullptr;
std::string mKernelNames;
std::atomic<cl_uint> mNumAttachedKernels;
friend class Kernel;
friend class Object; friend class Object;
}; };
...@@ -75,6 +116,23 @@ inline const DevicePtrs &Program::getDevices() const ...@@ -75,6 +116,23 @@ inline const DevicePtrs &Program::getDevices() const
return mDevices; 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> template <typename T>
inline T &Program::getImpl() const inline T &Program::getImpl() const
{ {
......
...@@ -54,9 +54,7 @@ using DevicePtrs = std::vector<DevicePtr>; ...@@ -54,9 +54,7 @@ using DevicePtrs = std::vector<DevicePtr>;
using EventPtrs = std::vector<EventPtr>; using EventPtrs = std::vector<EventPtr>;
using KernelPtrs = std::vector<KernelPtr>; using KernelPtrs = std::vector<KernelPtr>;
using PlatformPtrs = std::vector<PlatformPtr>; using PlatformPtrs = std::vector<PlatformPtr>;
using ProgramPtrs = std::vector<ProgramPtr>;
using Binary = std::vector<unsigned char>;
using Binaries = std::vector<Binary>;
struct ImageDescriptor struct ImageDescriptor
{ {
......
...@@ -53,7 +53,8 @@ class CLContextImpl : angle::NonCopyable ...@@ -53,7 +53,8 @@ class CLContextImpl : angle::NonCopyable
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
virtual CLProgramImpl::Ptr createProgramWithBinary(const cl::Program &program, 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 *binaryStatus,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
...@@ -61,6 +62,13 @@ class CLContextImpl : angle::NonCopyable ...@@ -61,6 +62,13 @@ class CLContextImpl : angle::NonCopyable
const char *kernel_names, const char *kernel_names,
cl_int &errorCode) = 0; 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 CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) = 0;
virtual cl_int waitForEvents(const cl::EventPtrs &events) = 0; virtual cl_int waitForEvents(const cl::EventPtrs &events) = 0;
......
...@@ -60,6 +60,8 @@ class CLPlatformImpl : angle::NonCopyable ...@@ -60,6 +60,8 @@ class CLPlatformImpl : angle::NonCopyable
bool userSync, bool userSync,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
virtual cl_int unloadCompiler() = 0;
protected: protected:
const cl::Platform &mPlatform; const cl::Platform &mPlatform;
}; };
......
...@@ -23,6 +23,27 @@ class CLProgramImpl : angle::NonCopyable ...@@ -23,6 +23,27 @@ class CLProgramImpl : angle::NonCopyable
virtual std::string getSource(cl_int &errorCode) const = 0; 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, virtual CLKernelImpl::Ptr createKernel(const cl::Kernel &kernel,
const char *name, const char *name,
cl_int &errorCode) = 0; cl_int &errorCode) = 0;
......
...@@ -232,26 +232,21 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithIL(const cl::Program &program, ...@@ -232,26 +232,21 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithIL(const cl::Program &program,
} }
CLProgramImpl::Ptr CLContextCL::createProgramWithBinary(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 *binaryStatus,
cl_int &errorCode) cl_int &errorCode)
{ {
ASSERT(program.getDevices().size() == binaries.size());
std::vector<cl_device_id> nativeDevices; std::vector<cl_device_id> nativeDevices;
for (const cl::DevicePtr &device : program.getDevices()) for (const cl::DevicePtr &device : program.getDevices())
{ {
nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative()); nativeDevices.emplace_back(device->getImpl<CLDeviceCL>().getNative());
} }
std::vector<size_t> lengths;
std::vector<const unsigned char *> nativeBinaries; cl_program nativeProgram = mNative->getDispatch().clCreateProgramWithBinary(
for (const cl::Binary &binary : binaries) mNative, static_cast<cl_uint>(nativeDevices.size()), nativeDevices.data(), lengths,
{ binaries, binaryStatus, &errorCode);
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);
return CLProgramImpl::Ptr(nativeProgram != nullptr ? new CLProgramCL(program, nativeProgram) return CLProgramImpl::Ptr(nativeProgram != nullptr ? new CLProgramCL(program, nativeProgram)
: nullptr); : nullptr);
} }
...@@ -272,6 +267,37 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithBuiltInKernels(const cl::Progra ...@@ -272,6 +267,37 @@ CLProgramImpl::Ptr CLContextCL::createProgramWithBuiltInKernels(const cl::Progra
: nullptr); : 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) CLEventImpl::Ptr CLContextCL::createUserEvent(const cl::Event &event, cl_int &errorCode)
{ {
const cl_event nativeEvent = mNative->getDispatch().clCreateUserEvent(mNative, &errorCode); const cl_event nativeEvent = mNative->getDispatch().clCreateUserEvent(mNative, &errorCode);
......
...@@ -47,7 +47,8 @@ class CLContextCL : public CLContextImpl ...@@ -47,7 +47,8 @@ class CLContextCL : public CLContextImpl
cl_int &errorCode) override; cl_int &errorCode) override;
CLProgramImpl::Ptr createProgramWithBinary(const cl::Program &program, CLProgramImpl::Ptr createProgramWithBinary(const cl::Program &program,
const cl::Binaries &binaries, const size_t *lengths,
const unsigned char **binaries,
cl_int *binaryStatus, cl_int *binaryStatus,
cl_int &errorCode) override; cl_int &errorCode) override;
...@@ -55,6 +56,13 @@ class CLContextCL : public CLContextImpl ...@@ -55,6 +56,13 @@ class CLContextCL : public CLContextImpl
const char *kernel_names, const char *kernel_names,
cl_int &errorCode) override; 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; CLEventImpl::Ptr createUserEvent(const cl::Event &event, cl_int &errorCode) override;
cl_int waitForEvents(const cl::EventPtrs &events) override; cl_int waitForEvents(const cl::EventPtrs &events) override;
......
...@@ -18,7 +18,7 @@ class CLDeviceCL : public CLDeviceImpl ...@@ -18,7 +18,7 @@ class CLDeviceCL : public CLDeviceImpl
public: public:
~CLDeviceCL() override; ~CLDeviceCL() override;
cl_device_id getNative(); cl_device_id getNative() const;
Info createInfo(cl::DeviceType type) const override; Info createInfo(cl::DeviceType type) const override;
...@@ -41,7 +41,7 @@ class CLDeviceCL : public CLDeviceImpl ...@@ -41,7 +41,7 @@ class CLDeviceCL : public CLDeviceImpl
friend class CLPlatformCL; friend class CLPlatformCL;
}; };
inline cl_device_id CLDeviceCL::getNative() inline cl_device_id CLDeviceCL::getNative() const
{ {
return mNative; return mNative;
} }
......
...@@ -21,7 +21,7 @@ class CLEventCL : public CLEventImpl ...@@ -21,7 +21,7 @@ class CLEventCL : public CLEventImpl
CLEventCL(const cl::Event &event, cl_event native); CLEventCL(const cl::Event &event, cl_event native);
~CLEventCL() override; ~CLEventCL() override;
cl_event getNative(); cl_event getNative() const;
cl_int getCommandExecutionStatus(cl_int &executionStatus) override; cl_int getCommandExecutionStatus(cl_int &executionStatus) override;
...@@ -37,7 +37,7 @@ class CLEventCL : public CLEventImpl ...@@ -37,7 +37,7 @@ class CLEventCL : public CLEventImpl
const cl_event mNative; const cl_event mNative;
}; };
inline cl_event CLEventCL::getNative() inline cl_event CLEventCL::getNative() const
{ {
return mNative; return mNative;
} }
......
...@@ -21,7 +21,7 @@ class CLKernelCL : public CLKernelImpl ...@@ -21,7 +21,7 @@ class CLKernelCL : public CLKernelImpl
CLKernelCL(const cl::Kernel &kernel, cl_kernel native); CLKernelCL(const cl::Kernel &kernel, cl_kernel native);
~CLKernelCL() override; ~CLKernelCL() override;
cl_kernel getNative(); cl_kernel getNative() const;
Info createInfo(cl_int &errorCode) const override; Info createInfo(cl_int &errorCode) const override;
...@@ -29,7 +29,7 @@ class CLKernelCL : public CLKernelImpl ...@@ -29,7 +29,7 @@ class CLKernelCL : public CLKernelImpl
const cl_kernel mNative; const cl_kernel mNative;
}; };
inline cl_kernel CLKernelCL::getNative() inline cl_kernel CLKernelCL::getNative() const
{ {
return mNative; return mNative;
} }
......
...@@ -19,7 +19,7 @@ class CLMemoryCL : public CLMemoryImpl ...@@ -19,7 +19,7 @@ class CLMemoryCL : public CLMemoryImpl
CLMemoryCL(const cl::Memory &memory, cl_mem native); CLMemoryCL(const cl::Memory &memory, cl_mem native);
~CLMemoryCL() override; ~CLMemoryCL() override;
cl_mem getNative(); cl_mem getNative() const;
size_t getSize(cl_int &errorCode) const override; size_t getSize(cl_int &errorCode) const override;
...@@ -31,7 +31,7 @@ class CLMemoryCL : public CLMemoryImpl ...@@ -31,7 +31,7 @@ class CLMemoryCL : public CLMemoryImpl
const cl_mem mNative; const cl_mem mNative;
}; };
inline cl_mem CLMemoryCL::getNative() inline cl_mem CLMemoryCL::getNative() const
{ {
return mNative; return mNative;
} }
......
...@@ -401,6 +401,11 @@ CLContextImpl::Ptr CLPlatformCL::createContextFromType(cl::Context &context, ...@@ -401,6 +401,11 @@ CLContextImpl::Ptr CLPlatformCL::createContextFromType(cl::Context &context,
: nullptr); : nullptr);
} }
cl_int CLPlatformCL::unloadCompiler()
{
return mNative->getDispatch().clUnloadPlatformCompiler(mNative);
}
void CLPlatformCL::Initialize(CreateFuncs &createFuncs, bool isIcd) void CLPlatformCL::Initialize(CreateFuncs &createFuncs, bool isIcd)
{ {
// Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to // Using khrIcdInitialize() of the third party Khronos OpenCL ICD Loader to
......
...@@ -18,7 +18,7 @@ class CLPlatformCL : public CLPlatformImpl ...@@ -18,7 +18,7 @@ class CLPlatformCL : public CLPlatformImpl
public: public:
~CLPlatformCL() override; ~CLPlatformCL() override;
cl_platform_id getNative(); cl_platform_id getNative() const;
Info createInfo() const override; Info createInfo() const override;
CLDeviceImpl::CreateDatas createDevices() const override; CLDeviceImpl::CreateDatas createDevices() const override;
...@@ -33,6 +33,8 @@ class CLPlatformCL : public CLPlatformImpl ...@@ -33,6 +33,8 @@ class CLPlatformCL : public CLPlatformImpl
bool userSync, bool userSync,
cl_int &errorCode) override; cl_int &errorCode) override;
cl_int unloadCompiler() override;
static void Initialize(CreateFuncs &createFuncs, bool isIcd); static void Initialize(CreateFuncs &createFuncs, bool isIcd);
private: private:
...@@ -43,7 +45,7 @@ class CLPlatformCL : public CLPlatformImpl ...@@ -43,7 +45,7 @@ class CLPlatformCL : public CLPlatformImpl
friend class CLContextCL; friend class CLContextCL;
}; };
inline cl_platform_id CLPlatformCL::getNative() inline cl_platform_id CLPlatformCL::getNative() const
{ {
return mNative; return mNative;
} }
......
...@@ -7,8 +7,12 @@ ...@@ -7,8 +7,12 @@
#include "libANGLE/renderer/cl/CLProgramCL.h" #include "libANGLE/renderer/cl/CLProgramCL.h"
#include "libANGLE/renderer/cl/CLDeviceCL.h"
#include "libANGLE/renderer/cl/CLKernelCL.h" #include "libANGLE/renderer/cl/CLKernelCL.h"
#include "libANGLE/CLDevice.h"
#include "libANGLE/CLProgram.h"
namespace rx namespace rx
{ {
...@@ -45,6 +49,71 @@ std::string CLProgramCL::getSource(cl_int &errorCode) const ...@@ -45,6 +49,71 @@ std::string CLProgramCL::getSource(cl_int &errorCode) const
return std::string{}; 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, CLKernelImpl::Ptr CLProgramCL::createKernel(const cl::Kernel &kernel,
const char *name, const char *name,
cl_int &errorCode) cl_int &errorCode)
...@@ -78,4 +147,9 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels, ...@@ -78,4 +147,9 @@ cl_int CLProgramCL::createKernels(cl_uint numKernels,
return errorCode; return errorCode;
} }
void CLProgramCL::Callback(cl_program program, void *userData)
{
static_cast<cl::Program *>(userData)->callback();
}
} // namespace rx } // namespace rx
...@@ -21,8 +21,29 @@ class CLProgramCL : public CLProgramImpl ...@@ -21,8 +21,29 @@ class CLProgramCL : public CLProgramImpl
CLProgramCL(const cl::Program &program, cl_program native); CLProgramCL(const cl::Program &program, cl_program native);
~CLProgramCL() override; ~CLProgramCL() override;
cl_program getNative() const;
std::string getSource(cl_int &errorCode) const override; 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, CLKernelImpl::Ptr createKernel(const cl::Kernel &kernel,
const char *name, const char *name,
cl_int &errorCode) override; cl_int &errorCode) override;
...@@ -32,9 +53,18 @@ class CLProgramCL : public CLProgramImpl ...@@ -32,9 +53,18 @@ class CLProgramCL : public CLProgramImpl
cl_uint *numKernelsRet) override; cl_uint *numKernelsRet) override;
private: private:
static void CL_CALLBACK Callback(cl_program program, void *userData);
const cl_program mNative; const cl_program mNative;
friend class CLContextCL;
}; };
inline cl_program CLProgramCL::getNative() const
{
return mNative;
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_CL_CLPROGRAMCL_H_ #endif // LIBANGLE_RENDERER_CL_CLPROGRAMCL_H_
...@@ -83,6 +83,11 @@ CLContextImpl::Ptr CLPlatformVk::createContextFromType(cl::Context &context, ...@@ -83,6 +83,11 @@ CLContextImpl::Ptr CLPlatformVk::createContextFromType(cl::Context &context,
return contextImpl; return contextImpl;
} }
cl_int CLPlatformVk::unloadCompiler()
{
return CL_SUCCESS;
}
void CLPlatformVk::Initialize(CreateFuncs &createFuncs) void CLPlatformVk::Initialize(CreateFuncs &createFuncs)
{ {
createFuncs.emplace_back( createFuncs.emplace_back(
......
...@@ -31,6 +31,8 @@ class CLPlatformVk : public CLPlatformImpl ...@@ -31,6 +31,8 @@ class CLPlatformVk : public CLPlatformImpl
bool userSync, bool userSync,
cl_int &errorCode) override; cl_int &errorCode) override;
cl_int unloadCompiler() override;
static void Initialize(CreateFuncs &createFuncs); static void Initialize(CreateFuncs &createFuncs);
static constexpr cl_version GetVersion(); static constexpr cl_version GetVersion();
......
...@@ -1155,6 +1155,49 @@ cl_int ValidateBuildProgram(cl_program program, ...@@ -1155,6 +1155,49 @@ cl_int ValidateBuildProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const 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; return CL_SUCCESS;
} }
...@@ -1164,14 +1207,15 @@ cl_int ValidateGetProgramInfo(cl_program program, ...@@ -1164,14 +1207,15 @@ cl_int ValidateGetProgramInfo(cl_program program,
const void *param_value, const void *param_value,
const size_t *param_value_size_ret) 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)) if (!Program::IsValid(program))
{ {
return CL_INVALID_PROGRAM; return CL_INVALID_PROGRAM;
} }
const Program &prog = program->cast<Program>();
// CL_INVALID_VALUE if param_name is not valid. // 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) switch (param_name)
{ {
case ProgramInfo::NumKernels: case ProgramInfo::NumKernels:
...@@ -1202,6 +1246,36 @@ cl_int ValidateGetProgramBuildInfo(cl_program program, ...@@ -1202,6 +1246,36 @@ cl_int ValidateGetProgramBuildInfo(cl_program program,
const void *param_value, const void *param_value,
const size_t *param_value_size_ret) 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; return CL_SUCCESS;
} }
...@@ -2534,6 +2608,62 @@ cl_int ValidateCompileProgram(cl_program program, ...@@ -2534,6 +2608,62 @@ cl_int ValidateCompileProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const 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; return CL_SUCCESS;
} }
...@@ -2546,11 +2676,61 @@ cl_int ValidateLinkProgram(cl_context context, ...@@ -2546,11 +2676,61 @@ cl_int ValidateLinkProgram(cl_context context,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
const 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; return CL_SUCCESS;
} }
cl_int ValidateUnloadPlatformCompiler(cl_platform_id platform) 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; return CL_SUCCESS;
} }
......
...@@ -454,8 +454,7 @@ cl_int BuildProgram(cl_program program, ...@@ -454,8 +454,7 @@ cl_int BuildProgram(cl_program program,
void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
void *user_data) void *user_data)
{ {
WARN_NOT_SUPPORTED(BuildProgram); return program->cast<Program>().build(num_devices, device_list, options, pfn_notify, user_data);
return 0;
} }
cl_int CompileProgram(cl_program program, cl_int CompileProgram(cl_program program,
...@@ -468,8 +467,9 @@ 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(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
void *user_data) void *user_data)
{ {
WARN_NOT_SUPPORTED(CompileProgram); return program->cast<Program>().compile(num_devices, device_list, options, num_input_headers,
return 0; input_headers, header_include_names, pfn_notify,
user_data);
} }
cl_program LinkProgram(cl_context context, cl_program LinkProgram(cl_context context,
...@@ -482,8 +482,9 @@ cl_program LinkProgram(cl_context context, ...@@ -482,8 +482,9 @@ cl_program LinkProgram(cl_context context,
void *user_data, void *user_data,
cl_int &errorCode) cl_int &errorCode)
{ {
WARN_NOT_SUPPORTED(LinkProgram); return context->cast<Context>().linkProgram(num_devices, device_list, options,
return 0; num_input_programs, input_programs, pfn_notify,
user_data, errorCode);
} }
cl_int SetProgramReleaseCallback(cl_program program, cl_int SetProgramReleaseCallback(cl_program program,
...@@ -505,8 +506,7 @@ cl_int SetProgramSpecializationConstant(cl_program program, ...@@ -505,8 +506,7 @@ cl_int SetProgramSpecializationConstant(cl_program program,
cl_int UnloadPlatformCompiler(cl_platform_id platform) cl_int UnloadPlatformCompiler(cl_platform_id platform)
{ {
WARN_NOT_SUPPORTED(UnloadPlatformCompiler); return platform->cast<Platform>().unloadCompiler();
return 0;
} }
cl_int GetProgramInfo(cl_program program, cl_int GetProgramInfo(cl_program program,
...@@ -526,8 +526,8 @@ cl_int GetProgramBuildInfo(cl_program program, ...@@ -526,8 +526,8 @@ cl_int GetProgramBuildInfo(cl_program program,
void *param_value, void *param_value,
size_t *param_value_size_ret) size_t *param_value_size_ret)
{ {
WARN_NOT_SUPPORTED(GetProgramBuildInfo); return program->cast<Program>().getBuildInfo(device, param_name, param_value_size, param_value,
return 0; param_value_size_ret);
} }
cl_kernel CreateKernel(cl_program program, const char *kernel_name, cl_int &errorCode) 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) ...@@ -1161,8 +1161,8 @@ cl_int EnqueueBarrier(cl_command_queue command_queue)
cl_int UnloadCompiler() cl_int UnloadCompiler()
{ {
WARN_NOT_SUPPORTED(UnloadCompiler); Platform *const platform = Platform::GetDefault();
return 0; return platform != nullptr ? platform->unloadCompiler() : CL_SUCCESS;
} }
void *GetExtensionFunctionAddress(const char *func_name) 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