18 #ifndef viskores_interop_cuda_internal_TransferToOpenGL_h
19 #define viskores_interop_cuda_internal_TransferToOpenGL_h
31 #include <thrust/copy.h>
32 #include <thrust/device_ptr.h>
33 #include <thrust/system/cuda/execution_policy.h>
34 #include <viskores/exec/cuda/internal/ExecutionPolicy.h>
49 class CudaTransferResource :
public viskores::interop::internal::TransferResource
52 CudaTransferResource()
53 :
viskores::interop::internal::TransferResource()
55 this->Registered =
false;
58 ~CudaTransferResource()
63 cudaGraphicsUnregisterResource(this->CudaResource);
67 bool IsRegistered()
const {
return Registered; }
69 void Register(GLuint* handle)
75 cudaGraphicsUnregisterResource(this->CudaResource);
78 this->Registered =
true;
80 cudaGraphicsGLRegisterBuffer(&this->CudaResource, *handle, cudaGraphicsMapFlagsWriteDiscard);
81 if (cError != cudaSuccess)
90 cudaError_t cError = cudaGraphicsMapResources(1, &this->CudaResource, cudaStreamPerThread);
91 if (cError != cudaSuccess)
94 "Could not allocate enough memory in CUDA for OpenGL interop.");
98 template <
typename ValueType>
102 std::size_t cuda_size;
103 ValueType* pointer =
nullptr;
105 cudaGraphicsResourceGetMappedPointer((
void**)&pointer, &cuda_size, this->CudaResource);
107 if (cError != cudaSuccess)
110 "Unable to get pointers to CUDA memory for OpenGL buffer.");
118 void UnMap() { cudaGraphicsUnmapResources(1, &this->CudaResource, cudaStreamPerThread); }
122 cudaGraphicsResource_t CudaResource;
130 template <
typename ValueType>
140 if (!this->State.HasType())
142 this->State.DeduceAndSetType(ValueType());
146 dynamic_cast<viskores::interop::internal::CudaTransferResource*
>(state.GetResource());
149 viskores::interop::internal::CudaTransferResource* cudaResource =
150 new viskores::interop::internal::CudaTransferResource();
153 this->State.SetResource(cudaResource);
154 this->Resource = cudaResource;
158 template <
typename StorageTag>
163 if (!glIsBuffer(*this->State.GetHandle()))
165 glGenBuffers(1, this->State.GetHandle());
169 glBindBuffer(this->State.GetType(), *this->State.GetHandle());
174 this->State.SetSize(size);
175 const bool resize = this->State.ShouldRealloc(size);
179 glBufferData(this->State.GetType(),
static_cast<GLsizeiptr
>(size), 0, GL_DYNAMIC_DRAW);
181 this->State.SetCapacity(size);
184 if (!this->Resource->IsRegistered() || resize)
189 this->Resource->Register(this->State.GetHandle());
192 this->Resource->Map();
194 ValueType* beginPointer = this->Resource->GetMappedPoiner<ValueType>(size);
202 this->Resource->UnMap();
207 viskores::interop::internal::CudaTransferResource* Resource;