#[derive(Debug, Clone)]
pub struct WebGLParams {
pub vendor: String,
pub renderer: String,
pub version: String,
pub shading_language_version: String,
pub max_texture_size: i32,
pub max_renderbuffer_size: i32,
pub max_viewport_dims: [i32; 2],
pub max_vertex_attribs: i32,
pub max_varying_vectors: i32,
pub max_combined_texture_image_units: i32,
pub max_texture_image_units: i32,
pub max_fragment_uniform_vectors: i32,
pub max_vertex_uniform_vectors: i32,
pub max_vertex_texture_image_units: i32,
pub aliased_line_width_range: [f32; 2],
pub aliased_point_size_range: [f32; 2],
pub extensions: Vec<String>,
pub high_float_precision: ShaderPrecision,
pub medium_float_precision: ShaderPrecision,
}
#[derive(Debug, Clone, Copy)]
pub struct ShaderPrecision {
pub range_min: i32,
pub range_max: i32,
pub precision: i32,
}
pub const VENDOR: u32 = 0x1F00;
pub const RENDERER: u32 = 0x1F01;
pub const VERSION: u32 = 0x1F02;
pub const SHADING_LANGUAGE_VERSION: u32 = 0x8B8C;
pub const MAX_TEXTURE_SIZE: u32 = 0x0D33;
pub const MAX_RENDERBUFFER_SIZE: u32 = 0x84E8;
pub const MAX_VERTEX_ATTRIBS: u32 = 0x8869;
pub const MAX_VARYING_VECTORS: u32 = 0x8DFC;
pub const MAX_COMBINED_TEXTURE_IMAGE_UNITS: u32 = 0x8B4D;
pub const MAX_TEXTURE_IMAGE_UNITS: u32 = 0x8872;
pub const MAX_FRAGMENT_UNIFORM_VECTORS: u32 = 0x8DFD;
pub const MAX_VERTEX_UNIFORM_VECTORS: u32 = 0x8DFB;
pub const MAX_VERTEX_TEXTURE_IMAGE_UNITS: u32 = 0x8B4C;
pub const ALIASED_LINE_WIDTH_RANGE: u32 = 0x846E;
pub const ALIASED_POINT_SIZE_RANGE: u32 = 0x846D;
pub const UNMASKED_VENDOR_WEBGL: u32 = 0x9245;
pub const UNMASKED_RENDERER_WEBGL: u32 = 0x9246;
impl WebGLParams {
pub fn get_parameter_string(&self, pname: u32) -> Option<String> {
match pname {
VENDOR => Some("WebKit".to_string()),
RENDERER => Some("WebKit WebGL".to_string()),
VERSION => Some(self.version.clone()),
SHADING_LANGUAGE_VERSION => Some(self.shading_language_version.clone()),
UNMASKED_VENDOR_WEBGL => Some(self.vendor.clone()),
UNMASKED_RENDERER_WEBGL => Some(self.renderer.clone()),
_ => None,
}
}
pub fn get_parameter_int(&self, pname: u32) -> Option<i32> {
match pname {
MAX_TEXTURE_SIZE => Some(self.max_texture_size),
MAX_RENDERBUFFER_SIZE => Some(self.max_renderbuffer_size),
MAX_VERTEX_ATTRIBS => Some(self.max_vertex_attribs),
MAX_VARYING_VECTORS => Some(self.max_varying_vectors),
MAX_COMBINED_TEXTURE_IMAGE_UNITS => Some(self.max_combined_texture_image_units),
MAX_TEXTURE_IMAGE_UNITS => Some(self.max_texture_image_units),
MAX_FRAGMENT_UNIFORM_VECTORS => Some(self.max_fragment_uniform_vectors),
MAX_VERTEX_UNIFORM_VECTORS => Some(self.max_vertex_uniform_vectors),
MAX_VERTEX_TEXTURE_IMAGE_UNITS => Some(self.max_vertex_texture_image_units),
_ => None,
}
}
pub fn nvidia_rtx_3080() -> Self {
Self {
vendor: "Google Inc. (NVIDIA)".into(),
renderer: "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)"
.into(),
version: "WebGL 2.0 (OpenGL ES 3.0 Chromium)".into(),
shading_language_version: "WebGL GLSL ES 3.00 (OpenGL ES GLSL ES 3.0 Chromium)".into(),
max_texture_size: 16384,
max_renderbuffer_size: 16384,
max_viewport_dims: [32767, 32767],
max_vertex_attribs: 16,
max_varying_vectors: 30,
max_combined_texture_image_units: 32,
max_texture_image_units: 16,
max_fragment_uniform_vectors: 1024,
max_vertex_uniform_vectors: 4096,
max_vertex_texture_image_units: 16,
aliased_line_width_range: [1.0, 1.0],
aliased_point_size_range: [1.0, 1024.0],
extensions: standard_extensions(),
high_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
medium_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
}
}
pub fn intel_iris_xe() -> Self {
Self {
vendor: "Google Inc. (Intel)".into(),
renderer: "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)"
.into(),
version: "WebGL 2.0 (OpenGL ES 3.0 Chromium)".into(),
shading_language_version: "WebGL GLSL ES 3.00 (OpenGL ES GLSL ES 3.0 Chromium)".into(),
max_texture_size: 16384,
max_renderbuffer_size: 16384,
max_viewport_dims: [16384, 16384],
max_vertex_attribs: 16,
max_varying_vectors: 30,
max_combined_texture_image_units: 32,
max_texture_image_units: 16,
max_fragment_uniform_vectors: 1024,
max_vertex_uniform_vectors: 4096,
max_vertex_texture_image_units: 16,
aliased_line_width_range: [1.0, 1.0],
aliased_point_size_range: [1.0, 1024.0],
extensions: standard_extensions(),
high_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
medium_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
}
}
pub fn apple_m2() -> Self {
Self {
vendor: "Google Inc. (Apple)".into(),
renderer: "ANGLE (Apple, ANGLE Metal Renderer: Apple M2, Unspecified Version)".into(),
version: "WebGL 2.0 (OpenGL ES 3.0 Chromium)".into(),
shading_language_version: "WebGL GLSL ES 3.00 (OpenGL ES GLSL ES 3.0 Chromium)".into(),
max_texture_size: 16384,
max_renderbuffer_size: 16384,
max_viewport_dims: [16384, 16384],
max_vertex_attribs: 16,
max_varying_vectors: 30,
max_combined_texture_image_units: 32,
max_texture_image_units: 16,
max_fragment_uniform_vectors: 1024,
max_vertex_uniform_vectors: 4096,
max_vertex_texture_image_units: 16,
aliased_line_width_range: [1.0, 1.0],
aliased_point_size_range: [1.0, 1024.0],
extensions: standard_extensions(),
high_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
medium_float_precision: ShaderPrecision {
range_min: 127,
range_max: 127,
precision: 23,
},
}
}
}
fn standard_extensions() -> Vec<String> {
[
"ANGLE_instanced_arrays",
"EXT_blend_minmax",
"EXT_color_buffer_half_float",
"EXT_float_blend",
"EXT_frag_depth",
"EXT_shader_texture_lod",
"EXT_texture_compression_bptc",
"EXT_texture_compression_rgtc",
"EXT_texture_filter_anisotropic",
"EXT_sRGB",
"OES_element_index_uint",
"OES_fbo_render_mipmap",
"OES_standard_derivatives",
"OES_texture_float",
"OES_texture_float_linear",
"OES_texture_half_float",
"OES_texture_half_float_linear",
"OES_vertex_array_object",
"WEBGL_color_buffer_float",
"WEBGL_compressed_texture_s3tc",
"WEBGL_compressed_texture_s3tc_srgb",
"WEBGL_debug_renderer_info",
"WEBGL_debug_shaders",
"WEBGL_depth_texture",
"WEBGL_draw_buffers",
"WEBGL_lose_context",
"WEBGL_multi_draw",
]
.iter()
.map(ToString::to_string)
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn nvidia_profile_params() {
let p = WebGLParams::nvidia_rtx_3080();
assert_eq!(p.get_parameter_int(MAX_TEXTURE_SIZE), Some(16384));
let renderer = p
.get_parameter_string(UNMASKED_RENDERER_WEBGL)
.expect("renderer should exist");
assert!(renderer.contains("RTX 3080"));
let vendor = p
.get_parameter_string(UNMASKED_VENDOR_WEBGL)
.expect("vendor should exist");
assert!(vendor.contains("NVIDIA"));
}
#[test]
fn intel_profile_params() {
let p = WebGLParams::intel_iris_xe();
let renderer = p
.get_parameter_string(UNMASKED_RENDERER_WEBGL)
.expect("renderer should exist");
assert!(renderer.contains("Iris"));
}
#[test]
fn extensions_nonempty() {
let p = WebGLParams::nvidia_rtx_3080();
assert!(p.extensions.len() > 20);
assert!(
p.extensions
.contains(&"WEBGL_debug_renderer_info".to_string())
);
}
}