// OpenCL functions int InitialiseCLEnvironment(cl_platform_id **platform, cl_device_id ***device_id, cl_program *program, renderStruct *render) { // error flag cl_int err; char infostring[1024]; char deviceInfo[1024]; // need to ensure platform supports OpenGL OpenCL interop before querying devices // to avoid segfault when calling clGetGLContextInfoKHR int *platformSupportsInterop; //get kernel from file FILE* kernelFile = fopen(kernelFileName, "rb"); fseek(kernelFile, 0, SEEK_END); long fileLength = ftell(kernelFile); rewind(kernelFile); char *kernelSource = malloc(fileLength*sizeof(char)); long read = fread(kernelSource, sizeof(char), fileLength, kernelFile); if (fileLength != read) printf("Error reading kernel file, line %d\n", __LINE__); fclose(kernelFile); //get platform and device information cl_uint numPlatforms; err = clGetPlatformIDs(0, NULL, &numPlatforms); *platform = malloc(numPlatforms * sizeof(cl_platform_id)); *device_id = malloc(numPlatforms * sizeof(cl_device_id*)); platformSupportsInterop = malloc(numPlatforms * sizeof(*platformSupportsInterop)); err |= clGetPlatformIDs(numPlatforms, *platform, NULL); CheckOpenCLError(err, __LINE__); cl_uint *numDevices; numDevices = malloc(numPlatforms * sizeof(cl_uint)); for (cl_uint i = 0; i < numPlatforms; i++) { clGetPlatformInfo((*platform)[i], CL_PLATFORM_VENDOR, sizeof(infostring), infostring, NULL); printf("\n---OpenCL: Platform Vendor %d: %s\n", i, infostring); err = clGetDeviceIDs((*platform)[i], CL_DEVICE_TYPE_ALL, 0, NULL, &(numDevices[i])); CheckOpenCLError(err, __LINE__); (*device_id)[i] = malloc(numDevices[i] * sizeof(cl_device_id)); platformSupportsInterop[i] = 0; err = clGetDeviceIDs((*platform)[i], CL_DEVICE_TYPE_ALL, numDevices[i], (*device_id)[i], NULL); CheckOpenCLError(err, __LINE__); for (cl_uint j = 0; j < numDevices[i]; j++) { char deviceName[200]; clGetDeviceInfo((*device_id)[i][j], CL_DEVICE_NAME, sizeof(deviceName), deviceName, NULL); printf("---OpenCL: Device found %d. %s\n", j, deviceName); clGetDeviceInfo((*device_id)[i][j], CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL); if (strstr(deviceInfo, "cl_khr_gl_sharing") != NULL) { printf("---OpenCL: cl_khr_gl_sharing supported!\n"); platformSupportsInterop[i] = 1; } else { printf("---OpenCL: cl_khr_gl_sharing NOT supported!\n"); platformSupportsInterop[i] |= 0; } if (strstr(deviceInfo, "cl_khr_fp64") != NULL) { printf("---OpenCL: cl_khr_fp64 supported!\n"); } else { printf("---OpenCL: cl_khr_fp64 NOT supported!\n"); } } } printf("\n"); //////////////////////////////// // This part is different to how we usually do things. Need to get context and device from existing // OpenGL context. Loop through all platforms looking for the device: cl_device_id device = NULL; int deviceFound = 0; cl_uint checkPlatform = 0; #ifdef TRYINTEROP while (!deviceFound) { if (platformSupportsInterop[checkPlatform]) { printf("---OpenCL: Looking for OpenGL Context device on platform %d ... ", checkPlatform); clGetGLContextInfoKHR_fn pclGetGLContextInfoKHR; PTR_FUNC_PTR pclGetGLContextInfoKHR = clGetExtensionFunctionAddressForPlatform((*platform)[checkPlatform], "clGetGLContextInfoKHR"); cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glfwGetGLXContext(render->window), CL_GLX_DISPLAY_KHR, (cl_context_properties) glfwGetX11Display(), CL_CONTEXT_PLATFORM, (cl_context_properties) (*platform)[checkPlatform], 0}; err = pclGetGLContextInfoKHR(properties, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR, sizeof(cl_device_id), &device, NULL); if (err != CL_SUCCESS) { printf("Not Found.\n"); checkPlatform++; if (checkPlatform > numPlatforms-1) { printf("---OpenCL: Error! Could not find OpenGL sharing device.\n"); deviceFound = 1; render->glclInterop = 0; } } else { printf("Found!\n"); deviceFound = 1; render->glclInterop = 1; } } else { checkPlatform++; } } if (render->glclInterop) { // Check the device we've found supports double precision clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL); if (strstr(deviceInfo, "cl_khr_fp64") == NULL) { printf("---OpenCL: Interop device doesn't support double precision! We cannot use it.\n"); } else { cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties) glfwGetGLXContext(render->window), CL_GLX_DISPLAY_KHR, (cl_context_properties) glfwGetX11Display(), CL_CONTEXT_PLATFORM, (cl_context_properties) (*platform)[checkPlatform], 0}; render->contextCL = clCreateContext(properties, 1, &device, NULL, 0, &err); CheckOpenCLError(err, __LINE__); } } #endif // if render->glclInterop is 0, either we are not trying to use it, we couldn't find an interop // device, or we found an interop device but it doesn't support double precision. // In these cases, have the user choose a platform and device manually. if (!(render->glclInterop)) { printf("Choose a platform and device.\n"); checkPlatform = numPlatforms; while (checkPlatform >= numPlatforms) { printf("Platform: "); scanf("%u", &checkPlatform); if (checkPlatform >= numPlatforms) { printf("Invalid Platform choice.\n"); } } cl_uint chooseDevice = numDevices[checkPlatform]; while (chooseDevice >= numDevices[checkPlatform]) { printf("Device: "); scanf("%u", &chooseDevice); if (chooseDevice >= numDevices[checkPlatform]) { printf("Invalid Device choice.\n"); } else { // Check the device we've chosen supports double precision clGetDeviceInfo((*device_id)[checkPlatform][chooseDevice], CL_DEVICE_EXTENSIONS, sizeof(deviceInfo), deviceInfo, NULL); if (strstr(deviceInfo, "cl_khr_fp64") == NULL) { printf("---OpenCL: Interop device doesn't support double precision! We cannot use it.\n"); chooseDevice = numDevices[checkPlatform]; } } } // Create non-interop context render->contextCL = clCreateContext(NULL, 1, &((*device_id)[checkPlatform][chooseDevice]), NULL, NULL, &err); device = (*device_id)[checkPlatform][chooseDevice]; } //////////////////////////////// // device is now fixed. Query its max global memory allocation size and store it, used in // HighResolutionRender routine, to determine into how many tiles we need to split the // computation. clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(render->deviceMaxAlloc), &(render->deviceMaxAlloc), NULL); printf("---OpenCL: Selected device has CL_DEVICE_MAX_MEM_ALLOC_SIZE: %lfMB\n", render->deviceMaxAlloc/1024.0/1024.0); // create a command queue render->queue = clCreateCommandQueue(render->contextCL, device, 0, &err); CheckOpenCLError(err, __LINE__); //create the program with the source above // printf("Creating CL Program...\n"); *program = clCreateProgramWithSource(render->contextCL, 1, (const char**)&kernelSource, NULL, &err); if (err != CL_SUCCESS) { printf("Error in clCreateProgramWithSource: %d, line %d.\n", err, __LINE__); return EXIT_FAILURE; } //build program executable err = clBuildProgram(*program, 0, NULL, "-I. -I src/", NULL, NULL); if (err != CL_SUCCESS) { printf("Error in clBuildProgram: %d, line %d.\n", err, __LINE__); char buffer[5000]; clGetProgramBuildInfo(*program, device, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, NULL); printf("%s\n", buffer); return EXIT_FAILURE; } // dump ptx size_t binSize; clGetProgramInfo(*program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binSize, NULL); unsigned char *bin = malloc(binSize); clGetProgramInfo(*program, CL_PROGRAM_BINARIES, sizeof(unsigned char *), &bin, NULL); FILE *fp = fopen("openclPTX.ptx", "wb"); fwrite(bin, sizeof(char), binSize, fp); fclose(fp); free(bin); free(numDevices); free(kernelSource); printf("\n"); return EXIT_SUCCESS; }
void init_cl(const char ** sources, int count) { int err = CL_SUCCESS; // get the platform id for this system cl_platform_id platform; err = clGetPlatformIDs(1, &platform, NULL); cl_check_err(err, "clGetPlatformIDs(...)"); // connect to the compute device err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); cl_check_err(err, "clGetDeviceIDs(...)"); // set the platform specific context properties for OpenGL + OpenCL sharing #ifdef __APPLE__ cl_context_properties ctx_prop[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)CGLGetShareGroup(CGLGetCurrentContext()), 0}; #elif defined __linux__ cl_context_properties ctx_prop[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glfwGetGLXContext(window), CL_GLX_DISPLAY_KHR, (cl_context_properties)glfwGetX11Display(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; #elif defined __MINGW32__ cl_context_properties ctx_prop[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0}; #endif // create the working context context = clCreateContext(ctx_prop, 1, &device_id, NULL, NULL, &err); cl_check_err(err, "clCreateContext(...)"); // next up is the command queue command_queue = clCreateCommandQueue(context, device_id, 0, &err); cl_check_err(err, "clCreateCommandQueue(...)"); // create a single source buffer for the program from the input files size_t length = 0; for (int i = 0; i < count; i++) { length += file_length(sources[i]); } char * buffer = (char *)malloc(length); buffer[0] = '\0'; for (int i = 0; i < count; i++) { char * tmp = read_file(sources[i]); strcat(buffer, tmp); free(tmp); } // create the compute program from 'kernels.cl' program = clCreateProgramWithSource(context, 1, (const char **)&buffer, NULL, &err); cl_check_err(err, "clCreateProgramWithSource(...)"); free(buffer); // program already read, we don't need the buffer anymore // compile the program for our device err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); cl_check_err(err, "clBuildProgram(...)"); // create the computer kernel in the program we wish to run kernel = clCreateKernel(program, "ray_tracer", &err); cl_check_err(err, "clCreateKernel(...)"); }
int main(int argc, char** argv){ cl_int err; // START OPENGL INIT Magick::InitializeMagick(argv[0]); // start GL context and O/S window using the GLFW helper library if (!glfwInit ()) { fprintf (stderr, "ERROR: could not start GLFW3\n"); return 1; } // Demand OpenGL 4.1 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); #ifdef __APPLE__ // Use Core profile to obtain a context for the latest OpenGL spec. // Otherwise we're stuck at 2.1 std::cout<<"Apple FTW\n"; glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif window = glfwCreateWindow (WIDTH, HEIGHT, "Hello Triangle", NULL, NULL); if (!window) { fprintf (stderr, "ERROR: could not open window with GLFW3\n"); glfwTerminate(); return 1; } glfwSetWindowSize( window, WIDTH/2 , HEIGHT/2); //glfwWindowHint(GLFW_SAMPLES, 4); //glEnable( GL_MULTISAMPLE ); glfwMakeContextCurrent (window); checkGLErr( "glfwMakeContextCurrent" ); // start GLEW extension handler glewExperimental = GL_TRUE; glewInit(); glGetError(); //checkGLErr( "GLEW init" ); // END OPENGL INIT.. // START OPENCL.. std::vector<cl::Platform> platformList; cl::Platform::get(&platformList); checkErr(platformList.size()!=0 ? CL_SUCCESS : -1, "cl::Platform::get"); std::cerr << "Platform number is: " << platformList.size() << std::endl; std::string platformVendor; platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor); std::cerr << "Platform is by: " << platformVendor << "\n"; #ifdef __APPLE__ CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties cprops[6] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(),CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE , (cl_context_properties) kCGLShareGroup, 0, 0}; cl::Context context( CL_DEVICE_TYPE_CPU, cprops, NULL, NULL, &err); #endif #ifdef __linux__ cl_platform_id platform; err = clGetPlatformIDs(1, &platform, NULL); cl_context_properties props[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glfwGetGLXContext( window ), CL_GLX_DISPLAY_KHR, (cl_context_properties)glfwGetX11Display(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; cl::Context context( CL_DEVICE_TYPE_CPU, props, NULL, NULL, &err); //cl::Context context = clCreateContextFromType(props, CL_DEVICE_TYPE_CPU, NULL, NULL, &err); #endif checkErr(err, "Context::Context()"); std::cout<<"Created context."<< std::endl; // Create shared texture. pCLTarget = new RenderTarget( WIDTH, HEIGHT, GL_RGBA , GL_RGBA, GL_FLOAT, 0, false ); checkGLErr( "RenderTarget::RenderTarget" ); pAccumulator = new RenderTarget( WIDTH, HEIGHT, GL_RGBA, GL_RGBA, GL_FLOAT, 0, false ); checkGLErr( "RenderTarget::RenderTarget" ); const int inSizeS = 3; const int inSizeP = 0; const int inSizeT = 12; const int inSurf = 5; /* float* outH = new float[inSize]; cl::Buffer outCL( context, CL_MEM_WRITE_ONLY, inSize * sizeof( float ) ); */ Sphere* spheres = new Sphere[inSizeS]; std::cout<<"Sphere: "<< spheres[0].radius << "\n"; spheres[1].uSurf = 0; spheres[1].center = glm::vec4( 0.0f, -2.0f, 0.0f, 0.0f ); spheres[1].radius = 1.0f; /*spheres[1].uSurf = 0; spheres[1].center = glm::vec4( +1.0f, 0.0f, +1.0f, 0.0f); spheres[1].radius = 1.0f;*/ spheres[0].uSurf = 2; spheres[0].center = glm::vec4( 0.0f, +1.50f, 0.0f, 0.0f); spheres[0].radius = 0.2f; /*spheres[2].uSurf = 0; spheres[2].center = glm::vec4( +0.0f, 0.0f, -0.0f, 0.0f); spheres[2].radius = 1.0f;*/ spheres[2].uSurf = 0; spheres[2].center = glm::vec4( -2.0f, -2.0f, -2.0f, 0.0f); spheres[2].radius = 1.0f; /*spheres[4].uSurf = 0; spheres[4].center = glm::vec4( -1.0f, -0.0f, +1.0f, 0.0f); spheres[4].radius = 1.0f;*/ Plane* planes = new Plane[inSizeP]; int planeSize = 3.0f; //std::cout<<"Sphere: "<< planes[0].radius << "\n"; /*planes[0].normal = glm::vec4( 0.0f, 1.0f, 0.0f, 0.0f ); planes[0].point = glm::vec4( 0.0f, -planeSize, 0.0f, 0.0f ); planes[0].uSurf = 1; planes[1].normal = glm::vec4( 0.0f, -1.0f, 0.0f, 0.0f ); planes[1].point = glm::vec4( 0.0f, planeSize, 0.0f, 0.0f ); planes[1].uSurf = 1; planes[2].normal = glm::vec4( 1.0f, 0.0f, 0.0f, 0.0f ); planes[2].point = glm::vec4( -planeSize, 0.0f, 0.0f, 0.0f ); planes[2].uSurf = 1; planes[3].normal = glm::vec4( -1.0f, 0.0f, 0.0f, 0.0f ); planes[3].point = glm::vec4( planeSize, 0.0f, 0.0f, 0.0f ); planes[3].uSurf = 1; planes[4].normal = glm::vec4( 0.0f, 0.0f, +1.0f, +0.0f ); planes[4].point = glm::vec4( 0.0f, 0.0f, -planeSize, 0.0f ); planes[4].uSurf = 1; planes[5].normal = glm::vec4( 0.0f, 0.0f, -1.0f, 0.0f ); planes[5].point = glm::vec4( 0.0f, 0.0f, +planeSize, 0.0f ); planes[5].uSurf = 1;*/ Triangle* triangles = new Triangle[inSizeT]; //std::cout<<"Sphere: "<< spheres[0].radius << "\n"; float boxSize = 3.0f; triangles[0].uSurf = 1; triangles[0].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f); triangles[0].p1 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f); triangles[0].p2 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f); triangles[1].uSurf = 1; triangles[1].p0 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f); triangles[1].p2 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f); triangles[1].p1 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f); triangles[2].uSurf = 1; triangles[2].p0 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f); triangles[2].p2 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f); triangles[2].p1 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f); triangles[3].uSurf = 1; triangles[3].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f); triangles[3].p1 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f); triangles[3].p2 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f); triangles[4].uSurf = 1; triangles[4].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f); triangles[4].p2 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f); triangles[4].p1 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f); triangles[5].uSurf = 1; triangles[5].p0 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f); triangles[5].p1 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f); triangles[5].p2 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f); triangles[6].uSurf = 1; triangles[6].p0 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f); triangles[6].p1 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f); triangles[6].p2 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f); triangles[7].uSurf = 1; triangles[7].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f); triangles[7].p2 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f); triangles[7].p1 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f); triangles[8].uSurf = 3; triangles[8].p0 = glm::vec4( -boxSize, -boxSize, -boxSize, 0.0f); triangles[8].p1 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f); triangles[8].p2 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f); triangles[9].uSurf = 3; triangles[9].p0 = glm::vec4( boxSize, boxSize, -boxSize, 0.0f); triangles[9].p2 = glm::vec4( boxSize, -boxSize, -boxSize, 0.0f); triangles[9].p1 = glm::vec4( -boxSize, boxSize, -boxSize, 0.0f); triangles[10].uSurf = 4; triangles[10].p0 = glm::vec4( -boxSize, -boxSize, boxSize, 0.0f); triangles[10].p2 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f); triangles[10].p1 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f); triangles[11].uSurf = 4; triangles[11].p0 = glm::vec4( boxSize, boxSize, boxSize, 0.0f); triangles[11].p1 = glm::vec4( boxSize, -boxSize, boxSize, 0.0f); triangles[11].p2 = glm::vec4( -boxSize, boxSize, boxSize, 0.0f); /*triangles[12].uSurf = 1; triangles[12].p0 = glm::vec4( -boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f); triangles[12].p1 = glm::vec4( boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f); triangles[12].p2 = glm::vec4( -boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f); triangles[13].uSurf = 1; triangles[13].p0 = glm::vec4( boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f); triangles[13].p2 = glm::vec4( boxSize/4.0f, boxSize, -boxSize/4.0f, 0.0f); triangles[13].p1 = glm::vec4( -boxSize/4.0f, boxSize, boxSize/4.0f, 0.0f);*/ GeometryDescriptor* geometry = new GeometryDescriptor( inSizeS, inSizeP, inSizeT ); Surface* pSurf = new Surface[inSurf]; pSurf[0].vColor = glm::vec4( 1.0f, 1.0f, 0.0f, 1.0f ); pSurf[1].vColor = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f ); pSurf[2].vColor = glm::vec4( 1.0f, 1.0f, 1.0f, 1.0f ); float lPower = 5.0f; pSurf[2].vEmissive = glm::vec4( lPower, lPower, lPower, lPower ); pSurf[3].vColor = glm::vec4( 1.0f, 0.0f, 0.0f, 1.0f ); pSurf[4].vColor = glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ); cl::Buffer clSpheres( context, CL_MEM_READ_ONLY, inSizeS * sizeof( Sphere )); checkErr(err, "Buffer::Buffer()"); cl::Buffer clPlanes( context, CL_MEM_READ_ONLY, inSizeP * sizeof( Plane ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clTriangles( context, CL_MEM_READ_ONLY, inSizeT * sizeof( Triangle ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clCamera( context, CL_MEM_READ_ONLY, 1 * sizeof( CLCamera ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clGeom( context, CL_MEM_READ_ONLY, 1 * sizeof( GeometryDescriptor ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clImgDesc( context, CL_MEM_READ_ONLY, 1 * sizeof( ImageDescriptor ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clSeed( context, CL_MEM_READ_WRITE, WIDTH * HEIGHT * 4 * sizeof( uint ) ); checkErr(err, "Buffer::Buffer()"); cl::Buffer clSurf( context, CL_MEM_READ_WRITE, inSurf * sizeof( Surface ) ); checkErr(err, "Buffer::Buffer()"); cl::ImageGL imgGL( context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, pCLTarget->getColorTexture()->glGetInternalTexture(), &err ); checkErr(err, "ImageGL::ImageGL()"); cl::ImageGL accGL( context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, pAccumulator->getColorTexture()->glGetInternalTexture(), &err ); checkErr(err, "ImageGL::ImageGL()"); std::cout<<"Created buffers."<< std::endl; srand( time( NULL ) ); uint *pSeeds = new uint[WIDTH * HEIGHT * 4]; for( int i = 0; i < WIDTH * HEIGHT * 4; i++ ){ pSeeds[i] = rand(); } std::vector<cl::Device> devices; devices = context.getInfo<CL_CONTEXT_DEVICES>(); checkErr(devices.size() > 0 ? CL_SUCCESS : -1, "devices.size() > 0"); std::cout<<"Num available devices: "<< devices.size()<< std::endl; std::ifstream file("src/kernel/kernel0.cl"); checkErr(file.is_open() ? CL_SUCCESS:-1, "src/kernel/kernel0.cl"); std::string prog( std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>())); cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length()+1)); std::cout<<"Source obtained."<< std::endl; cl::Program program(context, source); err = program.build(devices,"-cl-opt-disable"); std::cout<<"Source obtained."<< std::endl; std::string buildLog; program.getBuildInfo( devices[0], CL_PROGRAM_BUILD_LOG, &buildLog ); std::cout<<"Build log:" << buildLog<< std::endl; checkErr(err, "Program::build()"); std::cout<<"Built program"<< std::endl; cl::Kernel kernel(program, "bi_directional_path_trace", &err); checkErr(err, "Kernel::Kernel()"); err = kernel.setArg(0, clCamera); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(1, imgGL); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(2, accGL); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(3, clSpheres); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(4, clPlanes); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(5, clTriangles); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(6, clGeom); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(7, clImgDesc); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(8, clSeed); checkErr(err, "Kernel::setArg()"); err = kernel.setArg(9, clSurf); checkErr(err, "Kernel::setArg()"); std::cout<<"Built Kernel"<< std::endl; pCamera = new ModelCamera( window ); pCamera->setSpeedX( 0.03f ); pCamera->setSpeedY( 0.03f ); pCamera->setRadius( 8.0f ); pCamera->setOrientation( glm::vec3( 0.0f, -1.0f, 0.0f ) ); pCamera->reset( glm::vec3( 1.0f, 0.1f, -0.1f ) ); cl::CommandQueue queue(context, devices[0], 0, &err); checkErr(err, "CommandQueue::CommandQueue()"); CLCamera* cam = pCamera->getCLCamera(); std::cout<<cam->vPos.x<<","<<cam->vPos.y<<","<<cam->vPos.z<<std::endl; std::cout<<cam->vLookAt.x<<","<<cam->vLookAt.y<<","<<cam->vLookAt.z<<std::endl; std::cout<<cam->vUp.x<<","<<cam->vUp.y<<","<<cam->vUp.z<<std::endl; std::cout<< sizeof( Plane )<< std::endl; queue.enqueueWriteBuffer( clCamera, CL_TRUE, 0, 1 * sizeof(CLCamera), (const void*)cam ); queue.enqueueWriteBuffer( clSpheres, CL_TRUE, 0, inSizeS * sizeof(Sphere), (const void*)spheres); queue.enqueueWriteBuffer( clPlanes, CL_TRUE, 0, inSizeP * sizeof(Plane), (const void*)planes); queue.enqueueWriteBuffer( clTriangles, CL_TRUE, 0, inSizeT * sizeof(Triangle), (const void*)triangles); queue.enqueueWriteBuffer( clGeom, CL_TRUE, 0, 1 * sizeof(GeometryDescriptor), (const void*)geometry); queue.enqueueWriteBuffer( clSeed, CL_TRUE, 0, WIDTH * HEIGHT * 4 * sizeof(uint), (const void*)pSeeds); queue.enqueueWriteBuffer( clSurf, CL_TRUE, 0, inSurf * sizeof(Surface), (const void*)pSurf); vSharedUnits = new std::vector<cl::Memory>(); vSharedUnits->push_back( imgGL ); vSharedUnits->push_back( accGL ); //Initialise counter. imgDesc.numSamples = 0; imgDesc.sampleRate = SAMPLES; cLast = clock(); while( !glfwWindowShouldClose( window ) ){ //usleep( 1000000 ); mainLoop( queue, context, kernel, clImgDesc, clCamera ); } /* Previous Program. Remove these if you think they are not required. float *fout = new float[inSize]; err = queue.enqueueReadBuffer( clSpheres, CL_TRUE, 0, inSize * sizeof(Sphere), fout); */ checkErr(err, "ComamndQueue::enqueueReadBuffer()"); std::cout<<"Kernel finished executing."<< std::endl; delete vSharedUnits; return EXIT_SUCCESS; }