Skip to main content
GameDev.net gamedev.net
🔒 Locked

clCreateFromGLBuffer crash

Started by Alex Garcin Oct 27, 2018 at 6:25 PM 15 replies 13k views
Original Post
Alex Garcin
Alex Garcin

Hello every one,

When I tried to use my vbo with opencl I get a crash when calling clCreateFromGLBuffer

Below a small code that reproduce the issue:

initialisation of the opengl context

sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.antialiasingLevel = 2;
sf::Window window(sf::VideoMode(2048, 1024), "GAME",
        sf::Style::Fullscreen, settings);
glewInit();

initialisation of the opencl context

cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);

ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id,
        &ret_num_devices);

cl_context_properties props[] = { CL_GL_CONTEXT_KHR,
        (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR,
        (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM,
        (cl_context_properties) platform_id, 0 };

cl_context context = clCreateContext(props, 1, &device_id, NULL, NULL,
        &ret);

GLuint vboID_m = 0;

Creation of the vertex buffer object

glGenBuffers(1, &vboID_m);
glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
{

    std::vector<float> tmp = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };

    glBufferData(GL_ARRAY_BUFFER, (tmp.size()) * sizeof(float), 0,
    GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, 0, tmp.size() * sizeof(float),
            tmp.data());
}
glBindBuffer(GL_ARRAY_BUFFER, 0);

glFlush();

Linkage of the opencl buffer with the opengl vertex buffer object

cl_int status;
clCreateFromGLBuffer(context, CL_MEM_READ_WRITE, vboID_m, &status);
return 0;

Thanks for your help!

irreversible
irreversible

Is clCreateFromGLBuffer a valid function pointer? Eg have you tested it for null?

Other than that, I've no idea what your code is doing, but there are two primary reasons why it can crash like this:

- the simpler reason has to do with your function arguments. Is the context valid? You're not running any checks at or around clCreateContext (or any other CL API functions, for that matter)? How can you be sure it succeeds? Add an error check after each call (better yet - wrap each call in a checker macro that you can later define to empty).

- the more complex reason has to do with the rest of your code. Create a test project. Remove any and all outside factors (multi-threading, prior code not related to the call, etc). If it you've checked everything outlined above and it still crashes, then you're looking at a more serious problem.

Unless you've borked your arguments somewhere, the most likely culprit here is a buffer overflow (eg writing out of bounds) anywhere else in your program, which isn't detected, but thrashes the pointer to clCreateFromGLBuffer. Catching this can be hard. However, for starters, if your IDE supports it, you could try setting a hardware/data breakpoint to clCreateFromGLBuffer after it's been loaded and letting your program run to see if the address is modified. If it is, you'll hopefully know where the problem is.

PS - the code you posted doesn't necessarily reproduce the issue for someone else, because it's not a full program.

PPS - you're asking for a solution, but your code doesn't seem to be doing any validation/error checking of its own. Without knowing anything about CL, I'm going to go out on a limb and say either your call to clCreateContext is malformed or you have a memory write problem literally anywhere else in your code.

cgrant
cgrant

I think I had this issue once, and it was relate to the order of creation CL and OpenGL context. If you've validate all irreversible has mentioned above and all is well, try swapping the order of our context creation.

Alex Garcin
Alex Garcin


@irreversible

  • Is clCreateFromGLBuffer a valid function pointer? Eg have you tested it for null?

What do you mean by function pointer ? clCreateFromGLBuffer is not a pointer ?!

  • - the simpler reason has to do with your function arguments. Is the context valid? You're not running any checks at or around clCreateContext (or any other CL API functions, for that matter)? How can you be sure it succeeds? Add an error check after each call (better yet - wrap each call in a checker macro that you can later define to empty)

I have allready check all the return statment and opengl errors and everything is ok

  •  - the more complex reason has to do with the rest of your code. Create a test project. Remove any and all outside factors (multi-threading, prior code not related to the call, etc). If it you've checked everything outlined above and it still crashes, then you're looking at a more serious problem.

It's allready a "test project", I have put that in a main without any other code and it crash.

  •  Unless you've borked your arguments somewhere, the most likely culprit here is a buffer overflow (eg writing out of bounds) anywhere else in your program, which isn't detected, but thrashes the pointer to clCreateFromGLBuffer. Catching this can be hard. However, for starters, if your IDE supports it, you could try setting a hardware/data breakpoint to clCreateFromGLBuffer after it's been loaded and letting your program run to see if the address is modified. If it is, you'll hopefully know where the problem is.

No because of the previous point.

@cgrant

  • try swapping the order of our context creation.

You mean moving :

cl_platform_id platform_id = NULL;
cl_device_id device_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);

ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id,
        &ret_num_devices);

