コード例 #1
0
ファイル: clewTest.cpp プロジェクト: 20-sim/bullet3
int main(int argc, char* argv[])
{
	int result = -1;

#ifdef _WIN32
	const char* cl = "OpenCL.dll";
#elif defined __APPLE__
	const char* cl = "/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL";
#else//presumable Linux?
	//linux (tested on Ubuntu 12.10 with Catalyst 13.4 beta drivers, not that there is no symbolic link from libOpenCL.so
	const char* cl = "libOpenCL.so.1";
	result = clewInit(cl);
	if (result != CLEW_SUCCESS)
	{
		cl = "libOpenCL.so";
	} else
	{
		clewExit();
	}
#endif
	result = clewInit(cl);
	if (result!=CLEW_SUCCESS)
		printf("clewInit failed with error code %d\n",result);
	else
	{
		printf("clewInit succesfull using %s\n",cl);

		//some test and then
		clewExit();
	}
	

	return 0;
}
コード例 #2
0
void EasyCL::commonConstructor(cl_platform_id platform_id, cl_device_id device, bool verbose) {
    this->verbose = verbose;
    queue = 0;
    context = 0;
    profilingOn = false;

    #ifdef USE_CLEW
        bool clpresent = 0 == clewInit();
        if(!clpresent) {
            throw std::runtime_error("OpenCL library not found");
        }
    #endif
    this->platform_id = platform_id;
    this->device = device;

    if(verbose) {
        std::cout << "Using " << getPlatformInfoString(platform_id, CL_PLATFORM_VENDOR) << " , OpenCL platform: " << getPlatformInfoString(platform_id, CL_PLATFORM_NAME) << std::endl;
    //    std::cout << "Using " << getPlatformInfoString(platform_id, CL_PLATFORM_NAME) << std::endl;
        std::cout << "Using OpenCL device: " << getDeviceInfoString(device, CL_DEVICE_NAME) << std::endl;
    }

    // Context
    context = new cl_context();
    *context = clCreateContext(0, 1, &device, NULL, NULL, &error);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error creating OpenCL context, OpenCL errocode: " + errorMessage(error));
    }
    // Command-queue
    queue = new cl_command_queue;
    *queue = clCreateCommandQueue(*context, device, 0, &error);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error creating OpenCL command queue, OpenCL errorcode: " + errorMessage(error));
    }
    default_queue = new CLQueue(this, *queue);
}
コード例 #3
0
bool EasyCL::isOpenCLAvailable() {
    #ifdef USE_CLEW
        return 0 == clewInit();
    #else
        return true; // I guess?
    #endif
}
コード例 #4
0
ファイル: device_opencl.cpp プロジェクト: UPBGE/blender
bool device_opencl_init(void)
{
	static bool initialized = false;
	static bool result = false;

	if(initialized)
		return result;

	initialized = true;

	if(OpenCLInfo::device_type() != 0) {
		int clew_result = clewInit();
		if(clew_result == CLEW_SUCCESS) {
			VLOG(1) << "CLEW initialization succeeded.";
			result = true;
		}
		else {
			VLOG(1) << "CLEW initialization failed: "
			        << ((clew_result == CLEW_ERROR_ATEXIT_FAILED)
			            ? "Error setting up atexit() handler"
			            : "Error opening the library");
		}
	}
	else {
		VLOG(1) << "Skip initializing CLEW, platform is force disabled.";
		result = false;
	}

	return result;
}
コード例 #5
0
cOpenClHardware::cOpenClHardware(QObject *parent) : QObject(parent)
{
	openClAvailable = false;
	contextReady = false;
	// TODO: confirm initial value
	// initialize multi-gpu devices' indices list with empty QList
	selectedDevicesIndices = QList<int>();
	missingOpenClDLL = false;
	selectedPlatformIndex = 0;

#ifdef USE_OPENCL
#ifdef _WIN32
#ifndef _MSC_VER
	const std::wstring openclDll(L"OpenCL.dll");
	int err = clewInit(openclDll.c_str());
	if (err)
	{
		qCritical() << clewErrorString(err);
		missingOpenClDLL = true;
	}
#endif //   _MSC_VER
#endif
	isNVidia = false;
	isAMD = false;
	context = nullptr;
#endif
}
コード例 #6
0
ファイル: opencl.c プロジェクト: Photosounder/rouziclib
cl_int init_cl_context(clctx_t *c, const int from_gl)
{
	cl_int i, ret, pf_index=-1;
	cl_platform_id	platform_id[16]={0};
	cl_device_id	device_id[16]={0};
	cl_uint		ret_num_platforms=0;
	cl_uint		ret_num_devices=0;

	ret = clewInit();
	if (ret)
	{
		fprintf_rl(stderr, "clewInit() failed with code %d\n", ret);
		return -1024;
	}

	ret = clGetPlatformIDs(sizeof(platform_id)/sizeof(*platform_id), platform_id, &ret_num_platforms);	// get all the platforms
	CL_ERR_RET("clGetPlatformIDs (in init_cl_context)", ret);

	for (i=0; i<ret_num_platforms; i++)		// go through all the platforms
	{
		ret = clGetDeviceIDs(platform_id[i], CL_DEVICE_TYPE_GPU, sizeof(device_id)/sizeof(*device_id), device_id, &ret_num_devices);	// get all the suitable GPU devices

		if (ret_num_devices > 0)		// stop trying platforms when a suitable device is found
		{
			pf_index = i;
			break;
		}
	}

	if (ret_num_devices==0)				// if a non-GPU wasn't found try again with CPUs included
		for (i=0; i<ret_num_platforms; i++)	// go through all the platforms
		{
			ret = clGetDeviceIDs(platform_id[i], CL_DEVICE_TYPE_ALL, sizeof(device_id)/sizeof(*device_id), device_id, &ret_num_devices);	// get all the suitable devices, CPU included

			if (ret_num_devices > 0)
			{
				pf_index = i;
				break;
			}
		}
	CL_ERR_RET("clGetDeviceIDs (in init_cl_context)", ret);
	c->device_id = device_id[0];

	if (from_gl)	// get context from OpenGL
	{
		ret = init_cl_context_from_gl(c, platform_id[pf_index]);
		CL_ERR_RET("init_cl_context_from_gl (in init_cl_context)", ret);
	}
	else
	{
		c->context = clCreateContext(NULL, ret_num_devices, device_id, NULL, NULL, &ret);
		CL_ERR_RET("clCreateContext (in init_cl_context)", ret);
	}

	c->command_queue = clCreateCommandQueue(c->context, device_id[0], 0*CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | 0*CL_QUEUE_PROFILING_ENABLE, &ret);
	CL_ERR_RET("clCreateCommandQueue (in init_cl_context)", ret);

	return ret;
}
コード例 #7
0
void EasyCL::init(int gpuIndex, bool verbose) {
    #ifdef USE_CLEW
        bool clpresent = 0 == clewInit();
        if(!clpresent) {
            throw std::runtime_error("OpenCL library not found");
        }
    #endif

//        std::cout << "this: " << this << std::endl;
//        this->gpuIndex = gpuindex;
    error = 0;

    queue = 0;
    context = 0;

    // Platform
    cl_uint num_platforms;
    error = clGetPlatformIDs(1, &platform_id, &num_platforms);
//        std::cout << "num platforms: " << num_platforms << std::endl;
//        assert (num_platforms == 1);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL platforms ids: " + errorMessage(error));
    }
    if(num_platforms == 0) {
       throw std::runtime_error("Error: no OpenCL platforms available");
    }

    cl_uint num_devices;
    error = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR , 0, 0, &num_devices);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL device ids: " + errorMessage(error));
    }
