| // |
| // 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. |
| // |
| // CLProgram.h: Defines the cl::Program class, which consists of a set of OpenCL kernels. |
| |
| #ifndef LIBANGLE_CLPROGRAM_H_ |
| #define LIBANGLE_CLPROGRAM_H_ |
| |
| #include "libANGLE/CLDevice.h" |
| #include "libANGLE/CLKernel.h" |
| #include "libANGLE/renderer/CLProgramImpl.h" |
| |
| #include "common/Spinlock.h" |
| #include "common/SynchronizedValue.h" |
| |
| #include <atomic> |
| |
| namespace cl |
| { |
| |
| 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); |
| |
| public: |
| ~Program() override; |
| |
| 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, |
| 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); |
| |
| using CallbackData = std::pair<ProgramCB, void *>; |
| |
| const ContextPtr mContext; |
| const DevicePtrs mDevices; |
| const std::string mIL; |
| |
| // mCallback might be accessed from implementation initialization |
| // and needs to be initialized first. |
| angle::SynchronizedValue<CallbackData, angle::Spinlock> mCallback; |
| std::atomic<cl_uint> mNumAttachedKernels; |
| |
| const rx::CLProgramImpl::Ptr mImpl; |
| const std::string mSource; |
| |
| friend class Kernel; |
| friend class Object; |
| }; |
| |
| inline Context &Program::getContext() |
| { |
| return *mContext; |
| } |
| |
| inline const Context &Program::getContext() const |
| { |
| return *mContext; |
| } |
| |
| inline const DevicePtrs &Program::getDevices() const |
| { |
| return mDevices; |
| } |
| |
| inline bool Program::hasDevice(const _cl_device_id *device) const |
| { |
| return std::find(mDevices.cbegin(), mDevices.cend(), device) != mDevices.cend(); |
| } |
| |
| inline bool Program::isBuilding() const |
| { |
| return mCallback->first != nullptr; |
| } |
| |
| inline bool Program::hasAttachedKernels() const |
| { |
| return mNumAttachedKernels != 0u; |
| } |
| |
| template <typename T> |
| inline T &Program::getImpl() const |
| { |
| return static_cast<T &>(*mImpl); |
| } |
| |
| } // namespace cl |
| |
| #endif // LIBANGLE_CLPROGRAM_H_ |