diff options
Diffstat (limited to 'third_party/rust/glslopt/src')
-rw-r--r-- | third_party/rust/glslopt/src/bindings.rs | 135 | ||||
-rw-r--r-- | third_party/rust/glslopt/src/lib.rs | 102 |
2 files changed, 237 insertions, 0 deletions
diff --git a/third_party/rust/glslopt/src/bindings.rs b/third_party/rust/glslopt/src/bindings.rs new file mode 100644 index 0000000000..f4e5bebd08 --- /dev/null +++ b/third_party/rust/glslopt/src/bindings.rs @@ -0,0 +1,135 @@ +/* automatically generated by rust-bindgen */ + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct glslopt_shader { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct glslopt_ctx { + _unused: [u8; 0], +} +pub const glslopt_shader_type_kGlslOptShaderVertex: glslopt_shader_type = 0; +pub const glslopt_shader_type_kGlslOptShaderFragment: glslopt_shader_type = 1; +pub type glslopt_shader_type = u32; +pub const glslopt_options_kGlslOptionSkipPreprocessor: glslopt_options = 1; +pub const glslopt_options_kGlslOptionNotFullShader: glslopt_options = 2; +pub type glslopt_options = u32; +pub const glslopt_target_kGlslTargetOpenGL: glslopt_target = 0; +pub const glslopt_target_kGlslTargetOpenGLES20: glslopt_target = 1; +pub const glslopt_target_kGlslTargetOpenGLES30: glslopt_target = 2; +pub const glslopt_target_kGlslTargetMetal: glslopt_target = 3; +pub type glslopt_target = u32; +pub const glslopt_basic_type_kGlslTypeFloat: glslopt_basic_type = 0; +pub const glslopt_basic_type_kGlslTypeInt: glslopt_basic_type = 1; +pub const glslopt_basic_type_kGlslTypeBool: glslopt_basic_type = 2; +pub const glslopt_basic_type_kGlslTypeTex2D: glslopt_basic_type = 3; +pub const glslopt_basic_type_kGlslTypeTex3D: glslopt_basic_type = 4; +pub const glslopt_basic_type_kGlslTypeTexCube: glslopt_basic_type = 5; +pub const glslopt_basic_type_kGlslTypeTex2DShadow: glslopt_basic_type = 6; +pub const glslopt_basic_type_kGlslTypeTex2DArray: glslopt_basic_type = 7; +pub const glslopt_basic_type_kGlslTypeOther: glslopt_basic_type = 8; +pub const glslopt_basic_type_kGlslTypeCount: glslopt_basic_type = 9; +pub type glslopt_basic_type = u32; +pub const glslopt_precision_kGlslPrecHigh: glslopt_precision = 0; +pub const glslopt_precision_kGlslPrecMedium: glslopt_precision = 1; +pub const glslopt_precision_kGlslPrecLow: glslopt_precision = 2; +pub const glslopt_precision_kGlslPrecCount: glslopt_precision = 3; +pub type glslopt_precision = u32; +extern "C" { + pub fn glslopt_initialize(target: glslopt_target) -> *mut glslopt_ctx; +} +extern "C" { + pub fn glslopt_cleanup(ctx: *mut glslopt_ctx); +} +extern "C" { + pub fn glslopt_set_max_unroll_iterations( + ctx: *mut glslopt_ctx, + iterations: ::std::os::raw::c_uint, + ); +} +extern "C" { + pub fn glslopt_optimize( + ctx: *mut glslopt_ctx, + type_: glslopt_shader_type, + shaderSource: *const ::std::os::raw::c_char, + options: ::std::os::raw::c_uint, + ) -> *mut glslopt_shader; +} +extern "C" { + pub fn glslopt_get_status(shader: *mut glslopt_shader) -> bool; +} +extern "C" { + pub fn glslopt_get_output(shader: *mut glslopt_shader) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn glslopt_get_raw_output(shader: *mut glslopt_shader) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn glslopt_get_log(shader: *mut glslopt_shader) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn glslopt_shader_delete(shader: *mut glslopt_shader); +} +extern "C" { + pub fn glslopt_shader_get_input_count(shader: *mut glslopt_shader) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn glslopt_shader_get_input_desc( + shader: *mut glslopt_shader, + index: ::std::os::raw::c_int, + outName: *mut *const ::std::os::raw::c_char, + outType: *mut glslopt_basic_type, + outPrec: *mut glslopt_precision, + outVecSize: *mut ::std::os::raw::c_int, + outMatSize: *mut ::std::os::raw::c_int, + outArraySize: *mut ::std::os::raw::c_int, + outLocation: *mut ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn glslopt_shader_get_uniform_count(shader: *mut glslopt_shader) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn glslopt_shader_get_uniform_total_size( + shader: *mut glslopt_shader, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn glslopt_shader_get_uniform_desc( + shader: *mut glslopt_shader, + index: ::std::os::raw::c_int, + outName: *mut *const ::std::os::raw::c_char, + outType: *mut glslopt_basic_type, + outPrec: *mut glslopt_precision, + outVecSize: *mut ::std::os::raw::c_int, + outMatSize: *mut ::std::os::raw::c_int, + outArraySize: *mut ::std::os::raw::c_int, + outLocation: *mut ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn glslopt_shader_get_texture_count(shader: *mut glslopt_shader) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn glslopt_shader_get_texture_desc( + shader: *mut glslopt_shader, + index: ::std::os::raw::c_int, + outName: *mut *const ::std::os::raw::c_char, + outType: *mut glslopt_basic_type, + outPrec: *mut glslopt_precision, + outVecSize: *mut ::std::os::raw::c_int, + outMatSize: *mut ::std::os::raw::c_int, + outArraySize: *mut ::std::os::raw::c_int, + outLocation: *mut ::std::os::raw::c_int, + ); +} +extern "C" { + pub fn glslopt_shader_get_stats( + shader: *mut glslopt_shader, + approxMath: *mut ::std::os::raw::c_int, + approxTex: *mut ::std::os::raw::c_int, + approxFlow: *mut ::std::os::raw::c_int, + ); +} diff --git a/third_party/rust/glslopt/src/lib.rs b/third_party/rust/glslopt/src/lib.rs new file mode 100644 index 0000000000..e06ec1a4c6 --- /dev/null +++ b/third_party/rust/glslopt/src/lib.rs @@ -0,0 +1,102 @@ +use std::ffi::{CString, CStr}; +use std::ptr; + +#[allow(dead_code)] +#[allow(non_camel_case_types)] +#[allow(non_upper_case_globals)] +mod bindings; + +pub enum ShaderType { + Vertex, + Fragment, +} + +pub enum Target { + OpenGl, + OpenGles20, + OpenGles30, + Metal, +} + +pub struct Context { + ctx: *mut bindings::glslopt_ctx, +} + +impl Context { + pub fn new(target: Target) -> Self { + let target = match target { + Target::OpenGl => bindings::glslopt_target_kGlslTargetOpenGL, + Target::OpenGles20 => bindings::glslopt_target_kGlslTargetOpenGLES20, + Target::OpenGles30 => bindings::glslopt_target_kGlslTargetOpenGLES30, + Target::Metal => bindings::glslopt_target_kGlslTargetMetal, + }; + + let ctx = unsafe { bindings::glslopt_initialize(target) }; + + Self { + ctx, + } + } + + pub fn optimize(&self, shader_type: ShaderType, source: String) -> Shader { + let shader_type = match shader_type { + ShaderType::Vertex => bindings::glslopt_shader_type_kGlslOptShaderVertex, + ShaderType::Fragment => bindings::glslopt_shader_type_kGlslOptShaderFragment, + }; + let source = CString::new(source).unwrap(); + + let shader = unsafe { bindings::glslopt_optimize(self.ctx, shader_type, source.as_ptr(), 0) }; + assert_ne!(shader, ptr::null_mut()); + Shader { + shader, + } + } +} + +impl Drop for Context { + fn drop(&mut self) { + unsafe { + bindings::glslopt_cleanup(self.ctx); + } + } +} + +pub struct Shader { + shader: *mut bindings::glslopt_shader, +} + +impl Shader { + pub fn get_status(&self) -> bool { + unsafe { bindings::glslopt_get_status(self.shader) } + } + + pub fn get_output(&self) -> Result<&str, ()> { + unsafe { + let cstr = bindings::glslopt_get_output(self.shader); + if cstr == ptr::null() { + Err(()) + } else { + Ok(CStr::from_ptr(cstr).to_str().unwrap()) + } + } + } + + pub fn get_log(&self) -> &str { + unsafe { + let cstr = bindings::glslopt_get_log(self.shader); + if cstr == ptr::null() { + "" + } else { + CStr::from_ptr(cstr).to_str().unwrap() + } + } + } +} + +impl Drop for Shader { + fn drop(&mut self) { + unsafe { + bindings::glslopt_shader_delete(self.shader); + } + } +} |