This project is read-only.

About CUDAfy with SharpGL

Mar 14, 2014 at 3:55 AM
Edited Mar 14, 2014 at 4:05 AM
Hi, everyone. I get a practice from cuda example "SimpleGL".It's a project that CUDA device memory binding OpenGL to work realtime graphic.And I follow the code step get crash all the way.Here is the comparison with code .I think the problem is wrong Intptr?

//CUDA Part
void createVBO(GLuint *vbo, struct cudaGraphicsResource **vbo_res, unsigned int vbo_res_flags)
{
assert(vbo);
// create buffer object
glGenBuffers(1, vbo);
glBindBuffer(GL_ARRAY_BUFFER, *vbo);
// initialize buffer object
unsigned int size = mesh_width * mesh_height * 4 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// register this buffer object with CUDA
checkCudaErrors(cudaGraphicsGLRegisterBuffer(vbo_res, *vbo, vbo_res_flags));
SDK_CHECK_ERROR_GL();
}

//CUDAfy Part
private static void createVBO()
    {
        // create buffer object
        ivOpenGLControl.OpenGL.GenBuffers(1, ivVBO); // Pass!
        ivOpenGLControl.OpenGL.BindBuffer(OpenGL.GL_ARRAY_BUFFER, ivVBO[0]); // Pass!
        // initialize buffer object
        int size = ivMesh_Width * ivMesh_Height * 4 * sizeof(float);
        ivOpenGLControl.OpenGL.BufferData(OpenGL.GL_ARRAY_BUFFER, size, IntPtr.Zero, OpenGL.GL_DYNAMIC_DRAW); // Pass!
        ivOpenGLControl.OpenGL.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0); // Pass!
        // register this buffer object with CUDA
        CUOpenGLRuntime.cudaGraphicsGLRegisterBuffer(ivCudaGraphicsResourceArray, ivVBO[0], (uint)cudaGLMapFlags.WriteDiscard); // Pass!
        //CUOpenGLDriver.cuGraphicsGLRegisterBuffer(ref ivCUgraphicsResource, ivVBO[0], (uint)cudaGLMapFlags.WriteDiscard);
    }
//CUDA Part
void runCuda(struct cudaGraphicsResource **vbo_resource)
{
// map OpenGL buffer object for writing from CUDA
float4 *dptr;
checkCudaErrors(cudaGraphicsMapResources(1, vbo_resource, 0));
size_t num_bytes;
checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&dptr, &num_bytes,
                                                     *vbo_resource));
// execute the kernel
//    dim3 block(8, 8, 1);
//    dim3 grid(mesh_width / block.x, mesh_height / block.y, 1);
//    kernel<<< grid, block>>>(dptr, mesh_width, mesh_height, g_fAnim);

launch_kernel(dptr, mesh_width, mesh_height, g_fAnim);
// unmap buffer object
checkCudaErrors(cudaGraphicsUnmapResources(1, vbo_resource, 0));
}

//CUDAfy Part
private static void runCUDA()
    {
        int[] dev_width = gpu.CopyToDevice(new int[] { (int)ivMesh_Width });
        int[] dev_height = gpu.CopyToDevice(new int[] { (int)ivMesh_Height });
        int[] devG_FAnim = gpu.CopyToDevice(new int[] { (int)ivG_FAnim });
        myFloat4[] pos = new myFloat4[1];
        myFloat4[] dev_pos = gpu.Allocate<myFloat4>(pos);
        SizeT num_bytes = new SizeT();

        // map OpenGL buffer object for writing from CUDA
        cudaStream thecudaStream = new cudaStream() { Value = 0 };
        CUDARuntime.cudaGraphicsMapResources(1, ivCudaGraphicsResourceArray, thecudaStream); // Pass!
        GCHandle theGCHandle = GCHandle.Alloc(dev_pos, GCHandleType.Pinned);
        IntPtr P1 = theGCHandle.AddrOfPinnedObject();

        //or try, not work
        //unsafe
        //{
        //    fixed (myFloat4* pointer = pos)
        //    {
        //        IntPtr intPtr = new IntPtr((void*)pointer);
        //        CUdeviceptr theCUdeviceptr = new CUdeviceptr() { Pointer = intPtr };
        //        CUDARuntime.cudaGraphicsResourceGetMappedPointer(ref theCUdeviceptr, num_bytes, ref ivCudaGraphicsResourceArray[0]);
        //    }
        //}

        CUdeviceptr theCUdeviceptr = new CUdeviceptr() { Pointer = P1 };
        CUDARuntime.cudaGraphicsResourceGetMappedPointer(ref theCUdeviceptr, num_bytes, ref ivCudaGraphicsResourceArray[0]); //Crash here!!

        dim3 block = new dim3(8, 8, 1);
        dim3 grid = new dim3(ivMesh_Width / block.x, ivMesh_Height / block.y, 1);

        gpu.Launch(grid, block).kernel(dev_pos, dev_width, dev_height, devG_FAnim);

        // unmap buffer object
        thecudaStream.Value = 0;
        CUDARuntime.cudaGraphicsUnmapResources(1, ivCudaGraphicsResourceArray, thecudaStream);
    }
Mar 14, 2014 at 1:22 PM
Hi
I skimmed your code, and noticed this:

... GCHandle.Alloc(dev_pos ....

That's wrong. dev_pos is a "handle" to a memory block on the device. You can't reasonably try to pin it as if it were host memory.

I don't know about the rest.
Mar 18, 2014 at 11:25 AM
THX, I try ... (CUDARuntime is not work, but CUDADriver)

theCUdeviceptr = cuda.Allocate<Float4>(dev_Float4);// Got the pointer
Or
myFloat4[] dev_pos = gpu.Allocate<myFloat4>(pos);// Got the pointer
DevicePtrEx ttt = gpu.TryGetDeviceMemory(dev_pos);
theCUdeviceptr.Pointer = ttt.Pointer;

CUDADriver.cuGraphicsResourceGetMappedPointer(ref theCUdeviceptr, ref num_bytes, ivCUgraphicsResource); //pass this line, theCUdeviceptr.pointer is 0 !!
Mar 27, 2014 at 3:30 AM
Another Q,

Is it possible that theCUdeviceptr.pointer pass to CUDAfy kernel computing?

[GASS]
theCUdeviceptr.pointer from here.
"CUDADriver.cuGraphicsResourceGetMappedPointer(ref theCUdeviceptr, ref num_bytes, ivCUgraphicsResource);"