cl_context_properties props[] = { CL_GL_CONTEXT_KHR,
        (cl_context_properties) wglGetCurrentContext(), CL_WGL_HDC_KHR,
        (cl_context_properties) wglGetCurrentDC(), CL_CONTEXT_PLATFORM,
        (cl_context_properties) platform_id, 0 };

cl_context context = clCreateContext(props, 1, &device_id, NULL, NULL,
        &ret);

GLuint vboID_m = 0;

before :

sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.antialiasingLevel = 2;
sf::Window window(sf::VideoMode(2048, 1024), "GAME",
        sf::Style::Fullscreen, settings);
glewInit();

? Because when I do that I get a CL_INVALID_CONTEXT error.

cgrant
cgrant

So I dug up my example code that kinda does the same thing you are doing and I had an explicit note in the code ( granted this is on AMD platform ) to create the OpenCL context prior to creating any GL objects, especially buffered object. I would expect context creation would fail is you did NOT specify a valid OpenGL context handle and device context. I don't know what other objects SMFL creates in the process of its OpenGL context initialization, but it would be good to investigate. Also, how are you retrieving/initializing your OpenCL entry points ? Remember OpenCL follows a similar model to OpenGL. In your example you are using GLEW to initialize your OpenGL entry points (function pointers.) What are you using for OpenCL ?

Alex Garcin
Alex Garcin
  • Remember OpenCL follows a similar model to OpenGL. In your example you are using GLEW to initialize your OpenGL entry points (function pointers.) What are you using for OpenCL ?

Nothing more that what I have written in my code exemple, I have followed all the tutorial I have found on the web...

AndreyVK_D3D
AndreyVK_D3D

Hi, @Alex Garcin

1) wglGetCurrentContext() != NULL ? wglGetCurrentDC() != NULL ?

2) Try to create OpenGL Context without SMFL(VERY BAD library) or try to use SDL :)))

3) Can you attach your test project ? I can test him.


3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms
irreversible
irreversible
15 hours ago, Alex Garcin said:

What do you mean by function pointer ? clCreateFromGLBuffer is not a pointer ?!

if(clCreateFromGLBuffer == NULL) ...

15 hours ago, Alex Garcin said:

I have allready check all the return statment and opengl errors and everything is ok

How? I can't see it in your code.

15 hours ago, Alex Garcin said:
  •  - the more complex reason has to do with the rest of your code. Create a test project. Remove any and all outside factors (multi-threading, prior code not related to the call, etc). If it you've checked everything outlined above and it still crashes, then you're looking at a more serious problem.

It's allready a "test project", I have put that in a main without any other code and it crash.

Try stepping through your program an check if anything looks out of the ordinary. Like I said, unless you've malformed one or more of your calls, the culprit is most likely somewhere else in your program.

Just to have a point of reference, try running your program on a different computer with a different hardware setup. It's unlikely, but not impossible that your driver installation is corrupted etc.

What version is whatever library you use to initialize OpenCL? (update to the latest one)

This might hurt your ego, but if something crashes, then 99.999% of the time it's because of your code :). Except when it isn't...

Alex Garcin
Alex Garcin
8 hours ago, Andrey OGL_D3D said:

Hi, @Alex Garcin

1) wglGetCurrentContext() != NULL ? wglGetCurrentDC() != NULL ?

2) Try to create OpenGL Context without SMFL(VERY BAD library) or try to use SDL :)))

3) Can you attach your test project ? I can test him.


Thanks for your reply,

1) wglGetCurrentContext() != NULL ? wglGetCurrentDC() != NULL ?

None of them are null.


2) Try to create OpenGL Context without SMFL(VERY BAD library) or try to use SDL icon_smile.gif))

Will try.


3) Can you attach your test project ? I can test him.

http://garcin.alex.free.fr/partage/test.rar

7 hours ago, irreversible said:

if(clCreateFromGLBuffer == NULL) ...

How? I can't see it in your code.

Try stepping through your program an check if anything looks out of the ordinary. Like I said, unless you've malformed one or more of your calls, the culprit is most likely somewhere else in your program.

Just to have a point of reference, try running your program on a different computer with a different hardware setup. It's unlikely, but not impossible that your driver installation is corrupted etc.

What version is whatever library you use to initialize OpenCL? (update to the latest one)

This might hurt your ego, but if something crashes, then 99.999% of the time it's because of your code :). Except when it isn't...

  • if(clCreateFromGLBuffer == NULL) ...

    they aren't null


  • How? I can't see it in your code.

    For simplicity I don't have post it.


  • Try stepping through your program an check if anything looks out of the ordinary. Like I said, unless you've malformed one or more of your calls, the culprit is most likely somewhere else in your program.

    As I have said, The small code that I have post in this forum reproduce the issue by itself without any other code addition


  • What version is whatever library you use to initialize OpenCL? (update to the latest one)

    4.6.0
