feat: shaders!! working!!

This commit is contained in:
Nova
2023-06-26 19:49:10 -04:00
parent 444146fa21
commit ea0f174da7
4 changed files with 241 additions and 170 deletions

View File

@@ -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<ffi::types::GLuint, GlesError> {
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("<Error Message no utf8>")
);
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<ffi::types::GLuint, GlesError> {
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("<Error Message no utf8>")
);
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(())
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}