Skip to content

Commit

Permalink
rt: implement filter chain loading in terms of pack
Browse files Browse the repository at this point in the history
  • Loading branch information
chyyran committed Oct 2, 2024
1 parent 877238a commit 7fc724d
Show file tree
Hide file tree
Showing 26 changed files with 414 additions and 194 deletions.
10 changes: 9 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion librashader-pack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ description = "RetroArch shaders for all."
[dependencies]
librashader-presets = { path = "../librashader-presets", 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"
serde = { version = "1.0", features = ["derive"], optional = true }
Expand Down
1 change: 0 additions & 1 deletion librashader-pack/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ impl LoadableResource for TextureMeta {
/// The configuration for a single shader pass.
pub type ShaderPassData = ShaderPresetResource<ShaderPassMeta>;
pub type TextureData = ShaderPresetResource<TextureMeta>;

/// A shader preset, not reliant on disk, with all information needed.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand Down
1 change: 1 addition & 0 deletions librashader-reflect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ bitflags = "2.4.2"
librashader-common = { path = "../librashader-common", version = "0.4.5" }
librashader-preprocess = { path = "../librashader-preprocess", 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 }

Expand Down
30 changes: 15 additions & 15 deletions librashader-reflect/src/reflect/presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use crate::reflect::semantics::{
Semantic, ShaderSemantics, TextureSemantics, UniformSemantic, UniqueSemantics,
};
use librashader_common::map::{FastHashMap, ShortString};
use librashader_pack::ShaderPassData;
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.
///
Expand Down Expand Up @@ -36,9 +37,9 @@ impl<T: OutputTarget> CompilePresetTarget for T {}
pub trait CompilePresetTarget: OutputTarget {
/// Compile passes of a shader preset given the applicable
/// shader output target, compilation type, and resulting error.
fn compile_preset_passes<I, R, E>(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
fn compile_preset_passes<'a, I, R, E>(
passes: Vec<ShaderPassData>,
textures: impl Iterator<Item = &'a TextureMeta>,
) -> Result<
(
Vec<ShaderPassArtifact<<Self as FromCompilation<I, R>>::Output>>,
Expand All @@ -61,9 +62,9 @@ pub trait CompilePresetTarget: OutputTarget {

/// Compile passes of a shader preset given the applicable
/// shader output target, compilation type, and resulting error.
fn compile_preset_passes<T, I, R, E>(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
fn compile_preset_passes<'a, T, I, R, E>(
passes: Vec<ShaderPassData>,
textures: impl Iterator<Item = &'a TextureMeta>,
) -> Result<
(
Vec<ShaderPassArtifact<<T as FromCompilation<I, R>>::Output>>,
Expand All @@ -87,8 +88,7 @@ where
let passes = passes
.into_iter()
.map(|shader| {
let source: ShaderSource = ShaderSource::load(&shader.path)?;

let source = shader.data;
let compiled = I::Compiler::compile(&source)?;
let reflect = T::from_compilation(compiled)?;

Expand Down Expand Up @@ -188,17 +188,17 @@ fn insert_pass_semantics(
}

/// Insert the available semantics for the input texture config into the provided semantic maps.
fn insert_lut_semantics(
textures: &[TextureConfig],
fn insert_lut_semantics<'a>(
textures: impl Iterator<Item = &'a TextureMeta>,
uniform_semantics: &mut FastHashMap<ShortString, UniformSemantic>,
texture_semantics: &mut FastHashMap<ShortString, Semantic<TextureSemantics>>,
) {
for (index, texture) in textures.iter().enumerate() {
let mut size_semantic = texture.meta.name.clone();
for (index, texture) in textures.enumerate() {
let mut size_semantic = texture.name.clone();
size_semantic.push_str("Size");

texture_semantics.insert(
texture.meta.name.clone(),
texture.name.clone(),
Semantic {
semantics: TextureSemantics::User,
index,
Expand Down Expand Up @@ -261,7 +261,7 @@ impl ShaderSemantics {
config.meta.id as usize,
);
insert_lut_semantics(
preset.textures.as_slice(),
preset.textures.iter().map(|t| &t.meta),
&mut uniform_semantics,
&mut texture_semantics,
);
Expand Down
1 change: 1 addition & 0 deletions librashader-runtime-d3d11/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ description = "RetroArch shaders for all."
librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.4.5" }
librashader-presets = { path = "../librashader-presets", 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-runtime = { path = "../librashader-runtime", version = "0.4.5" }
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }
Expand Down
70 changes: 54 additions & 16 deletions librashader-runtime-d3d11/src/filter_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use crate::texture::InputTexture;
use librashader_common::{ImageFormat, Size, Viewport};

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::{CompileReflectShader, CompileShader};
use librashader_reflect::front::SpirvCompilation;
use librashader_reflect::reflect::semantics::ShaderSemantics;
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::path::Path;
Expand Down Expand Up @@ -75,6 +75,7 @@ pub(crate) struct FilterCommon {

mod compile {
use super::*;
use librashader_pack::{ShaderPassData, TextureData};

#[cfg(not(feature = "stable"))]
pub type ShaderPassMeta =
Expand All @@ -86,19 +87,20 @@ mod compile {
>;

pub fn compile_passes(
shaders: Vec<ShaderPassConfig>,
textures: &[TextureConfig],
shaders: Vec<ShaderPassData>,
textures: &[TextureData],
disable_cache: bool,
) -> Result<(Vec<ShaderPassMeta>, ShaderSemantics), FilterChainError> {
let (passes, semantics) = if !disable_cache {
HLSL::compile_preset_passes::<
CachedCompilation<SpirvCompilation>,
SpirvCross,
FilterChainError,
>(shaders, &textures)?
>(shaders, textures.iter().map(|t| &t.meta))?
} else {
HLSL::compile_preset_passes::<SpirvCompilation, SpirvCross, FilterChainError>(
shaders, &textures,
shaders,
textures.iter().map(|t| &t.meta),
)?
};

Expand All @@ -107,6 +109,7 @@ mod compile {
}

use compile::{compile_passes, ShaderPassMeta};
use librashader_pack::{ShaderPresetPack, TextureData};
use librashader_runtime::parameters::RuntimeParameters;

impl FilterChainD3D11 {
Expand All @@ -132,6 +135,16 @@ impl FilterChainD3D11 {
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
/// 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,
Expand All @@ -152,6 +165,31 @@ impl FilterChainD3D11 {
device: &ID3D11Device,
ctx: &ID3D11DeviceContext,
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> {
let disable_cache = options.map_or(false, |o| o.disable_cache);

Expand All @@ -165,7 +203,7 @@ impl FilterChainD3D11 {
let immediate_context = unsafe { device.GetImmediateContext()? };

// load luts
let luts = FilterChainD3D11::load_luts(device, &ctx, &preset.textures)?;
let luts = FilterChainD3D11::load_luts(device, &ctx, preset.textures)?;

let framebuffer_gen =
|| OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false);
Expand Down Expand Up @@ -361,21 +399,21 @@ impl FilterChainD3D11 {
fn load_luts(
device: &ID3D11Device,
context: &ID3D11DeviceContext,
textures: &[TextureConfig],
textures: Vec<TextureData>,
) -> error::Result<FastHashMap<usize, LutTexture>> {
let mut luts = FastHashMap::default();
let images = textures
.par_iter()
.map(|texture| Image::load(&texture.path, UVDirection::TopLeft))
.collect::<Result<Vec<Image>, ImageError>>()?;
let textures = textures
.into_par_iter()
.map(|texture| LoadedTexture::from_texture(texture, UVDirection::TopLeft))
.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 {
Width: image.size.width,
Height: image.size.height,
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
Usage: D3D11_USAGE_DEFAULT,
MiscFlags: if texture.meta.mipmap {
MiscFlags: if meta.mipmap {
D3D11_RESOURCE_MISC_GENERATE_MIPS.0 as u32
} else {
0
Expand All @@ -388,8 +426,8 @@ impl FilterChainD3D11 {
context,
&image,
desc,
texture.meta.filter_mode,
texture.meta.wrap_mode,
meta.filter_mode,
meta.wrap_mode,
)?;
luts.insert(index, texture);
}
Expand Down
1 change: 1 addition & 0 deletions librashader-runtime-d3d12/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ librashader-common = { path = "../librashader-common", features = ["d3d12"], ver
librashader-presets = { path = "../librashader-presets", 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-pack = { path = "../librashader-pack", version = "0.4.5" }
librashader-runtime = { path = "../librashader-runtime", version = "0.4.5" }
librashader-cache = { path = "../librashader-cache", version = "0.4.5", features = ["d3d"] }

Expand Down
Loading

0 comments on commit 7fc724d

Please sign in to comment.