rt: implement filter chain loading in terms of pack
This commit is contained in:
parent
75b70cc0e6
commit
32c99d9f4a
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1641,7 +1641,6 @@ dependencies = [
|
||||||
"image",
|
"image",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
|
||||||
"rayon",
|
"rayon",
|
||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -1687,6 +1686,7 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"glslang",
|
"glslang",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"naga",
|
"naga",
|
||||||
|
@ -1724,6 +1724,7 @@ dependencies = [
|
||||||
"gfx-maths",
|
"gfx-maths",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
@ -1746,6 +1747,7 @@ dependencies = [
|
||||||
"gpu-allocator 0.27.0",
|
"gpu-allocator 0.27.0",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
@ -1767,11 +1769,13 @@ dependencies = [
|
||||||
"gfx-maths",
|
"gfx-maths",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
"librashader-runtime",
|
"librashader-runtime",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"rayon",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"windows 0.58.0",
|
"windows 0.58.0",
|
||||||
"windows-core 0.58.0",
|
"windows-core 0.58.0",
|
||||||
|
@ -1787,6 +1791,7 @@ dependencies = [
|
||||||
"glow 0.14.1",
|
"glow 0.14.1",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
@ -1803,6 +1808,7 @@ dependencies = [
|
||||||
"array-concat",
|
"array-concat",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
@ -1828,6 +1834,7 @@ dependencies = [
|
||||||
"gpu-allocator 0.27.0",
|
"gpu-allocator 0.27.0",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
@ -1850,6 +1857,7 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"librashader-cache",
|
"librashader-cache",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
"librashader-pack",
|
||||||
"librashader-preprocess",
|
"librashader-preprocess",
|
||||||
"librashader-presets",
|
"librashader-presets",
|
||||||
"librashader-reflect",
|
"librashader-reflect",
|
||||||
|
|
|
@ -13,7 +13,6 @@ description = "RetroArch shaders for all."
|
||||||
[dependencies]
|
[dependencies]
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5", features = ["serde"] }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5", features = ["serde"] }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5", features = ["serde"] }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5", features = ["serde"] }
|
||||||
librashader-reflect= { path = "../librashader-reflect", version = "0.4.5" }
|
|
||||||
|
|
||||||
thiserror = "1.0.64"
|
thiserror = "1.0.64"
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|
|
@ -87,7 +87,6 @@ impl LoadableResource for TextureMeta {
|
||||||
/// The configuration for a single shader pass.
|
/// The configuration for a single shader pass.
|
||||||
pub type ShaderPassData = ShaderPresetResource<ShaderPassMeta>;
|
pub type ShaderPassData = ShaderPresetResource<ShaderPassMeta>;
|
||||||
pub type TextureData = ShaderPresetResource<TextureMeta>;
|
pub type TextureData = ShaderPresetResource<TextureMeta>;
|
||||||
|
|
||||||
/// A shader preset, not reliant on disk, with all information needed.
|
/// A shader preset, not reliant on disk, with all information needed.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
|
|
@ -21,6 +21,7 @@ bitflags = "2.4.2"
|
||||||
librashader-common = { path = "../librashader-common", version = "0.4.5" }
|
librashader-common = { path = "../librashader-common", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
|
|
||||||
spirv-cross2 = { workspace = true, optional = true }
|
spirv-cross2 = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@ use crate::reflect::semantics::{
|
||||||
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
|
||||||
};
|
};
|
||||||
use librashader_common::map::{FastHashMap, ShortString};
|
use librashader_common::map::{FastHashMap, ShortString};
|
||||||
|
use librashader_pack::ShaderPassData;
|
||||||
use librashader_preprocess::{PreprocessError, ShaderSource};
|
use librashader_preprocess::{PreprocessError, ShaderSource};
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPassMeta, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassMeta, ShaderPreset, TextureMeta};
|
||||||
|
|
||||||
/// Artifacts of a reflected and compiled shader pass.
|
/// Artifacts of a reflected and compiled shader pass.
|
||||||
///
|
///
|
||||||
|
@ -36,9 +37,9 @@ impl<T: OutputTarget> CompilePresetTarget for T {}
|
||||||
pub trait CompilePresetTarget: OutputTarget {
|
pub trait CompilePresetTarget: OutputTarget {
|
||||||
/// Compile passes of a shader preset given the applicable
|
/// Compile passes of a shader preset given the applicable
|
||||||
/// shader output target, compilation type, and resulting error.
|
/// shader output target, compilation type, and resulting error.
|
||||||
fn compile_preset_passes<I, R, E>(
|
fn compile_preset_passes<'a, I, R, E>(
|
||||||
passes: Vec<ShaderPassConfig>,
|
passes: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: impl Iterator<Item = &'a TextureMeta>,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
Vec<ShaderPassArtifact<<Self as FromCompilation<I, R>>::Output>>,
|
Vec<ShaderPassArtifact<<Self as FromCompilation<I, R>>::Output>>,
|
||||||
|
@ -61,9 +62,9 @@ pub trait CompilePresetTarget: OutputTarget {
|
||||||
|
|
||||||
/// Compile passes of a shader preset given the applicable
|
/// Compile passes of a shader preset given the applicable
|
||||||
/// shader output target, compilation type, and resulting error.
|
/// shader output target, compilation type, and resulting error.
|
||||||
fn compile_preset_passes<T, I, R, E>(
|
fn compile_preset_passes<'a, T, I, R, E>(
|
||||||
passes: Vec<ShaderPassConfig>,
|
passes: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: impl Iterator<Item = &'a TextureMeta>,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
Vec<ShaderPassArtifact<<T as FromCompilation<I, R>>::Output>>,
|
Vec<ShaderPassArtifact<<T as FromCompilation<I, R>>::Output>>,
|
||||||
|
@ -87,8 +88,7 @@ where
|
||||||
let passes = passes
|
let passes = passes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|shader| {
|
.map(|shader| {
|
||||||
let source: ShaderSource = ShaderSource::load(&shader.path)?;
|
let source = shader.data;
|
||||||
|
|
||||||
let compiled = I::Compiler::compile(&source)?;
|
let compiled = I::Compiler::compile(&source)?;
|
||||||
let reflect = T::from_compilation(compiled)?;
|
let reflect = T::from_compilation(compiled)?;
|
||||||
|
|
||||||
|
@ -188,17 +188,17 @@ fn insert_pass_semantics(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert the available semantics for the input texture config into the provided semantic maps.
|
/// Insert the available semantics for the input texture config into the provided semantic maps.
|
||||||
fn insert_lut_semantics(
|
fn insert_lut_semantics<'a>(
|
||||||
textures: &[TextureConfig],
|
textures: impl Iterator<Item = &'a TextureMeta>,
|
||||||
uniform_semantics: &mut FastHashMap<ShortString, UniformSemantic>,
|
uniform_semantics: &mut FastHashMap<ShortString, UniformSemantic>,
|
||||||
texture_semantics: &mut FastHashMap<ShortString, Semantic<TextureSemantics>>,
|
texture_semantics: &mut FastHashMap<ShortString, Semantic<TextureSemantics>>,
|
||||||
) {
|
) {
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.enumerate() {
|
||||||
let mut size_semantic = texture.meta.name.clone();
|
let mut size_semantic = texture.name.clone();
|
||||||
size_semantic.push_str("Size");
|
size_semantic.push_str("Size");
|
||||||
|
|
||||||
texture_semantics.insert(
|
texture_semantics.insert(
|
||||||
texture.meta.name.clone(),
|
texture.name.clone(),
|
||||||
Semantic {
|
Semantic {
|
||||||
semantics: TextureSemantics::User,
|
semantics: TextureSemantics::User,
|
||||||
index,
|
index,
|
||||||
|
@ -261,7 +261,7 @@ impl ShaderSemantics {
|
||||||
config.meta.id as usize,
|
config.meta.id as usize,
|
||||||
);
|
);
|
||||||
insert_lut_semantics(
|
insert_lut_semantics(
|
||||||
preset.textures.as_slice(),
|
preset.textures.iter().map(|t| &t.meta),
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics,
|
&mut texture_semantics,
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,6 +15,7 @@ description = "RetroArch shaders for all."
|
||||||
librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.4.5" }
|
librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.4.5" }
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
||||||
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
||||||
|
|
|
@ -2,13 +2,13 @@ use crate::texture::InputTexture;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
|
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::SpirvCompilation;
|
use librashader_reflect::front::SpirvCompilation;
|
||||||
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection, RGBA8};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -75,6 +75,7 @@ pub(crate) struct FilterCommon {
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::{ShaderPassData, TextureData};
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type ShaderPassMeta =
|
pub type ShaderPassMeta =
|
||||||
|
@ -86,8 +87,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -95,10 +96,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ mod compile {
|
||||||
}
|
}
|
||||||
|
|
||||||
use compile::{compile_passes, ShaderPassMeta};
|
use compile::{compile_passes, ShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
impl FilterChainD3D11 {
|
impl FilterChainD3D11 {
|
||||||
|
@ -132,6 +135,16 @@ impl FilterChainD3D11 {
|
||||||
unsafe { Self::load_from_preset_deferred(preset, device, &immediate_context, options) }
|
unsafe { Self::load_from_preset_deferred(preset, device, &immediate_context, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
|
pub unsafe fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: &ID3D11Device,
|
||||||
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
|
) -> error::Result<FilterChainD3D11> {
|
||||||
|
let immediate_context = unsafe { device.GetImmediateContext()? };
|
||||||
|
unsafe { Self::load_from_pack_deferred(preset, device, &immediate_context, options) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||||
/// to the caller. This function is therefore requires no external synchronization of the
|
/// to the caller. This function is therefore requires no external synchronization of the
|
||||||
/// immediate context, as long as the immediate context is not used as the input context,
|
/// immediate context, as long as the immediate context is not used as the input context,
|
||||||
|
@ -152,6 +165,31 @@ impl FilterChainD3D11 {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
ctx: &ID3D11DeviceContext,
|
ctx: &ID3D11DeviceContext,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
|
) -> error::Result<FilterChainD3D11> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack_deferred(preset, device, ctx, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function is therefore requires no external synchronization of the
|
||||||
|
/// immediate context, as long as the immediate context is not used as the input context,
|
||||||
|
/// nor of the device, as long as the device is not single-threaded only.
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
/// The provided context must either be immediate, or immediately submitted after this function
|
||||||
|
/// returns, **before drawing frames**, or lookup textures will fail to load and the filter chain
|
||||||
|
/// will be in an invalid state.
|
||||||
|
///
|
||||||
|
/// If the context is deferred, it must be ready for command recording, and have no prior commands
|
||||||
|
/// recorded. No commands shall be recorded after, the caller must immediately call [`FinishCommandList`](https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-finishcommandlist)
|
||||||
|
/// and execute the command list on the immediate context after this function returns.
|
||||||
|
///
|
||||||
|
/// If the context is immediate, then access to the immediate context requires external synchronization.
|
||||||
|
pub unsafe fn load_from_pack_deferred(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: &ID3D11Device,
|
||||||
|
ctx: &ID3D11DeviceContext,
|
||||||
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
|
||||||
|
@ -165,7 +203,7 @@ impl FilterChainD3D11 {
|
||||||
let immediate_context = unsafe { device.GetImmediateContext()? };
|
let immediate_context = unsafe { device.GetImmediateContext()? };
|
||||||
|
|
||||||
// load luts
|
// load luts
|
||||||
let luts = FilterChainD3D11::load_luts(device, &ctx, &preset.textures)?;
|
let luts = FilterChainD3D11::load_luts(device, &ctx, preset.textures)?;
|
||||||
|
|
||||||
let framebuffer_gen =
|
let framebuffer_gen =
|
||||||
|| OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
|
|| OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
|
||||||
|
@ -361,21 +399,21 @@ impl FilterChainD3D11 {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
context: &ID3D11DeviceContext,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture<RGBA8>>, ImageError>>()?;
|
||||||
|
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.iter().enumerate() {
|
||||||
let desc = D3D11_TEXTURE2D_DESC {
|
let desc = D3D11_TEXTURE2D_DESC {
|
||||||
Width: image.size.width,
|
Width: image.size.width,
|
||||||
Height: image.size.height,
|
Height: image.size.height,
|
||||||
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
Usage: D3D11_USAGE_DEFAULT,
|
Usage: D3D11_USAGE_DEFAULT,
|
||||||
MiscFlags: if texture.meta.mipmap {
|
MiscFlags: if meta.mipmap {
|
||||||
D3D11_RESOURCE_MISC_GENERATE_MIPS.0 as u32
|
D3D11_RESOURCE_MISC_GENERATE_MIPS.0 as u32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
@ -388,8 +426,8 @@ impl FilterChainD3D11 {
|
||||||
context,
|
context,
|
||||||
&image,
|
&image,
|
||||||
desc,
|
desc,
|
||||||
texture.meta.filter_mode,
|
meta.filter_mode,
|
||||||
texture.meta.wrap_mode,
|
meta.wrap_mode,
|
||||||
)?;
|
)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ librashader-common = { path = "../librashader-common", features = ["d3d12"], ver
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5", features = ["dxil"] }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5", features = ["dxil"] }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
||||||
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use d3d12_descriptor_heap::{
|
||||||
use gpu_allocator::d3d12::{Allocator, AllocatorCreateDesc, ID3D12DeviceVersion};
|
use gpu_allocator::d3d12::{Allocator, AllocatorCreateDesc, ID3D12DeviceVersion};
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::targets::{DXIL, HLSL};
|
use librashader_reflect::back::targets::{DXIL, HLSL};
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::SpirvCompilation;
|
use librashader_reflect::front::SpirvCompilation;
|
||||||
|
@ -25,7 +25,7 @@ use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtif
|
||||||
use librashader_reflect::reflect::semantics::{ShaderSemantics, MAX_BINDINGS_COUNT};
|
use librashader_reflect::reflect::semantics::{ShaderSemantics, MAX_BINDINGS_COUNT};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::{BindingUtil, TextureInput};
|
use librashader_runtime::binding::{BindingUtil, TextureInput};
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
@ -175,6 +175,7 @@ impl Drop for FrameResiduals {
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::ShaderPassData;
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type DxilShaderPassMeta =
|
pub type DxilShaderPassMeta =
|
||||||
|
@ -186,8 +187,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes_dxil(
|
pub fn compile_passes_dxil(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<DxilShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<DxilShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -195,10 +196,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
DXIL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
DXIL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -215,8 +217,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes_hlsl(
|
pub fn compile_passes_hlsl(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<HlslShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<HlslShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -224,10 +226,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -237,6 +240,7 @@ mod compile {
|
||||||
|
|
||||||
use crate::resource::OutlivesFrame;
|
use crate::resource::OutlivesFrame;
|
||||||
use compile::{compile_passes_dxil, compile_passes_hlsl, DxilShaderPassMeta, HlslShaderPassMeta};
|
use compile::{compile_passes_dxil, compile_passes_hlsl, DxilShaderPassMeta, HlslShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
impl FilterChainD3D12 {
|
impl FilterChainD3D12 {
|
||||||
|
@ -257,6 +261,16 @@ impl FilterChainD3D12 {
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
|
) -> error::Result<FilterChainD3D12> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack(preset, device, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
pub unsafe fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: &ID3D12Device,
|
||||||
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// 1 time queue infrastructure for lut uploads
|
// 1 time queue infrastructure for lut uploads
|
||||||
|
@ -275,7 +289,7 @@ impl FilterChainD3D12 {
|
||||||
let fence_event = CreateEventA(None, false, false, None)?;
|
let fence_event = CreateEventA(None, false, false, None)?;
|
||||||
let fence: ID3D12Fence = device.CreateFence(0, D3D12_FENCE_FLAG_NONE)?;
|
let fence: ID3D12Fence = device.CreateFence(0, D3D12_FENCE_FLAG_NONE)?;
|
||||||
|
|
||||||
let filter_chain = Self::load_from_preset_deferred(preset, device, &cmd, options)?;
|
let filter_chain = Self::load_from_pack_deferred(preset, device, &cmd, options)?;
|
||||||
|
|
||||||
cmd.Close()?;
|
cmd.Close()?;
|
||||||
queue.ExecuteCommandLists(&[Some(cmd.cast()?)]);
|
queue.ExecuteCommandLists(&[Some(cmd.cast()?)]);
|
||||||
|
@ -303,6 +317,23 @@ impl FilterChainD3D12 {
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
cmd: &ID3D12GraphicsCommandList,
|
cmd: &ID3D12GraphicsCommandList,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
|
) -> error::Result<FilterChainD3D12> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack_deferred(preset, device, cmd, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed, loaded `ShaderPresetPack`, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
/// The provided command list must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command list and immediately submitting it to a
|
||||||
|
/// graphics queue. The command list must be completely executed before calling [`frame`](Self::frame).
|
||||||
|
pub unsafe fn load_from_pack_deferred(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: &ID3D12Device,
|
||||||
|
cmd: &ID3D12GraphicsCommandList,
|
||||||
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
let shader_count = preset.shaders.len();
|
let shader_count = preset.shaders.len();
|
||||||
let lut_count = preset.textures.len();
|
let lut_count = preset.textures.len();
|
||||||
|
@ -364,7 +395,7 @@ impl FilterChainD3D12 {
|
||||||
&mut staging_heap,
|
&mut staging_heap,
|
||||||
&mut mipmap_heap,
|
&mut mipmap_heap,
|
||||||
&mut residuals,
|
&mut residuals,
|
||||||
&preset.textures,
|
preset.textures,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let framebuffer_gen = || {
|
let framebuffer_gen = || {
|
||||||
|
@ -430,27 +461,27 @@ impl FilterChainD3D12 {
|
||||||
staging_heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
staging_heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
mipmap_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
mipmap_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||||
gc: &mut FrameResiduals,
|
gc: &mut FrameResiduals,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
// use separate mipgen to load luts.
|
// use separate mipgen to load luts.
|
||||||
let mipmap_gen = D3D12MipmapGen::new(device, true)?;
|
let mipmap_gen = D3D12MipmapGen::new(device, true)?;
|
||||||
|
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture>, ImageError>>()?;
|
||||||
|
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.iter().enumerate() {
|
||||||
let texture = LutTexture::new(
|
let texture = LutTexture::new(
|
||||||
device,
|
device,
|
||||||
allocator,
|
allocator,
|
||||||
staging_heap,
|
staging_heap,
|
||||||
cmd,
|
cmd,
|
||||||
&image,
|
&image,
|
||||||
texture.meta.filter_mode,
|
meta.filter_mode,
|
||||||
texture.meta.wrap_mode,
|
meta.wrap_mode,
|
||||||
texture.meta.mipmap,
|
meta.mipmap,
|
||||||
gc,
|
gc,
|
||||||
)?;
|
)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
|
|
|
@ -619,9 +619,9 @@ pub mod d3d12_hello_triangle {
|
||||||
filter
|
filter
|
||||||
.frame(
|
.frame(
|
||||||
command_list,
|
command_list,
|
||||||
D3D12InputImage {
|
D3D12InputImage::External {
|
||||||
resource: resources.framebuffer.to_ref(),
|
resource: resources.framebuffer.clone(),
|
||||||
descriptor: Some(framebuffer),
|
descriptor: framebuffer,
|
||||||
},
|
},
|
||||||
&Viewport {
|
&Viewport {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
|
|
|
@ -16,6 +16,7 @@ librashader-common = { path = "../librashader-common", features = ["d3d9", "d3d1
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
|
||||||
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ thiserror = "1.0.37"
|
||||||
bytemuck = "1.12.3"
|
bytemuck = "1.12.3"
|
||||||
array-concat = "0.5.2"
|
array-concat = "0.5.2"
|
||||||
num-traits = "0.2.18"
|
num-traits = "0.2.18"
|
||||||
|
rayon = "1.10.0"
|
||||||
windows-core = "0.58.0"
|
windows-core = "0.58.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -12,7 +12,7 @@ use librashader_cache::{cache_shader_object, CachedCompilation};
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_presets::context::VideoDriver;
|
use librashader_presets::context::VideoDriver;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::hlsl::HlslShaderModel;
|
use librashader_reflect::back::hlsl::HlslShaderModel;
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
|
@ -23,16 +23,18 @@ use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::{BindingUtil, TextureInput};
|
use librashader_runtime::binding::{BindingUtil, TextureInput};
|
||||||
use librashader_runtime::framebuffer::FramebufferInit;
|
use librashader_runtime::framebuffer::FramebufferInit;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection, BGRA8};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use librashader_common::GetSize;
|
use librashader_common::GetSize;
|
||||||
|
use rayon::iter::IntoParallelIterator;
|
||||||
|
use rayon::iter::ParallelIterator;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9};
|
use windows::Win32::Graphics::Direct3D9::{IDirect3DDevice9, IDirect3DSurface9, IDirect3DTexture9};
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ pub struct FilterChainD3D9 {
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::{ShaderPassData, TextureData};
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type ShaderPassMeta =
|
pub type ShaderPassMeta =
|
||||||
|
@ -72,8 +75,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -81,10 +84,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -93,6 +97,7 @@ mod compile {
|
||||||
}
|
}
|
||||||
|
|
||||||
use compile::{compile_passes, ShaderPassMeta};
|
use compile::{compile_passes, ShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
impl FilterChainD3D9 {
|
impl FilterChainD3D9 {
|
||||||
|
@ -184,16 +189,16 @@ impl FilterChainD3D9 {
|
||||||
|
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &IDirect3DDevice9,
|
device: &IDirect3DDevice9,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
let images = textures
|
let images = textures
|
||||||
.iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image<BGRA8>>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture<BGRA8>>, ImageError>>()?;
|
||||||
|
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in images.iter().enumerate() {
|
||||||
let texture = LutTexture::new(device, &image, &texture.meta)?;
|
let texture = LutTexture::new(device, &image, &meta)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
|
@ -213,11 +218,21 @@ impl FilterChainD3D9 {
|
||||||
unsafe { Self::load_from_preset(preset, device, options) }
|
unsafe { Self::load_from_preset(preset, device, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
pub unsafe fn load_from_preset(
|
pub unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
device: &IDirect3DDevice9,
|
device: &IDirect3DDevice9,
|
||||||
options: Option<&FilterChainOptionsD3D9>,
|
options: Option<&FilterChainOptionsD3D9>,
|
||||||
|
) -> error::Result<FilterChainD3D9> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack(preset, device, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
pub unsafe fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: &IDirect3DDevice9,
|
||||||
|
options: Option<&FilterChainOptionsD3D9>,
|
||||||
) -> error::Result<FilterChainD3D9> {
|
) -> error::Result<FilterChainD3D9> {
|
||||||
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
let disable_cache = options.map_or(false, |o| o.disable_cache);
|
||||||
|
|
||||||
|
@ -229,7 +244,7 @@ impl FilterChainD3D9 {
|
||||||
let filters = FilterChainD3D9::init_passes(device, passes, &semantics, disable_cache)?;
|
let filters = FilterChainD3D9::init_passes(device, passes, &semantics, disable_cache)?;
|
||||||
|
|
||||||
// load luts
|
// load luts
|
||||||
let luts = FilterChainD3D9::load_luts(device, &preset.textures)?;
|
let luts = FilterChainD3D9::load_luts(device, preset.textures)?;
|
||||||
|
|
||||||
let framebuffer_gen =
|
let framebuffer_gen =
|
||||||
|| D3D9Texture::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
|
|| D3D9Texture::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
|
||||||
|
|
|
@ -16,6 +16,7 @@ librashader-common = { path = "../librashader-common", features = ["opengl"], ve
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
||||||
librashader-cache = { path = "../librashader-cache", version = "0.4.5" }
|
librashader-cache = { path = "../librashader-cache", version = "0.4.5" }
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ use crate::util::{gl_get_version, gl_u16_to_version};
|
||||||
use crate::{error, GLImage};
|
use crate::{error, GLImage};
|
||||||
use librashader_common::Viewport;
|
use librashader_common::Viewport;
|
||||||
|
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
|
||||||
use librashader_reflect::back::glsl::GlslVersion;
|
use librashader_reflect::back::glsl::GlslVersion;
|
||||||
use librashader_reflect::back::targets::GLSL;
|
use librashader_reflect::back::targets::GLSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
|
@ -22,6 +21,7 @@ use librashader_reflect::reflect::semantics::{ShaderSemantics, UniformMeta};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use librashader_cache::CachedCompilation;
|
use librashader_cache::CachedCompilation;
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
|
use librashader_pack::{ShaderPassData, ShaderPresetPack, TextureData};
|
||||||
use librashader_reflect::reflect::cross::SpirvCross;
|
use librashader_reflect::reflect::cross::SpirvCross;
|
||||||
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
|
@ -30,6 +30,7 @@ use librashader_runtime::framebuffer::FramebufferInit;
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -107,8 +108,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -116,10 +117,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
GLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
GLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,8 +134,8 @@ use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChainImpl<T> {
|
impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub(crate) unsafe fn load_from_preset(
|
pub(crate) unsafe fn load_from_pack(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPresetPack,
|
||||||
context: Arc<glow::Context>,
|
context: Arc<glow::Context>,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
|
@ -156,7 +158,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
let samplers = SamplerSet::new(&context)?;
|
let samplers = SamplerSet::new(&context)?;
|
||||||
|
|
||||||
// load luts
|
// load luts
|
||||||
let luts = T::LoadLut::load_luts(&context, &preset.textures)?;
|
let luts = T::LoadLut::load_luts(&context, preset.textures)?;
|
||||||
|
|
||||||
let framebuffer_gen = || T::FramebufferInterface::new(&context, 1);
|
let framebuffer_gen = || T::FramebufferInterface::new(&context, 1);
|
||||||
let input_gen = || InputTexture {
|
let input_gen = || InputTexture {
|
||||||
|
|
|
@ -14,6 +14,7 @@ mod parameters;
|
||||||
|
|
||||||
pub(crate) use chain::FilterCommon;
|
pub(crate) use chain::FilterCommon;
|
||||||
use librashader_common::Viewport;
|
use librashader_common::Viewport;
|
||||||
|
use librashader_pack::ShaderPresetPack;
|
||||||
use librashader_presets::context::VideoDriver;
|
use librashader_presets::context::VideoDriver;
|
||||||
|
|
||||||
/// An OpenGL filter chain.
|
/// An OpenGL filter chain.
|
||||||
|
@ -22,23 +23,33 @@ pub struct FilterChainGL {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilterChainGL {
|
impl FilterChainGL {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
pub unsafe fn load_from_preset(
|
pub unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
ctx: Arc<glow::Context>,
|
ctx: Arc<glow::Context>,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack(preset, ctx, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
|
pub unsafe fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
ctx: Arc<glow::Context>,
|
||||||
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let result = catch_unwind(|| {
|
let result = catch_unwind(|| {
|
||||||
if options.is_some_and(|options| options.use_dsa) {
|
if options.is_some_and(|options| options.use_dsa) {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
filter: FilterChainDispatch::DirectStateAccess(unsafe {
|
filter: FilterChainDispatch::DirectStateAccess(unsafe {
|
||||||
FilterChainImpl::load_from_preset(preset, ctx, options)?
|
FilterChainImpl::load_from_pack(preset, ctx, options)?
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
filter: FilterChainDispatch::Compatibility(unsafe {
|
filter: FilterChainDispatch::Compatibility(unsafe {
|
||||||
FilterChainImpl::load_from_preset(preset, ctx, options)?
|
FilterChainImpl::load_from_pack(preset, ctx, options)?
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,8 +4,8 @@ use crate::gl::LoadLut;
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
use glow::{HasContext, PixelUnpackData};
|
use glow::{HasContext, PixelUnpackData};
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_presets::TextureConfig;
|
use librashader_pack::TextureData;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection};
|
||||||
use librashader_runtime::scaling::MipmapSize;
|
use librashader_runtime::scaling::MipmapSize;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
@ -13,29 +13,31 @@ use std::num::NonZeroU32;
|
||||||
pub struct Gl3LutLoad;
|
pub struct Gl3LutLoad;
|
||||||
impl LoadLut for Gl3LutLoad {
|
impl LoadLut for Gl3LutLoad {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
ctx: &glow::Context,
|
context: &glow::Context,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> Result<FastHashMap<usize, InputTexture>> {
|
) -> Result<FastHashMap<usize, InputTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
let pixel_unpack = unsafe { ctx.get_parameter_i32(glow::PIXEL_UNPACK_BUFFER_BINDING) };
|
let pixel_unpack = unsafe { context.get_parameter_i32(glow::PIXEL_UNPACK_BUFFER_BINDING) };
|
||||||
|
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<std::result::Result<Vec<Image>, ImageError>>()?;
|
.collect::<std::result::Result<Vec<LoadedTexture>, ImageError>>()?;
|
||||||
|
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.iter().enumerate() {
|
||||||
let levels = if texture.meta.mipmap {
|
let levels = if meta.mipmap {
|
||||||
image.size.calculate_miplevels()
|
image.size.calculate_miplevels()
|
||||||
} else {
|
} else {
|
||||||
1u32
|
1u32
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle = unsafe {
|
let handle = unsafe {
|
||||||
let handle = ctx.create_texture().map_err(FilterChainError::GlError)?;
|
let handle = context
|
||||||
|
.create_texture()
|
||||||
|
.map_err(FilterChainError::GlError)?;
|
||||||
|
|
||||||
ctx.bind_texture(glow::TEXTURE_2D, Some(handle));
|
context.bind_texture(glow::TEXTURE_2D, Some(handle));
|
||||||
ctx.tex_storage_2d(
|
context.tex_storage_2d(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
levels as i32,
|
levels as i32,
|
||||||
glow::RGBA8,
|
glow::RGBA8,
|
||||||
|
@ -43,11 +45,11 @@ impl LoadLut for Gl3LutLoad {
|
||||||
image.size.height as i32,
|
image.size.height as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 0);
|
context.pixel_store_i32(glow::UNPACK_ROW_LENGTH, 0);
|
||||||
ctx.pixel_store_i32(glow::UNPACK_ALIGNMENT, 4);
|
context.pixel_store_i32(glow::UNPACK_ALIGNMENT, 4);
|
||||||
ctx.bind_buffer(glow::PIXEL_UNPACK_BUFFER, None);
|
context.bind_buffer(glow::PIXEL_UNPACK_BUFFER, None);
|
||||||
|
|
||||||
ctx.tex_sub_image_2d(
|
context.tex_sub_image_2d(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -61,10 +63,10 @@ impl LoadLut for Gl3LutLoad {
|
||||||
|
|
||||||
let mipmap = levels > 1;
|
let mipmap = levels > 1;
|
||||||
if mipmap {
|
if mipmap {
|
||||||
ctx.generate_mipmap(glow::TEXTURE_2D);
|
context.generate_mipmap(glow::TEXTURE_2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.bind_texture(glow::TEXTURE_2D, None);
|
context.bind_texture(glow::TEXTURE_2D, None);
|
||||||
handle
|
handle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,9 +78,9 @@ impl LoadLut for Gl3LutLoad {
|
||||||
format: glow::RGBA8,
|
format: glow::RGBA8,
|
||||||
size: image.size,
|
size: image.size,
|
||||||
},
|
},
|
||||||
filter: texture.meta.filter_mode,
|
filter: meta.filter_mode,
|
||||||
mip_filter: texture.meta.filter_mode,
|
mip_filter: meta.filter_mode,
|
||||||
wrap_mode: texture.meta.wrap_mode,
|
wrap_mode: meta.wrap_mode,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +91,7 @@ impl LoadLut for Gl3LutLoad {
|
||||||
.ok()
|
.ok()
|
||||||
.map(glow::NativeBuffer);
|
.map(glow::NativeBuffer);
|
||||||
|
|
||||||
ctx.bind_buffer(glow::PIXEL_UNPACK_BUFFER, pixel_unpack);
|
context.bind_buffer(glow::PIXEL_UNPACK_BUFFER, pixel_unpack);
|
||||||
};
|
};
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ use crate::gl::LoadLut;
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
use glow::{HasContext, PixelUnpackData};
|
use glow::{HasContext, PixelUnpackData};
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_presets::TextureConfig;
|
use librashader_pack::TextureData;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection};
|
||||||
use librashader_runtime::scaling::MipmapSize;
|
use librashader_runtime::scaling::MipmapSize;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
|
@ -13,19 +13,19 @@ pub struct Gl46LutLoad;
|
||||||
impl LoadLut for Gl46LutLoad {
|
impl LoadLut for Gl46LutLoad {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
context: &glow::Context,
|
context: &glow::Context,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> Result<FastHashMap<usize, InputTexture>> {
|
) -> Result<FastHashMap<usize, InputTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
|
|
||||||
// don't need this for texture DSA api.
|
// don't need this for texture DSA api.
|
||||||
|
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<std::result::Result<Vec<Image>, ImageError>>()?;
|
.collect::<std::result::Result<Vec<LoadedTexture>, ImageError>>()?;
|
||||||
|
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.iter().enumerate() {
|
||||||
let levels = if texture.meta.mipmap {
|
let levels = if meta.mipmap {
|
||||||
image.size.calculate_miplevels()
|
image.size.calculate_miplevels()
|
||||||
} else {
|
} else {
|
||||||
1u32
|
1u32
|
||||||
|
@ -75,9 +75,9 @@ impl LoadLut for Gl46LutLoad {
|
||||||
format: glow::RGBA8,
|
format: glow::RGBA8,
|
||||||
size: image.size,
|
size: image.size,
|
||||||
},
|
},
|
||||||
filter: texture.meta.filter_mode,
|
filter: meta.filter_mode,
|
||||||
mip_filter: texture.meta.filter_mode,
|
mip_filter: meta.filter_mode,
|
||||||
wrap_mode: texture.meta.wrap_mode,
|
wrap_mode: meta.wrap_mode,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::texture::InputTexture;
|
||||||
pub use framebuffer::GLFramebuffer;
|
pub use framebuffer::GLFramebuffer;
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_presets::{Scale2D, TextureConfig};
|
use librashader_presets::Scale2D;
|
||||||
use librashader_reflect::back::glsl::CrossGlslContext;
|
use librashader_reflect::back::glsl::CrossGlslContext;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
use librashader_reflect::reflect::semantics::{BufferReflection, TextureBinding};
|
use librashader_reflect::reflect::semantics::{BufferReflection, TextureBinding};
|
||||||
|
@ -60,7 +60,7 @@ static FINAL_VBO_DATA: &[VertexInput; 4] = &[
|
||||||
pub(crate) trait LoadLut {
|
pub(crate) trait LoadLut {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
context: &glow::Context,
|
context: &glow::Context,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> Result<FastHashMap<usize, InputTexture>>;
|
) -> Result<FastHashMap<usize, InputTexture>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,3 +172,4 @@ pub(crate) trait GLInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use framebuffer::OutputFramebuffer;
|
pub(crate) use framebuffer::OutputFramebuffer;
|
||||||
|
use librashader_pack::TextureData;
|
||||||
|
|
|
@ -17,6 +17,7 @@ description = "RetroArch shaders for all."
|
||||||
librashader-common = { path = "../librashader-common", features = ["metal"], version = "0.4.5" }
|
librashader-common = { path = "../librashader-common", features = ["metal"], version = "0.4.5" }
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::texture::{get_texture_size, InputTexture, MetalTextureRef, OwnedTextu
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_common::{ImageFormat, Size, Viewport};
|
use librashader_common::{ImageFormat, Size, Viewport};
|
||||||
use librashader_presets::context::VideoDriver;
|
use librashader_presets::context::VideoDriver;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::msl::MslVersion;
|
use librashader_reflect::back::msl::MslVersion;
|
||||||
use librashader_reflect::back::targets::MSL;
|
use librashader_reflect::back::targets::MSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
|
@ -22,7 +22,7 @@ use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::BindingUtil;
|
use librashader_runtime::binding::BindingUtil;
|
||||||
use librashader_runtime::framebuffer::FramebufferInit;
|
use librashader_runtime::framebuffer::FramebufferInit;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection, BGRA8};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||||
|
@ -41,6 +41,7 @@ use std::path::Path;
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::{ShaderPassData, TextureData};
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type ShaderPassMeta =
|
pub type ShaderPassMeta =
|
||||||
|
@ -51,18 +52,20 @@ mod compile {
|
||||||
ShaderPassArtifact<Box<dyn CompileReflectShader<MSL, SpirvCompilation, SpirvCross> + Send>>;
|
ShaderPassArtifact<Box<dyn CompileReflectShader<MSL, SpirvCompilation, SpirvCross> + Send>>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) =
|
let (passes, semantics) = MSL::compile_preset_passes::<
|
||||||
MSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
SpirvCompilation,
|
||||||
shaders, &textures,
|
SpirvCross,
|
||||||
)?;
|
FilterChainError,
|
||||||
|
>(shaders, textures.iter().map(|t| &t.meta))?;
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use compile::{compile_passes, ShaderPassMeta};
|
use compile::{compile_passes, ShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
/// A Metal filter chain.
|
/// A Metal filter chain.
|
||||||
|
@ -119,13 +122,23 @@ impl FilterChainMetal {
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
queue: &ProtocolObject<dyn MTLCommandQueue>,
|
queue: &ProtocolObject<dyn MTLCommandQueue>,
|
||||||
options: Option<&FilterChainOptionsMetal>,
|
options: Option<&FilterChainOptionsMetal>,
|
||||||
|
) -> error::Result<FilterChainMetal> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
Self::load_from_pack(preset, queue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
pub fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
queue: &ProtocolObject<dyn MTLCommandQueue>,
|
||||||
|
options: Option<&FilterChainOptionsMetal>,
|
||||||
) -> error::Result<FilterChainMetal> {
|
) -> error::Result<FilterChainMetal> {
|
||||||
let cmd = queue
|
let cmd = queue
|
||||||
.commandBuffer()
|
.commandBuffer()
|
||||||
.ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
|
.ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
|
||||||
|
|
||||||
let filter_chain =
|
let filter_chain =
|
||||||
Self::load_from_preset_deferred_internal(preset, queue.device(), &cmd, options)?;
|
Self::load_from_pack_deferred_internal(preset, queue.device(), &cmd, options)?;
|
||||||
|
|
||||||
cmd.commit();
|
cmd.commit();
|
||||||
unsafe { cmd.waitUntilCompleted() };
|
unsafe { cmd.waitUntilCompleted() };
|
||||||
|
@ -136,7 +149,7 @@ impl FilterChainMetal {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ProtocolObject<dyn MTLDevice>,
|
device: &ProtocolObject<dyn MTLDevice>,
|
||||||
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
|
|
||||||
|
@ -144,12 +157,12 @@ impl FilterChainMetal {
|
||||||
.blitCommandEncoder()
|
.blitCommandEncoder()
|
||||||
.ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
|
.ok_or(FilterChainError::FailedToCreateCommandBuffer)?;
|
||||||
|
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::<BGRA8>::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::<BGRA8>::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image<BGRA8>>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture<BGRA8>>, ImageError>>()?;
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.into_iter().enumerate() {
|
||||||
let texture = LutTexture::new(device, image, &texture.meta, &mipmapper)?;
|
let texture = LutTexture::new(device, image, &meta, &mipmapper)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +282,8 @@ impl FilterChainMetal {
|
||||||
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||||
options: Option<&FilterChainOptionsMetal>,
|
options: Option<&FilterChainOptionsMetal>,
|
||||||
) -> error::Result<FilterChainMetal> {
|
) -> error::Result<FilterChainMetal> {
|
||||||
Self::load_from_preset_deferred_internal(preset, queue.device(), &cmd, options)
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
Self::load_from_pack_deferred(preset, queue, cmd, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||||
|
@ -279,8 +293,24 @@ impl FilterChainMetal {
|
||||||
/// The provided command buffer must be ready for recording.
|
/// The provided command buffer must be ready for recording.
|
||||||
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||||
fn load_from_preset_deferred_internal(
|
pub fn load_from_pack_deferred(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPresetPack,
|
||||||
|
queue: &ProtocolObject<dyn MTLCommandQueue>,
|
||||||
|
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||||
|
options: Option<&FilterChainOptionsMetal>,
|
||||||
|
) -> error::Result<FilterChainMetal> {
|
||||||
|
Self::load_from_pack_deferred_internal(preset, queue.device(), &cmd, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
/// The provided command buffer must be ready for recording.
|
||||||
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
|
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||||
|
fn load_from_pack_deferred_internal(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
device: Id<ProtocolObject<dyn MTLDevice>>,
|
device: Id<ProtocolObject<dyn MTLDevice>>,
|
||||||
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
cmd: &ProtocolObject<dyn MTLCommandBuffer>,
|
||||||
options: Option<&FilterChainOptionsMetal>,
|
options: Option<&FilterChainOptionsMetal>,
|
||||||
|
@ -290,7 +320,7 @@ impl FilterChainMetal {
|
||||||
let filters = Self::init_passes(&device, passes, &semantics)?;
|
let filters = Self::init_passes(&device, passes, &semantics)?;
|
||||||
|
|
||||||
let samplers = SamplerSet::new(&device)?;
|
let samplers = SamplerSet::new(&device)?;
|
||||||
let luts = FilterChainMetal::load_luts(&device, &cmd, &preset.textures)?;
|
let luts = FilterChainMetal::load_luts(&device, &cmd, preset.textures)?;
|
||||||
let framebuffer_gen = || {
|
let framebuffer_gen = || {
|
||||||
Ok::<_, error::FilterChainError>(OwnedTexture::new(
|
Ok::<_, error::FilterChainError>(OwnedTexture::new(
|
||||||
&device,
|
&device,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::error::{FilterChainError, Result};
|
use crate::error::{FilterChainError, Result};
|
||||||
use crate::texture::InputTexture;
|
use crate::texture::InputTexture;
|
||||||
use librashader_presets::{TextureConfig, TextureMeta};
|
use librashader_presets::TextureMeta;
|
||||||
use librashader_runtime::image::{Image, BGRA8};
|
use librashader_runtime::image::{Image, BGRA8};
|
||||||
use librashader_runtime::scaling::MipmapSize;
|
use librashader_runtime::scaling::MipmapSize;
|
||||||
use objc2::runtime::ProtocolObject;
|
use objc2::runtime::ProtocolObject;
|
||||||
|
|
|
@ -16,6 +16,7 @@ description = "RetroArch shaders for all."
|
||||||
[dependencies]
|
[dependencies]
|
||||||
librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.4.5" }
|
librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.4.5" }
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5" }
|
||||||
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
||||||
|
|
|
@ -18,7 +18,7 @@ use gpu_allocator::vulkan::Allocator;
|
||||||
use librashader_cache::CachedCompilation;
|
use librashader_cache::CachedCompilation;
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_presets::context::VideoDriver;
|
use librashader_presets::context::VideoDriver;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::targets::SPIRV;
|
use librashader_reflect::back::targets::SPIRV;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::SpirvCompilation;
|
use librashader_reflect::front::SpirvCompilation;
|
||||||
|
@ -28,7 +28,7 @@ use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::BindingUtil;
|
use librashader_runtime::binding::BindingUtil;
|
||||||
use librashader_runtime::framebuffer::FramebufferInit;
|
use librashader_runtime::framebuffer::FramebufferInit;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection, BGRA8};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection, BGRA8};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
use librashader_runtime::scaling::ScaleFramebuffer;
|
use librashader_runtime::scaling::ScaleFramebuffer;
|
||||||
|
@ -250,6 +250,7 @@ impl Drop for FrameResiduals {
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::ShaderPassData;
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type ShaderPassMeta =
|
pub type ShaderPassMeta =
|
||||||
|
@ -261,8 +262,8 @@ mod compile {
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
disable_cache: bool,
|
disable_cache: bool,
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) = if !disable_cache {
|
let (passes, semantics) = if !disable_cache {
|
||||||
|
@ -270,10 +271,11 @@ mod compile {
|
||||||
CachedCompilation<SpirvCompilation>,
|
CachedCompilation<SpirvCompilation>,
|
||||||
SpirvCross,
|
SpirvCross,
|
||||||
FilterChainError,
|
FilterChainError,
|
||||||
>(shaders, &textures)?
|
>(shaders, textures.iter().map(|t| &t.meta))?
|
||||||
} else {
|
} else {
|
||||||
SPIRV::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
SPIRV::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
|
||||||
shaders, &textures,
|
shaders,
|
||||||
|
textures.iter().map(|t| &t.meta),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,6 +284,7 @@ mod compile {
|
||||||
}
|
}
|
||||||
|
|
||||||
use compile::{compile_passes, ShaderPassMeta};
|
use compile::{compile_passes, ShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
impl FilterChainVulkan {
|
impl FilterChainVulkan {
|
||||||
|
@ -297,8 +300,7 @@ impl FilterChainVulkan {
|
||||||
{
|
{
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::Vulkan)?;
|
let preset = ShaderPreset::try_parse_with_driver_context(path, VideoDriver::Vulkan)?;
|
||||||
|
unsafe { Self::load_from_preset::<V, E>(preset, vulkan, options) }
|
||||||
unsafe { Self::load_from_preset(preset, vulkan, options) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
|
@ -307,6 +309,20 @@ impl FilterChainVulkan {
|
||||||
vulkan: V,
|
vulkan: V,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan>
|
) -> error::Result<FilterChainVulkan>
|
||||||
|
where
|
||||||
|
V: TryInto<VulkanObjects, Error = E>,
|
||||||
|
FilterChainError: From<E>,
|
||||||
|
{
|
||||||
|
let pack = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack(pack, vulkan, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
|
pub unsafe fn load_from_pack<V, E>(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
vulkan: V,
|
||||||
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
) -> error::Result<FilterChainVulkan>
|
||||||
where
|
where
|
||||||
V: TryInto<VulkanObjects, Error = E>,
|
V: TryInto<VulkanObjects, Error = E>,
|
||||||
FilterChainError: From<E>,
|
FilterChainError: From<E>,
|
||||||
|
@ -342,12 +358,7 @@ impl FilterChainVulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
let filter_chain = unsafe {
|
let filter_chain = unsafe {
|
||||||
Self::load_from_preset_deferred::<_, Infallible>(
|
Self::load_from_pack_deferred::<_, Infallible>(preset, vulkan, command_buffer, options)?
|
||||||
preset,
|
|
||||||
vulkan,
|
|
||||||
command_buffer,
|
|
||||||
options,
|
|
||||||
)?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -378,6 +389,27 @@ impl FilterChainVulkan {
|
||||||
cmd: vk::CommandBuffer,
|
cmd: vk::CommandBuffer,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
) -> error::Result<FilterChainVulkan>
|
) -> error::Result<FilterChainVulkan>
|
||||||
|
where
|
||||||
|
V: TryInto<VulkanObjects, Error = E>,
|
||||||
|
FilterChainError: From<E>,
|
||||||
|
{
|
||||||
|
let pack = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
unsafe { Self::load_from_pack_deferred(pack, vulkan, cmd, options) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed, loaded `ShaderPresetPack`, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
/// The provided command buffer must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
|
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||||
|
pub unsafe fn load_from_pack_deferred<V, E>(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
vulkan: V,
|
||||||
|
cmd: vk::CommandBuffer,
|
||||||
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
) -> error::Result<FilterChainVulkan>
|
||||||
where
|
where
|
||||||
V: TryInto<VulkanObjects, Error = E>,
|
V: TryInto<VulkanObjects, Error = E>,
|
||||||
FilterChainError: From<E>,
|
FilterChainError: From<E>,
|
||||||
|
@ -402,7 +434,7 @@ impl FilterChainVulkan {
|
||||||
disable_cache,
|
disable_cache,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let luts = FilterChainVulkan::load_luts(&device, cmd, &preset.textures)?;
|
let luts = FilterChainVulkan::load_luts(&device, cmd, preset.textures)?;
|
||||||
let samplers = SamplerSet::new(&device.device)?;
|
let samplers = SamplerSet::new(&device.device)?;
|
||||||
|
|
||||||
let framebuffer_gen =
|
let framebuffer_gen =
|
||||||
|
@ -527,15 +559,15 @@ impl FilterChainVulkan {
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
vulkan: &VulkanObjects,
|
vulkan: &VulkanObjects,
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
let images = textures
|
let textures = textures
|
||||||
.par_iter()
|
.into_par_iter()
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image<BGRA8>>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture<BGRA8>>, ImageError>>()?;
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.into_iter().enumerate() {
|
||||||
let texture = LutTexture::new(vulkan, command_buffer, image, &texture.meta)?;
|
let texture = LutTexture::new(vulkan, command_buffer, image, &meta)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
|
|
|
@ -17,6 +17,7 @@ description = "RetroArch shaders for all."
|
||||||
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.4.5" }
|
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.4.5" }
|
||||||
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
librashader-presets = { path = "../librashader-presets", version = "0.4.5" }
|
||||||
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
librashader-preprocess = { path = "../librashader-preprocess", version = "0.4.5" }
|
||||||
|
librashader-pack = { path = "../librashader-pack", version = "0.4.5" }
|
||||||
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5", features = ["wgsl"], default-features = false }
|
librashader-reflect = { path = "../librashader-reflect", version = "0.4.5", features = ["wgsl"], default-features = false }
|
||||||
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
librashader-runtime = { path = "../librashader-runtime" , version = "0.4.5" }
|
||||||
librashader-cache = { path = "../librashader-cache", version = "0.4.5" }
|
librashader-cache = { path = "../librashader-cache", version = "0.4.5" }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use librashader_common::map::FastHashMap;
|
use librashader_common::map::FastHashMap;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::ShaderPreset;
|
||||||
use librashader_reflect::back::targets::WGSL;
|
use librashader_reflect::back::targets::WGSL;
|
||||||
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
use librashader_reflect::back::{CompileReflectShader, CompileShader};
|
||||||
use librashader_reflect::front::SpirvCompilation;
|
use librashader_reflect::front::SpirvCompilation;
|
||||||
|
@ -7,7 +7,7 @@ use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtif
|
||||||
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
use librashader_reflect::reflect::semantics::ShaderSemantics;
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use librashader_runtime::binding::BindingUtil;
|
use librashader_runtime::binding::BindingUtil;
|
||||||
use librashader_runtime::image::{Image, ImageError, UVDirection};
|
use librashader_runtime::image::{ImageError, LoadedTexture, UVDirection};
|
||||||
use librashader_runtime::quad::QuadType;
|
use librashader_runtime::quad::QuadType;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
@ -40,6 +40,7 @@ use crate::texture::{InputImage, OwnedImage};
|
||||||
|
|
||||||
mod compile {
|
mod compile {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use librashader_pack::{ShaderPassData, TextureData};
|
||||||
|
|
||||||
#[cfg(not(feature = "stable"))]
|
#[cfg(not(feature = "stable"))]
|
||||||
pub type ShaderPassMeta =
|
pub type ShaderPassMeta =
|
||||||
|
@ -50,18 +51,20 @@ mod compile {
|
||||||
ShaderPassArtifact<Box<dyn CompileReflectShader<WGSL, SpirvCompilation, Naga> + Send>>;
|
ShaderPassArtifact<Box<dyn CompileReflectShader<WGSL, SpirvCompilation, Naga> + Send>>;
|
||||||
|
|
||||||
pub fn compile_passes(
|
pub fn compile_passes(
|
||||||
shaders: Vec<ShaderPassConfig>,
|
shaders: Vec<ShaderPassData>,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureData],
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
|
||||||
let (passes, semantics) =
|
let (passes, semantics) = WGSL::compile_preset_passes::<
|
||||||
WGSL::compile_preset_passes::<SpirvCompilation, Naga, FilterChainError>(
|
SpirvCompilation,
|
||||||
shaders, &textures,
|
Naga,
|
||||||
)?;
|
FilterChainError,
|
||||||
|
>(shaders, textures.iter().map(|t| &t.meta))?;
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use compile::{compile_passes, ShaderPassMeta};
|
use compile::{compile_passes, ShaderPassMeta};
|
||||||
|
use librashader_pack::{ShaderPresetPack, TextureData};
|
||||||
use librashader_runtime::parameters::RuntimeParameters;
|
use librashader_runtime::parameters::RuntimeParameters;
|
||||||
|
|
||||||
/// A wgpu filter chain.
|
/// A wgpu filter chain.
|
||||||
|
@ -109,11 +112,22 @@ impl FilterChainWgpu {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue: Arc<wgpu::Queue>,
|
queue: Arc<wgpu::Queue>,
|
||||||
options: Option<&FilterChainOptionsWgpu>,
|
options: Option<&FilterChainOptionsWgpu>,
|
||||||
|
) -> error::Result<FilterChainWgpu> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
Self::load_from_pack(preset, device, queue, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed and loaded `ShaderPresetPack`.
|
||||||
|
pub fn load_from_pack(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: Arc<Device>,
|
||||||
|
queue: Arc<wgpu::Queue>,
|
||||||
|
options: Option<&FilterChainOptionsWgpu>,
|
||||||
) -> error::Result<FilterChainWgpu> {
|
) -> error::Result<FilterChainWgpu> {
|
||||||
let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
let mut cmd = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
label: Some("librashader load cmd"),
|
label: Some("librashader load cmd"),
|
||||||
});
|
});
|
||||||
let filter_chain = Self::load_from_preset_deferred(
|
let filter_chain = Self::load_from_pack_deferred(
|
||||||
preset,
|
preset,
|
||||||
Arc::clone(&device),
|
Arc::clone(&device),
|
||||||
Arc::clone(&queue),
|
Arc::clone(&queue),
|
||||||
|
@ -143,6 +157,24 @@ impl FilterChainWgpu {
|
||||||
queue: Arc<wgpu::Queue>,
|
queue: Arc<wgpu::Queue>,
|
||||||
cmd: &mut wgpu::CommandEncoder,
|
cmd: &mut wgpu::CommandEncoder,
|
||||||
options: Option<&FilterChainOptionsWgpu>,
|
options: Option<&FilterChainOptionsWgpu>,
|
||||||
|
) -> error::Result<FilterChainWgpu> {
|
||||||
|
let preset = ShaderPresetPack::load_from_preset::<FilterChainError>(preset)?;
|
||||||
|
Self::load_from_pack_deferred(preset, device, queue, cmd, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a filter chain from a pre-parsed `ShaderPreset`, deferring and GPU-side initialization
|
||||||
|
/// to the caller. This function therefore requires no external synchronization of the device queue.
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
/// The provided command buffer must be ready for recording and contain no prior commands.
|
||||||
|
/// The caller is responsible for ending the command buffer and immediately submitting it to a
|
||||||
|
/// graphics queue. The command buffer must be completely executed before calling [`frame`](Self::frame).
|
||||||
|
pub fn load_from_pack_deferred(
|
||||||
|
preset: ShaderPresetPack,
|
||||||
|
device: Arc<Device>,
|
||||||
|
queue: Arc<wgpu::Queue>,
|
||||||
|
cmd: &mut wgpu::CommandEncoder,
|
||||||
|
options: Option<&FilterChainOptionsWgpu>,
|
||||||
) -> error::Result<FilterChainWgpu> {
|
) -> error::Result<FilterChainWgpu> {
|
||||||
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?;
|
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
|
@ -166,7 +198,7 @@ impl FilterChainWgpu {
|
||||||
cmd,
|
cmd,
|
||||||
&mut mipmapper,
|
&mut mipmapper,
|
||||||
&samplers,
|
&samplers,
|
||||||
&preset.textures,
|
preset.textures,
|
||||||
)?;
|
)?;
|
||||||
//
|
//
|
||||||
let framebuffer_gen = || {
|
let framebuffer_gen = || {
|
||||||
|
@ -226,29 +258,21 @@ impl FilterChainWgpu {
|
||||||
cmd: &mut wgpu::CommandEncoder,
|
cmd: &mut wgpu::CommandEncoder,
|
||||||
mipmapper: &mut MipmapGen,
|
mipmapper: &mut MipmapGen,
|
||||||
sampler_set: &SamplerSet,
|
sampler_set: &SamplerSet,
|
||||||
textures: &[TextureConfig],
|
textures: Vec<TextureData>,
|
||||||
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
) -> error::Result<FastHashMap<usize, LutTexture>> {
|
||||||
let mut luts = FastHashMap::default();
|
let mut luts = FastHashMap::default();
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let images_iter = textures.par_iter();
|
let images_iter = textures.into_par_iter();
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
let images_iter = textures.iter();
|
let images_iter = textures.into_iter();
|
||||||
|
|
||||||
let images = images_iter
|
let textures = images_iter
|
||||||
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
|
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
|
||||||
.collect::<Result<Vec<Image>, ImageError>>()?;
|
.collect::<Result<Vec<LoadedTexture>, ImageError>>()?;
|
||||||
for (index, (texture, image)) in textures.iter().zip(images).enumerate() {
|
for (index, LoadedTexture { meta, image }) in textures.into_iter().enumerate() {
|
||||||
let texture = LutTexture::new(
|
let texture = LutTexture::new(device, queue, cmd, image, &meta, mipmapper, sampler_set);
|
||||||
device,
|
|
||||||
queue,
|
|
||||||
cmd,
|
|
||||||
image,
|
|
||||||
&texture.meta,
|
|
||||||
mipmapper,
|
|
||||||
sampler_set,
|
|
||||||
);
|
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
|
|
|
@ -4,8 +4,9 @@ use std::marker::PhantomData;
|
||||||
|
|
||||||
use image::error::{LimitError, LimitErrorKind};
|
use image::error::{LimitError, LimitErrorKind};
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
use librashader_pack::TextureBuffer;
|
use librashader_pack::{TextureBuffer, TextureData};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use librashader_presets::TextureMeta;
|
||||||
|
|
||||||
/// An uncompressed raw image ready to upload to GPU buffers.
|
/// An uncompressed raw image ready to upload to GPU buffers.
|
||||||
pub struct Image<P: PixelFormat = RGBA8> {
|
pub struct Image<P: PixelFormat = RGBA8> {
|
||||||
|
@ -116,6 +117,25 @@ impl<P: PixelFormat> Image<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loaded texture data in the proper pixel format from a [`TextureData`].
|
||||||
|
pub struct LoadedTexture<P: PixelFormat = RGBA8> {
|
||||||
|
/// The loaded image data
|
||||||
|
pub image: Image<P>,
|
||||||
|
/// Meta information about the texture
|
||||||
|
pub meta: TextureMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <P: PixelFormat> LoadedTexture<P> {
|
||||||
|
/// Load the texture with the given UV direction and subpixel ordering.
|
||||||
|
pub fn from_texture(texture: TextureData, direction: UVDirection) -> Result<Self, ImageError> {
|
||||||
|
Ok(LoadedTexture {
|
||||||
|
meta: texture.meta,
|
||||||
|
image: Image::load_from_buffer(texture.data, direction)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// load-bearing #[inline(always)], without it llvm will not vectorize.
|
// load-bearing #[inline(always)], without it llvm will not vectorize.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn swizzle_pixels(pixels: &mut Vec<u8>, swizzle: &'static [usize; 32]) {
|
fn swizzle_pixels(pixels: &mut Vec<u8>, swizzle: &'static [usize; 32]) {
|
||||||
|
|
Loading…
Reference in a new issue