//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. // // Copyright 2014 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_interop_TransferToOpenGL_h #define vtk_m_interop_TransferToOpenGL_h #include #include #include #include #include #include #include #include #include namespace vtkm { namespace interop { namespace detail { template struct PrepareForInteropFunctor { ArrayT& Array; PrepareForInteropFunctor(ArrayT& array) : Array(array) { } template bool operator()(DeviceAdapterTag) const { using Traits = vtkm::cont::DeviceAdapterTraits; this->Array.PrepareForInput(DeviceAdapterTag()); return this->Array.GetDeviceAdapterId() == Traits::GetId(); } }; } /// \brief Manages transferring an ArrayHandle to opengl . /// /// \c TransferToOpenGL manages to transfer the contents of an ArrayHandle /// to OpenGL as efficiently as possible. Will use the given \p state to determine /// what buffer handle to use, and the type to bind the buffer handle too. /// If the type of buffer hasn't been determined the transfer will use /// deduceAndSetBufferType to do so. Lastly state also holds on to per backend resources /// that allow for efficient updating to open gl /// /// This function keeps the buffer as the active buffer of the input type. /// /// This function will throw exceptions if the transfer wasn't possible /// template VTKM_CONT void TransferToOpenGL(vtkm::cont::ArrayHandle handle, BufferState& state, DeviceAdapterTag) { vtkm::interop::internal::TransferToOpenGL toGL(state); return toGL.Transfer(handle); } /// Dispatch overload for TransferToOpenGL that deduces the DeviceAdapter for /// the given ArrayHandle. /// /// \overload /// template VTKM_CONT void TransferToOpenGL(vtkm::cont::ArrayHandle handle, BufferState& state) { vtkm::cont::DeviceAdapterId devId = handle.GetDeviceAdapterId(); if (devId == VTKM_DEVICE_ADAPTER_UNDEFINED) { using ArrayT = vtkm::cont::ArrayHandle; using Functor = detail::PrepareForInteropFunctor; // Undefined device means that the array is not in an execution environment. // In this case, call PrepareForInput using the devices in the tracker // to move the data onto a device. This is required for a CUDA usecase // where a device pointer is set as control memory to reuse an already // allocated buffer. PrepareForInput on CUDA will detect this and set the // execution pointer to match the control pointer. vtkm::cont::TryExecute(Functor(handle)); devId = handle.GetDeviceAdapterId(); } switch (devId) { case VTKM_DEVICE_ADAPTER_SERIAL: TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagSerial()); break; #ifdef VTKM_ENABLE_TBB case VTKM_DEVICE_ADAPTER_TBB: TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagTBB()); break; #endif #ifdef VTKM_CUDA case VTKM_DEVICE_ADAPTER_CUDA: TransferToOpenGL(handle, state, vtkm::cont::DeviceAdapterTagCuda()); break; #endif default: throw vtkm::cont::ErrorBadValue("Unknown device id."); } } } } #endif //vtk_m_interop_TransferToOpenGL_h