use super::shaderc_serde;
use serde::Deserialize;
#[derive(Deserialize, Copy, Clone, Debug)]
pub struct TargetEnvArgs {
#[serde(with = "shaderc_serde::TargetEnv")]
pub env: shaderc::TargetEnv,
#[serde(with = "shaderc_serde::EnvVersion")]
pub version: shaderc::EnvVersion,
}
#[derive(Deserialize, Copy, Clone, Debug, Default)]
pub struct ForcedVersionProfileArgs {
#[serde(default)]
pub version: Option<u32>,
#[serde(deserialize_with = "shaderc_serde::de_opt_glsl_profile", default)]
pub profile: Option<shaderc::GlslProfile>,
}
#[derive(Deserialize, Copy, Clone, Debug)]
pub struct LimitArgs {
#[serde(with = "shaderc_serde::Limit")]
pub limit: shaderc::Limit,
pub value: i32,
}
#[derive(Deserialize, Copy, Clone, Debug)]
pub struct BindingBaseArgs {
#[serde(with = "shaderc_serde::ResourceKind")]
pub resource_kind: shaderc::ResourceKind,
pub base: u32,
}
#[derive(Deserialize, Copy, Clone, Debug)]
pub struct BindingBaseForStageArgs {
#[serde(with = "shaderc_serde::ResourceKind")]
pub resource_kind: shaderc::ResourceKind,
pub base: u32,
#[serde(with = "shaderc_serde::ShaderKind")]
pub shader_kind: shaderc::ShaderKind,
}
#[derive(Deserialize, Clone, Debug)]
pub struct HlslRegisterSetAndBindingArgs {
pub register: String,
pub set: String,
pub binding: String,
}
#[derive(Deserialize, Clone, Debug)]
pub struct HlslRegisterSetAndBindingForStageArgs {
#[serde(with = "shaderc_serde::ShaderKind")]
pub kind: shaderc::ShaderKind,
pub register: String,
pub set: String,
pub binding: String,
}
#[derive(Deserialize, Clone, Debug)]
pub struct MacroDefinitionArgs {
pub name: String,
#[serde(default)]
pub value: Option<String>,
}
#[derive(Deserialize, Clone, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct Args {
#[serde(default, deserialize_with = "shaderc_serde::de_opt_shader_kind")]
pub kind: Option<shaderc::ShaderKind>,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub entry: Option<String>,
#[serde(default, alias = "env")]
pub target_env: Option<TargetEnvArgs>,
#[serde(
default,
alias = "spirv",
deserialize_with = "shaderc_serde::de_opt_spirv_version"
)]
pub target_spirv: Option<shaderc::SpirvVersion>,
#[serde(
default,
alias = "lang",
deserialize_with = "shaderc_serde::de_opt_source_language"
)]
pub source_language: Option<shaderc::SourceLanguage>,
#[serde(flatten)]
pub forced_version_profile: ForcedVersionProfileArgs,
#[serde(default)]
pub limit: Vec<LimitArgs>,
#[serde(default)]
pub auto_bind_uniforms: Option<bool>,
#[serde(default)]
pub hlsl_io_mapping: Option<bool>,
#[serde(default)]
pub hlsl_offsets: Option<bool>,
#[serde(default)]
pub binding_base: Vec<BindingBaseArgs>,
#[serde(default)]
pub binding_base_for_stage: Vec<BindingBaseForStageArgs>,
#[serde(default)]
pub hlsl_register_set_and_binding: Vec<HlslRegisterSetAndBindingArgs>,
#[serde(default)]
pub hlsl_register_set_and_binding_for_stage: Vec<HlslRegisterSetAndBindingForStageArgs>,
#[serde(default)]
pub hlsl_functionality: Option<bool>,
#[serde(default)]
pub invert_y: Option<bool>,
#[serde(default)]
pub nan_clamp: Option<bool>,
#[serde(default, alias = "define")]
pub macro_definition: Vec<MacroDefinitionArgs>,
#[serde(default, deserialize_with = "shaderc_serde::de_opt_optimization_level")]
pub optimization_level: Option<shaderc::OptimizationLevel>,
#[serde(default, alias = "debug")]
pub generate_debug_info: bool,
#[serde(default)]
pub suppress_warnings: bool,
#[serde(default)]
pub warnings_as_errors: bool,
}
impl Args {
pub fn to_options(&self) -> Option<shaderc::CompileOptions> {
#[cfg(feature = "debug")]
{
emit_call_site_warning!("debugging compiler options");
}
let mut options = shaderc::CompileOptions::new()?;
if let Some(TargetEnvArgs { env, version }) = self.target_env {
options.set_target_env(env, version as u32);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!(
"options.set_target_env({:?}, {:?});",
env, version
));
}
}
if let Some(target_spirv) = self.target_spirv {
options.set_target_spirv(target_spirv);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_target_spirv({:?});", target_spirv));
}
}
if let Some(source_language) = self.source_language {
options.set_source_language(source_language);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!(
"options.set_source_language({:?});",
source_language
));
}
}
if let ForcedVersionProfileArgs {
version: Some(version),
profile,
} = self.forced_version_profile
{
let profile = profile.unwrap_or(shaderc::GlslProfile::None);
options.set_forced_version_profile(version, profile);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!(
"options.set_forced_version_profile({:?}, {:?});",
version, profile
));
}
}
for LimitArgs { limit, value } in &self.limit {
options.set_limit(*limit, *value);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_limit({:?}, {:?});", limit, value));
}
}
if let Some(auto_bind_uniforms) = self.auto_bind_uniforms {
options.set_auto_bind_uniforms(auto_bind_uniforms);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!(
"options.set_auto_bind_uniforms({:?});",
auto_bind_uniforms
));
}
}
if let Some(hlsl_io_mapping) = self.hlsl_io_mapping {
options.set_hlsl_io_mapping(hlsl_io_mapping);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_hlsl_io_mapping({:?});", hlsl_io_mapping));
}
}
if let Some(hlsl_offsets) = self.hlsl_offsets {
options.set_hlsl_offsets(hlsl_offsets);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_hlsl_offsets({:?});", hlsl_offsets));
}
}
for BindingBaseArgs {
resource_kind,
base,
} in &self.binding_base
{
options.set_binding_base(*resource_kind, *base);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_binding_base({:?}, {:?});", resource_kind, base));
}
}
for BindingBaseForStageArgs {
shader_kind,
resource_kind,
base,
} in &self.binding_base_for_stage
{
options.set_binding_base_for_stage(*shader_kind, *resource_kind, *base);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_binding_base_for_stage({:?}, {:?}, {:?});", shader_kind, resource_kind, base));
}
}
for HlslRegisterSetAndBindingArgs {
register,
set,
binding,
} in &self.hlsl_register_set_and_binding
{
options.set_hlsl_register_set_and_binding(register, set, binding);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_hlsl_register_set_and_binding({:?}, {:?}, {:?});", register, set, binding));
}
}
for HlslRegisterSetAndBindingForStageArgs {
kind,
register,
set,
binding,
} in &self.hlsl_register_set_and_binding_for_stage
{
options.set_hlsl_register_set_and_binding_for_stage(*kind, register, set, binding);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_hlsl_register_set_and_binding_for_stage({:?}, {:?}, {:?}, {:?});", kind, register, set, binding));
}
}
if let Some(hlsl_functionality) = self.hlsl_functionality {
options.set_hlsl_functionality1(hlsl_functionality);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_hlsl_functionality1({:?});", hlsl_functionality));
}
}
if let Some(invert_y) = self.invert_y {
options.set_invert_y(invert_y);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_invert_y({:?});", invert_y));
}
}
if let Some(nan_clamp) = self.nan_clamp {
options.set_nan_clamp(nan_clamp);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_nan_clamp({:?});", nan_clamp));
}
}
for MacroDefinitionArgs { name, value } in &self.macro_definition {
options.add_macro_definition(name, value.as_ref().map(|s| s.as_str()));
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.add_macro_definition({:?}, {:?});", name, value));
}
}
if let Some(optimization_level) = self.optimization_level {
options.set_optimization_level(optimization_level);
#[cfg(feature = "debug")]
{
emit_call_site_warning!(format!("options.set_optimization_level({:?});", optimization_level));
}
}
if self.generate_debug_info {
options.set_generate_debug_info();
#[cfg(feature = "debug")]
{
emit_call_site_warning!("options.set_generate_debug_info();");
}
}
if self.suppress_warnings {
options.set_suppress_warnings();
#[cfg(feature = "debug")]
{
emit_call_site_warning!("options.set_suppress_warnings();");
}
}
if self.warnings_as_errors {
options.set_warnings_as_errors();
#[cfg(feature = "debug")]
{
emit_call_site_warning!("options.set_warnings_as_errors();");
}
}
Some(options)
}
}