cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

jstier
Journeyman III

OpenCL / OpenGL interoperability

Is there an example somewhere that demonstrates OpenCL/OpenGL interoperability with the latest ATI Stream Sdk 2.0. I have done some code searches on the samples for clCreateFromGLTexture2D, clCreateFromGLBuffer and the likes, but I couldn't find anything. Am I under the right impression that the latest sdk has interoperability as a preview feature?

 

In any case, I am creating the OpenCL context after creating the OpenGL context using

 

cl_context_properties lProperties[] = {

CL_CONTEXT_PLATFORM, (cl_context_properties)lPlatform,

CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),

CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),

0

};

sContextCL = clCreateContextFromType(lProperties, CL_DEVICE_TYPE_GPU, NULL, NULL, &sStatus);

 

Then I create an OpenGL texture using

 

glGenTextures(1, &lTextureID);

glBindTexture(GL_TEXTURE_2D, lTextureID);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGB, GL_FLOAT, 0);

glBindTexture(GL_TEXTURE_2D, 0);

 

 

And then, evey call to clCreateFromGLTexture2D returns CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, no matter what texture format I use. I tried GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.

 

mBufferCL = clCreateFromGLTexture2D(sContextCL, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, lTextureID, &sStatus);

 

If anyone could point me to a compliable demo, that would be very helpful.

Plus, what tag do I use to enter source code into a post ?

 

Cheers

 

 

 

0 Likes
34 Replies
genaganna
Journeyman III

Originally posted by: jstier Is there a example somewhere that demonstrates OpenCL/OpenGL interoperability with the latest ATI Stream Sdk 2.0. I have done some code searches on the samples for clCreateFromGLTexture2D, clCreateFromGLBuffer and the likes, but I couldn't find anything. Am I under the right impression that the latest sdk has interoperability as a preview feature ?

 

In any case, I am creating the OpenCL context after creating the OpenGL context using

 

 

cl_context_properties lProperties[] = {

 

CL_CONTEXT_PLATFORM, (cl_context_properties)lPlatform,

 

CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),

 

CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),

 

0

 

};

 

sContextCL = clCreateContextFromType(lProperties, CL_DEVICE_TYPE_GPU, NULL, NULL, &sStatus);

 

 

Then I create an OpenGL texture using

 

 

glGenTextures(1, &lTextureID);

 

glBindTexture(GL_TEXTURE_2D, lTextureID);

 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGB, GL_FLOAT, 0);

 

glBindTexture(GL_TEXTURE_2D, 0);

 

 

 

 

And then, evey call to clCreateFromGLTexture2D returns CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, no matter what texture format I use. I tried GL_FLOAT, GL_UNSIGNED_INT, GL_UNSIGNED_BYTE etc.

 

 

mBufferCL = clCreateFromGLTexture2D(sContextCL, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, lTextureID, &sStatus);

 

 

 

 

If anyone could point me to a compliable demo, that would be very helpful.

 

Plus, what tag do I use to enter source code into a post ?

 

 

 

Cheers

 

 

 

 



 

Jstier,

        Images are not supported.  so use only clCreateFromGLBuffer.

        Presently there is no sample in SDK which shows GL interoperability.

0 Likes

you can try search for example in nvidia SDK. there is some examples.

you have attach code button. it will open new window and you can past your code.

0 Likes

I have modified old Nvidia SimpleGL sample which works with latest SDK. Have a look at this.

SimpleGL.cpp file ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| /* * Copyright 1993-2009 NVIDIA Corporation. All rights reserved. * * NVIDIA Corporation and its licensors retain all intellectual property and * proprietary rights in and to this software and related documentation. * Any use, reproduction, disclosure, or distribution of this software * and related documentation without an express license agreement from * NVIDIA Corporation is strictly prohibited. * * Please refer to the applicable NVIDIA end user license agreement (EULA) * associated with this source code for terms and conditions that govern * your use of this NVIDIA software. * */ /* This example demonstrates how to use the OpenCL/OpenGL interoperability to dynamically modify a vertex buffer using a OpenCL kernel. The steps are: 1. Create an empty vertex buffer object (VBO) 2. Create an OpenCL memory object from the vertex buffer object 3. Acquire the VBO for writing from OpenCL 4. Run OpenCL kernel to modify the vertex positions 5. Release the VBO for returning ownership to OpenGL 6. Render the results using OpenGL Host code */ // standard utility and system includes #include <oclUtils.h> #ifndef _WIN32 #include <GL/glx.h> #endif //!_WIN32 // GLEW and GLUT includes #include <GL/glew.h> #if defined (__APPLE__) || defined(MACOSX) #include <GLUT/glut.h> #else #include <GL/glut.h> #endif // Extra CL/GL include #include <CL/cl_gl.h> // Constants, defines, typedefs and global declarations //***************************************************************************** //#define GPU_PROFILING shrBOOL profiling = shrFALSE; // Uncomment this #define to enable CL/GL Interop //#define GL_INTEROP shrBOOL glInterop = shrFALSE; // Rendering window vars const unsigned int window_width = 512; const unsigned int window_height = 512; const unsigned int mesh_width = 256; const unsigned int mesh_height = 256; // OpenCL vars cl_context cxGPUContext; cl_device_id cdDevice; cl_command_queue cqCommandQueue; cl_kernel ckKernel; cl_mem vbo_cl; cl_program cpProgram; cl_int ciErrNum; char* cPathAndName = NULL; // var for full paths to data, src, etc. char* cSourceCL = NULL; // Buffer to hold source for compilation // vbo variables GLuint vbo; int iGLUTWindowHandle = 0; // handle to the GLUT window // mouse controls int mouse_old_x, mouse_old_y; int mouse_buttons = 0; float rotate_x = 0.0, rotate_y = 0.0; float translate_z = -3.0; // Sim and Auto-Verification parameters float anim = 0.0; int iFrameCount = 0; // FPS count for averaging int iFrameTrigger = 90; // FPS trigger for sampling int iFramesPerSec = 0; // frames per second int iTestSets = 3; const int iRefFrameNumber = 4; int g_Index = 0; shrBOOL bQATest = shrFALSE; shrBOOL g_bFBODisplay = shrFALSE; shrBOOL bNoPrompt = shrFALSE; // Forward Function declarations //***************************************************************************** // OpenCL functionality void runKernel(); void checkResultOpenCL(int argc, const char** argv, const GLuint& vbo); // GL functionality void InitGL(int argc, const char** argv); void createVBO(GLuint* vbo); void deleteVBO(GLuint* vbo); void DisplayGL(); void KeyboardGL(unsigned char key, int x, int y); void mouse(int button, int state, int x, int y); void motion(int x, int y); // Helpers void TestNoGL(); void Cleanup(int iExitCode); void (*pCleanup)(int) = &Cleanup; // Main program //***************************************************************************** int main(int argc, const char **argv) { //process command line args if(shrCheckCmdLineFlag( argc, argv, "help")) { shrLog(LOGBOTH, 0, "Usage: SimpleGL [OPTION]...\n"); shrLog(LOGBOTH, 0, "Example: running on cpu\n"); shrLog(LOGBOTH, 0, "./oclSimpleGL --deviceType=cpu\n"); shrLog(LOGBOTH, 0, "\n"); shrLog(LOGBOTH, 0, "Options:\n"); shrLog(LOGBOTH, 0, "--help\tDisplay this help menu\n"); shrLog(LOGBOTH, 0, "--deviceType=[gpu|cpu]\tSpecity the deviceType to be used\n"); shrLog(LOGBOTH, 0, "--profiling\tRuns for profiling\n"); shrLog(LOGBOTH, 0, "--noprompt\tExits sample after running\n"); shrLog(LOGBOTH, 0, "--qatest\tSkips user interface\n"); shrLog(LOGBOTH, 0, "--glinterop\tEnables GL interoperability\n"); return 0; } // start logs shrSetLogFileName ("oclSimpleGL.txt"); shrLog(LOGBOTH, 0, "%s Starting...\n\n", argv[0]); cl_device_type dType = CL_DEVICE_TYPE_GPU; char* dTypeStr = NULL; // check command line args if (argc > 1) { bQATest = shrCheckCmdLineFlag(argc, argv, "qatest"); bNoPrompt = shrCheckCmdLineFlag(argc, argv, "noprompt"); profiling = shrCheckCmdLineFlag(argc, argv, "profiling"); glInterop = shrCheckCmdLineFlag(argc, argv, "glinterop"); if(glInterop == shrTRUE) bQATest = shrFALSE; // Select deviceType to be used if(shrGetCmdLineArgumentstr(argc, argv, "deviceType", &dTypeStr)) { if(strcmp(dTypeStr, "cpu") == 0 ) { dType = CL_DEVICE_TYPE_CPU; } else if(strcmp(dTypeStr, "gpu") == 0) { dType = CL_DEVICE_TYPE_GPU; } else { shrLog(LOGBOTH, 0, "Invalid deviceType - valid deviceTypes are gpu or cpu\n"); shrLog(LOGBOTH, 0, "use --deviceType=cpu or --deviceType=gpu \n default is gpu\n"); return -1000; } } else { //default - gpu dType = CL_DEVICE_TYPE_GPU; } } // Initialize OpenGL context, so we can properly set the GL for CL. if(!bQATest) { InitGL(argc, argv); } cl_uint numPlatforms; cl_platform_id platform = NULL; ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); if (CL_SUCCESS != ciErrNum) { fputs("clGetPlatformIDs() failed", stderr); exit(-1); } if (0 < numPlatforms) { cl_platform_id* platforms = new cl_platform_id[numPlatforms]; ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL); if (CL_SUCCESS != ciErrNum) { fputs("clGetPlatformIDs() failed", stderr); exit(-1); } for (unsigned i = 0; i < numPlatforms; ++i) { char pbuf[100]; ciErrNum = clGetPlatformInfo( platforms, CL_PLATFORM_VENDOR, sizeof(pbuf), pbuf, NULL); platform = platforms; if (!strcmp(pbuf, "Advanced Micro Devices, Inc.")) { break; } } delete platforms; } #ifdef _WIN32 HGLRC glCtx = wglGetCurrentContext(); #else //!_WIN32 GLXContext glCtx = glXGetCurrentContext(); #endif //!_WIN32 cl_context_properties cpsGL[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform #ifdef _WIN32 , CL_WGL_HDC_KHR, (intptr_t) wglGetCurrentDC(), #else //!_WIN32 , CL_GLX_DISPLAY_KHR, (intptr_t) glXGetCurrentDisplay(), #endif //!_WIN32 CL_GL_CONTEXT_KHR, (intptr_t) glCtx, 0}; /* * If we could find our platform, use it. Otherwise pass a NULL and get whatever the * implementation thinks we should be using. */ cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; /* Use NULL for backward compatibility */ cl_context_properties* cprops = NULL; if(glInterop == shrTRUE) cprops = (NULL == platform) ? NULL : cpsGL; else cprops = (NULL == platform) ? NULL : cps; // create the OpenCL context cxGPUContext = clCreateContextFromType(cprops, dType, NULL, NULL, &ciErrNum); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // Get and log the device info if(shrCheckCmdLineFlag(argc, argv, "device")) { int device_nr = 0; shrGetCmdLineArgumenti(argc, argv, "device", &device_nr); cdDevice = oclGetDev(cxGPUContext, device_nr); } else { cdDevice = oclGetMaxFlopsDev(cxGPUContext); } oclPrintDevInfo(LOGBOTH, cdDevice); // create a command-queue cqCommandQueue = clCreateCommandQueue(cxGPUContext, cdDevice, 0, &ciErrNum); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // Program Setup size_t program_length; cPathAndName = shrFindFilePath("simpleGL.cl", argv[0]); shrCheckErrorEX(cPathAndName != NULL, shrTRUE, pCleanup); cSourceCL = oclLoadProgSource(cPathAndName, "", &program_length); shrCheckErrorEX(cSourceCL != NULL, shrTRUE, pCleanup); // create the program cpProgram = clCreateProgramWithSource(cxGPUContext, 1, (const char **) &cSourceCL, &program_length, &ciErrNum); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // build the program ciErrNum = clBuildProgram(cpProgram, 0, NULL, "-cl-mad-enable", NULL, NULL); if (ciErrNum != CL_SUCCESS) { // write out standard error, Build Log and PTX, then cleanup and exit shrLog(LOGBOTH | ERRORMSG, ciErrNum, STDERROR); oclLogBuildInfo(cpProgram, oclGetFirstDev(cxGPUContext)); oclLogPtx(cpProgram, oclGetFirstDev(cxGPUContext), "oclSimpleGL.ptx"); Cleanup(EXIT_FAILURE); } // create the kernel ckKernel = clCreateKernel(cpProgram, "sine_wave", &ciErrNum); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // create VBO if(!bQATest) { createVBO(&vbo); // set the args values ciErrNum = clSetKernelArg(ckKernel, 0, sizeof(cl_mem), (void *) &vbo_cl); ciErrNum |= clSetKernelArg(ckKernel, 1, sizeof(unsigned int), &mesh_width); ciErrNum |= clSetKernelArg(ckKernel, 2, sizeof(unsigned int), &mesh_height); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // If specified, compute and save off data for regression tests if(shrCheckCmdLineFlag(argc, (const char**) argv, "regression")) { // run OpenCL kernel once to generate vertex positions runKernel(); checkResultOpenCL(argc, argv, vbo); } // init timer 1 for fps measurement shrDeltaT(1); } // Start main GLUT rendering loop for processing and rendering, // or otherwise run No-GL Q/A test sequence if(!bQATest) { glutMainLoop(); } else { TestNoGL(); } // Normally unused return path Cleanup(EXIT_FAILURE); } // Initialize GL //***************************************************************************** void InitGL(int argc, const char** argv) { // initialize GLUT glutInit(&argc, (char**)argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition (glutGet(GLUT_SCREEN_WIDTH)/2 - window_width/2, glutGet(GLUT_SCREEN_HEIGHT)/2 - window_height/2); glutInitWindowSize(window_width, window_height); iGLUTWindowHandle = glutCreateWindow("OpenCL/GL Interop (VBO)"); // register GLUT callback functions glutDisplayFunc(DisplayGL); glutKeyboardFunc(KeyboardGL); glutMouseFunc(mouse); glutMotionFunc(motion); // initialize necessary OpenGL extensions glewInit(); GLboolean bGLEW = glewIsSupported("GL_VERSION_2_0 GL_ARB_pixel_buffer_object"); shrCheckErrorEX(bGLEW, shrTRUE, pCleanup); // default initialization glClearColor(0.0, 0.0, 0.0, 1.0); glDisable(GL_DEPTH_TEST); // viewport glViewport(0, 0, window_width, window_height); // projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 0.1, 10.0); // set view matrix glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, translate_z); glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(rotate_y, 0.0, 1.0, 0.0); return; } // Run the OpenCL part of the computation //***************************************************************************** void runKernel() { ciErrNum = CL_SUCCESS; size_t szGlobalWorkSize[2]; if(glInterop == shrTRUE) { ciErrNum |= clEnqueueAcquireGLObjects(cqCommandQueue, 1, &vbo_cl, 0,0,NULL); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); } // Set work size and execute the kernel szGlobalWorkSize[0] = mesh_width; szGlobalWorkSize[1] = mesh_height; ciErrNum |= clSetKernelArg(ckKernel, 3, sizeof(float), &anim); #if 1 // There is bug on this AMD_Bug - 3124 cl_event x[1]; ciErrNum |= clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 2, NULL, szGlobalWorkSize, NULL, 0,0,x ); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); ciErrNum = clWaitForEvents(1, x); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); clReleaseEvent(x[0]); #else ciErrNum |= clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 2, NULL, szGlobalWorkSize, NULL, 0,0,NULL); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); #endif if(glInterop == shrTRUE) { // unmap buffer object ciErrNum |= clEnqueueReleaseGLObjects(cqCommandQueue, 1, &vbo_cl, 0,0,0); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); clFinish(cqCommandQueue); } else { // Explicit Copy // map the PBO to copy data from the CL buffer via host glBindBufferARB(GL_ARRAY_BUFFER, vbo); // map the buffer object into client's memory void* ptr = glMapBufferARB(GL_ARRAY_BUFFER, GL_WRITE_ONLY_ARB); ciErrNum |= clEnqueueReadBuffer(cqCommandQueue, vbo_cl, CL_TRUE, 0, sizeof(float) * 4 * mesh_height * mesh_width, ptr, 0, NULL, NULL); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); glUnmapBufferARB(GL_ARRAY_BUFFER); } } // Create VBO //***************************************************************************** void createVBO(GLuint* 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); if(glInterop == shrTRUE) { // create OpenCL buffer from GL VBO vbo_cl = clCreateFromGLBuffer(cxGPUContext,CL_MEM_WRITE_ONLY, *vbo, &ciErrNum); } else { vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size, NULL, &ciErrNum); } shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); } // Delete VBO //***************************************************************************** void deleteVBO(GLuint* vbo) { clReleaseMemObject(vbo_cl); glBindBuffer(1, *vbo); glDeleteBuffers(1, vbo); *vbo = 0; } // Display callback //***************************************************************************** void DisplayGL() { // increment the geometry computation parameter (or set to reference for Q/A check) if (iFrameCount < iFrameTrigger) { anim += 0.01f; } // start timer 0 if it's update time double dProcessingTime = 0.0; if (iFrameCount >= iFrameTrigger) { shrDeltaT(0); } // run OpenCL kernel to generate vertex positions runKernel(); // get processing time from timer 0, if it's update time if (iFrameCount >= iFrameTrigger) { dProcessingTime = shrDeltaT(0); } // clear graphics then render from the vbo glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexPointer(4, GL_FLOAT, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glColor3f(1.0, 0.0, 0.0); glDrawArrays(GL_POINTS, 0, mesh_width * mesh_height); glDisableClientState(GL_VERTEX_ARRAY); // flip backbuffer to screen glutSwapBuffers(); glutPostRedisplay(); // Increment the frame counter, and do fps if it's time if (iFrameCount++ > iFrameTrigger) { // set GLUT Window Title char cTitle[256]; iFramesPerSec = (int)((double)iFrameCount/shrDeltaT(1)); if(profiling == shrTRUE) { #ifdef _WIN32 sprintf_s(cTitle, 256, "OpenCL Simple GL (VBO) | %u x %u | %i fps | Proc. t = %.3f s", mesh_width, mesh_height, iFramesPerSec, dProcessingTime); #else sprintf(cTitle, "OpenCL Simple GL (VBO) | %u x %u | %i fps | Proc. t = %.3f s", mesh_width, mesh_height, iFramesPerSec, dProcessingTime); #endif } else { #ifdef _WIN32 sprintf_s(cTitle, 256, "OpenCL Simple GL (VBO) | W: %u H: %u", mesh_width, mesh_height ); #else sprintf(cTitle, "OpenCL Simple GL (VBO) | W: %u H: %u", mesh_width, mesh_height); #endif } glutSetWindowTitle(cTitle); // Log fps and processing info to console and file shrLog(LOGBOTH, 0, " %s\n", cTitle); // Cleanup up and quit if requested and counter is up iTestSets--; if (bNoPrompt && (!iTestSets)) { Cleanup(EXIT_SUCCESS); } // reset framecount, trigger and timer iFrameCount = 0; iFrameTrigger = (iFramesPerSec > 1) ? iFramesPerSec * 2 : 1; } } // Keyboard events handler //***************************************************************************** void KeyboardGL(unsigned char key, int x, int y) { switch(key) { case '\033': // escape quits case '\015': // Enter quits case 'Q': // Q quits case 'q': // q (or escape) quits // Cleanup up and quit Cleanup(EXIT_SUCCESS); break; } } // Mouse event handlers //***************************************************************************** void mouse(int button, int state, int x, int y) { if (state == GLUT_DOWN) { mouse_buttons |= 1<<button; } else if (state == GLUT_UP) { mouse_buttons = 0; } mouse_old_x = x; mouse_old_y = y; glutPostRedisplay(); } void motion(int x, int y) { float dx, dy; dx = x - mouse_old_x; dy = y - mouse_old_y; if (mouse_buttons & 1) { rotate_x += dy * 0.2; rotate_y += dx * 0.2; } else if (mouse_buttons & 4) { translate_z += dy * 0.01; } mouse_old_x = x; mouse_old_y = y; // set view matrix glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, translate_z); glRotatef(rotate_x, 1.0, 0.0, 0.0); glRotatef(rotate_y, 0.0, 1.0, 0.0); glutPostRedisplay(); } // If specified, write data to file for external regression testing //***************************************************************************** void checkResultOpenCL(int argc, const char** argv, const GLuint& vbo) { // map buffer object glBindBuffer(GL_ARRAY_BUFFER_ARB, vbo); float* data = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); // save data for regression testing result shrWriteFilef("./data/regression.dat", data, mesh_width * mesh_height * 3, 0.0); // unmap GL buffer object if(!glUnmapBuffer(GL_ARRAY_BUFFER)) { shrLog(LOGBOTH, 0, "Unmap buffer failed !\n"); } } // Run a test sequence without any GL //***************************************************************************** void TestNoGL() { // Set work size and execute the kernel without GL ciErrNum = CL_SUCCESS; size_t szGlobalWorkSize[2]; szGlobalWorkSize[0] = mesh_width; szGlobalWorkSize[1] = mesh_height; unsigned int size = mesh_width * mesh_height * 4 * sizeof(float); vbo_cl = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, size, NULL, &ciErrNum); ciErrNum = clSetKernelArg(ckKernel, 0, sizeof(cl_mem), (void *) &vbo_cl); ciErrNum |= clSetKernelArg(ckKernel, 1, sizeof(unsigned int), &mesh_width); ciErrNum |= clSetKernelArg(ckKernel, 2, sizeof(unsigned int), &mesh_height); ciErrNum |= clSetKernelArg(ckKernel, 3, sizeof(float), &anim); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); // Warmup call to assure OpenCL driver is awake ciErrNum = clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 2, NULL, szGlobalWorkSize, NULL, 0, 0, 0 ); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); clFinish(cqCommandQueue); // Start timer 0 and process n loops on the GPU int iterations = 1; if(profiling == shrTRUE) iterations = 10; shrDeltaT(0); for (int i = 0; i < iterations; i++) { ciErrNum = clEnqueueNDRangeKernel(cqCommandQueue, ckKernel, 2, NULL, szGlobalWorkSize, NULL, 0, 0, 0 ); shrCheckErrorEX(ciErrNum, CL_SUCCESS, pCleanup); clFinish(cqCommandQueue); } // Get elapsed time and throughput, then log to sample and master logs double dAvgTime = shrDeltaT(0)/(double)iterations; shrLog(LOGBOTH | MASTER, 0, "oclSimpleGL, Throughput = %.4f, Time = %.5f, Size = %u, NumDevsUsed = %u\n", (1.0e-6 * mesh_width * mesh_height)/dAvgTime, dAvgTime, (mesh_width * mesh_height), 1); // Cleanup and exit Cleanup(EXIT_SUCCESS); } // Function to clean up and exit //***************************************************************************** void Cleanup(int iExitCode) { // Cleanup allocated objects shrLog(LOGBOTH, 0, "\nStarting Cleanup...\n\n"); if(cPathAndName)free(cPathAndName); if(cSourceCL)free(cSourceCL); if(vbo_cl && vbo)deleteVBO(&vbo); if(ckKernel)clReleaseKernel(ckKernel); if(cpProgram)clReleaseProgram(cpProgram); if(cqCommandQueue)clReleaseCommandQueue(cqCommandQueue); if(cxGPUContext)clReleaseContext(cxGPUContext); if(iGLUTWindowHandle)glutDestroyWindow(iGLUTWindowHandle); shrLog(LOGBOTH, 0, "TEST %s\n\n", iExitCode == 0 ? "PASSED" : "FAILED !!!"); // finalize logs and leave if (bQATest || bNoPrompt) { shrLog(LOGBOTH | CLOSELOG, 0, "oclSimpleGL.exe Exiting...\n"); } else { shrLog(LOGBOTH | CLOSELOG, 0, "oclSimpleGL.exe Exiting...\nPress <Enter> to Quit\n"); #ifdef WIN32 getchar(); #endif } exit (iExitCode); } ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| simpleGL.cl file /* * Copyright 1993-2009 NVIDIA Corporation. All rights reserved. * * NVIDIA Corporation and its licensors retain all intellectual property and * proprietary rights in and to this software and related documentation. * Any use, reproduction, disclosure, or distribution of this software * and related documentation without an express license agreement from * NVIDIA Corporation is strictly prohibited. * * Please refer to the applicable NVIDIA end user license agreement (EULA) * associated with this source code for terms and conditions that govern * your use of this NVIDIA software. * */ /* This example demonstrates how to use the OpenCL/OpenGL bindings */ /////////////////////////////////////////////////////////////////////////////// //! Simple kernel to modify vertex positions in sine wave pattern //! @param data data in global memory /////////////////////////////////////////////////////////////////////////////// __kernel void sine_wave(__global float4* pos, unsigned int width, unsigned int height, float time) { unsigned int x = get_global_id(0); unsigned int y = get_global_id(1); // calculate uv coordinates float u = x / (float) width; float v = y / (float) height; u = u*2.0f - 1.0f; v = v*2.0f - 1.0f; // calculate simple sine wave pattern float freq = 4.0f; float w = sin(u*freq + time) * cos(v*freq + time) * 0.5f; // write output vertex pos[y*width+x] = (float4)(u, w, v, 1.0f); }

