Skip to content

Commit

Permalink
a
Browse files Browse the repository at this point in the history
  • Loading branch information
fornwall committed Aug 21, 2023
1 parent a70e885 commit ee3563f
Show file tree
Hide file tree
Showing 23 changed files with 170 additions and 32 deletions.
2 changes: 2 additions & 0 deletions src/back/glsl/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,4 +480,6 @@ pub const RESERVED_KEYWORDS: &[&str] = &[
// Naga utilities:
super::MODF_FUNCTION,
super::MODF_STRUCT,
super::FREXP_FUNCTION,
super::FREXP_STRUCT,
];
32 changes: 29 additions & 3 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub const SUPPORTED_ES_VERSIONS: &[u16] = &[300, 310, 320];
/// of detail for bounds checking in `ImageLoad`
const CLAMPED_LOD_SUFFIX: &str = "_clamped_lod";

pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
pub(crate) const FREXP_STRUCT: &str = "naga_frexp_struct";
pub(crate) const MODF_FUNCTION: &str = "naga_modf";
pub(crate) const MODF_STRUCT: &str = "naga_modf_struct";

Expand Down Expand Up @@ -623,6 +625,22 @@ impl<'a, W: Write> Writer<'a, W> {
)?;
}

if self.module.special_types.frexp_result.is_some() {
writeln!(
self.out,
"struct {FREXP_STRUCT} {{
float fract;
float exp;
}};
{FREXP_STRUCT} {FREXP_FUNCTION}(float arg) {{
float exp;
float fract = modf(arg, exp);
return {MODF_STRUCT}(fract, exp);
}}"
)?;
}

