// // Copyright (c) 2008 Advanced Micro Devices, Inc. All rights reserved. // #ifndef CONTEXT_HPP_ #define CONTEXT_HPP_ #include "top.hpp" #include "device/device.hpp" #include "platform/object.hpp" #include "platform/agent.hpp" #include #include namespace amd { /*! \addtogroup Runtime * @{ * * \addtogroup Contexts * @{ */ class GLFunctions; class DeviceQueue; class Context : public RuntimeObject { std::vector devices_; public: enum DeviceFlagIdx { GLDeviceKhrIdx = 0, //!< GL D3D10DeviceKhrIdx, //!< D3D10 OfflineDevicesIdx, //!< Offline devices CommandInterceptIdx, //!< Command intercept D3D11DeviceKhrIdx, //!< D3D11 InteropUserSyncIdx, //!< Interop user sync enabled D3D9DeviceKhrIdx, //!< d3d9 device D3D9DeviceEXKhrIdx, //!< d3d9EX device D3D9DeviceVAKhrIdx, //!< d3d9VA device EGLDeviceKhrIdx, //!< EGL device LastDeviceFlagIdx }; enum Flags { GLDeviceKhr = 1 << GLDeviceKhrIdx, //!< GL D3D10DeviceKhr = 1 << D3D10DeviceKhrIdx, //!< D3D10 OfflineDevices = 1 << OfflineDevicesIdx, //!< Offline devices CommandIntercept = 1 << CommandInterceptIdx, //!< Command intercept D3D11DeviceKhr = 1 << D3D11DeviceKhrIdx, //!< D3D11 InteropUserSync = 1 << InteropUserSyncIdx, //!< Interop user sync enabled D3D9DeviceKhr = 1 << D3D9DeviceKhrIdx, //!< d3d9 device D3D9DeviceEXKhr = 1 << D3D9DeviceEXKhrIdx, //!< d3d9EX device D3D9DeviceVAKhr = 1 << D3D9DeviceVAKhrIdx, //!< d3d9VA device EGLDeviceKhr = 1 << EGLDeviceKhrIdx, //!< EGL device }; //! Context info structure struct Info { uint flags_; //!< Context info flags void* hDev_[LastDeviceFlagIdx]; //!< Device object reference void* hCtx_; //!< Context object reference size_t propertiesSize_; //!< Size of the original properties in bytes cl_int(CL_CALLBACK* commandIntercept_)(cl_event, cl_int*); }; struct DeviceQueueInfo { DeviceQueue* defDeviceQueue_; //!< Default device queue uint deviceQueueCnt_; //!< The number of device queues DeviceQueueInfo() : defDeviceQueue_(NULL), deviceQueueCnt_(0) {} }; private: // Copying a Context is not allowed Context(const Context&); Context& operator=(const Context&); protected: bool terminate() { if (Agent::shouldPostContextEvents()) { Agent::postContextFree(as_cl(this)); } return true; } //! Context destructor ~Context(); public: /*! \brief Helper function to check the context properties and initialize * context info structure * * \return An errcode if invalid, CL_SUCCESS if valid */ static int checkProperties(const cl_context_properties* properties, //!< Properties Info* info //!< Info structure ); //! Default constructor Context(const std::vector& devices, //!< List of all devices const Info& info //!< Context info structure ); //! Compare two Context instances. bool operator==(const Context& rhs) const { return this == &rhs; } bool operator!=(const Context& rhs) const { return !(*this == rhs); } /*! Creates the context * * \return An errcode if runtime fails the context creation, * CL_SUCCESS otherwise */ int create(const intptr_t* properties //!< Original context properties ); /** * Allocate host memory using either a custom device allocator or a generic * OS allocator * * @param size Allocation size, in bytes * @param alignment Desired alignment, in bytes * @param atomics The buffer should support platform (SVM) atomics */ void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const; /** * Release host memory * @param ptr Pointer allocated using ::hostAlloc. If the pointer has been * allocated elsewhere, the behavior is undefined */ void hostFree(void* ptr) const; /** * Allocate SVM buffer * * @param size Allocation size, in bytes * @param alignment Desired alignment, in bytes * @param flags The flags to create a svm space */ void* svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags = CL_MEM_READ_WRITE); /** * Release SVM buffer * @param ptr Pointer allocated using ::svmAlloc. If the pointer has been * allocated elsewhere, the behavior is undefined */ void svmFree(void* ptr) const; //! Return the devices associated with this context. const std::vector& devices() const { return devices_; } //! Return the SVM capable devices associated with this context. const std::vector& svmDevices() const { return svmAllocDevice_; } //! Returns true if the given device is associated with this context. bool containsDevice(const Device* device) const; //! Returns the context info structure const Info& info() const { return info_; } //! Returns a pointer to the original properties const cl_context_properties* properties() const { return properties_; } //! Returns a pointer to the OpenGL context GLFunctions* glenv() const { return glenv_; } //! RTTI internal implementation virtual ObjectType objectType() const { return ObjectTypeContext; } //! Returns context lock for the serialized access to the context Monitor& lock() { return ctxLock_; } //! Returns TRUE if runtime succesfully added a device queue DeviceQueue* defDeviceQueue(const Device& dev) const; //! Returns TRUE if runtime succesfully added a device queue bool isDevQueuePossible(const Device& dev); //! Returns TRUE if runtime succesfully added a device queue void addDeviceQueue(const Device& dev, //!< Device object DeviceQueue* queue, //!< Device queue bool defDevQueue //!< Added device queue will be the default queue ); //! Removes a device queue from the list of queues void removeDeviceQueue(const Device& dev, //!< Device object DeviceQueue* queue //!< Device queue ); //! Set the default device queue void setDefDeviceQueue(const Device& dev, DeviceQueue* queue) { deviceQueues_[&dev].defDeviceQueue_ = queue; }; private: const Info info_; //!< Context info structure cl_context_properties* properties_; //!< Original properties GLFunctions* glenv_; //!< OpenGL context Device* customHostAllocDevice_; //!< Device responsible for host allocations std::vector svmAllocDevice_; //!< Devices can support SVM allocations std::unordered_map deviceQueues_; //!< Device queues mapping mutable Monitor ctxLock_; //!< Lock for the context access }; /*! @} * @} */ } // namespace amd #endif /*CONTEXT_HPP_*/