0 Likes

Is this problem solved in SDK v2.1?

I try but I still got CL_INVALID_IMAGE_FORMAT_DESCRIPTOR error

Any one konws how to create image object from GL texture?

Thank u in advance!

0 Likes

libai,

Could you post your source code?(host and kernel)

Its easy to track down the problem that way. 

0 Likes

sure,omkaranathan.

can i just post the related part here, the whole code is too long.

I got CL_INVALID_IMAGE_FORMAT_DESCRIPTO  error with the code.

Thank u!

GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_INT, NULL); outputImage2D = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, &clErr);

0 Likes

i think problem is with internal format.it should match with supported formats in OpenCL. currently it is only bare minimum which define OpenCL specificaton.

try change GL_RGBA to GL_RGBA

0 Likes
libai
Journeyman III

nou, thank u.

I try change CL_RGBA to GL_RGBA and find that now it doesn't return CL_INVALID_IMAGE_FORMAT_DESCRIPTO error anymore.

However, clErr still doesn't equal to CL_SUCCESS

I try the code below to check the error. The output is just "error create from gl texture." and nothing else.

Anyone konws what's wrong?

Thank u all.

GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_INT, NULL); outputImage2D = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, &clErr); if(clErr != CL_SUCCESS) std::cout << "error create from gl texture.\n"; if(clErr == CL_INVALID_CONTEXT) std::cout << "error invalid context.\n"; else if(clErr == CL_INVALID_VALUE) std::cout << "error invalid value.\n"; else if(clErr == CL_INVALID_GL_OBJECT) std::cout << "error invalid gl object.\n"; else if(clErr == CL_INVALID_IMAGE_FORMAT_DESCRIPTOR) std::cout << "error invalid image format descriptor.\n"; else if(clErr == CL_OUT_OF_HOST_MEMORY) std::cout << "error out of host memory.\n";