AndreyVK_D3D
AndreyVK_D3D

HI @Alex Garcin,

I have tested your project. On my system i have a few platforms and few GPU witch support OpenCL, so i added choice platform for GPU using clGetGLContextInfoKHR, I replace SFML to glut. I have no crash.


	glutInit(&argc, argv);
	glutInitWindowSize(800, 600);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glutCreateWindow("Test OpenCL");


	glewInit();

	cl_platform_id platform_ids[16] = { NULL };
	cl_device_id device_id = NULL;
	cl_uint ret_num_devices;
	cl_uint ret_num_platforms;

	cl_platform_id platform_id = 0;
	cl_int ret = clGetPlatformIDs(_countof(platform_ids), platform_ids, &ret_num_platforms);

	size_t n = 0;

	cl_context_properties props[] = { CL_GL_CONTEXT_KHR,
			(cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR,
			(cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM,
			(cl_context_properties)platform_id, 0 };
	
	for (size_t i = 0; i < ret_num_platforms; ++i) {
		platform_id = platform_ids[i];
		cl_device_id curDevice_id = 0;
		ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &curDevice_id, &ret_num_devices);
		if (curDevice_id) {
			clGetGLContextInfoKHR_fn clGetGLContextInfo = reinterpret_cast<clGetGLContextInfoKHR_fn>(clGetExtensionFunctionAddressForPlatform(platform_id, "clGetGLContextInfoKHR"));
			if (clGetGLContextInfo) {
				cl_device_id clGLDevice = 0;
				props[5] = reinterpret_cast<cl_context_properties>(platform_id);
				clGetGLContextInfo(props, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_uint), &clGLDevice, &n);
				if (clGLDevice == curDevice_id) {
					device_id = clGLDevice;
				}
			}
		}
		if (device_id) {
			break;
		}
	}

	cl_context context = clCreateContext(props, 1, &device_id, NULL, NULL,
			&ret);

	GLuint vboID_m = 0;

	glGenBuffers(1, &vboID_m);
	glBindBuffer(GL_ARRAY_BUFFER, vboID_m);

	{

		std::vector<float> tmp = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };

		glBufferData(GL_ARRAY_BUFFER, (tmp.size()) * sizeof(float), 0,
		GL_STATIC_DRAW);
		glBufferSubData(GL_ARRAY_BUFFER, 0, tmp.size() * sizeof(float),
				tmp.data());
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	cl_int status;

	glFinish();

	clCreateFromGLBuffer(context, CL_MEM_READ_ONLY, vboID_m, &status);
	std::cout << status << std::endl;

	return EXIT_SUCCESS;

I attached modified project:testOpenCL.7z

Please let me know, why do you have error with using SFML(very bad library!)

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms
Alex Garcin
Alex Garcin
When I run your code, ret_num_platform value is 2 and for each of them clGetGLContextInfo give a clGLDevice of 0 and so the device_id is not set icon_sad.gif
AndreyVK_D3D
AndreyVK_D3D
3 minutes ago, Alex Garcin said:
When I run your code, ret_num_platform value is 2 and for each of them clGetGLContextInfo give a clGLDevice of 0 and so the device_id is not set icon_sad.gif

Ok, please test new code testOpenCL.7z:


	for (size_t i = 0; i < ret_num_platforms; ++i) {
		platform_id = platform_ids[i];
		cl_device_id curDevices_id[16];
		
		ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, _countof(curDevices_id), curDevices_id, &ret_num_devices);
		for(cl_uint nDevices = 0; nDevices < ret_num_devices; ++nDevices) {
			cl_device_id curDevice_id = curDevices_id[nDevices];
			char str[1024];
			size_t strSize = 0;
			ret = clGetDeviceInfo(curDevice_id, CL_DEVICE_NAME, sizeof(str), str, &strSize);
			fprintf(stderr, "OpenCL Device Name %s\n", str);
			ret = clGetDeviceInfo(curDevice_id, CL_DEVICE_VENDOR, sizeof(str), str, &strSize);
			fprintf(stderr, "OpenCL Device Vendor %s\n", str);
			ret = clGetDeviceInfo(curDevice_id, CL_DEVICE_EXTENSIONS, sizeof(str), str, &strSize);
			fprintf(stderr, "OpenCL Device Extensions %s\n", str);
			bool supportGLSharing = strstr(str, "cl_khr_gl_sharing") != NULL;
			fprintf(stderr, "OpenCL Supports OpenCL/OpenGL sharing: %s\n", supportGLSharing ? "true" : "false");
			clGetGLContextInfoKHR_fn clGetGLContextInfo = reinterpret_cast<clGetGLContextInfoKHR_fn>(clGetExtensionFunctionAddressForPlatform(platform_id, "clGetGLContextInfoKHR"));
			if (clGetGLContextInfo) {
				cl_device_id clGLDevice = 0;
				props[5] = reinterpret_cast<cl_context_properties>(platform_id);
				clGetGLContextInfo(props, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_uint), &clGLDevice, &n);
				if (clGLDevice == curDevice_id) {
					device_id = clGLDevice;
				}
			}
		}
		if (device_id) {
			break;
		}
	}

