From 56d6e3b159614735f42bc4d3e4bc4db559e333ef Mon Sep 17 00:00:00 2001 From: Facundo Villa Date: Fri, 5 Apr 2024 15:16:29 -0300 Subject: [PATCH] Partially fixed intrinsics. --- .vscode/tasks.json | 2 +- jspd/src/lexer.rs | 98 ++++++------------- jspd/src/parser.rs | 7 ++ .../visibility_model/render_domain.rs | 2 + src/rendering/visibility_shader_generator.rs | 12 ++- 5 files changed, 50 insertions(+), 71 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1ecbfd97..225bb45c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,7 +6,7 @@ { "label": "Clear engine caches", "type": "shell", - "command": "rm -rf resources/* & rm -rf .byte-editor/*", + "command": "rm -rf resources/* && rm -rf .byte-editor/*", "problemMatcher": [] } ] diff --git a/jspd/src/lexer.rs b/jspd/src/lexer.rs index ad784179..2a777fed 100644 --- a/jspd/src/lexer.rs +++ b/jspd/src/lexer.rs @@ -331,10 +331,10 @@ impl Node { pub fn get_child(&self, child_name: &str) -> Option { match &self.node { - Nodes::Scope { children, .. } => { - for child in children { - if let Some(x) = child.borrow().get_child_a(child_name, child.clone()) { - return Some(x); + Nodes::Scope { children: members, .. } | Nodes::Struct { fields: members, .. } | Nodes::PushConstant { members } => { + for member in members { + if let Some(c) = RefCell::borrow(&member).get_child_a(child_name, member.clone()) { + return Some(c); } } } @@ -390,7 +390,12 @@ impl Node { } } } - _ => {} + Nodes::Intrinsic { body, .. } => { + if let Some(c) = RefCell::borrow(&body).get_child_a(child_name, body.clone()) { + return Some(c); + } + } + Nodes::Member { .. } | Nodes::Binding { .. } | Nodes::Specialization { .. } | Nodes::Null => {} } None @@ -398,17 +403,7 @@ impl Node { fn get_child_a(&self, child_name: &str, r: NodeReference) -> Option { match &self.node { - Nodes::Scope { name, .. } => { - if child_name == name { - return Some(r); - } - } - Nodes::Struct { name, .. } => { - if child_name == name { - return Some(r); - } - } - Nodes::Function { name, .. } => { + Nodes::Scope { name, .. } | Nodes::Struct { name, .. } | Nodes::Function { name, .. } | Nodes::Binding { name, .. } | Nodes::Specialization { name, .. } | Nodes::Member { name, .. } | Nodes::Intrinsic { name, .. } => { if child_name == name { return Some(r); } @@ -418,16 +413,6 @@ impl Node { return Some(r); } } - Nodes::Binding { name, .. } => { - if child_name == name { - return Some(r); - } - } - Nodes::Specialization { name, .. } => { - if child_name == name { - return Some(r); - } - } Nodes::Expression(expression) => { match expression { Expressions::Operator { left, right, .. } => { @@ -453,16 +438,6 @@ impl Node { } } } - Nodes::Member { name, .. } => { - if child_name == name { - return Some(r); - } - } - Nodes::Intrinsic { name, .. } => { - if child_name == name { - return Some(r); - } - } Nodes::Null => {} } @@ -496,16 +471,7 @@ impl Node { pub fn get_name(&self) -> Option { match &self.node { - Nodes::Scope { name, .. } => { - Some(name.clone()) - } - Nodes::Function { name, .. } => { - Some(name.clone()) - } - Nodes::Member { name, .. } => { - Some(name.clone()) - } - Nodes::Struct { name, .. } => { + Nodes::Scope { name, .. } | Nodes::Function { name, .. } | Nodes::Member { name, .. } | Nodes::Struct { name, .. } | Nodes::Intrinsic { name, .. } => { Some(name.clone()) } _ => { @@ -539,6 +505,12 @@ impl Node { } } } + + fn null() -> Node { + Self { + node: Nodes::Null, + } + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -681,6 +653,7 @@ fn get_reference(chain: &[&Node], name: &str) -> Option { fn lex_parsed_node<'a>(chain: Vec<&'a Node>, parser_node: &parser::Node, parser_program: &parser::ProgramState) -> Result { let node = match &parser_node.node { + parser::Nodes::Null => { Node::new(Nodes::Null) } parser::Nodes::Scope{ name, children } => { assert_ne!(name, "root"); // The root scope node cannot be an inner part of the program. @@ -913,26 +886,24 @@ fn lex_parsed_node<'a>(chain: Vec<&'a Node>, parser_node: &parser::Node, parser_ let function = lex_parsed_node(chain.clone(), t, parser_program,)?; let parameters = parameters.iter().map(|e| lex_parsed_node(chain.clone(), e, parser_program,)).collect::, LexError>>()?; - { // Validate function call - let function = RefCell::borrow(&function.0); - let function = function.node(); + let r = function.clone(); // Clone to be able to borrow it in and return it - match function { - Nodes::Function { params, .. } => { + { // Validate function call + let b = RefCell::borrow(&function.0); + match b.node() { + Nodes::Function { params, .. } | Nodes::Struct { fields: params, .. } => { if params.len() != parameters.len() { return Err(LexError::FunctionCallParametersDoNotMatchFunctionParameters); } + Node::expression(Expressions::FunctionCall { + function: r, + parameters, + }) } - Nodes::Struct { fields, .. } => { - if parameters.len() != fields.len() { return Err(LexError::FunctionCallParametersDoNotMatchFunctionParameters); } + Nodes::Intrinsic { body, .. } => { + Node::intrinsic(&name, body.clone()) } - Nodes::Intrinsic { .. } => {} _ => { return Err(LexError::Undefined { message: Some("Encountered parsing error while evaluating function call. Expected Function | Struct | Intrinsic, but found other.".to_string()) }); } } } - - Node::expression(Expressions::FunctionCall { - function, - parameters, - }) } parser::Expressions::Operator{ name, left, right } => { Node::expression(Expressions::Operator { @@ -963,14 +934,7 @@ fn lex_parsed_node<'a>(chain: Vec<&'a Node>, parser_node: &parser::Node, parser_ this } parser::Nodes::Intrinsic { name, body } => { - let mut this = Node::intrinsic(name, Node::expression(Expressions::Return).into()); - - { - let c = lex_parsed_node(chain.clone(), body, parser_program,)?; - this.add_child(c); - } - - this + Node::intrinsic(name, lex_parsed_node(chain.clone(), body, parser_program,)?) } }; diff --git a/jspd/src/parser.rs b/jspd/src/parser.rs index 58843d73..6a50246a 100644 --- a/jspd/src/parser.rs +++ b/jspd/src/parser.rs @@ -66,6 +66,7 @@ impl Node { #[derive(Clone, Debug)] pub enum Nodes { + Null, Scope { name: String, children: Vec, @@ -292,6 +293,12 @@ impl NodeReference { }, })) } + + pub fn null() -> NodeReference { + NodeReference(Rc::new(Node { + node: Nodes::Null, + })) + } } impl From for NodeReference { diff --git a/src/rendering/visibility_model/render_domain.rs b/src/rendering/visibility_model/render_domain.rs index b2a43054..5992e6fa 100644 --- a/src/rendering/visibility_model/render_domain.rs +++ b/src/rendering/visibility_model/render_domain.rs @@ -436,6 +436,8 @@ impl VisibilityWorldRenderDomain { let buffer = if let Some(b) = resource.get_buffer() { b } else { + log::warn!("The image '{}' won't be available because the resource did not provide a buffer.", resource.id()); + // TODO: maybe fill buffer with a default color return; }; diff --git a/src/rendering/visibility_shader_generator.rs b/src/rendering/visibility_shader_generator.rs index 9c225a4a..174ca963 100644 --- a/src/rendering/visibility_shader_generator.rs +++ b/src/rendering/visibility_shader_generator.rs @@ -127,7 +127,7 @@ impl VisibilityShaderGenerator { let camera_struct = NodeReference::r#struct("Camera", vec![NodeReference::member("view", "mat4f"), NodeReference::member("projection_matrix", "mat4f"), NodeReference::member("view_projection", "mat4f"), NodeReference::member("inverse_view_matrix", "mat4f"), NodeReference::member("inverse_projection_matrix", "mat4f"), NodeReference::member("inverse_view_projection_matrix", "mat4f")]); let meshlet_struct = NodeReference::r#struct("Meshlet", vec![NodeReference::member("instance_index", "u32"), NodeReference::member("vertex_offset", "u16"), NodeReference::member("triangle_offset", "u16"), NodeReference::member("vertex_count", "u8"), NodeReference::member("triangle_count", "u8")]); let light_struct = NodeReference::r#struct("Light", vec![NodeReference::member("view_matrix", "mat4f"), NodeReference::member("projection_matrix", "mat4f"), NodeReference::member("vp_matrix", "mat4f"), NodeReference::member("position", "vec3f"), NodeReference::member("color", "vec3f"), NodeReference::member("light_type", "u8")]); - let material_struct = NodeReference::r#struct("Material", vec![NodeReference::member("textures", "mat4f")]); + let material_struct = NodeReference::r#struct("Material", vec![NodeReference::member("textures", "u32[16]")]); let set0_binding1 = NodeReference::binding("meshes", NodeReference::buffer("MeshBuffer", vec![NodeReference::member("meshes", "Mesh[64]")]), 0, 1, true, false); let set0_binding2 = NodeReference::binding("positions", NodeReference::buffer("Positions", vec![NodeReference::member("positions", "vec3f[8192]")]), 0, 2, true, false); @@ -161,7 +161,7 @@ impl VisibilityShaderGenerator { let calculate_full_bary = NodeReference::function("calculate_full_bary", vec![NodeReference::member("pt0", "vec4f"), NodeReference::member("pt1", "vec4f"), NodeReference::member("pt2", "vec4f"), NodeReference::member("pixelNdc", "vec2f"), NodeReference::member("winSize", "vec2f")], "BarycentricDeriv", vec![NodeReference::glsl("BarycentricDeriv ret = BarycentricDeriv(vec3(0), vec3(0), vec3(0)); vec3 invW = 1.0 / vec3(pt0.w, pt1.w, pt2.w); vec2 ndc0 = pt0.xy * invW.x; vec2 ndc1 = pt1.xy * invW.y; vec2 ndc2 = pt2.xy * invW.z; float invDet = 1.0 / determinant(mat2(ndc2 - ndc1, ndc0 - ndc1)); ret.ddx = vec3(ndc1.y - ndc2.y, ndc2.y - ndc0.y, ndc0.y - ndc1.y) * invDet * invW; ret.ddy = vec3(ndc2.x - ndc1.x, ndc0.x - ndc2.x, ndc1.x - ndc0.x) * invDet * invW; float ddxSum = dot(ret.ddx, vec3(1)); float ddySum = dot(ret.ddy, vec3(1)); vec2 deltaVec = pixelNdc - ndc0; float interpInvW = invW.x + deltaVec.x * ddxSum + deltaVec.y * ddySum; float interpW = 1.0 / interpInvW; ret.lambda.x = interpW * (invW.x + deltaVec.x * ret.ddx.x + deltaVec.y * ret.ddy.x); ret.lambda.y = interpW * (0.0 + deltaVec.x * ret.ddx.y + deltaVec.y * ret.ddy.y); ret.lambda.z = interpW * (0.0 + deltaVec.x * ret.ddx.z + deltaVec.y * ret.ddy.z); ret.ddx *= (2.0 / winSize.x); ret.ddy *= (2.0 / winSize.y); ddxSum *= (2.0 / winSize.x); ddySum *= (2.0 / winSize.y); float interpW_ddx = 1.0 / (interpInvW + ddxSum); float interpW_ddy = 1.0 / (interpInvW + ddySum); ret.ddx = interpW_ddx * (ret.lambda * interpInvW + ret.ddx) - ret.lambda; ret.ddy = interpW_ddy * (ret.lambda * interpInvW + ret.ddy) - ret.lambda; return ret;", Vec::new(), Vec::new())]); - let sample_function = NodeReference::intrinsic("sample", NodeReference::glsl("texture(textures[nonuniformEXT(material.textures[0])], uv)", vec!["textures".to_string()], Vec::new())); + let sample_function = NodeReference::intrinsic("sample", NodeReference::glsl("texture(textures[nonuniformEXT(material.textures[0])], uv).rgb", vec!["textures".to_string()], Vec::new())); Self { mesh_struct, @@ -306,6 +306,11 @@ float roughness = float(0.5);"; program_state.insert(name.to_string(), x.clone()); extra.push(x); } + "Texture2D" => { + let x = jspd::parser::NodeReference::intrinsic(name, jspd::parser::NodeReference::glsl("texture(textures[nonuniformEXT(material.textures[0])], uv).rgb", vec!["textures".to_string()], Vec::new())); + program_state.insert(name.to_string(), x.clone()); + extra.push(x); + } _ => {} } } @@ -440,8 +445,9 @@ imageStore(out_diffuse, pixel_coordinates, vec4(diffuse, 1.0));"; program_state.insert("sample".to_string(), self.sample_function.clone()); let mut ret = Vec::with_capacity(32); + ret.append(&mut vec![push_constant, self.barycentric_deriv.clone(), set2_binding11, material_offset, meshes, set0_binding1, set1_binding0, set0_binding7, set1_binding4, set1_binding6, set2_binding1, meshlets, material, set2_binding5, set2_binding10, primitive_indices, vertex_indices, positions, normals, lighting_data, out_albedo, out_diffuse, self.calculate_full_bary.clone(), self.distribution_ggx.clone(), self.geometry_schlick_ggx.clone(), self.geometry_smith.clone(), self.fresnel_schlick.clone(), self.sample_function.clone()]); ret.append(&mut extra); - ret.append(&mut vec![self.sample_function.clone(), push_constant, self.barycentric_deriv.clone(), set2_binding11, material_offset, meshes, set0_binding1, set1_binding0, set0_binding7, set1_binding4, set1_binding6, set2_binding1, meshlets, material, set2_binding5, set2_binding10, primitive_indices, vertex_indices, positions, normals, lighting_data, out_albedo, out_diffuse, self.calculate_full_bary.clone(), self.distribution_ggx.clone(), self.geometry_schlick_ggx.clone(), self.geometry_smith.clone(), self.fresnel_schlick.clone(), m]); + ret.push(m); ret } }