0 Likes

What is the error code the program is returning? 

0 Likes

omkaranathan, thank u.

There is NO error code return so I feel confused.

Thanks again.

0 Likes

What is the value of clErr after the clCreateFromGLTexture2D call?

0 Likes

omkaranathan, the value is -4.

accoding to cl.h, this error means CL_MEM_OBJECT_ALLOCATION_FAILURE.

I never expect clCreateFromGLTexture2D will return this error, so I feel confused

Thank u.

0 Likes

Please post your source code, (compilable testcase). It would be easier to track down the problem that way.

0 Likes

ok, thank u, omkaranathan.

I write the test code below. I have tried to make it short.

Thank u!

#include<iostream> #include<cmath> using namespace std; #ifndef _WIN32 #include <GL/glx.h> #endif //!_WIN32 #include <windows.h> #include <GL/glew.h> #if defined (__APPLE__) || defined(MACOSX) #include <GLUT/glut.h> #else #include <GL/glut.h> #endif #include <CL/cl_gl.h> static GLint ImageWidth = 2592; static GLint ImageHeight = 1920; //vars cl_uchar* inputImageData; cl_uchar* outputImageData; cl_uint* inputImageTemp; cl_uint* outputImageTemp; cl_context context; cl_device_id Device; cl_platform_id platform; cl_mem inputImageBuffer; cl_mem outputImage2D; cl_command_queue commandQueue; cl_program program; cl_kernel kernel; cl_int width; cl_int height; size_t kernelWorkGroupSize; size_t blockSizeX; size_t blockSizeY; //kernel : For test only const char *OpenCLSource[] = { "__kernel void bilinear(__global const unsigned int* inputImage, __write_only image2d_t outputImage)\n", "{\n", " unsigned int x = get_global_id(0);\n", " unsigned int y = get_global_id(1);\n", " int2 coord = (int2)(get_global_id(0), get_global_id(1));\n", " unsigned int width = get_global_size(0);\n", " unsigned int height = get_global_size(1);\n", " uint4 temp;\n", " unsigned int c = x + y * width;\n", " if( x >= 1 && x < (width-1) && y >= 1 && y < (height - 1) )\n", " {\n", " temp = inputImage;\n", " write_imageui(outputImage, coord, temp);\n", " }\n", "}\n", }; //GL display function void displayFunc(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); //paste texture glBegin(GL_QUADS); glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(1.0f, -1.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(1.0f, 1.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex2f(-1.0f, 1.0f); glEnd(); glutSwapBuffers(); } void main(int argc, char * argv[]) { //setup GL glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(ImageWidth, ImageHeight); glutCreateWindow("test"); // GL init glewInit(); glEnable(GL_TEXTURE_2D); glClearColor(0.0, 0.0, 0.0, 1.0); glDisable(GL_DEPTH_TEST); glViewport(0, 0, ImageWidth, ImageHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( 60.0, (GLfloat)ImageWidth / (GLfloat) ImageHeight, 0.1, 10.0); glutDisplayFunc(displayFunc); //read input image FILE * img; fopen_s(&img, "Bilinear_Input.bmp", "rb"); width = ImageWidth; height = ImageHeight; inputImageData = (cl_uchar*)malloc(sizeof(cl_uchar) * width * height * 3); fseek(img, 54, SEEK_SET); fread(inputImageData, 1, sizeof(cl_uchar) * width * height * 3, img); fclose(img); inputImageTemp = (cl_uint *)malloc(sizeof(cl_uint) * width * height * 3); for(int i = 0; i < width * height * 3; i ++) inputImageTemp = inputImageData - '0'; outputImageTemp = (cl_uint*)malloc(sizeof(cl_uint) * width * height * 3); memset(outputImageTemp, 0, sizeof(cl_uint) * width * height * 3); cl_int clErr = CL_SUCCESS; cl_device_type dType = CL_DEVICE_TYPE_GPU; //get platform id clErr = clGetPlatformIDs(1, &platform, NULL); if(clErr != CL_SUCCESS) std::cout << "error get platform ID\n"; //get device id clErr = clGetDeviceIDs(platform, dType, 1, &Device, NULL); if(clErr != CL_SUCCESS) std::cout << "error get device ID\n"; //check image support cl_bool imageSupport; clErr = clGetDeviceInfo(Device, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &imageSupport, 0); if(imageSupport != CL_TRUE) std::cout << "image not support.\n"; //create GL context #ifdef _WIN32 HGLRC glCtx = wglGetCurrentContext(); #else //!_WIN32 GLXContext glCtx = glXGetCurrentContext(); #endif //!_WIN32 cl_context_properties cpsGL[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, #ifdef _WIN32 CL_WGL_HDC_KHR, (intptr_t) wglGetCurrentDC(), #else //!_WIN32 CL_GLX_DISPLAY_KHR, (intptr_t) glXGetCurrentDisplay(), #endif //!_WIN32 CL_GL_CONTEXT_KHR, (intptr_t) glCtx, 0}; context = clCreateContextFromType( cpsGL, dType, NULL, NULL, &clErr); if(clErr != CL_SUCCESS) std::cout << "error creat context form type\n"; // create a command-queue commandQueue = clCreateCommandQueue(context, Device, 0, &clErr); if(clErr != CL_SUCCESS) std::cout << "error create command queue\n"; //craete input image buffer inputImageBuffer = clCreateBuffer( context, CL_MEM_READ_ONLY| CL_MEM_COPY_HOST_PTR, sizeof(cl_uint) * width * height * 3, inputImageTemp, &clErr); if(clErr != CL_SUCCESS) std::cout << "error create input image buffer.\n"; if(clErr == CL_INVALID_CONTEXT) std::cout << "error invalid context\n"; else if(clErr == CL_INVALID_VALUE) std::cout << "error invalid value\n"; else if(clErr == CL_INVALID_BUFFER_SIZE) std::cout << "error invalid buffer size.\n"; else if(clErr == CL_INVALID_HOST_PTR) std::cout << "error invalid host ptr.\n"; else if(clErr == CL_MEM_OBJECT_ALLOCATION_FAILURE) std::cout << "error mem object allocation failure.\n"; else if(clErr == CL_OUT_OF_HOST_MEMORY) std::cout << "error out of host memory.\n"; //create GL texture GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_INT, NULL); //CL image object create from GL texture outputImage2D = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, &clErr); if(clErr != CL_SUCCESS) std::cout << "error create from gl texture.\n"; if(clErr == CL_INVALID_CONTEXT) std::cout << "error invalid context.\n"; else if(clErr == CL_INVALID_VALUE) std::cout << "error invalid value.\n"; else if(clErr == CL_INVALID_GL_OBJECT) std::cout << "error invalid gl object.\n"; else if(clErr == CL_INVALID_IMAGE_FORMAT_DESCRIPTOR) std::cout << "error invalid image format descriptor.\n"; else if(clErr == CL_OUT_OF_HOST_MEMORY) std::cout << "error out of host memory.\n"; // Program Setup // create the program program = clCreateProgramWithSource(context, 15, OpenCLSource, NULL, &clErr); if(clErr != CL_SUCCESS) std::cout << "error create program with source\n"; // build the program cl_device_id deviceIDs[] = {Device}; clErr = clBuildProgram(program, 1, deviceIDs, NULL, NULL, NULL); if(clErr != CL_SUCCESS) std::cout << "error build program\n"; if(clErr == CL_INVALID_PROGRAM) std::cout << "error invalid program.\n"; else if(clErr == CL_INVALID_VALUE) std::cout << "error invalid value.\n"; else if(clErr == CL_INVALID_DEVICE) std::cout << "error invalid device.\n"; else if(clErr == CL_INVALID_BINARY) std::cout << "error invalid binary.\n"; else if(clErr == CL_INVALID_BUILD_OPTIONS) std::cout << "error invalid build options.\n"; else if(clErr == CL_INVALID_OPERATION) std::cout << "error invalid operation.\n"; else if(clErr == CL_COMPILER_NOT_AVAILABLE) std::cout << "error compiler not available.\n"; else if(clErr == CL_BUILD_PROGRAM_FAILURE) std::cout << "error build program failure.\n"; else if(clErr == CL_OUT_OF_HOST_MEMORY) std::cout << "error out of host memory.\n"; // create the kernel kernel = clCreateKernel(program, "bilinear", &clErr); if(clErr != CL_SUCCESS) std::cout << "error create kernel.\n"; blockSizeX = 216; blockSizeY = 1; //set args clErr = clSetKernelArg( kernel, 0, sizeof(cl_mem), (void *)&inputImageBuffer); if(clErr != CL_SUCCESS) std::cout << "error set arg 0.\n"; clErr = clSetKernelArg( kernel, 1, sizeof(cl_mem), (void *)&outputImage2D); if(clErr != CL_SUCCESS) std::cout << "error set arg 1\n"; clErr = clGetKernelWorkGroupInfo(kernel, Device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &kernelWorkGroupSize, 0); if(clErr != CL_SUCCESS) std::cout << "error get kernel work group info.\n"; /* * Enqueue a kernel run call. */ size_t globalThreads[] = {width, height}; size_t localThreads[] = {blockSizeX, blockSizeY}; cl_event evt1, evt2; //acquire GL object clErr = clEnqueueAcquireGLObjects(commandQueue, 1, &outputImage2D, 0, NULL, &evt1); if(clErr != CL_SUCCESS) std::cout << "error enqueue acquire GL object.\n"; clErr = clEnqueueNDRangeKernel( commandQueue, kernel, 2, NULL, globalThreads, localThreads, 0, NULL, &evt2); if(clErr != CL_SUCCESS) std::cout << "error enqueue nd range kernel.\n"; cl_event events[] = {evt2}; /* Enqueue readBuffer*/ size_t origin[] = {0, 0, 0}; size_t region[] = {width, height, 1}; clErr = clEnqueueReadImage( commandQueue, outputImage2D, 1, origin, region, 0, 0, outputImageTemp, 1, events, NULL); if(clErr != CL_SUCCESS) std::cout << "error enqueue read image.\n"; clErr = clEnqueueReleaseGLObjects(commandQueue, 1, &outputImage2D, 0, 0, NULL); if(clErr != CL_SUCCESS) std::cout << "error cl enqueue release GL object.\n"; clErr = clFinish(commandQueue); if(clErr != CL_SUCCESS) std::cout << "error cl finish command queue.\n"; glutMainLoop(); //clean up clErr = clReleaseMemObject(inputImageBuffer); clErr = clReleaseMemObject(outputImage2D); clErr = clReleaseKernel(kernel); clErr = clReleaseProgram(program); if(clErr != CL_SUCCESS) std::cout << "error release program.\n"; clErr = clReleaseCommandQueue(commandQueue); clErr = clReleaseContext(context); }