I think your device doesn't support OpenCL/OpenGL Interop, please post OpenCL info.

I tested on 2 system:

Windows & X64 - single GPU AMD R7240

Windows 10 X64 - GPU 1: nVidia 610(Monitor uses for this GPU) , GPU 2 - AMD R7 350X

I have no problem on this systems.




3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms
Alex Garcin
Alex Garcin

OK, when I replace sizeof(cl_uint) by sizeof(clGLDevice), I get a context in:


clGetGLContextInfo(props, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_uint), &clGLDevice, &n);

If I don't break on the line clGLDevice == curDevice_id, I get:


OpenCL Device Name Intel(R) HD Graphics 530
OpenCL Device Vendor Intel(R) Corporation
OpenCL Device Extensions  cl_khr_3d_image_writes cl_khr_byte_addressable_store cl_khr_fp16 cl_khr_depth_images cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_icd cl_khr_image2d_from_buffer cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_intel_subgroups cl_intel_required_subgroup_size cl_intel_subgroups_short cl_khr_spir cl_intel_accelerator cl_intel_media_block_io cl_intel_driver_diagnostics cl_intel_device_side_avc_motion_estimation cl_khr_priority_hints cl_khr_throttle_hints cl_khr_create_command_queue cl_khr_fp64 cl_khr_subgroups cl_khr_il_program cl_khr_mipmap_image cl_khr_mipmap_image_writes cl_intel_planar_yuv cl_intel_packed_yuv cl_intel_motion_estimation cl_intel_advanced_motion_estimation cl_khr_gl_sharing cl_khr_gl_depth_images cl_khr_gl_event cl_khr_gl_msaa_sharing cl_intel_dx9_media_sharing cl_khr_dx9_media_sharing cl_khr_d3d10_sharing cl_khr_d3d11_sharing cl_intel_d3d11_nv12_media_sharing cl_intel_simultaneous_sharing 
OpenCL Supports OpenCL/OpenGL sharing: true
OpenCL Device Name GeForce GTX 1080
OpenCL Device Vendor NVIDIA Corporation
OpenCL Device Extensions  cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_fp64 cl_khr_byte_addressable_store cl_khr_icd cl_khr_gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unroll cl_nv_d3d10_sharing cl_khr_d3d10_sharing cl_nv_d3d11_sharing cl_nv_copy_opts cl_nv_create_buffer
OpenCL Supports OpenCL/OpenGL sharing: true


For the first device I get the crash, and for the second every things works great, But why does't it works for my cpu gpu, while supportGLSharing says that it is supported ?

Is it because opengl used the second device ?

If so, how to check which device is used by opengl ? (Wasn't if (clGLDevice == curDevice_id) supposed to do that ? Because it breaks on the first device when it is supposed to break on the second one)


By the way, I have tried to replace glut by sfml and it still works, my question is "why are you saying that it's a bad library" ?

AndreyVK_D3D
AndreyVK_D3D

Hi, @Alex Garcin

Quote

For the first device I get the crash, and for the second every things works great, But why does't it works for my cpu gpu, while supportGLSharing says that it support it ?

1) Support of OpenCL extension this is not enough for working OpenGL/OpenCL together.

2) If we have more than one GPU in system, we should find one OpenGL context and share it with OpenCL, so your monitor is connected to second GPU Geforce GTX 1080, only this GPU has correct OpenGL context and can work with OpenCL using some sharing objects(VBO,Texture...)

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms
Alex Garcin
Alex Garcin

OK so how should I do to know which of the two contexts is the one used by opengl?

AndreyVK_D3D
AndreyVK_D3D
25 minutes ago, Alex Garcin said:

OK so how should I do to know which of the two contexts is the one used by opengl?

I have never had same task.. I think you should create separate OpenCL context for each OpenGL context.

Usually, the different OpenGL contexts can be used in separate threads, so we can also use different OpenCL context in different threads, because OpenCL runtime is thread safe(except some functions: clSetKernelArg, ...)

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.