//      std::cout << "num devices: " << num_devices << std::endl;
    cl_device_id *device_ids = new cl_device_id[num_devices];
    error = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR, num_devices, device_ids, &num_devices);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL device ids: " + errorMessage(error));
    }

    if(gpuIndex >= static_cast<int>(num_devices) ) {
       throw std::runtime_error("requested gpuindex " + toString(gpuIndex) + " goes beyond number of available device " + toString(num_devices) );
    }
    device = device_ids[gpuIndex];
    delete[] device_ids;

    // Context
    context = new cl_context();
    *context = clCreateContext(0, 1, &device, NULL, NULL, &error);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error creating OpenCL context, OpenCL errorcode: " + errorMessage(error));
    }
    // Command-queue
    queue = new cl_command_queue;
    *queue = clCreateCommandQueue(*context, device, 0, &error);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error creating OpenCL command queue, OpenCL errorcode: " + errorMessage(error));
    }
}
コード例 #8
0
ファイル: opencl.c プロジェクト: Photosounder/rouziclib
cl_int init_cl_context_from_gl(clctx_t *c, cl_platform_id platform)
{
	cl_int ret=0;

	ret = clewInit();
	if (ret)
	{
		fprintf_rl(stderr, "clewInit() failed with code %d\n", ret);
		return -1024;
	}

	#ifdef RL_OPENCL_GL

	#if defined(_WIN32)		// Windows	from http://stackoverflow.com/a/30529217/1675589
	cl_context_properties properties[] =
	{
		CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),
		CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
		CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
		0
	};
	#elif defined(__APPLE__)	// OS X
	CGLContextObj     kCGLContext     = CGLGetCurrentContext();
	CGLShareGroupObj  kCGLShareGroup  = CGLGetShareGroup(kCGLContext);

	cl_context_properties properties[] =
	{
		CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
		(cl_context_properties) kCGLShareGroup,
		0
	};
	#else				// Linux
	cl_context_properties properties[] =
	{
		CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
		CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
		CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
		0
	};
	#endif

	//c->context = clCreateContext(NULL, ret_num_devices, device_id, NULL, NULL, &ret);
	c->context = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, NULL, NULL, &ret);
	CL_ERR_RET("clCreateContextFromType (in init_cl_context_from_gl)", ret);

	#endif
	return ret;
}
コード例 #9
0
/*static*/
bool
CLDeviceContext::HAS_CL_VERSION_1_1 () {

#ifdef OPENSUBDIV_HAS_CLEW
    static bool clewInitialized = false;
    static bool clewLoadSuccess;
    if (!clewInitialized) {
        clewInitialized = true;
        clewLoadSuccess = clewInit() == CLEW_SUCCESS;
        if (!clewLoadSuccess) {
            error("Loading OpenCL failed.\n");
        }
    }
    return clewLoadSuccess;
#endif
    return true;
}
コード例 #10
0
EasyCL *EasyCL::createForIndexedGpu(int gpu, bool verbose) {
//  cout << "createForindexedgpu gpu=" << gpu << " verbose=" << verbose << endl;
    #ifdef USE_CLEW
        bool clpresent = 0 == clewInit();
        if(!clpresent) {
            throw std::runtime_error("OpenCL library not found");
        }
    #endif
    cl_int error;
    int currentGpuIndex = 0;
    cl_platform_id platform_ids[10];
    cl_uint num_platforms;
    error = clGetPlatformIDs(10, platform_ids, &num_platforms);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL platforms ids, OpenCL errorcode: " + errorMessage(error));
    }
    if(num_platforms == 0) {
       throw std::runtime_error("Error: no OpenCL platforms available");
    }
    for(int platform =  0; platform < (int)num_platforms; platform++) {
        cl_platform_id platform_id = platform_ids[platform];
//        cout << "checking platform id " << platform_id << endl;
        cl_device_id device_ids[100];
        cl_uint num_devices;
        error = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR , 100, device_ids, &num_devices);
        if (error != CL_SUCCESS) {
            continue;
//           throw std::runtime_error("Error getting device ids for platform " + toString(platform) + ": " + errorMessage(error));
        }