0 Likes

Still no answers?

0 Likes

libai,

I'm able to reproduce the issue.  I have informed the developers and they r looking into it.

0 Likes

Thanks, omkaranathan.

0 Likes

If there's any update news, please let me kown. thanks

0 Likes

libai,
The default state of a texture in OpenGL for GL_TEXTURE_MIN_FILTER is
GL_NEAREST_MIPMAP_LINEAR. Therefore the texture is INVALID when the clCreateFromGLTexture2D is made which is the reason for failure.

0 Likes

Hi,

I've been trying for a while to share Texture2D/Image2D between OpenGL and OpenCL. Until now no success.

In my code, althouth no error is shown, the texture that I process using OpenCL ends up empty (all black, completly filled with zeros).

Does anyone has used this feature (sharing textures between CL-GL) successfully?

Thaks

0 Likes

did you try SimpleGL sample?

0 Likes

nosense,

you can look at the simpleGL sample to see cl/GL interop as nou suggested?

There is also a webinar which addressed this topic.

http://developer.amd.com/zones/OpenCLZone/Events/pages/OpenCLWebinars.aspx

0 Likes

In fact I have already done CL/GL interop using "buffer objects" (with the funtion clCreateFromGLBuffer). Sorry for not clearing that out in the first post.

My problem is to share other GL-objects like "Texture2D" or "RenderBuffers" using the CL funtions "clCreateFromGLTexture2D" and "clCreateFromGLRenderbuffer".

