#![allow(clippy::struct_excessive_bools)]
use crate::sksl::glsl::GLSLGeneration;
use crate::sksl::version::Version;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub enum AdvBlendEqInteraction {
NotSupported,
Automatic,
GeneralEnable,
}
#[derive(Debug)]
pub struct ShaderCaps {
glsl_generation: GLSLGeneration,
dual_source_blending_support: bool,
shader_derivative_support: bool,
explicit_texture_lod_support: bool,
integer_support: bool,
non_square_matrix_support: bool,
inverse_hyperbolic_support: bool,
fb_fetch_support: bool,
fb_fetch_needs_custom_output: bool,
uses_precision_modifiers: bool,
flat_interpolation_support: bool,
no_perspective_interpolation_support: bool,
sample_mask_support: bool,
external_texture_support: bool,
float_is_32_bits: bool,
infinity_support: bool,
builtin_fma_support: bool,
builtin_determinant_support: bool,
can_use_void_in_sequence_expressions: bool,
can_use_min_and_abs_together: bool,
can_use_fract_for_negative_values: bool,
must_force_negated_atan_param_to_float: bool,
must_force_negated_ldexp_param_to_multiply: bool,
atan2_implemented_as_atan_y_over_x: bool,
must_do_op_between_floor_and_abs: bool,
must_guard_division_even_after_explicit_zero_check: bool,
can_use_frag_coord: bool,
add_and_true_to_loop_condition: bool,
unfold_short_circuit_as_ternary: bool,
emulated_abs_int_function: bool,
rewrite_do_while_loops: bool,
rewrite_switch_statements: bool,
remove_pow_with_constatnt_exponent: bool,
no_default_precision_for_external_samplers: bool,
rewrite_matrix_vector_mulitply: bool,
rewrite_matrix_comparisons: bool,
remove_const_from_function_parameters: bool,
perlin_noise_rounding_fix: bool,
must_declare_fragment_front_facing: bool,
version_decl_string: String,
shader_derivative_extension_string: Option<String>,
external_texture_extension_string: Option<String>,
second_external_texture_extension_string: Option<String>,
fb_fetch_color_name: Option<String>,
adv_blend_eq_interaction: AdvBlendEqInteraction,
}
impl Default for ShaderCaps {
fn default() -> Self {
Self {
glsl_generation: GLSLGeneration::V330,
dual_source_blending_support: false,
shader_derivative_support: false,
explicit_texture_lod_support: false,
integer_support: false,
non_square_matrix_support: false,
inverse_hyperbolic_support: false,
fb_fetch_support: false,
fb_fetch_needs_custom_output: false,
uses_precision_modifiers: false,
flat_interpolation_support: false,
no_perspective_interpolation_support: false,
sample_mask_support: false,
external_texture_support: false,
float_is_32_bits: true,
infinity_support: false,
builtin_fma_support: true,
builtin_determinant_support: true,
can_use_void_in_sequence_expressions: true,
can_use_min_and_abs_together: true,
can_use_fract_for_negative_values: true,
must_force_negated_atan_param_to_float: false,
must_force_negated_ldexp_param_to_multiply: false,
atan2_implemented_as_atan_y_over_x: false,
must_do_op_between_floor_and_abs: false,
must_guard_division_even_after_explicit_zero_check: false,
can_use_frag_coord: true,
add_and_true_to_loop_condition: false,
unfold_short_circuit_as_ternary: false,
emulated_abs_int_function: false,
rewrite_do_while_loops: false,
rewrite_switch_statements: false,
remove_pow_with_constatnt_exponent: false,
no_default_precision_for_external_samplers: false,
rewrite_matrix_vector_mulitply: false,
rewrite_matrix_comparisons: false,
remove_const_from_function_parameters: false,
perlin_noise_rounding_fix: false,
must_declare_fragment_front_facing: false,
version_decl_string: String::new(),
shader_derivative_extension_string: None,
external_texture_extension_string: None,
second_external_texture_extension_string: None,
fb_fetch_color_name: None,
adv_blend_eq_interaction: AdvBlendEqInteraction::NotSupported,
}
}
}
impl ShaderCaps {
#[must_use]
#[inline]
pub fn must_enable_adv_blend_eqs(&self) -> bool {
self.adv_blend_eq_interaction >= AdvBlendEqInteraction::GeneralEnable
}
#[must_use]
#[inline]
pub fn must_declare_fragment_shader_output(&self) -> bool {
self.glsl_generation > GLSLGeneration::V110
}
#[must_use]
#[inline]
pub fn shader_derivative_extension_string(&self) -> Option<String> {
debug_assert!(self.shader_derivative_support);
self.shader_derivative_extension_string.clone()
}
#[must_use]
#[inline]
pub fn external_texture_extension_string(&self) -> Option<String> {
debug_assert!(self.external_texture_support);
self.external_texture_extension_string.clone()
}
#[must_use]
#[inline]
pub fn second_external_texture_extension_string(&self) -> Option<String> {
debug_assert!(self.external_texture_support);
self.second_external_texture_extension_string.clone()
}
#[must_use]
#[inline]
pub fn supported_sksl_verion(&self) -> Version {
if self.shader_derivative_support
&& self.non_square_matrix_support
&& self.integer_support
&& self.glsl_generation >= GLSLGeneration::V330
{
Version::V300
} else {
Version::V100
}
}
#[must_use]
#[inline]
pub const fn supports_distance_field_text(&self) -> bool {
self.shader_derivative_support
}
}
pub struct ShaderCapsFactory {}
impl ShaderCapsFactory {
#[must_use]
pub fn make_default() -> ShaderCaps {
ShaderCaps {
version_decl_string: "#version 400".to_owned(),
shader_derivative_support: true,
..Default::default()
}
}
#[must_use]
pub fn standalone() -> ShaderCaps {
ShaderCaps {
shader_derivative_support: true,
explicit_texture_lod_support: true,
flat_interpolation_support: true,
no_perspective_interpolation_support: true,
sample_mask_support: true,
external_texture_support: true,
..Default::default()
}
}
}