//        cout << "gpu=" << gpu << " currentGpuIndex=" << currentGpuIndex << " num_devices=" << num_devices << endl;
        if(( gpu - currentGpuIndex) < (int)num_devices) {
            return new EasyCL(platform_id, device_ids[(gpu - currentGpuIndex)], verbose);
        } else {
            currentGpuIndex += num_devices;
        }
    }
    if(gpu == 0) {
        throw std::runtime_error("No OpenCL-enabled GPUs found");
    } else {
        throw std::runtime_error("Not enough OpenCL-enabled GPUs found to satisfy gpu index: " + toString(gpu) );
    }
}
コード例 #11
0
ファイル: clewTestC.c プロジェクト: hughperkins/clew
int main(int argc, char* argv[])
{
    int clpresent = 0 == clewInit();
    if( !clpresent ) {
        printf("opencl library not found.\n");
        return -1;
    }

    cl_int error = 0;
    cl_platform_id platform_ids[10];
    cl_uint num_platforms;
    error = clGetPlatformIDs(10, platform_ids, &num_platforms);
  	if (error != CL_SUCCESS) {
        printf("something went wrong, errorcode %i\n", error);
    		return -1;
  	}
    printf("num platforms: %i\n", num_platforms);

	  return 0;
}
コード例 #12
0
ファイル: opencl.cpp プロジェクト: Nocte-/hexahedra
void init_opencl()
{
    if (initialized_)
        return;

    initialized_ = true;

    if (clewInit(OPENCL_DLL_NAME) < 0)
        return;

    try {
        uint32_t platform_index(0);
        uint32_t device_index(0);

        std::vector<cl::Platform> platform_list;
        cl::Platform::get(&platform_list);

        if (platform_index >= platform_list.size())
            return;

        std::vector<cl::Device> device_list;
        auto& pl(platform_list[platform_index]);
        pl.getDevices(CL_DEVICE_TYPE_ALL, &device_list);

        if (device_index >= device_list.size())
            return;

        cl_context_properties properties[]
            = {CL_CONTEXT_PLATFORM, (cl_context_properties)(pl)(), 0};

        ctx_ = cl::Context(CL_DEVICE_TYPE_ALL, properties);
        dev_ = device_list[device_index];

        have_opencl_ = true;
    } catch (...) {
        have_opencl_ = false;
    }
}
コード例 #13
0
EasyCL *EasyCL::createForPlatformDeviceIndexes(int platformIndex, int deviceIndex) {
    #ifdef USE_CLEW
        bool clpresent = 0 == clewInit();
        if(!clpresent) {
            throw std::runtime_error("OpenCL library not found");
        }
    #endif
    cl_int error;
//    int currentGpuIndex = 0;
    cl_platform_id platform_ids[10];
    cl_uint num_platforms;
    error = clGetPlatformIDs(10, platform_ids, &num_platforms);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL platforms ids, OpenCL errorcode: " + errorMessage(error));
    }
    if(num_platforms == 0) {
       throw std::runtime_error("Error: no OpenCL platforms available");
    }
    if(platformIndex >= (int)num_platforms) {
       throw std::runtime_error("Error: OpenCL platform index " + toString(platformIndex) + " not available. There are only: " + toString(num_platforms) + " platforms available");
    }
    cl_platform_id platform_id = platform_ids[platformIndex];
    cl_device_id device_ids[100];
    cl_uint num_devices;
    error = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_ALL, 100, device_ids, &num_devices);
    if (error != CL_SUCCESS) {
       throw std::runtime_error("Error getting OpenCL device ids for platform index " + toString(platformIndex) + ": OpenCL errorcode: " + errorMessage(error));
    }
    if(num_devices == 0) {
       throw std::runtime_error("Error: no OpenCL devices available for platform index " + toString(platformIndex) );
    }
    if(deviceIndex >= (int)num_devices) {
       throw std::runtime_error("Error: OpenCL device index " + toString(deviceIndex) + " goes beyond the available devices on platform index " + toString(platformIndex) + ", which has " + toString(num_devices) + " devices");
    }
    return new EasyCL(platform_id, device_ids[deviceIndex]);
}
コード例 #14
0
ファイル: COM_WorkScheduler.cpp プロジェクト: diekev/blender
void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads)
{
	/* initialize highlighting */
	if (!g_highlightInitialized) {
		if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
		if (g_highlightedNodes)     MEM_freeN(g_highlightedNodes);

		g_highlightedNodesRead = NULL;
		g_highlightedNodes = NULL;

		COM_startReadHighlights();

		g_highlightInitialized = true;
	}

#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
	/* deinitialize if number of threads doesn't match */
	if (g_cpudevices.size() != num_cpu_threads) {
		Device *device;

		while (g_cpudevices.size() > 0) {
			device = g_cpudevices.back();
			g_cpudevices.pop_back();
			device->deinitialize();
			delete device;
		}
		if (g_cpuInitialized) {
			BLI_thread_local_delete(g_thread_device);
		}
		g_cpuInitialized = false;
	}

	/* initialize CPU threads */
	if (!g_cpuInitialized) {
		for (int index = 0; index < num_cpu_threads; index++) {
			CPUDevice *device = new CPUDevice(index);
			device->initialize();
			g_cpudevices.push_back(device);
		}
		BLI_thread_local_create(g_thread_device);
		g_cpuInitialized = true;
	}

#ifdef COM_OPENCL_ENABLED
	/* deinitialize OpenCL GPU's */
	if (use_opencl && !g_openclInitialized) {
		g_context = NULL;
		g_program = NULL;

		if (clewInit() != CLEW_SUCCESS) /* this will check for errors and skip if already initialized */
			return;

		if (clCreateContextFromType) {
			cl_uint numberOfPlatforms = 0;
			cl_int error;
			error = clGetPlatformIDs(0, 0, &numberOfPlatforms);
			if (error == -1001) { }   /* GPU not supported */
			else if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
			if (G.f & G_DEBUG) printf("%u number of platforms\n", numberOfPlatforms);
			cl_platform_id *platforms = (cl_platform_id *)MEM_mallocN(sizeof(cl_platform_id) * numberOfPlatforms, __func__);
			error = clGetPlatformIDs(numberOfPlatforms, platforms, 0);
			unsigned int indexPlatform;
			for (indexPlatform = 0; indexPlatform < numberOfPlatforms; indexPlatform++) {
				cl_platform_id platform = platforms[indexPlatform];
				cl_uint numberOfDevices = 0;
				clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, 0, &numberOfDevices);
				if (numberOfDevices <= 0)
					continue;

				cl_device_id *cldevices = (cl_device_id *)MEM_mallocN(sizeof(cl_device_id) * numberOfDevices, __func__);
				clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numberOfDevices, cldevices, 0);

				g_context = clCreateContext(NULL, numberOfDevices, cldevices, clContextError, NULL, &error);
				if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
				const char *cl_str[2] = {datatoc_COM_OpenCLKernels_cl, NULL};
				g_program = clCreateProgramWithSource(g_context, 1, cl_str, 0, &error);
				error = clBuildProgram(g_program, numberOfDevices, cldevices, 0, 0, 0);
				if (error != CL_SUCCESS) {
					cl_int error2;
					size_t ret_val_size = 0;
					printf("CLERROR[%d]: %s\n", error, clewErrorString(error));
					error2 = clGetProgramBuildInfo(g_program, cldevices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
					if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
					char *build_log = (char *)MEM_mallocN(sizeof(char) * ret_val_size + 1, __func__);
					error2 = clGetProgramBuildInfo(g_program, cldevices[0], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
					if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
					build_log[ret_val_size] = '\0';
					printf("%s", build_log);
					MEM_freeN(build_log);
				}
				else {
					unsigned int indexDevices;
					for (indexDevices = 0; indexDevices < numberOfDevices; indexDevices++) {
						cl_device_id device = cldevices[indexDevices];
						cl_int vendorID = 0;
						cl_int error2 = clGetDeviceInfo(device, CL_DEVICE_VENDOR_ID, sizeof(cl_int), &vendorID, NULL);
						if (error2 != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error2, clewErrorString(error2)); }
						OpenCLDevice *clDevice = new OpenCLDevice(g_context, device, g_program, vendorID);
						clDevice->initialize();
						g_gpudevices.push_back(clDevice);
					}
				}
				MEM_freeN(cldevices);
			}
			MEM_freeN(platforms);
		}

		g_openclInitialized = true;
	}
