Constant WGSL
Source pub const WGSL: &str = r#"
struct Upscale {
content: vec4f,
source: vec2f,
mode: u32,
transfer: u32,
bars: vec4f,
backdrop: u32,
pad0: u32,
pad1: u32,
pad2: u32,
}
@group(0) @binding(0) var upscale_source: texture_2d<f32>;
@group(0) @binding(1) var<uniform> upscale: Upscale;
@vertex
fn upscale_vertex(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f {
let xy = array<vec2f, 3>(vec2f(-1.0, -1.0), vec2f(3.0, -1.0), vec2f(-1.0, 3.0));
return vec4f(xy[index], 0.0, 1.0);
}
fn upscale_texel(p: vec2i) -> vec4f {
let last = vec2i(upscale.source) - vec2i(1);
return textureLoad(upscale_source, clamp(p, vec2i(0), last), 0);
}
fn upscale_weights(t: f32) -> vec4f {
let t2 = t * t;
let t3 = t2 * t;
return vec4f(
0.5 * (-t3 + 2.0 * t2 - t),
0.5 * (3.0 * t3 - 5.0 * t2 + 2.0),
0.5 * (-3.0 * t3 + 4.0 * t2 + t),
0.5 * (t3 - t2),
);
}
fn upscale_decode(c: vec3f) -> vec3f {
return select(pow((c + vec3f(0.055)) / 1.055, vec3f(2.4)), c / 12.92, c <= vec3f(0.04045));
}
fn upscale_encode(c: vec3f) -> vec3f {
let v = max(c, vec3f(0.0));
return select(1.055 * pow(v, vec3f(1.0 / 2.4)) - vec3f(0.055), v * 12.92, v <= vec3f(0.0031308));
}
fn upscale_transfer(c: vec4f) -> vec4f {
if (upscale.transfer == 1u) {
return vec4f(upscale_decode(c.rgb), c.a);
}
if (upscale.transfer == 2u) {
return vec4f(upscale_encode(c.rgb), c.a);
}
return c;
}
@fragment
fn upscale_fragment(@builtin(position) position: vec4f) -> @location(0) vec4f {
let c = upscale.content;
let p = position.xy;
if (p.x < c.x || p.y < c.y || p.x >= c.x + c.z || p.y >= c.y + c.w) {
if (upscale.backdrop == 1u) {
discard;
}
return upscale.bars;
}
return upscale_transfer(upscale_filtered(p));
}
fn upscale_filtered(p: vec2f) -> vec4f {
let c = upscale.content;
let uv = (p - c.xy) / c.zw * upscale.source - vec2f(0.5);
if (upscale.mode == 1u) {
return upscale_texel(vec2i(floor(uv + vec2f(0.5))));
}
let base = floor(uv);
let f = uv - base;
let wx = upscale_weights(f.x);
let wy = upscale_weights(f.y);
let b = vec2i(base);
var sum = vec4f(0.0);
for (var j = 0; j < 4; j++) {
var row = vec4f(0.0);
for (var i = 0; i < 4; i++) {
row += upscale_texel(b + vec2i(i - 1, j - 1)) * wx[i];
}
sum += row * wy[j];
}
let t00 = upscale_texel(b);
let t10 = upscale_texel(b + vec2i(1, 0));
let t01 = upscale_texel(b + vec2i(0, 1));
let t11 = upscale_texel(b + vec2i(1, 1));
let lo = min(min(t00, t10), min(t01, t11));
let hi = max(max(t00, t10), max(t01, t11));
return clamp(sum, lo, hi);
}
"#;