I'm assuming that this functionality is already provided by AMD drivers. Although, I cannot find any place stating that assumption or negating it.

himanshu.gautam - I'll try to search in the webinar.

Thanks

0 Likes

in  fact sharing textures are same as buffers. only difference is that you got a image2d_t.

and i got similiar black result when you use wrong format of GL texture and write_imagef().

what format do you use in OpenGL texture inicialization and what function write_image() in OpenCL kernel?

0 Likes

Ok, I'll start by explaining my code, I created a simple CLKernel that reads from a "CL/GL-BufferObject" and writes to another "CL/GL-BufferObject". After I got this working, I replaced the input "CL/GL-BufferObject" by a "CL/GL-Texture2D".

In OpenGL I use "Rgba8" with pixel type "UnsignedByte". In OpenCL kernel I am using "read_imageui(...)", because I am reading from a texture and writing in a buffer object.

Thanks

kernel void MySuperKernel( __read_only image2d_t imageIn, // data IN global uchar4 *data // data OUT ) { int gidX = get_global_id(0); int gidY = get_global_id(1); int2 myCoords = (int2)(gidX, gidY); const sampler_t mySampler = CLK_NORMALIZED_COORDS_FALSE | //Natural coordinates CLK_ADDRESS_CLAMP | //Clamp to zeros CLK_FILTER_NEAREST; //Don't interpolate uchar4 color = convert_uchar4(read_imageui(imageIn, mySampler, myCoords)); data[gidX + gidY*800] = color; // the texture 'imageIn' has 800x450pixels }

0 Likes

from GL_RGBA8 it create image with CL_RGBA or CL_BGRA with data type CL_UNORM_INT8

whci can be read/write only with float variant of functions. refer to table 9.4 and sectio 6.11.13.2

0 Likes

Thanks nou, I've totally missed that.

I changed my kernel to get the texel using "read_imagef()" and convert it from [0,1] to [0, 255] but the result remains. Zero everywhere. =\

Have anyone successefully worked with this before?

0 Likes

i use OpenGL/OpenCL interoperbility in my application with textures.

0 Likes

Finally, I have figure out what I was doing wrong (beware, noob error ahead!).

So, after correcting the problem pointed out by nou, and after I knew for sure this should work, I read (again) thoroughly my code.

I then I found out that I was creating the texture I wanted to share before I created the OpenCL context.

Once I changed the order of this operations it was all running smoothly.

Thanks for all the input.

0 Likes
ha88
Journeyman III

Hi ,

I am writing a cl-gl interop in which I am sharing a texture object created in openGL with OpenCL.

I created the texture object in openGL like this

glGenTextures(1,&texture);

glBindTexture(GL_TEXTURE_2D, texture);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_FLOAT, 0);



 