#endif
#endif
}
コード例 #15
0
int ocl_wrapper_init(void) {
  return clewInit("OpenCL.dll");
}
コード例 #16
0
ファイル: voronoi.cpp プロジェクト: alexshafranov/corridormap
int main()
{
    glfw_context glfw_ctx;

    if (!glfw_ctx.ok)
    {
        fprintf(stderr, "failed to initialize GLFW context.\n");
        return 1;
    }

    glfw_window_context glfw_window_ctx(screen_width, screen_height, "voronoi");
    GLFWwindow* window = glfw_window_ctx.window;

    if (!window)
    {
        fprintf(stderr, "failed to create GLFW window.\n");
        return 1;
    }

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glewInit();

    if (clewInit("OpenCL.dll") != CLEW_SUCCESS)
    {
        return 1;
    }

    const unsigned char* vendor = glGetString(GL_VENDOR);
    const unsigned char* version = glGetString(GL_VERSION);

    printf("opengl vendor=%s version=%s\n", vendor, version);

    corridormap::Memory_Malloc mem;

    float obstacle_verts_x[] = {
        546.04233f, 586.87983f, 586.87983f, 546.04233f, 484.7861f, 443.9486f, 443.9486f, 484.7861f, 219.27517f, 299.49779f, 367.03349f, 286.81087f, 461.04229f, 567.87837f, 549.26637f, 442.43029f, 655.31886f,
        757.95437f, 790.9898f, 688.35429f, 103.76307f, 307.49818f, 332.23693f, 128.50182f, 482.48372f, 665.65059f, 633.51629f, 450.34941f, 862.14993f, 778.93614f, 719.02164f, 802.23542f, 87.27517f, 167.49779f,
        235.03349f, 154.81087f, 359.17335f, 439.50653f, 507.13531f, 426.80213f, 886.58172f, 791.09332f, 761.96796f, 792.52284f, 828.33099f, 845.80621f, 952.58172f, 857.09332f, 827.96796f, 858.52284f, 894.33099f,
        911.80621f, 83.84732f, 221.04656f, 272.15267f, 134.95344f, 159.50583f, 175.66538f, 165.88157f, 130.15439f, 91.23934f, 75.07979f, 84.8636f, 120.59078f,
    };

    float obstacle_verts_y[] = {
        366.49453f, 413.80088f, 461.10723f, 508.41357f, 508.41357f, 461.10723f, 413.80088f, 366.49453f, 276.47356f, 203.07432f, 276.8883f, 350.28754f, 135.41626f, 155.64419f, 253.9456f, 233.71767f, 259.41453f,
        223.51093f, 317.94733f, 353.85093f, 639.66596f, 563.66847f, 622.46545f, 698.46295f, 602.91856f, 720.10861f, 775.21285f, 658.02281f, 470.77478f, 673.8586f, 651.35665f, 448.27281f, 432.47356f, 359.07432f,
        432.8883f, 506.28754f, 868.83723f, 823.54104f, 869.09317f, 914.38936f, 901.90592f, 949.29104f, 890.59889f, 802.29103f, 784.52161f, 819.73691f, 219.90592f, 267.29104f, 208.59889f, 120.29103f, 102.52161f,
        137.73691f, 914.32913f, 745.62826f, 783.80228f, 952.5032f, 122.51486f, 161.9206f, 193.21563f, 216.39993f, 204.23386f, 164.82812f, 133.53309f, 110.34879f,
    };

    int num_poly_verts[] = { 8, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 4, 8, };

    corridormap::Footprint obstacles;
    obstacles.x = obstacle_verts_x;
    obstacles.y = obstacle_verts_y;
    obstacles.num_polys = sizeof(num_poly_verts)/sizeof(num_poly_verts[0]);
    obstacles.num_verts = sizeof(obstacle_verts_x)/sizeof(obstacle_verts_x[0]);
    obstacles.num_poly_verts = num_poly_verts;

    const float border = 10.f;
    corridormap::Bbox2 obstacle_bounds = corridormap::bounds(obstacles, border);

    const float max_dist = corridormap::max_distance(obstacle_bounds);
    const float max_error = 0.1f;

    corridormap::Distance_Mesh mesh = corridormap::allocate_distance_mesh(&mem, obstacles.num_polys, max_distance_mesh_verts(obstacles, max_dist, max_error));
    corridormap::build_distance_mesh(obstacles, obstacle_bounds, max_dist, max_error, mesh);
    corridormap::set_segment_colors(mesh, colors, sizeof(colors)/sizeof(colors[0]));

    corridormap::Renderer_GL render_iface;
    corridormap::Renderer::Parameters render_params;
    render_params.render_target_width = render_target_width;
    render_params.render_target_height = render_target_height;
    render_params.min[0] = obstacle_bounds.min[0];
    render_params.min[1] = obstacle_bounds.min[1];
    render_params.max[0] = obstacle_bounds.max[0];
    render_params.max[1] = obstacle_bounds.max[1];
    render_params.far_plane = max_dist + 0.1f;

    if (!render_iface.initialize(render_params, &mem))
    {
        fprintf(stderr, "failed to initialize render interface.\n");
        return 1;
    }

    corridormap::render_distance_mesh(&render_iface, mesh);

    corridormap::Renderer::Opencl_Shared cl_shared = render_iface.create_opencl_shared();
    corridormap::Opencl_Runtime cl_runtime = corridormap::init_opencl_runtime(cl_shared);

    // build kernels.
    {
        corridormap::Compilation_Status status = corridormap::build_kernels(cl_runtime);

        if (status.kernel != corridormap::kernel_id_count)
        {
            fprintf(stderr, "failed to build kernels: code=%d, kernel=%d\n", status.code, status.kernel);
            size_t build_log_size;
            clGetProgramBuildInfo(cl_runtime.programs[status.kernel], cl_runtime.device, CL_PROGRAM_BUILD_LOG, 0, 0, &build_log_size);
            char* build_log = corridormap::allocate<char>(&mem, build_log_size);
            clGetProgramBuildInfo(cl_runtime.programs[status.kernel], cl_runtime.device, CL_PROGRAM_BUILD_LOG, build_log_size, build_log, 0);
            fprintf(stderr, "build log: %s\n", build_log);
            return 1;
        }
    }

    {
        cl_int error_code;
        cl_mem voronoi_image = render_iface.share_pixels(cl_runtime.context, CL_MEM_READ_WRITE, &error_code);

        if (error_code != CL_SUCCESS)
        {
            fprintf(stderr, "failed to create opencl voronoi image.\n");
            return 1;
        }

        render_iface.acquire_shared(cl_runtime.queue, voronoi_image);
        error_code = corridormap::mark_voronoi_features(cl_runtime, voronoi_image);
        error_code = corridormap::debug_voronoi_features(cl_runtime, voronoi_image, cl_runtime.voronoi_edges_img, 0xff000000, 0);
        error_code = corridormap::debug_voronoi_features(cl_runtime, voronoi_image, cl_runtime.voronoi_vertices_img, 0xffffffff, 4);
        error_code = corridormap::compact_voronoi_features(cl_runtime);
        error_code = corridormap::store_obstacle_ids(cl_runtime, voronoi_image);
        render_iface.release_shared(cl_runtime.queue, voronoi_image);

        clFinish(cl_runtime.queue);

        corridormap::Voronoi_Features features = corridormap::allocate_voronoi_features(&mem, render_target_width, render_target_height, cl_runtime.voronoi_vertex_mark_count, cl_runtime.voronoi_edge_mark_count);
        error_code = corridormap::transfer_voronoi_features(cl_runtime, features);

        clFinish(cl_runtime.queue);

        if (error_code != CL_SUCCESS)
        {
            fprintf(stderr, "failed to run opencl kernels.\n");
            return 1;
        }

        printf("voronoi vertices: %d\n", cl_runtime.voronoi_vertex_mark_count);
        printf("voronoi edge marks: %d\n", cl_runtime.voronoi_edge_mark_count);
    }

    while (!glfwWindowShouldClose(window))
    {
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);

        render_iface.blit_frame_buffer(width, height);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    corridormap::deallocate(&mem, mesh);

    return 0;
}