render/wgpu: Drop `naga_oil` in favor of manual string manipulation

This commit is contained in:
TÖRÖK Attila 2024-05-14 12:50:37 +02:00 committed by Nathan Adams
parent 6c144a038f
commit f9f4c3bb82
25 changed files with 128 additions and 255 deletions

View File

@ -27,7 +27,6 @@ updates:
- "winit"
- "wgpu"
- "naga"
- "naga_oil"
- "egui*"
- "raw-window-handle"
wasm-bindgen:

38
Cargo.lock generated
View File

@ -1333,12 +1333,6 @@ dependencies = [
"dasp_sample",
]
[[package]]
name = "data-encoding"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "deranged"
version = "0.3.11"
@ -3278,7 +3272,6 @@ dependencies = [
"indexmap",
"log",
"num-traits",
"pp-rs",
"rustc-hash",
"serde",
"spirv",
@ -3304,30 +3297,9 @@ version = "0.1.0"
dependencies = [
"anyhow",
"naga",
"naga_oil",
"ruffle_render",
]
[[package]]
name = "naga_oil"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1"
dependencies = [
"bit-set",
"codespan-reporting",
"data-encoding",
"indexmap",
"naga",
"once_cell",
"regex",
"regex-syntax 0.8.3",
"rustc-hash",
"thiserror",
"tracing",
"unicode-ident",
]
[[package]]
name = "ndk"
version = "0.8.0"
@ -3847,15 +3819,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "pp-rs"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee"
dependencies = [
"unicode-xid",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
@ -4495,7 +4458,6 @@ dependencies = [
"naga",
"naga-agal",
"naga-pixelbender",
"naga_oil",
"profiling",
"ruffle_render",
"swf",

View File

@ -48,7 +48,6 @@ version = "0.1.0"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
naga = { version = "0.19.2", features = ["wgsl-out"] }
naga_oil = "0.13.0"
wgpu = "0.19.4"
egui = "0.27.2"
clap = { version = "4.5.4", features = ["derive"] }

View File

@ -13,6 +13,5 @@ workspace = true
[dependencies]
ruffle_render = { path = "../" }
naga = { workspace = true }
naga_oil = { workspace = true }
anyhow = { workspace = true }

View File

@ -8,14 +8,13 @@ use naga::{
ImageQuery, Literal, LocalVariable, MathFunction, Module, RelationalFunction, ResourceBinding,
ScalarKind, ShaderStage, Span, Statement, SwizzleComponent, Type, TypeInner, VectorSize,
};
use naga_oil::compose::{Composer, NagaModuleDescriptor};
use ruffle_render::pixel_bender::{
Opcode, Operation, PixelBenderParam, PixelBenderParamQualifier, PixelBenderReg,
PixelBenderRegChannel, PixelBenderRegKind, PixelBenderShader, PixelBenderTypeOpcode,
OUT_COORD_NAME,
};
pub const VERTEX_SHADER_ENTRYPOINT: &str = "main_vertex";
pub const VERTEX_SHADER_ENTRYPOINT: &str = "filter__vertex_entry_point";
pub const FRAGMENT_SHADER_ENTRYPOINT: &str = "main";
pub struct NagaModules {
@ -127,25 +126,8 @@ impl<'a> ShaderBuilder<'a> {
static VERTEX_SHADER: OnceLock<Module> = OnceLock::new();
let vertex_shader = VERTEX_SHADER
.get_or_init(|| {
let mut composer = Composer::default();
// [NA] Hack to get all capabilities since nobody exposes this type easily
let capabilities = composer.capabilities;
composer = composer.with_capabilities(!capabilities);
composer
.make_naga_module(NagaModuleDescriptor {
source: ruffle_render::shader_source::SHADER_FILTER_COMMON,
file_path: "shaders/filter/common.wgsl",
shader_defs: Default::default(),
..Default::default()
})
.unwrap_or_else(|e| {
panic!(
"shader_filter_common.wgsl failed to compile:\n{}\n{:#?}",
e.emit_to_string(&composer),
e
)
})
naga::front::wgsl::parse_str(ruffle_render::shader_source::SHADER_FILTER_COMMON)
.expect("Failed to parse vertex shader")
})
.clone();

View File

@ -1,11 +1,12 @@
#define_import_path filter
/// This is prepended to many shaders at runtime before compiling them.
/// The `filter__` identifier prefix serves as pseudo-namespacing.
struct VertexOutput {
struct filter__VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
struct VertexInput {
struct filter__VertexInput {
/// The position of the vertex in texture space (topleft 0,0, bottomright 1,1)
@location(0) position: vec2<f32>,
@ -13,9 +14,14 @@ struct VertexInput {
@location(1) uv: vec2<f32>,
};
@vertex
fn main_vertex(in: VertexInput) -> VertexOutput {
fn filter__main_vertex(in: filter__VertexInput) -> filter__VertexOutput {
// Convert texture space (topleft 0,0 to bottomright 1,1) to render space (topleft -1,1 to bottomright 1,-1)
let pos = vec4<f32>((in.position.x * 2.0 - 1.0), (1.0 - in.position.y * 2.0), 0.0, 1.0);
return VertexOutput(pos, in.uv);
return filter__VertexOutput(pos, in.uv);
}
// Delegating because the one above is called from other shaders, so it can't be an entry point.
@vertex
fn filter__vertex_entry_point(in: filter__VertexInput) -> filter__VertexOutput {
return filter__main_vertex(in);
}

View File

@ -20,7 +20,6 @@ enum-map = { workspace = true }
fnv = "1.0.7"
swf = { path = "../../swf" }
image = { workspace = true }
naga_oil = { workspace = true }
naga-agal = { path = "../naga-agal" }
naga-pixelbender = { path = "../naga-pixelbender" }
profiling = { version = "1.0", default-features = false, optional = true }

View File

@ -1,22 +1,21 @@
/// Shader used for drawing bitmap fills.
#import common
/// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common__TextureTransforms;
@group(2) @binding(1) var texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let matrix_ = textureTransforms.texture_matrix;
let uv = (mat3x3<f32>(matrix_[0].xyz, matrix_[1].xyz, matrix_[2].xyz) * vec3<f32>(in.position, 1.0)).xy;
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
return VertexOutput(pos, uv);
}
@ -28,13 +27,15 @@ fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
if( color.a > 0.0 ) {
color = vec4<f32>(color.rgb / color.a, color.a);
color = color * transforms.mult_color + transforms.add_color;
#if early_saturate == true
// NOTE: `#EARLY_SATURATE#` is replaced with a boolean value at compile time.
// TODO: Switch to pipeline constants once `wgpu` is updated to `0.20`.
if (#EARLY_SATURATE# == true) {
color = saturate(color);
#endif
}
color = vec4<f32>(color.rgb * color.a, color.a);
#if early_saturate == false
if (#EARLY_SATURATE# == false) {
color = saturate(color);
#endif
}
}
return color;
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,18 +1,18 @@
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var parent_texture: texture_2d<f32>;
@group(2) @binding(1) var current_texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 1.0, 1.0);
let uv = vec2<f32>((pos.x + 1.0) / 2.0, -((pos.y - 1.0) / 2.0));
return VertexOutput(pos, uv);
}

View File

@ -1,6 +1,6 @@
/// Shader used for drawing solid color fills.
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexInput {
@location(0) position: vec2<f32>,
@ -12,11 +12,11 @@ struct VertexOutput {
@location(0) color: vec4<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@vertex
fn main_vertex(in: VertexInput) -> VertexOutput {
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let color = saturate(in.color * transforms.mult_color + transforms.add_color);
return VertexOutput(pos, vec4<f32>(color.rgb * color.a, color.a));
}

View File

@ -1,16 +1,15 @@
#define_import_path common
/// Common WGSL shared among all Ruffle shaders.
/// Ruffle prepends this file onto every shader at runtime.
/// Common WGSL shared among many Ruffle shaders.
/// This is prepended to a lot of shaders at runtime before compiling them.
/// The `common__` identifier prefix serves as pseudo-namespacing.
/// Global uniforms that are constant throughout a frame.
struct Globals {
struct common__Globals {
// The view matrix determined by the viewport and stage.
view_matrix: mat4x4<f32>,
};
/// Transform uniforms that are changed per object.
struct Transforms {
struct common__Transforms {
/// The world matrix that transforms this object into stage space.
world_matrix: mat4x4<f32>,
@ -22,23 +21,23 @@ struct Transforms {
};
/// Uniforms used by texture draws (bitmaps and gradients).
struct TextureTransforms {
struct common__TextureTransforms {
/// The transform matrix of the gradient or texture.
/// Transforms from object space to UV space.
texture_matrix: mat4x4<f32>,
};
/// The vertex format shared among most shaders.
struct VertexInput {
struct common__VertexInput {
/// The position of the vertex in object space.
@location(0) position: vec2<f32>,
};
/// Common uniform layout shared by all shaders.
@group(0) @binding(0) var<uniform> globals: Globals;
@group(0) @binding(0) var<uniform> common__globals: common__Globals;
/// Converts a color from linear to sRGB color space.
fn linear_to_srgb(linear_: vec4<f32>) -> vec4<f32> {
fn common__linear_to_srgb(linear_: vec4<f32>) -> vec4<f32> {
var rgb: vec3<f32> = linear_.rgb;
if( linear_.a > 0.0 ) {
rgb = rgb / linear_.a;
@ -50,7 +49,7 @@ fn linear_to_srgb(linear_: vec4<f32>) -> vec4<f32> {
}
/// Converts a color from sRGB to linear color space.
fn srgb_to_linear(srgb: vec4<f32>) -> vec4<f32> {
fn common__srgb_to_linear(srgb: vec4<f32>) -> vec4<f32> {
var rgb: vec3<f32> = srgb.rgb;
if( srgb.a > 0.0 ) {
rgb = rgb / srgb.a;

View File

@ -1,22 +1,22 @@
/// Shader used for drawing bitmap fills.
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common__TextureTransforms;
@group(2) @binding(1) var texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let matrix_ = textureTransforms.texture_matrix;
let uv = (mat3x3<f32>(matrix_[0].xyz, matrix_[1].xyz, matrix_[2].xyz) * vec3<f32>(in.position, 1.0)).xy;
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
return VertexOutput(pos, uv);
}

View File

@ -1,26 +1,26 @@
/// Shader used for drawing bitmap fills.
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common__TextureTransforms;
@group(2) @binding(1) var texture: texture_2d<f32>;
@group(2) @binding(2) var texture_sampler: sampler;
@vertex
fn main_vertex(in: common::VertexInput) -> VertexOutput {
fn main_vertex(in: common__VertexInput) -> VertexOutput {
let matrix_ = textureTransforms.texture_matrix;
let uv = (mat3x3<f32>(matrix_[0].xyz, matrix_[1].xyz, matrix_[2].xyz) * vec3<f32>(in.position, 1.0)).xy;
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
return VertexOutput(pos, uv);
}
@fragment
fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
return common::srgb_to_linear(textureSample(texture, texture_sampler, in.uv));
return common__srgb_to_linear(textureSample(texture, texture_sampler, in.uv));
}

View File

@ -1,4 +1,4 @@
#import filter
// NOTE: The `shader_filter_common.wgsl` source is prepended to this before compilation.
struct Filter {
// Secretly a vec2<f32> but within alignment rules.
@ -29,8 +29,8 @@ struct Filter {
@group(0) @binding(2) var<uniform> filter_args: Filter;
@vertex
fn main_vertex(in: filter::VertexInput) -> filter::VertexOutput {
var result = filter::main_vertex(in);
fn main_vertex(in: filter__VertexInput) -> filter__VertexOutput {
var result = filter__main_vertex(in);
let direction = vec2<f32>(filter_args.dir_x, filter_args.dir_y);
// Pre-shifting the UV coords to put the center of the first trivially
@ -41,7 +41,7 @@ fn main_vertex(in: filter::VertexInput) -> filter::VertexOutput {
}
@fragment
fn main_fragment(in: filter::VertexOutput) -> @location(0) vec4<f32> {
fn main_fragment(in: filter__VertexOutput) -> @location(0) vec4<f32> {
let direction = vec2<f32>(filter_args.dir_x, filter_args.dir_y);
var total = vec4<f32>(0.0);

View File

@ -1,4 +1,4 @@
#import filter
// NOTE: The `shader_filter_common.wgsl` source is prepended to this before compilation.
struct Filter {
r_to_r: f32,
@ -31,12 +31,12 @@ struct Filter {
@group(0) @binding(2) var<uniform> filter_args: Filter;
@vertex
fn main_vertex(in: filter::VertexInput) -> filter::VertexOutput {
return filter::main_vertex(in);
fn main_vertex(in: filter__VertexInput) -> filter__VertexOutput {
return filter__main_vertex(in);
}
@fragment
fn main_fragment(in: filter::VertexOutput) -> @location(0) vec4<f32> {
fn main_fragment(in: filter__VertexOutput) -> @location(0) vec4<f32> {
var src = textureSample(texture, texture_sampler, in.uv);
var f = filter_args;
var color = vec4<f32>(

View File

@ -1,13 +1,12 @@
#define_import_path gradient
#import common
// NOTE: The `common.wgsl` source is prepended to this before compilation.
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@group(1) @binding(0) var<uniform> transforms: common::Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common::TextureTransforms;
@group(1) @binding(0) var<uniform> transforms: common__Transforms;
@group(2) @binding(0) var<uniform> textureTransforms: common__TextureTransforms;
struct Gradient {
focal_point: f32,
@ -29,7 +28,7 @@ struct GradientVertexInput {
fn main_vertex(in: GradientVertexInput) -> VertexOutput {
let matrix_ = textureTransforms.texture_matrix;
let uv = (mat3x3<f32>(matrix_[0].xyz, matrix_[1].xyz, matrix_[2].xyz) * vec3<f32>(in.position, 1.0)).xy;
let pos = common::globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
let pos = common__globals.view_matrix * transforms.world_matrix * vec4<f32>(in.position.x, in.position.y, 0.0, 1.0);
return VertexOutput(pos, uv);
}
@ -76,7 +75,7 @@ fn main_fragment(in: VertexOutput) -> @location(0) vec4<f32> {
var color = textureSample(texture, texture_sampler, vec2<f32>(t, 0.0));
if( gradient.interpolation != 0 ) {
color = common::linear_to_srgb(color);
color = common__linear_to_srgb(color);
}
let out = saturate(color * transforms.mult_color + transforms.add_color);
let alpha = saturate(out.a);

View File

@ -1,10 +1,6 @@
use crate::blend::ComplexBlend;
use enum_map::{enum_map, EnumMap};
use naga_oil::compose::{
ComposableModuleDescriptor, Composer, ComposerError, NagaModuleDescriptor, ShaderDefValue,
};
use std::borrow::Cow;
use std::collections::HashMap;
use ruffle_render::shader_source::SHADER_FILTER_COMMON;
#[derive(Debug)]
pub struct Shaders {
@ -30,101 +26,65 @@ pub struct Shaders {
impl Shaders {
pub fn new(device: &wgpu::Device) -> Self {
let mut composer = composer().expect("Couldn't create shader composer");
let mut shader_defs = HashMap::new();
shader_defs.insert("early_saturate".to_owned(), ShaderDefValue::Bool(true));
let mut late_saturate_shader_defs = shader_defs.clone();
late_saturate_shader_defs.insert("early_saturate".to_owned(), ShaderDefValue::Bool(false));
let color_shader = make_shader(
device,
&mut composer,
&shader_defs,
"color.wgsl",
include_str!("../shaders/color.wgsl"),
);
let color_shader = make_shader(device, "color.wgsl", include_str!("../shaders/color.wgsl"));
let bitmap = include_str!("../shaders/bitmap.wgsl");
let bitmap_shader = make_shader(
device,
&mut composer,
&shader_defs,
"bitmap.wgsl",
include_str!("../shaders/bitmap.wgsl"),
&bitmap.replace("#EARLY_SATURATE#", "true"),
);
let bitmap_late_saturate_shader = make_shader(
device,
&mut composer,
&late_saturate_shader_defs,
"bitmap.wgsl",
include_str!("../shaders/bitmap.wgsl"),
&bitmap.replace("#EARLY_SATURATE#", "false"),
);
let copy_srgb_shader = make_shader(
device,
&mut composer,
&shader_defs,
"copy_srgb.wgsl",
include_str!("../shaders/copy_srgb.wgsl"),
);
let copy_shader = make_shader(
let copy_shader = make_shader(device, "copy.wgsl", include_str!("../shaders/copy.wgsl"));
let color_matrix_filter = make_filter_shader(
device,
&mut composer,
&shader_defs,
"copy.wgsl",
include_str!("../shaders/copy.wgsl"),
);
let color_matrix_filter = make_shader(
device,
&mut composer,
&shader_defs,
"filter/color_matrix.wgsl",
include_str!("../shaders/filter/color_matrix.wgsl"),
);
let blur_filter = make_shader(
let blur_filter = make_filter_shader(
device,
&mut composer,
&shader_defs,
"filter/blur.wgsl",
include_str!("../shaders/filter/blur.wgsl"),
);
let glow_filter = make_shader(
let glow_filter = make_filter_shader(
device,
&mut composer,
&shader_defs,
"filter/glow.wgsl",
include_str!("../shaders/filter/glow.wgsl"),
);
let bevel_filter = make_shader(
let bevel_filter = make_filter_shader(
device,
&mut composer,
&shader_defs,
"filter/bevel.wgsl",
include_str!("../shaders/filter/bevel.wgsl"),
);
let displacement_map_filter = make_shader(
let displacement_map_filter = make_filter_shader(
device,
&mut composer,
&shader_defs,
"filter/displacement_map.wgsl",
include_str!("../shaders/filter/displacement_map.wgsl"),
);
let gradient_shader = make_shader(
device,
&mut composer,
&shader_defs,
"gradient.wgsl",
include_str!("../shaders/gradient.wgsl"),
);
let blend_shaders = enum_map! {
ComplexBlend::Multiply => make_shader(device, &mut composer, &shader_defs, "blend/multiply.wgsl", include_str!("../shaders/blend/multiply.wgsl")),
ComplexBlend::Lighten => make_shader(device, &mut composer, &shader_defs, "blend/lighten.wgsl", include_str!("../shaders/blend/lighten.wgsl")),
ComplexBlend::Darken => make_shader(device, &mut composer, &shader_defs, "blend/darken.wgsl", include_str!("../shaders/blend/darken.wgsl")),
ComplexBlend::Difference => make_shader(device, &mut composer, &shader_defs, "blend/difference.wgsl", include_str!("../shaders/blend/difference.wgsl")),
ComplexBlend::Invert => make_shader(device, &mut composer, &shader_defs, "blend/invert.wgsl", include_str!("../shaders/blend/invert.wgsl")),
ComplexBlend::Alpha => make_shader(device, &mut composer, &shader_defs, "blend/alpha.wgsl", include_str!("../shaders/blend/alpha.wgsl")),
ComplexBlend::Erase => make_shader(device, &mut composer, &shader_defs, "blend/erase.wgsl", include_str!("../shaders/blend/erase.wgsl")),
ComplexBlend::Overlay => make_shader(device, &mut composer, &shader_defs, "blend/overlay.wgsl", include_str!("../shaders/blend/overlay.wgsl")),
ComplexBlend::HardLight => make_shader(device, &mut composer, &shader_defs, "blend/hardlight.wgsl", include_str!("../shaders/blend/hardlight.wgsl")),
ComplexBlend::Multiply => make_shader(device, "blend/multiply.wgsl", include_str!("../shaders/blend/multiply.wgsl")),
ComplexBlend::Lighten => make_shader(device, "blend/lighten.wgsl", include_str!("../shaders/blend/lighten.wgsl")),
ComplexBlend::Darken => make_shader(device, "blend/darken.wgsl", include_str!("../shaders/blend/darken.wgsl")),
ComplexBlend::Difference => make_shader(device, "blend/difference.wgsl", include_str!("../shaders/blend/difference.wgsl")),
ComplexBlend::Invert => make_shader(device, "blend/invert.wgsl", include_str!("../shaders/blend/invert.wgsl")),
ComplexBlend::Alpha => make_shader(device, "blend/alpha.wgsl", include_str!("../shaders/blend/alpha.wgsl")),
ComplexBlend::Erase => make_shader(device, "blend/erase.wgsl", include_str!("../shaders/blend/erase.wgsl")),
ComplexBlend::Overlay => make_shader(device, "blend/overlay.wgsl", include_str!("../shaders/blend/overlay.wgsl")),
ComplexBlend::HardLight => make_shader(device, "blend/hardlight.wgsl", include_str!("../shaders/blend/hardlight.wgsl")),
};
Self {
@ -144,48 +104,16 @@ impl Shaders {
}
}
fn composer() -> Result<Composer, ComposerError> {
let mut composer = Composer::default();
// [NA] Hack to get all capabilities since nobody exposes this type easily
let capabilities = composer.capabilities;
composer = composer.with_capabilities(!capabilities);
composer.add_composable_module(ComposableModuleDescriptor {
source: include_str!("../shaders/common.wgsl"),
file_path: "common.wgsl",
..Default::default()
})?;
composer.add_composable_module(ComposableModuleDescriptor {
source: ruffle_render::shader_source::SHADER_FILTER_COMMON,
file_path: "shader_filter_common.wgsl",
..Default::default()
})?;
Ok(composer)
}
fn make_shader(
device: &wgpu::Device,
composer: &mut Composer,
shader_defs: &HashMap<String, ShaderDefValue>,
name: &str,
source: &'static str,
) -> wgpu::ShaderModule {
fn make_shader(device: &wgpu::Device, name: &str, source: &str) -> wgpu::ShaderModule {
let common = include_str!("../shaders/common.wgsl");
device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: create_debug_label!("Shader {}", name).as_deref(),
source: wgpu::ShaderSource::Naga(Cow::Owned(
composer
.make_naga_module(NagaModuleDescriptor {
source,
file_path: name,
shader_defs: shader_defs.clone(),
..Default::default()
})
.unwrap_or_else(|e| {
panic!(
"{name} failed to compile:\n{}\n{:#?}",
e.emit_to_string(composer),
e
)
}),
)),
source: wgpu::ShaderSource::Wgsl(format!("{}\n{}", common, source).into()),
})
}
fn make_filter_shader(device: &wgpu::Device, name: &str, source: &str) -> wgpu::ShaderModule {
device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: create_debug_label!("Shader {}", name).as_deref(),
source: wgpu::ShaderSource::Wgsl(format!("{}\n{}", SHADER_FILTER_COMMON, source).into()),
})
}