// Write struct types.
//
// This are always ordered because the IR is structured in a way that
Expand Down Expand Up @@ -879,7 +897,8 @@ impl<'a, W: Write> Writer<'a, W> {
| TypeInner::Sampler { .. }
| TypeInner::AccelerationStructure
| TypeInner::RayQuery
| TypeInner::ModfResultF32
| TypeInner::ModfResult
| TypeInner::FrexpResult
| TypeInner::BindingArray { .. } => {
return Err(Error::Custom(format!("Unable to write type {inner:?}")))
}
Expand All @@ -905,7 +924,11 @@ impl<'a, W: Write> Writer<'a, W> {
}
// glsl array has the size separated from the base type
TypeInner::Array { base, .. } => self.write_type(base),
TypeInner::ModfResultF32 => {
TypeInner::FrexpResult => {
write!(self.out, "{FREXP_STRUCT}")?;
Ok(())
}
TypeInner::ModfResult => {
write!(self.out, "{MODF_STRUCT}")?;
Ok(())
}
Expand Down Expand Up @@ -2349,7 +2372,10 @@ impl<'a, W: Write> Writer<'a, W> {
&self.names[&NameKey::StructMember(ty, index)]
)?
}
TypeInner::ModfResultF32 => {
TypeInner::FrexpResult => {
write!(self.out, ".{}", if index == 0 { "fract" } else { "exp " })?
}
TypeInner::ModfResult => {
write!(self.out, ".{}", if index == 0 { "fract" } else { "whole " })?
}
ref other => return Err(Error::Custom(format!("Cannot index {other:?}"))),
Expand Down
22 changes: 22 additions & 0 deletions src/back/hlsl/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,28 @@ impl<'a, W: Write> super::Writer<'a, W> {
}

pub(super) fn write_special_functions(&mut self, module: &crate::Module) -> BackendResult {
if module.special_types.frexp_result.is_some() {
let function_name = super::writer::FREXP_FUNCTION;
let struct_name = super::writer::FREXP_STRUCT;
writeln!(
self.out,
"struct {struct_name} {{
float fract;
float exp;
}};
{struct_name} {function_name}(in float arg) {{
float exp;
float fract = modf(arg, exp);
{struct_name} result;
result.exp = exp;
result.fract = fract;
return result;
}}"
)?;
// Write extra new line
writeln!(self.out)?;
}
if module.special_types.modf_result.is_some() {
let function_name = super::writer::MODF_FUNCTION;
let struct_name = super::writer::MODF_STRUCT;
Expand Down
2 changes: 2 additions & 0 deletions src/back/hlsl/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,8 @@ pub const RESERVED: &[&str] = &[
"ConstantBuffer",
"RayQuery",
// Naga utilities
super::writer::FREXP_FUNCTION,
super::writer::FREXP_STRUCT,
super::writer::MODF_FUNCTION,
super::writer::MODF_STRUCT,
];
Expand Down
12 changes: 10 additions & 2 deletions src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const SPECIAL_BASE_VERTEX: &str = "base_vertex";
const SPECIAL_BASE_INSTANCE: &str = "base_instance";
const SPECIAL_OTHER: &str = "other";

pub(crate) const FREXP_FUNCTION: &str = "frexp_modf";
pub(crate) const FREXP_STRUCT: &str = "frexp_modf_result";
pub(crate) const MODF_FUNCTION: &str = "naga_modf";
pub(crate) const MODF_STRUCT: &str = "naga_modf_result";

Expand Down Expand Up @@ -1063,7 +1065,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
TypeInner::Array { base, size, .. } | TypeInner::BindingArray { base, size } => {
self.write_array_size(module, base, size)?;
}
TypeInner::ModfResultF32 => {
TypeInner::FrexpResult => {
write!(self.out, "struct {FREXP_STRUCT}")?;
}
TypeInner::ModfResult => {
write!(self.out, "struct {MODF_STRUCT}")?;
}
_ => return Err(Error::Unimplemented(format!("write_value_type {inner:?}"))),
Expand Down Expand Up @@ -2284,7 +2289,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
&writer.names[&NameKey::StructMember(ty, index)]
)?
}
TypeInner::ModfResultF32 => write!(
TypeInner::FrexpResult => {
write!(writer.out, ".{}", if index == 0 { "fract" } else { "exp" })?
}
TypeInner::ModfResult => write!(
writer.out,
".{}",
if index == 0 { "fract" } else { "whole" }
Expand Down
2 changes: 2 additions & 0 deletions src/back/msl/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ pub const RESERVED: &[&str] = &[
// Naga utilities
"DefaultConstructible",
"clamped_lod_e",
super::writer::FREXP_FUNCTION,
super::writer::FREXP_STRUCT,
super::writer::MODF_FUNCTION,
super::writer::MODF_STRUCT,
];
24 changes: 20 additions & 4 deletions src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const RAY_QUERY_FIELD_INTERSECTION: &str = "intersection";
const RAY_QUERY_FIELD_READY: &str = "ready";
const RAY_QUERY_FUN_MAP_INTERSECTION: &str = "_map_intersection_type";

pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
pub(crate) const FREXP_STRUCT: &str = "naga_frexp_result";
pub(crate) const MODF_FUNCTION: &str = "naga_modf";
pub(crate) const MODF_STRUCT: &str = "naga_modf_result";

Expand Down Expand Up @@ -146,7 +148,10 @@ impl<'a> Display for TypeContext<'a> {
crate::TypeInner::Struct { .. } => {
unreachable!()
}
crate::TypeInner::ModfResultF32 { .. } => {
crate::TypeInner::FrexpResult { .. } => {
write!(out, "{}", FREXP_STRUCT)
}
crate::TypeInner::ModfResult { .. } => {
write!(out, "{}", MODF_STRUCT)
}
crate::TypeInner::Image {
Expand Down Expand Up @@ -460,7 +465,8 @@ impl crate::Type {
| Ti::Sampler { .. }
| Ti::AccelerationStructure
| Ti::RayQuery
| Ti::ModfResultF32
| Ti::FrexpResult
| Ti::ModfResult
| Ti::BindingArray { .. } => false,
}
}
Expand Down Expand Up @@ -1644,6 +1650,15 @@ impl<W: Write> Writer<W> {
write!(self.out, "{NAMESPACE}::{op}")?;
self.put_call_parameters(iter::once(argument), context)?;
}
crate::Expression::Math {
fun: crate::MathFunction::Frexp,
arg,
..
} => {
write!(self.out, "{FREXP_FUNCTION}(")?;
self.put_expression(arg, context, false)?;
write!(self.out, ")")?;
}
crate::Expression::Math {
fun: crate::MathFunction::Modf,
arg,
Expand Down Expand Up @@ -2037,7 +2052,8 @@ impl<W: Write> Writer<W> {
}
match *base_inner {
crate::TypeInner::Struct { .. }
| crate::TypeInner::ModfResultF32 { .. } => (base, None),
| crate::TypeInner::FrexpResult
| crate::TypeInner::ModfResult { .. } => (base, None),
_ => (base, Some(index::GuardedIndex::Known(index))),
}
}
Expand Down Expand Up @@ -2152,7 +2168,7 @@ impl<W: Write> Writer<W> {
write!(self.out, ".{}", back::COMPONENTS[index as usize])?;
}
}
crate::TypeInner::ModfResultF32 => {
crate::TypeInner::ModfResult => {
self.put_access_chain(base, policy, context)?;
write!(self.out, ".{}", if index == 0 { "fract" } else { "whole" })?;
}
Expand Down
2 changes: 1 addition & 1 deletion src/back/spv/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ impl<'w> BlockContext<'w> {

load_id
}
crate::TypeInner::ModfResultF32 => {
crate::TypeInner::ModfResult => {
let id = self.gen_id();
let base_id = self.cached[base];
block.body.push(Instruction::composite_extract(
Expand Down
3 changes: 2 additions & 1 deletion src/back/spv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
crate::TypeInner::RayQuery => LocalType::RayQuery,
crate::TypeInner::Array { .. }
| crate::TypeInner::Struct { .. }
| crate::TypeInner::ModfResultF32
| crate::TypeInner::FrexpResult
| crate::TypeInner::ModfResult
| crate::TypeInner::BindingArray { .. } => return None,
})
}
Expand Down
15 changes: 13 additions & 2 deletions src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ impl Writer {
}
Instruction::type_struct(id, member_ids.as_slice())
}
crate::TypeInner::ModfResultF32 => {
crate::TypeInner::FrexpResult | crate::TypeInner::ModfResult => {
let float_ty = arena
.get(&crate::Type {
name: None,
Expand All @@ -1035,7 +1035,18 @@ impl Writer {
})
.unwrap(); // TODO: unwrap
self.decorate_struct_member_special(id, 0, 0, Some("fract"), float_ty, arena)?;
self.decorate_struct_member_special(id, 1, 4, Some("whole"), float_ty, arena)?;
self.decorate_struct_member_special(
id,
1,
4,
Some(if ty.inner == crate::TypeInner::FrexpResult {
"exp"
} else {
"whole"
}),
float_ty,
arena,
)?;

let float_id = self.get_float_type_id();
let member_ids = [float_id; 2];
Expand Down
5 changes: 4 additions & 1 deletion src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,10 @@ impl<W: Write> Writer<W> {
&self.names[&NameKey::StructMember(ty, index)]
)?
}
TypeInner::ModfResultF32 => {
TypeInner::FrexpResult => {
write!(self.out, ".{}", if index == 0 { "fract" } else { "exp" })?
}
TypeInner::ModfResult => {
write!(self.out, ".{}", if index == 0 { "fract" } else { "whole" })?
}
ref other => return Err(Error::Custom(format!("Cannot index {other:?}"))),
Expand Down
17 changes: 16 additions & 1 deletion src/front/type_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,26 @@ impl crate::Module {
let handle = self.types.insert(
crate::Type {
name: Some("__naga_modf_result".to_string()),
inner: crate::TypeInner::ModfResultF32,
inner: crate::TypeInner::ModfResult,
},
Span::UNDEFINED,
);
self.special_types.modf_result = Some(handle);
handle
}

pub fn generate_frexp_result(&mut self) -> Handle<crate::Type> {
if let Some(handle) = self.special_types.frexp_result {
return handle;
}
let handle = self.types.insert(
crate::Type {
name: Some("__naga_frexp_result".to_string()),
inner: crate::TypeInner::FrexpResult,
},
Span::UNDEFINED,
);
self.special_types.frexp_result = Some(handle);
handle
}
}
29 changes: 24 additions & 5 deletions src/front/wgsl/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1587,7 +1587,23 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
),
}
}
crate::TypeInner::ModfResultF32 => {
crate::TypeInner::FrexpResult => {
let index = if field.name == "fract" {
0
} else if field.name == "exp" {
1
} else {
return Err(Error::BadAccessor(field.span));
};
(
crate::Expression::AccessIndex {
base: handle,
index,
},
is_reference,
)
}
crate::TypeInner::ModfResult => {
let index = if field.name == "fract" {
0
} else if field.name == "whole" {
Expand Down Expand Up @@ -1731,9 +1747,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {

// Handle special functions return structures
match fun {
crate::MathFunction::Modf => {
crate::MathFunction::Frexp | crate::MathFunction::Modf => {
args.finish()?;
let _ = ctx.module.generate_modf_result();
let _ = if fun == crate::MathFunction::Frexp {
ctx.module.generate_frexp_result()
} else {
ctx.module.generate_modf_result()
};
crate::Expression::Math {
fun,
arg,
Expand Down Expand Up @@ -2122,8 +2142,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
return Ok(Some(result));
}
"rayQueryGetCommittedIntersection" => {
let mut args: ArgumentContext<'_, '_> =
ctx.prepare_args(arguments, 1, span);
let mut args = ctx.prepare_args(arguments, 1, span);
let query = self.ray_query_pointer(args.next()?, ctx.reborrow())?;
args.finish()?;

Expand Down
3 changes: 2 additions & 1 deletion src/front/wgsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ impl crate::TypeInner {
Ti::Sampler { .. } => "sampler".to_string(),
Ti::AccelerationStructure => "acceleration_structure".to_string(),
Ti::RayQuery => "ray_query".to_string(),
Ti::ModfResultF32 => "__modf_result_f32".to_string(),
Ti::FrexpResult => "__frexp_result_f32".to_string(),
Ti::ModfResult => "__modf_result_f32".to_string(),
Ti::BindingArray { base, size, .. } => {
let member_type = &gctx.types[base];
let base = member_type.name.as_deref().unwrap_or("unknown");
Expand Down
5 changes: 3 additions & 2 deletions src/front/wgsl/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,11 @@ fn binary_expression_mixed_scalar_and_vector_operands() {
#[test]
fn parse_pointers() {
parse_str(
"fn foo() {
"fn foo(a: ptr<private, f32>) -> f32 { return *a; }
fn bar() {
var x: f32 = 1.0;
let px = &x;
let py = frexp(0.5, px);
let py = foo(px);
}",
)
.unwrap();
Expand Down
Loading

0 comments on commit ee3563f

Please sign in to comment.