I created gl context then cl context and then shared the buffer with cl as follows:

cl_texture = clCreateFromGLTexture2D(context,CL_MEM_READ_WRITE,GL_TEXTURE_2D,0,texture,&status);

After running I get an error here -59 CL_INVALID_OPERATION  which acc to the spec for this function means: 

CL_INVALID_OPERATION if texture is a GL texture object created with a border width value greater than zero.

But in my openGL glTexImage2D function I am passing border size as 0.



What am I doing wrong? Please help.

0 Likes

Hi ha88,

 

I am only  reading my texure but this is how I created the texture buffer

glBindTexture(GL_TEXTURE_2D, c_TextureID[TEXTURE_ID_NORMAL]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, c_Width, c_Height, 0, GL_RGBA, GL_FLOAT, NULL); .... c_mem_Normal = clCreateFromGLTexture2D( device->c_Context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, p_CSMBuffers->NormalTextureID, &status);

0 Likes

Hi tonyo_au,

I tried changing to the code you gave, but I'm still getting the same error.

This error is returned by clCreateFromGLTexture2D. errorcode = -59

CL_INVALID_OPERATION if texture is a GL texture object created with a border width value greater than zero.

 any suggestions...

0 Likes
ha88
Journeyman III

Originally posted by: ha88 Hi tonyo_au,

 

I tried changing to the code you gave, but I'm still getting the same error.

 

This error is returned by clCreateFromGLTexture2D. errorcode = -59

 

CL_INVALID_OPERATION if texture is a GL texture object created with a border width value greater than zero.

 

 any suggestions...

 



 

 

Also,

Sharing VBO is  working fine, the problem is only when I share textures.

Is there something special the we must do when sharing textures that we different from vbos.

0 Likes

I tried to change my texture buffers to have a border of 1.

When I tried to attach it to the render buffer with

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+RENDER_ID_COLOUR, GL_TEXTURE_2D, c_TextureID[TEXTURE_ID_COLOUR], 0);

I also got an invalid operation with this.

I don't use the border parameter but it looks like there is some restriction with new OpenGL functions which may explain why OpenCL also fails

 

 

0 Likes