Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ShaderPrecisionFormat and get_shader_precision_format #320

Merged
merged 2 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ features = [
"WebGl2RenderingContext",
"WebGlSampler",
"WebGlShader",
"WebGlShaderPrecisionFormat",
"WebGlSync",
"WebGlTexture",
"WebGlTransformFeedback",
Expand Down
45 changes: 45 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,45 @@ pub struct ActiveTransformFeedback {
pub name: String,
}

#[derive(Debug)]
pub struct ShaderPrecisionFormat {
/// The base 2 log of the absolute value of the minimum value that can be represented
pub range_min: i32,
/// The base 2 log of the absolute value of the maximum value that can be represented.
pub range_max: i32,
/// The number of bits of precision that can be represented.
/// For integer formats this value is always 0.
pub precision: i32,
}

impl ShaderPrecisionFormat {
/// Returns OpenGL standard precision that most desktop hardware support
pub fn common_desktop_hardware(precision_type: u32, is_embedded: bool) -> Self {
let (range_min, range_max, precision) = match precision_type {
LOW_INT | MEDIUM_INT | HIGH_INT => {
// Precision: For integer formats this value is always 0
if is_embedded {
// These values are for a 32-bit twos-complement integer format.
(31, 30, 0)
} else {
// Range: from -2^24 to 2^24
(24, 24, 0)
}
}
// IEEE 754 single-precision floating-point
// Range: from -2^127 to 2^127
// Significand precision: 23 bits
LOW_FLOAT | MEDIUM_FLOAT | HIGH_FLOAT => (127, 127, 23),
_ => unreachable!("invalid precision"),
};
Self {
range_min,
range_max,
precision,
}
}
}

#[allow(dead_code)]
#[derive(Debug)]
pub struct DebugMessageLogEntry {
Expand Down Expand Up @@ -156,6 +195,12 @@ pub trait HasContext: __private::Sealed {

unsafe fn get_shader_info_log(&self, shader: Self::Shader) -> String;

unsafe fn get_shader_precision_format(
&self,
shader_type: u32,
precision_mode: u32,
) -> Option<ShaderPrecisionFormat>;

unsafe fn get_tex_image(
&self,
target: u32,
Expand Down
30 changes: 30 additions & 0 deletions src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,36 @@ impl HasContext for Context {
}
}

unsafe fn get_shader_precision_format(
&self,
shader_type: u32,
precision_type: u32,
) -> Option<ShaderPrecisionFormat> {
let gl = &self.raw;

if gl.GetShaderPrecisionFormat_is_loaded() {
let mut range = [0, 0];
let mut precision = 0;
gl.GetShaderPrecisionFormat(
shader_type,
precision_type,
range.as_mut_ptr(),
&mut precision,
);
// In some cases GetShaderPrecisionFormat exists but it's just a stub
// so we return only if variables got populated
if range[1] != 0 {
return Some(ShaderPrecisionFormat {
range_min: range[0],
range_max: range[1],
precision,
});
}
}

None
}

unsafe fn get_tex_image(
&self,
target: u32,
Expand Down
20 changes: 20 additions & 0 deletions src/web_sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,26 @@ impl HasContext for Context {
.unwrap_or_else(|| String::from(""))
}

unsafe fn get_shader_precision_format(
&self,
shader_type: u32,
precision_mode: u32,
) -> Option<ShaderPrecisionFormat> {
match self.raw {
RawRenderingContext::WebGl1(ref gl) => {
gl.get_shader_precision_format(shader_type, precision_mode)
}
RawRenderingContext::WebGl2(ref gl) => {
gl.get_shader_precision_format(shader_type, precision_mode)
}
}
.map(|spf| ShaderPrecisionFormat {
range_min: spf.range_min(),
range_max: spf.range_max(),
precision: spf.precision(),
})
}

unsafe fn get_tex_image(
&self,
_target: u32,
Expand Down
Loading