10 #ifndef vtkm_interop_cuda_internal_TransferToOpenGL_h
11 #define vtkm_interop_cuda_internal_TransferToOpenGL_h
22 VTKM_THIRDPARTY_PRE_INCLUDE
23 #include <thrust/copy.h>
24 #include <thrust/device_ptr.h>
25 #include <thrust/system/cuda/execution_policy.h>
26 #include <vtkm/exec/cuda/internal/ExecutionPolicy.h>
27 VTKM_THIRDPARTY_POST_INCLUDE
41 class CudaTransferResource :
public vtkm::interop::internal::TransferResource
44 CudaTransferResource()
45 :
vtkm::interop::internal::TransferResource()
47 this->Registered =
false;
50 ~CudaTransferResource()
55 cudaGraphicsUnregisterResource(this->CudaResource);
59 bool IsRegistered()
const {
return Registered; }
61 void Register(GLuint* handle)
67 cudaGraphicsUnregisterResource(this->CudaResource);
70 this->Registered =
true;
72 cudaGraphicsGLRegisterBuffer(&this->CudaResource, *handle, cudaGraphicsMapFlagsWriteDiscard);
73 if (cError != cudaSuccess)
82 cudaError_t cError = cudaGraphicsMapResources(1, &this->CudaResource, cudaStreamPerThread);
83 if (cError != cudaSuccess)
86 "Could not allocate enough memory in CUDA for OpenGL interop.");
90 template <
typename ValueType>
91 ValueType* GetMappedPoiner(vtkm::Int64 desiredSize)
94 std::size_t cuda_size;
95 ValueType* pointer =
nullptr;
97 cudaGraphicsResourceGetMappedPointer((
void**)&pointer, &cuda_size, this->CudaResource);
99 if (cError != cudaSuccess)
105 VTKM_ASSERT(cuda_size >=
static_cast<std::size_t
>(desiredSize));
109 void UnMap() { cudaGraphicsUnmapResources(1, &this->CudaResource, cudaStreamPerThread); }
113 cudaGraphicsResource_t CudaResource;
121 template <
typename ValueType>
124 using DeviceAdapterTag = vtkm::cont::DeviceAdapterTagCuda;
131 if (!this->State.HasType())
133 this->State.DeduceAndSetType(ValueType());
137 dynamic_cast<vtkm::interop::internal::CudaTransferResource*
>(state.GetResource());
140 vtkm::interop::internal::CudaTransferResource* cudaResource =
141 new vtkm::interop::internal::CudaTransferResource();
144 this->State.SetResource(cudaResource);
145 this->Resource = cudaResource;
149 template <
typename StorageTag>
153 if (!glIsBuffer(*this->State.GetHandle()))
155 glGenBuffers(1, this->State.GetHandle());
159 glBindBuffer(this->State.GetType(), *this->State.GetHandle());
162 const vtkm::Int64 size =
164 this->State.SetSize(size);
165 const bool resize = this->State.ShouldRealloc(size);
169 glBufferData(this->State.GetType(),
static_cast<GLsizeiptr
>(size), 0, GL_DYNAMIC_DRAW);
171 this->State.SetCapacity(size);
174 if (!this->Resource->IsRegistered() || resize)
179 this->Resource->Register(this->State.GetHandle());
182 this->Resource->Map();
184 ValueType* beginPointer = this->Resource->GetMappedPoiner<ValueType>(size);
192 this->Resource->UnMap();
197 vtkm::interop::internal::CudaTransferResource* Resource;