Skip to content

Instantly share code, notes, and snippets.

@Kerollmops
Created May 21, 2016 02:43
Show Gist options
  • Select an option

  • Save Kerollmops/e58c5a7048afd31c7600bf7b08f49615 to your computer and use it in GitHub Desktop.

Select an option

Save Kerollmops/e58c5a7048afd31c7600bf7b08f49615 to your computer and use it in GitHub Desktop.
#[macro_use]
extern crate glium;
extern crate opencl;
extern crate libc;
pub mod particle;
pub mod particles;
mod cgl;
use particles::Particles;
use glium::Surface;
use glium::glutin;
use glium::glutin::{ ElementState, Event, VirtualKeyCode };
use std::rc::Rc;
use std::os::raw::c_void;
use opencl::{ Context as CLContext, Device, Program as CLProgram, PreferedType, DeviceType, CommandQueue };
use opencl::cl::cl_context_properties;
use cgl::*;
// in order to create our context, we will need to provide an object which implements
// the `Backend` trait
struct Backend {
window: Rc<glutin::Window>,
}
unsafe impl glium::backend::Backend for Backend {
fn swap_buffers(&self) -> Result<(), glium::SwapBuffersError> {
match self.window.swap_buffers() {
Ok(()) => Ok(()),
Err(glutin::ContextError::IoError(_)) => panic!(),
Err(glutin::ContextError::ContextLost) => Err(glium::SwapBuffersError::ContextLost),
}
}
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
self.window.get_proc_address(symbol) as *const _
}
fn get_framebuffer_dimensions(&self) -> (u32, u32) {
self.window.get_inner_size().unwrap_or((128, 128))
}
fn is_current(&self) -> bool {
self.window.is_current()
}
unsafe fn make_current(&self) {
self.window.make_current().unwrap();
}
}
pub fn compute_context_prop_gpu(profiling: bool, prop: &[cl_context_properties])
-> Result<(Device, CLContext, CommandQueue), &'static str>
{
let platforms = opencl::platforms();
if platforms.len() == 0 {
return Err("No platform found");
}
let mut devices = platforms[0].get_devices_by_types(&[DeviceType::GPU]);
if devices.len() == 0 {
Err("No device found")
} else {
let device = devices.remove(0);
let context = CLContext::with_properties(&[device], prop);
let queue = CommandQueue::new(&context, &device, profiling, false);
Ok((device, context, queue))
}
}
fn main() {
// building the glutin window
// note that it's just `build` and not `build_glium`
let window = glutin::WindowBuilder::new().build().unwrap();
let window = Rc::new(window);
// now building the context
let context = unsafe {
glium::backend::Context::new::<_, ()>(Backend { window: window.clone() },
true, Default::default())
}.unwrap();
// drawing a frame to prove that it works
// note that constructing a `Frame` object manually is a bit hacky and may be changed
// in the future
let mut target = glium::Frame::new(context.clone(), context.get_framebuffer_dimensions());
target.clear_color(0.0, 1.0, 0.0, 1.0);
target.finish().unwrap();
let k_cglcontext = unsafe{ CGLGetCurrentContext() };
let k_cglsharegroup = unsafe{ CGLGetShareGroup(k_cglcontext) };
let prop = &[
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
k_cglsharegroup as cl_context_properties,
0
];
let (device, ctx, queue) = compute_context_prop_gpu(false, prop).unwrap();
let particles = Particles::new(&ctx, &device, &context, &queue, 1_000_000);
//
particles.init();
for event in window.wait_events() {
match event {
Event::Closed => return,
Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Escape)) => return,
// Event::DroppedFile(path) => println!("Hello file: {:?}", path),
_ => ()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment