473 lines
17 KiB
Rust
473 lines
17 KiB
Rust
/*const SOURCE: &'static str = r#"
|
|
DrawQuad: DrawShader {
|
|
uniform uni1: float
|
|
|
|
rust_type= {{0}},
|
|
|
|
const cnst1: float = 1.0
|
|
live: 1.0
|
|
|
|
Struct2: Struct {
|
|
field c: float
|
|
fn struct_2_set(inout self, x: float) {self.c = x;}
|
|
}
|
|
|
|
Struct1: Struct {
|
|
field a: float
|
|
field b: Struct2
|
|
fn struct_1_closure(inout self, c: fn(x: float) -> float) -> float {
|
|
return c(self.a);
|
|
}
|
|
fn struct_1_set(inout self) {self.a = 2.0; self.b.struct_2_set(self.struct_1_closure( | x | x + 1.0));}
|
|
}
|
|
|
|
fn pixel(self) -> vec4 {
|
|
let x = Struct1 {a: 1.0, b: Struct2 {c: 1.0 + self.dinst}};
|
|
let x = vec3(1.0) * self.dmat;
|
|
x.struct_1_set();
|
|
return #f;
|
|
}
|
|
|
|
fn override(self) {}
|
|
|
|
fn vertex(self) -> vec4 {
|
|
let x = Struct2 {c: self.uni1 + cnst1 + live};
|
|
x.struct_2_set(3.0);
|
|
let x = vec3(1.0) * self.dmat;
|
|
self.override();
|
|
return #f;
|
|
}
|
|
}
|
|
DrawQuad2: DrawQuad {
|
|
fn override(self) {1 + 1;}
|
|
}
|
|
"#;
|
|
|
|
const GLSL_OUTPUT: &'static str = r#"
|
|
VERTEXSHADER
|
|
// Uniform block user
|
|
uniform float ds_uni1;
|
|
uniform float ds_duni;
|
|
attribute vec4 packed_instance_0;
|
|
attribute vec4 packed_instance_1;
|
|
attribute vec2 packed_instance_2;
|
|
varying vec4 packed_varying_0;
|
|
varying vec4 packed_varying_1;
|
|
varying vec2 packed_varying_2;
|
|
float ds_dinst = 0.0;
|
|
mat3 ds_dmat = mat3(0.0);
|
|
uniform float live_0_1_3;
|
|
struct struct_0_1_4 {
|
|
float f_c;
|
|
};
|
|
const float const_0_1_2 = 1.0;
|
|
void fn_0_2_1_struct_2_set(inout struct_0_1_4 var_self_0, float var_x_0) {
|
|
(var_self_0.f_c = var_x_0);
|
|
}
|
|
void fn_0_1_16_override() {
|
|
(1 + 1);
|
|
}
|
|
vec4 fn_0_1_17_vertex() {
|
|
struct_0_1_4 var_x_0 = struct_0_1_4(((ds_uni1 + const_0_1_2) + live_0_1_3));
|
|
fn_0_2_1_struct_2_set (var_x_0, 3.0);
|
|
vec3 var_x_1 = (vec3(1.0) * ds_dmat);
|
|
fn_0_1_16_override ();
|
|
return vec4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
void main() {
|
|
ds_dinst = packed_instance_0.x;
|
|
ds_dmat[0][0] = packed_instance_0.y;
|
|
ds_dmat[0][1] = packed_instance_0.z;
|
|
ds_dmat[0][2] = packed_instance_0.w;
|
|
ds_dmat[0][3] = packed_instance_1.x;
|
|
ds_dmat[1][0] = packed_instance_1.y;
|
|
ds_dmat[1][1] = packed_instance_1.z;
|
|
ds_dmat[1][2] = packed_instance_1.w;
|
|
ds_dmat[1][3] = packed_instance_2.x;
|
|
ds_dmat[2][0] = packed_instance_2.y;
|
|
gl_Position = fn_0_1_17_vertex();
|
|
packed_varying_0.x = dinst;
|
|
packed_varying_0.y = dmat[0][0];
|
|
packed_varying_0.z = dmat[0][1];
|
|
packed_varying_0.w = dmat[0][2];
|
|
packed_varying_1.x = dmat[0][3];
|
|
packed_varying_1.y = dmat[1][0];
|
|
packed_varying_1.z = dmat[1][1];
|
|
packed_varying_1.w = dmat[1][2];
|
|
packed_varying_2.x = dmat[1][3];
|
|
packed_varying_2.y = dmat[2][0];
|
|
}
|
|
PIXELSHADER
|
|
// Uniform block user
|
|
uniform float ds_uni1;
|
|
uniform float ds_duni;
|
|
varying vec4 packed_varying_0;
|
|
varying vec4 packed_varying_1;
|
|
varying vec2 packed_varying_2;
|
|
float ds_dinst = 0.0;
|
|
mat3 ds_dmat = mat3(0.0);
|
|
uniform float live_0_1_3;
|
|
struct struct_0_1_4 {
|
|
float f_c;
|
|
};
|
|
struct struct_0_1_5 {
|
|
float f_a;
|
|
struct_0_1_4 f_b;
|
|
};
|
|
float closure_0_in_fn_0_2_5(float var_x_0) {
|
|
return (var_x_0 + 1.0);
|
|
}
|
|
float site_0_of_fn_0_2_5_struct_1_closure(inout struct_0_1_5 var_self_0) {
|
|
return closure_0_in_fn_0_2_5(var_self_0.f_a);
|
|
}
|
|
void fn_0_2_1_struct_2_set(inout struct_0_1_4 var_self_0, float var_x_0) {
|
|
(var_self_0.f_c = var_x_0);
|
|
}
|
|
void fn_0_2_5_struct_1_set(inout struct_0_1_5 var_self_0) {
|
|
(var_self_0.f_a = 2.0);
|
|
fn_0_2_1_struct_2_set (var_self_0.f_b, site_0_of_fn_0_2_5_struct_1_closure (var_self_0));
|
|
}
|
|
vec4 fn_0_1_15_pixel() {
|
|
struct_0_1_5 var_x_0 = struct_0_1_5(1.0, struct_0_1_4((1.0 + ds_dinst)));
|
|
vec3 var_x_1 = (vec3(1.0) * ds_dmat);
|
|
fn_0_2_5_struct_1_set (var_x_1);
|
|
return vec4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
void main() {
|
|
ds_dinst = packed_varying_0.x;
|
|
ds_dmat[0][0] = packed_varying_0.y;
|
|
ds_dmat[0][1] = packed_varying_0.z;
|
|
ds_dmat[0][2] = packed_varying_0.w;
|
|
ds_dmat[0][3] = packed_varying_1.x;
|
|
ds_dmat[1][0] = packed_varying_1.y;
|
|
ds_dmat[1][1] = packed_varying_1.z;
|
|
ds_dmat[1][2] = packed_varying_1.w;
|
|
ds_dmat[1][3] = packed_varying_2.x;
|
|
ds_dmat[2][0] = packed_varying_2.y;
|
|
gl_FragColor = fn_0_1_15_pixel();
|
|
}
|
|
"#;
|
|
|
|
const METAL_OUTPUT: &'static str = r#"
|
|
#include <metal_stdlib>
|
|
using namespace metal;
|
|
struct struct_0_1_4 {
|
|
float f_c;
|
|
};
|
|
struct struct_0_1_5 {
|
|
float f_a;
|
|
struct_0_1_4;
|
|
};
|
|
struct LiveUniforms {
|
|
float live_0_1_3;
|
|
};
|
|
struct Uniforms_user {
|
|
float ds_uni1;
|
|
float ds_duni;
|
|
};
|
|
struct Textures {
|
|
};
|
|
struct Geometries {
|
|
};
|
|
struct Instances {
|
|
float ds_dinst;
|
|
packed_float3 ds_dmat 0;
|
|
packed_float3 ds_dmat 1;
|
|
packed_float3 ds_dmat 2;
|
|
};
|
|
struct Varyings {
|
|
float4 position [[position]];
|
|
float ds_dinst;
|
|
float3 ds_dmat0;
|
|
float3 ds_dmat1;
|
|
float3 ds_dmat2;
|
|
};
|
|
constant float const_0_1_2 = 1.0;
|
|
float closure_0_in_fn_0_2_5(float var_x_0) {
|
|
return (var_x_0 + 1.0);
|
|
}
|
|
float site_0_of_fn_0_2_5_struct_1_closure(thread & struct_0_1_5) {
|
|
return closure_0_in_fn_0_2_5(var_self_0.f_a);
|
|
}
|
|
void fn_0_2_1_struct_2_set(thread & struct_0_1_4, float var_x_0) {
|
|
(var_self_0.f_c = var_x_0);
|
|
}
|
|
void fn_0_2_5_struct_1_set(thread & struct_0_1_5) {
|
|
(var_self_0.f_a = 2.0);
|
|
fn_0_2_1_struct_2_set (var_self_0.f_b, site_0_of_fn_0_2_5_struct_1_closure (var_self_0));
|
|
}
|
|
float4 fn_0_1_15_pixel(thread Varyings & varyings) {
|
|
struct_0_1_5 = struct_0_1_5(1.0, struct_0_1_4((1.0 + varyings.ds_dinst)));
|
|
float3 var_x_1 = (float3(float3(1.0)) * float3x3(varyings.ds_dmat0.x, varyings.ds_dmat1.x, varyings.ds_dmat2.x, varyings.ds_dmat0.y, varyings.ds_dmat1.y, varyings.ds_dmat2.y, varyings.ds_dmat0.z, varyings.ds_dmat1.z, varyings.ds_dmat2.z));
|
|
fn_0_2_5_struct_1_set (var_x_1);
|
|
return float4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
void fn_0_1_16_override() {
|
|
(1 + 1);
|
|
}
|
|
float4 fn_0_1_17_vertex(thread Varyings & varyings, constant Uniforms_user & uniforms_user, constant LiveUniforms & live_uniforms) {
|
|
struct_0_1_4 = struct_0_1_4(((uniforms_user.ds_uni1 + const_0_1_2) + live_uniforms.live_0_1_3));
|
|
fn_0_2_1_struct_2_set (var_x_0, 3.0);
|
|
float3 var_x_1 = (float3(float3(1.0)) * float3x3(varyings.ds_dmat0.x, varyings.ds_dmat1.x, varyings.ds_dmat2.x, varyings.ds_dmat0.y, varyings.ds_dmat1.y, varyings.ds_dmat2.y, varyings.ds_dmat0.z, varyings.ds_dmat1.z, varyings.ds_dmat2.z));
|
|
fn_0_1_16_override ();
|
|
return float4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
vertex Varyings vertex_main(Textures textures, const device Geometries * in_geometries [[buffer(0)]], const device Instances * in_instances [[buffer(1)]], constant LiveUniforms & live_uniforms [[buffer(2)]], constant const float * const_table [[buffer(3)]], constant Uniforms_user & uniforms_user [[buffer(4)]], uint vtx_id [[vertex_id]], uint inst_id [[instance_id]]) {
|
|
Geometries geometries = in_geometries[vtx_id];
|
|
Instances instances = in_instances[inst_id];
|
|
Varyings varyings;
|
|
varyings.ds_dinst = instances.ds_dinst;
|
|
varyings.ds_dmat0 = instances.ds_dmat0;
|
|
varyings.ds_dmat1 = instances.ds_dmat1;
|
|
varyings.ds_dmat2 = instances.ds_dmat2;
|
|
varyings.position = fn_0_1_17_vertex(varyings, uniforms_user, live_uniforms);
|
|
return varyings;
|
|
}
|
|
fragment float4 fragment_main(Varyings varyings[[stage_in]], Textures textures, constant LiveUniforms & live_uniforms [[buffer(2)]], constant const float * const_table [[buffer(3)]], constant Uniforms_user & uniforms_user [[buffer(4)]]) {
|
|
return fn_0_1_15_pixel(varyings);
|
|
}
|
|
|
|
"#;
|
|
|
|
const HLSL_OUTPUT: &'static str = r#"
|
|
|
|
struct struct_0_1_4 {
|
|
float f_c;
|
|
};
|
|
struct struct_0_1_5 {
|
|
float f_a;
|
|
struct_0_1_4 f_b;
|
|
};
|
|
cbuffer LiveUniforms: register(b0) {
|
|
float live_0_1_3;
|
|
};
|
|
cbuffer ConstTable: register(b1) {float4 const_table[0];};
|
|
cbuffer Uniforms_user: register(b2) {
|
|
float ds_uni1;
|
|
float ds_duni;
|
|
};
|
|
struct Geometries {
|
|
};
|
|
struct Instances {
|
|
float ds_dinst: INSTA;
|
|
float3 ds_dmat0: INSTB;
|
|
float3 ds_dmat1: INSTC;
|
|
float3 ds_dmat2: INSTD;
|
|
};
|
|
struct Varyings {
|
|
float4 position: SV_POSITION;
|
|
float ds_dinst: VARYA;
|
|
float3 ds_dmat0: VARYB;
|
|
float3 ds_dmat1: VARYC;
|
|
float3 ds_dmat2: VARYD;
|
|
};
|
|
static const float const_0_1_2 = 1.0;
|
|
float3 consfn_vec3_float(float x) {
|
|
return float3(x, x, x);
|
|
}
|
|
float closure_0_in_fn_0_2_5(float var_x_0) {
|
|
return (var_x_0 + 1.0);
|
|
}
|
|
float site_0_of_fn_0_2_5_struct_1_closure(inout struct_0_1_5 var_self_0) {
|
|
return closure_0_in_fn_0_2_5(var_self_0.f_a);
|
|
}
|
|
void fn_0_2_1_struct_2_set(inout struct_0_1_4 var_self_0, float var_x_0) {
|
|
(var_self_0.f_c = var_x_0);
|
|
}
|
|
void fn_0_2_5_struct_1_set(inout struct_0_1_5 var_self_0) {
|
|
(var_self_0.f_a = 2.0);
|
|
fn_0_2_1_struct_2_set (var_self_0.f_b, site_0_of_fn_0_2_5_struct_1_closure (var_self_0));
|
|
}
|
|
float4 fn_0_1_15_pixel(inout Varyings varyings) {
|
|
struct_0_1_5 var_x_0 = struct_0_1_5 {1.0, struct_0_1_4 {(1.0 + varyings.ds_dinst)}};
|
|
float3 var_x_1 = mul(consfn_vec3_float(1.0), float3x3(varyings.ds_dmat0.x, varyings.ds_dmat1.x, varyings.ds_dmat2.x, varyings.ds_dmat0.y, varyings.ds_dmat1.y, varyings.ds_dmat2.y, varyings.ds_dmat0.z, varyings.ds_dmat1.z, varyings.ds_dmat2.z));
|
|
fn_0_2_5_struct_1_set (var_x_1);
|
|
return float4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
void fn_0_1_16_override() {
|
|
(1 + 1);
|
|
}
|
|
float4 fn_0_1_17_vertex(inout Varyings varyings,,) {
|
|
struct_0_1_4 var_x_0 = struct_0_1_4 {((ds_uni1 + const_0_1_2) + live_0_1_3)};
|
|
fn_0_2_1_struct_2_set (var_x_0, 3.0);
|
|
float3 var_x_1 = mul(consfn_vec3_float(1.0), float3x3(varyings.ds_dmat0.x, varyings.ds_dmat1.x, varyings.ds_dmat2.x, varyings.ds_dmat0.y, varyings.ds_dmat1.y, varyings.ds_dmat2.y, varyings.ds_dmat0.z, varyings.ds_dmat1.z, varyings.ds_dmat2.z));
|
|
fn_0_1_16_override ();
|
|
return float4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
Varyings vertex_main(Geometries geometries, Instances instances, uint inst_id: SV_InstanceID) {
|
|
Varyings varyings = {float4(0.0, 0.0, 0.0, 0.0), 0.0, float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)};
|
|
varyings.ds_dinst = instances.ds_dinst;
|
|
varyings.ds_dmat0 = instances.ds_dmat0;
|
|
varyings.ds_dmat1 = instances.ds_dmat1;
|
|
varyings.ds_dmat2 = instances.ds_dmat2;
|
|
varyings.position = fn_0_1_17_vertex(varyings,,);
|
|
return varyings;
|
|
}
|
|
float4 pixel_main(Varyings varyings): SV_TARGET {
|
|
return fn_0_1_15_pixel(varyings);
|
|
}
|
|
|
|
|
|
"#;
|
|
|
|
use makepad_live_compiler::*;
|
|
use makepad_shader_compiler::shader_registry::ShaderRegistry;
|
|
use makepad_shader_compiler::shader_ast::DrawShaderPtr;
|
|
use makepad_shader_compiler::shader_ast::DrawShaderConstTable;
|
|
use makepad_shader_compiler::shader_ast::Ty;
|
|
use makepad_shader_compiler::generate_glsl;
|
|
use makepad_shader_compiler::generate_hlsl;
|
|
use makepad_shader_compiler::generate_metal;
|
|
// lets just test most features in one go.
|
|
|
|
fn compare_no_ws(a: &str, b: &str) -> Option<String> {
|
|
let mut b = b.to_string();
|
|
b.retain( | c | !c.is_whitespace());
|
|
let mut a = a.to_string();
|
|
a.retain( | c | !c.is_whitespace());
|
|
|
|
let b = b.as_bytes();
|
|
let a = a.as_bytes();
|
|
|
|
let mut start = 0;
|
|
let mut changed = false;
|
|
let len = b.len().min(a.len());
|
|
for i in 0..len {
|
|
if a[i] != b[i] {
|
|
changed = true;
|
|
break
|
|
}
|
|
start = i;
|
|
}
|
|
// now go from the back to i
|
|
let mut end = 0;
|
|
for i in 2..len {
|
|
end = i - 2;
|
|
if a[a.len() - i] != b[b.len() - i] {
|
|
changed = true;
|
|
break
|
|
}
|
|
}
|
|
// okaay so we have to show the changed thing
|
|
if changed {
|
|
let range_a = if start < (a.len() - end - 1) {std::str::from_utf8(&a[start..(a.len() - end - 1)]).unwrap()} else {""};
|
|
let range_b = if start < (b.len() - end - 1) {std::str::from_utf8(&b[start..(b.len() - end - 1)]).unwrap()} else {""};
|
|
Some(format!(
|
|
"########## OLD ########## {} to {}\n{}\n########## NEW ########## {} to {}\n{}\n########## END ##########",
|
|
start,
|
|
(a.len() - end - 1),
|
|
range_a,
|
|
start,
|
|
(b.len() - end - 1),
|
|
range_b
|
|
))
|
|
}
|
|
else {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn main() {
|
|
let mut sr = ShaderRegistry::new();
|
|
|
|
struct FakeType();
|
|
|
|
let fake_typeof = LiveType(std::any::TypeId::of::<FakeType>());
|
|
let module_path = ModulePath::from_str("test").unwrap();
|
|
match sr.live_registry.parse_live_file("test.live", module_path, SOURCE.to_string(), vec![fake_typeof]) {
|
|
Err(why) => panic!("Couldnt parse file {}", why),
|
|
_ => ()
|
|
}
|
|
|
|
let mut errors = Vec::new();
|
|
sr.live_registry.expand_all_documents(&mut errors);
|
|
|
|
for msg in errors {
|
|
println!("{}\n", msg.to_live_file_error("", SOURCE));
|
|
}
|
|
|
|
let shader_ptr = DrawShaderPtr(sr.live_registry.live_ptr_from_path(
|
|
module_path,
|
|
&[live_id!(DrawQuad2)]
|
|
).unwrap());
|
|
// lets just call the shader compiler on this thing
|
|
|
|
let result = sr.analyse_draw_shader(shader_ptr, | span, id, _live_type, draw_shader_def | {
|
|
if id == live_id!(rust_type) {
|
|
draw_shader_def.add_uniform(Id::from_str("duni").unwrap(), Ty::Float, span);
|
|
draw_shader_def.add_instance(Id::from_str("dinst").unwrap(), Ty::Float, span);
|
|
draw_shader_def.add_instance(Id::from_str("dmat").unwrap(), Ty::Mat3, span);
|
|
}
|
|
if id == live_id!(geometry) {
|
|
|
|
}
|
|
});
|
|
|
|
match result {
|
|
Err(e) => {
|
|
println!("Error {}", e.to_live_file_error("", SOURCE));
|
|
}
|
|
Ok(_) => {
|
|
println!("OK!");
|
|
}
|
|
}
|
|
|
|
/*
|
|
pub fn generate_glsl_shader(&mut self, shader_ptr: DrawShaderNodePtr) -> (String, String) {
|
|
// lets find the FullPointer
|
|
let draw_shader_decl = self.draw_shaders.get(&shader_ptr).unwrap();
|
|
// TODO this env needs its const table transferred
|
|
let vertex = generate_glsl::generate_vertex_shader(draw_shader_decl, self);
|
|
let pixel = generate_glsl::generate_pixel_shader(draw_shader_decl, self);
|
|
return (vertex, pixel)
|
|
}
|
|
|
|
pub fn generate_metal_shader(&mut self, shader_ptr: DrawShaderNodePtr) -> String{
|
|
// lets find the FullPointer
|
|
let draw_shader_decl = self.draw_shaders.get(&shader_ptr).unwrap();
|
|
let shader = generate_metal::generate_shader(draw_shader_decl, self);
|
|
return shader
|
|
}
|
|
|
|
pub fn generate_hlsl_shader(&mut self, shader_ptr: DrawShaderNodePtr) -> String{
|
|
// lets find the FullPointer
|
|
let draw_shader_decl = self.draw_shaders.get(&shader_ptr).unwrap();
|
|
let shader = generate_hlsl::generate_shader(draw_shader_decl, self);
|
|
return shader
|
|
}*/
|
|
|
|
// ok the shader is analysed.
|
|
// now we will generate the glsl shader.
|
|
let draw_shader_def = sr.draw_shader_defs.get(&shader_ptr).unwrap();
|
|
// TODO this env needs its const table transferred
|
|
let const_table = DrawShaderConstTable::default();
|
|
let vertex = generate_glsl::generate_vertex_shader(draw_shader_def, &const_table, &sr);
|
|
let pixel = generate_glsl::generate_pixel_shader(draw_shader_def, &const_table, &sr);
|
|
let compare = format!("\nVERTEXSHADER\n{}PIXELSHADER\n{}", vertex, pixel);
|
|
if let Some(change) = compare_no_ws(GLSL_OUTPUT, &compare) {
|
|
println!("GLSL OUTPUT CHANGED\n{}", change);
|
|
println!("########## ALL ##########\n{}\n########## END ##########", compare);
|
|
assert_eq!(true, false);
|
|
}
|
|
|
|
let shader = generate_metal::generate_shader(draw_shader_def, &const_table, &sr);
|
|
let compare = format!("\n{}", shader.mtlsl);
|
|
if let Some(change) = compare_no_ws(METAL_OUTPUT, &compare) {
|
|
println!("METAL OUTPUT CHANGED\n{}", change);
|
|
println!("########## ALL ##########\n{}\n########## END ##########", compare);
|
|
assert_eq!(true, false);
|
|
}
|
|
|
|
let shader = generate_hlsl::generate_shader(draw_shader_def, &const_table, &sr);
|
|
let compare = format!("\n{}", shader);
|
|
if let Some(change) = compare_no_ws(HLSL_OUTPUT, &compare) {
|
|
println!("HLSL OUTPUT CHANGED\n{}", change);
|
|
println!("########## ALL ##########\n{}\n########## END ##########", compare);
|
|
assert_eq!(true, false);
|
|
}
|
|
|
|
}*/
|
|
|
|
#[test]
|
|
fn main() {}
|