From c05921fd710fe69be7018dbf2e019594696f4738 Mon Sep 17 00:00:00 2001 From: Nova Date: Mon, 26 Jun 2023 19:49:10 -0400 Subject: [PATCH] feat: shaders!! working!! --- src/nodes/drawable/shaders.rs | 120 ++++++++++++++++++---- src/wayland/shaders/simula.frag | 152 +--------------------------- src/wayland/shaders/simula.vert | 64 +++++++++++- src/wayland/shaders/simula_old.frag | 75 ++++++++++++++ 4 files changed, 241 insertions(+), 170 deletions(-) create mode 100644 src/wayland/shaders/simula_old.frag diff --git a/src/nodes/drawable/shaders.rs b/src/nodes/drawable/shaders.rs index e8fd6d6..ed0ed94 100644 --- a/src/nodes/drawable/shaders.rs +++ b/src/nodes/drawable/shaders.rs @@ -1,7 +1,12 @@ -use std::{ffi::CString, mem::transmute}; +#![allow(dead_code)] -use smithay::backend::renderer::gles::ffi::{Gles2, FRAGMENT_SHADER, VERTEX_SHADER}; +use smithay::backend::renderer::gles::{ + ffi::{self, Gles2, FRAGMENT_SHADER, VERTEX_SHADER}, + GlesError, +}; +use std::mem::transmute; use stereokit::Shader; +use tracing::error; struct FfiAssetHeader { asset_type: i32, @@ -25,26 +30,103 @@ struct FfiShader { shader: FfiSkgShader, } -unsafe fn load_shader(c: &Gles2, source: &str, stage: u32) -> u32 { - let shader = c.CreateShader(stage); - let shader_source = CString::new(source).unwrap(); - c.ShaderSource(shader, 1, &shader_source.as_ptr(), std::ptr::null()); - c.CompileShader(shader); - shader +unsafe fn compile_shader( + gl: &ffi::Gles2, + variant: ffi::types::GLuint, + src: &str, +) -> Result { + let shader = gl.CreateShader(variant); + if shader == 0 { + return Err(GlesError::CreateShaderObject); + } + + gl.ShaderSource( + shader, + 1, + &src.as_ptr() as *const *const u8 as *const *const ffi::types::GLchar, + &(src.len() as i32) as *const _, + ); + gl.CompileShader(shader); + + let mut status = ffi::FALSE as i32; + gl.GetShaderiv(shader, ffi::COMPILE_STATUS, &mut status as *mut _); + if status == ffi::FALSE as i32 { + let mut max_len = 0; + gl.GetShaderiv(shader, ffi::INFO_LOG_LENGTH, &mut max_len as *mut _); + + let mut error = Vec::with_capacity(max_len as usize); + let mut len = 0; + gl.GetShaderInfoLog( + shader, + max_len as _, + &mut len as *mut _, + error.as_mut_ptr() as *mut _, + ); + error.set_len(len as usize); + + error!( + "[GL] {}", + std::str::from_utf8(&error).unwrap_or("") + ); + + gl.DeleteShader(shader); + return Err(GlesError::ShaderCompileError); + } + + Ok(shader) } -unsafe fn link_program(c: &Gles2, vert: u32, frag: u32) -> u32 { - let program = c.CreateProgram(); - c.AttachShader(program, vert); - c.AttachShader(program, frag); - c.LinkProgram(program); - program +unsafe fn link_program( + gl: &ffi::Gles2, + vert: ffi::types::GLuint, + frag: ffi::types::GLuint, +) -> Result { + let program = gl.CreateProgram(); + gl.AttachShader(program, vert); + gl.AttachShader(program, frag); + gl.LinkProgram(program); + // gl.DetachShader(program, vert); + // gl.DetachShader(program, frag); + // gl.DeleteShader(vert); + // gl.DeleteShader(frag); + + let mut status = ffi::FALSE as i32; + gl.GetProgramiv(program, ffi::LINK_STATUS, &mut status as *mut _); + if status == ffi::FALSE as i32 { + let mut max_len = 0; + gl.GetProgramiv(program, ffi::INFO_LOG_LENGTH, &mut max_len as *mut _); + + let mut error = Vec::with_capacity(max_len as usize); + let mut len = 0; + gl.GetProgramInfoLog( + program, + max_len as _, + &mut len as *mut _, + error.as_mut_ptr() as *mut _, + ); + error.set_len(len as usize); + + error!( + "[GL] {}", + std::str::from_utf8(&error).unwrap_or("") + ); + + gl.DeleteProgram(program); + return Err(GlesError::ProgramLinkError); + } + + Ok(program) } -pub unsafe fn shader_inject(c: &Gles2, sk_shader: &mut Shader, vert_str: &str, frag_str: &str) { - let gl_vert = dbg!(load_shader(c, vert_str, VERTEX_SHADER)); - let gl_frag = dbg!(load_shader(c, frag_str, FRAGMENT_SHADER)); - let gl_prog = dbg!(link_program(c, gl_vert, gl_frag)); +pub unsafe fn shader_inject( + c: &Gles2, + sk_shader: &mut Shader, + vert_str: &str, + frag_str: &str, +) -> Result<(), GlesError> { + let gl_vert = compile_shader(c, VERTEX_SHADER, vert_str)?; + let gl_frag = compile_shader(c, FRAGMENT_SHADER, frag_str)?; + let gl_prog = link_program(c, gl_vert, gl_frag)?; let shader: *mut FfiShader = transmute(sk_shader.0.as_mut()); if let Some(shader) = shader.as_mut() { @@ -52,4 +134,6 @@ pub unsafe fn shader_inject(c: &Gles2, sk_shader: &mut Shader, vert_str: &str, f shader.shader.pixel = gl_frag; shader.shader.program = gl_prog; } + + Ok(()) } diff --git a/src/wayland/shaders/simula.frag b/src/wayland/shaders/simula.frag index d1e0300..0752cbb 100644 --- a/src/wayland/shaders/simula.frag +++ b/src/wayland/shaders/simula.frag @@ -1,158 +1,16 @@ -// #version 320 es -// #extension GL_OES_EGL_image_external : require - -// precision highp float; - -// in vec2 vUV; -// uniform samplerExternalOES diffuse; -// uniform vec4 diffuse_i; -// uniform vec2 uv_scale; -// uniform vec2 uv_offset; -// uniform float fcFactor; -// uniform float ripple; -// uniform float alpha_min; -// uniform float alpha_max; - -// float map(float value, float min1, float max1, float min2, float max2) { -// return min2 + (value - min1) * (max2 - min2) / (max1 - min1); -// } - -// // float gaussian(float x, float t) { -// // float PI = 3.14159265358; -// // return exp(-x*x/(2.0 * t*t))/(sqrt(2.0*PI)*t); -// // } - -// float besselI0(float x) { -// return 1.0 + pow(x, 2.0) * (0.25 + pow(x, 2.0) * (0.015625 + pow(x, 2.0) * (0.000434028 + pow(x, 2.0) * (6.78168e-6 + pow(x, 2.0) * (6.78168e-8 + pow(x, 2.0) * (4.7095e-10 + pow(x, 2.0) * (2.40281e-12 + pow(x, 2.0) * (9.38597e-15 + pow(x, 2.0) * (2.8969e-17 + 7.24226e-20 * pow(x, 2.0)))))))))); -// } - -// float kaiser(float x, float alpha) { -// if (x > 1.0) { -// return 0.0; -// } -// return besselI0(alpha * sqrt(1.0-x*x)); -// } - -// vec4 lowpassFilter(samplerExternalOES tex, samplerExternalOES texSampler, vec2 uv, float alpha) { -// float PI = 3.14159265358; - -// vec4 q = vec4(0.0); - -// vec2 dx_uv = dFdx(uv); -// vec2 dy_uv = dFdy(uv); -// //float width = sqrt(max(dot(dx_uv, dx_uv), dot(dy_uv, dy_uv))); -// vec2 width = abs(vec2(dx_uv.x, dy_uv.y)); - -// vec2 pixelWidth = floor(width * diffuse_i.xy); -// vec2 aspectRatio = normalize(pixelWidth); - -// vec2 xyf = uv * diffuse_i.xy; -// ivec2 xy = ivec2(xyf); - -// pixelWidth = clamp(pixelWidth, vec2(1.0), vec2(2.0)); - -// ivec2 start = xy - ivec2(pixelWidth); -// ivec2 end = xy + ivec2(pixelWidth); - -// vec4 outColor = vec4(0.0); - -// float qSum = 0.0; - -// for (int v = start.y; v <= end.y; v++) { -// for (int u = start.x; u <= end.x; u++) { -// float kx = fcFactor * (xyf.x - float(u))/pixelWidth.x; -// float ky = fcFactor * (xyf.y - float(v))/pixelWidth.y; - -// //float lanczosValue = gaussian(kx, fcx); -// float lanczosValue = kaiser(sqrt(kx*kx + ky*ky), alpha); - -// q += texture2D(tex, (vec2(u, v)+vec2(0.5))/diffuse_i.xy) * lanczosValue; -// // q += tex.Load(int3(u, v, 0)) * lanczosValue; -// qSum += lanczosValue; -// } -// } - -// return q/qSum; -// } - -void main() { - //gl_FragColor = texture2D(diffuse, vec2(1.0 - vUV.x, vUV.y)); //to turn off - gl_FragColor = lowpassFilter(diffuse, vec2(1.0 - vUV.x, vUV.y), ripple); - gl_FragColor.a = map(col.a, 0, 1, alpha_min, alpha_max); -} - #version 320 es -#extension GL_OES_EGL_image_external : require precision mediump float; precision highp int; -layout(binding = 0, std140) uniform _Global -{ - highp vec4 diffuse_i; - highp vec2 uv_scale; - highp vec2 uv_offset; - highp float fcFactor; - highp float ripple; - highp float alpha_min; - highp float alpha_max; -} uniforms; - -layout(binding = 0) uniform highp samplerExternalOES diffuse; +layout(binding = 0) uniform highp sampler2D diffuse; layout(location = 0) in highp vec2 fs_uv; -layout(location = 0) out highp vec4 gl_FragColor; +layout(location = 0) out highp vec4 _entryPointOutput; void main() { - highp vec2 dx_uv = dFdx(fs_uv); - highp vec2 dy_uv = dFdy(fs_uv); - highp vec2 width = fs_uv * uniforms.diffuse_i.xy; - ivec2 _475 = ivec2(width); - highp vec2 _477 = clamp(floor(abs(vec2(dx_uv.x, dy_uv.y)) * uniforms.diffuse_i.xy), vec2(1.0), vec2(2.0)); - ivec2 _480 = ivec2(_477); - ivec2 _481 = _475 - _480; - ivec2 _485 = _475 + _480; - int _487 = _481.y; - highp vec4 _671; - highp float _672; - _672 = 0.0; - _671 = vec4(0.0); - highp vec4 _679; - highp float _681; - for (int _670 = _487; _670 <= _485.y; _672 = _681, _671 = _679, _670++) - { - int _496 = _481.x; - _681 = _672; - _679 = _671; - highp vec4 _553; - highp float _556; - for (int _673 = _496; _673 <= _485.x; _681 = _556, _679 = _553, _673++) - { - highp float _509 = float(_673); - highp float _514 = (uniforms.fcFactor * (width.x - _509)) / _477.x; - highp float _520 = float(_670); - highp float _525 = (uniforms.fcFactor * (width.y - _520)) / _477.y; - highp float _533 = sqrt((_514 * _514) + (_525 * _525)); - highp float _675; - do - { - if (_533 > 1.0) - { - _675 = 0.0; - break; - } - highp float _592 = pow(uniforms.ripple * sqrt(1.0 - (_533 * _533)), 2.0); - _675 = 1.0 + (_592 * (0.25 + (_592 * (0.015625 + (_592 * (0.00043402801384218037128448486328125 + (_592 * (6.7816799855791032314300537109375e-06 + (_592 * (6.7816799287356843706220388412476e-08 + (_592 * (4.709500012189948847662890329957e-10 + (_592 * (2.4028099388645474121517509047408e-12 + (_592 * (9.3859703944590075486154034933861e-15 + (_592 * (2.8968999943407451927966655969016e-17 + (7.242260299760125752555485045131e-20 * _592))))))))))))))))))); - break; - } while(false); - _553 = _679 + (texture(diffuse, (vec2(_509, _520) + vec2(0.5)) / uniforms.diffuse_i.xy) * _675); - _556 = _681 + _675; - } - } - highp vec4 _568 = _671 / vec4(_672); - highp vec3 _417 = pow(_568.xyz, vec3(2.2000000476837158203125)); - highp vec4 _669 = vec4(_417.x, _417.y, _417.z, _568.w); - _669.w = uniforms.alpha_min + (_568.w * (uniforms.alpha_max - uniforms.alpha_min)); - gl_FragColor = _669; + highp vec4 _101 = texture(diffuse, fs_uv); + highp vec3 _104 = pow(_101.xyz, vec3(2.2000000476837158203125)); + _entryPointOutput = vec4(_104.x, _104.y, _104.z, _101.w); } diff --git a/src/wayland/shaders/simula.vert b/src/wayland/shaders/simula.vert index f6f0bdd..ac8602c 100644 --- a/src/wayland/shaders/simula.vert +++ b/src/wayland/shaders/simula.vert @@ -1,7 +1,61 @@ #version 320 es -in vec2 UV; -out vec2 vUV; +// #ifdef GL_AMD_vertex_shader_layer +// #extension GL_AMD_vertex_shader_layer : enable +// #elif defined(GL_NV_viewport_array2) +// #extension GL_NV_viewport_array2 : enable +// #else +// #define gl_Layer int _dummy_gl_layer_var +// #endif + +struct Inst +{ + mat4 world; + vec4 color; +}; + +layout(binding = 1, std140) uniform StereoKitBuffer +{ + layout(row_major) mat4 sk_view[2]; + layout(row_major) mat4 sk_proj[2]; + layout(row_major) mat4 sk_proj_inv[2]; + layout(row_major) mat4 sk_viewproj[2]; + vec4 sk_lighting_sh[9]; + vec4 sk_camera_pos[2]; + vec4 sk_camera_dir[2]; + vec4 sk_fingertip[2]; + vec4 sk_cubemap_i; + float sk_time; + uint sk_view_count; +} _38; + +layout(binding = 2, std140) uniform TransformBuffer +{ + layout(row_major) Inst sk_inst[819]; +} _56; + +layout(binding = 0, std140) uniform _Global +{ + vec4 diffuse_i; + vec2 uv_scale; + vec2 uv_offset; + float fcFactor; + float ripple; + float alpha_min; + float alpha_max; +} _91; + +layout(location = 0) in vec4 input_pos; +layout(location = 1) in vec3 input_norm; +layout(location = 2) in vec2 input_uv; +layout(location = 0) out vec2 fs_uv; + +mat4 spvWorkaroundRowMajor(mat4 wrap) { return wrap; } + +void main() +{ + uint _155 = uint(gl_InstanceID) % _38.sk_view_count; + gl_Position = spvWorkaroundRowMajor(_38.sk_viewproj[_155]) * vec4((spvWorkaroundRowMajor(_56.sk_inst[uint(gl_InstanceID) / _38.sk_view_count].world) * vec4(input_pos.xyz, 1.0)).xyz, 1.0); + fs_uv = (input_uv + _91.uv_offset) * _91.uv_scale; + // gl_Layer = int(_155); +} -void main() { - vUV = UV; -} \ No newline at end of file diff --git a/src/wayland/shaders/simula_old.frag b/src/wayland/shaders/simula_old.frag new file mode 100644 index 0000000..c0b310f --- /dev/null +++ b/src/wayland/shaders/simula_old.frag @@ -0,0 +1,75 @@ +#version 320 es +#extension GL_OES_EGL_image_external : require +precision mediump float; +precision highp int; + +layout(binding = 0, std140) uniform _Global +{ + highp vec4 diffuse_i; + highp vec2 uv_scale; + highp vec2 uv_offset; + highp float fcFactor; + highp float ripple; + highp float alpha_min; + highp float alpha_max; +} uniforms; + +layout(binding = 0) uniform highp samplerExternalOES diffuse; + +layout(location = 0) in highp vec2 fs_uv; +layout(location = 0) out highp vec4 fragColor; + +void main() +{ + highp vec2 dx_uv = dFdx(fs_uv); + highp vec2 dy_uv = dFdy(fs_uv); + highp vec2 width = fs_uv * uniforms.diffuse_i.xy; + ivec2 _475 = ivec2(width); + highp vec2 _477 = clamp(floor(abs(vec2(dx_uv.x, dy_uv.y)) * uniforms.diffuse_i.xy), vec2(1.0), vec2(2.0)); + ivec2 _480 = ivec2(_477); + ivec2 _481 = _475 - _480; + ivec2 _485 = _475 + _480; + int _487 = _481.y; + highp vec4 _671; + highp float _672; + _672 = 0.0; + _671 = vec4(0.0); + highp vec4 _679; + highp float _681; + for (int _670 = _487; _670 <= _485.y; _672 = _681, _671 = _679, _670++) + { + int _496 = _481.x; + _681 = _672; + _679 = _671; + highp vec4 _553; + highp float _556; + for (int _673 = _496; _673 <= _485.x; _681 = _556, _679 = _553, _673++) + { + highp float _509 = float(_673); + highp float _514 = (uniforms.fcFactor * (width.x - _509)) / _477.x; + highp float _520 = float(_670); + highp float _525 = (uniforms.fcFactor * (width.y - _520)) / _477.y; + highp float _533 = sqrt((_514 * _514) + (_525 * _525)); + highp float _675; + do + { + if (_533 > 1.0) + { + _675 = 0.0; + break; + } + highp float _592 = pow(uniforms.ripple * sqrt(1.0 - (_533 * _533)), 2.0); + _675 = 1.0 + (_592 * (0.25 + (_592 * (0.015625 + (_592 * (0.00043402801384218037128448486328125 + (_592 * (6.7816799855791032314300537109375e-06 + (_592 * (6.7816799287356843706220388412476e-08 + (_592 * (4.709500012189948847662890329957e-10 + (_592 * (2.4028099388645474121517509047408e-12 + (_592 * (9.3859703944590075486154034933861e-15 + (_592 * (2.8968999943407451927966655969016e-17 + (7.242260299760125752555485045131e-20 * _592))))))))))))))))))); + break; + } while(false); + _553 = _679 + (texture2D(diffuse, (vec2(_509, _520) + vec2(0.5)) / uniforms.diffuse_i.xy) * _675); + _556 = _681 + _675; + } + } + highp vec4 _568 = _671 / vec4(_672); + highp vec3 _417 = pow(_568.xyz, vec3(2.2000000476837158203125)); + highp vec4 _669 = vec4(_417.x, _417.y, _417.z, _568.w); + _669.w = uniforms.alpha_min + (_568.w * (uniforms.alpha_max - uniforms.alpha_min)); + fragColor = _669; +} +