diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index a875303..7d50221 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index e0258f0..91b80a2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1162,15 +1162,6 @@ dependencies = [
"windows",
]
-[[package]]
-name = "librashader-common"
-version = "0.1.0-rc.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ff30c28bf8007f8061a3e429378a5d3682e61d15fe81825c9e5076a3091e349"
-dependencies = [
- "num-traits",
-]
-
[[package]]
name = "librashader-common"
version = "0.1.0-rc.3"
@@ -1181,6 +1172,15 @@ dependencies = [
"windows",
]
+[[package]]
+name = "librashader-common"
+version = "0.1.0-rc.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e22634fcfd3d0307db6d31366bb6bdd4422ec18a889a18ebe5572e47f366989"
+dependencies = [
+ "num-traits",
+]
+
[[package]]
name = "librashader-preprocess"
version = "0.1.0-rc.3"
@@ -1188,7 +1188,7 @@ dependencies = [
"encoding_rs",
"glob",
"librashader-common 0.1.0-rc.3",
- "librashader-presets 0.1.0-rc.2",
+ "librashader-presets 0.1.0-rc.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nom",
"rayon",
"rustc-hash",
@@ -1197,11 +1197,10 @@ dependencies = [
[[package]]
name = "librashader-presets"
-version = "0.1.0-rc.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de7bfd6903b4c52db1d220cb67d9e618ba87922300893586b2cf360b7591bde6"
+version = "0.1.0-rc.3"
dependencies = [
- "librashader-common 0.1.0-rc.2",
+ "glob",
+ "librashader-common 0.1.0-rc.3",
"nom",
"nom_locate",
"num-traits",
@@ -1211,9 +1210,10 @@ dependencies = [
[[package]]
name = "librashader-presets"
version = "0.1.0-rc.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ba84e8b4fdb76114d56f0ad2118e2cfbdde0666dd95e657afa4803c6f19bfee"
dependencies = [
- "glob",
- "librashader-common 0.1.0-rc.3",
+ "librashader-common 0.1.0-rc.3 (registry+https://github.com/rust-lang/crates.io-index)",
"nom",
"nom_locate",
"num-traits",
diff --git a/librashader-cache/Cargo.toml b/librashader-cache/Cargo.toml
index 006564e..a2d3cf9 100644
--- a/librashader-cache/Cargo.toml
+++ b/librashader-cache/Cargo.toml
@@ -12,8 +12,8 @@ description = "RetroArch shaders for all."
[dependencies]
serde = { version = "1.0" }
-librashader-reflect = { path = "../librashader-reflect", version = "0.1.0-rc.2", features = ["serialize", "dxil"] }
-librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.0-rc.2" }
+librashader-reflect = { path = "../librashader-reflect", version = "0.1.0-rc.3", features = ["serialize", "dxil"] }
+librashader-preprocess = { path = "../librashader-preprocess", version = "0.1.0-rc.3" }
platform-dirs = "0.3.0"
blake3 = { version = "1.3.3", features = ["rayon"] }
thiserror = "1.0.38"
diff --git a/librashader-cache/src/cache.rs b/librashader-cache/src/cache.rs
index d617366..65920b8 100644
--- a/librashader-cache/src/cache.rs
+++ b/librashader-cache/src/cache.rs
@@ -5,7 +5,7 @@ use rusqlite::{params, Connection, DatabaseName};
use std::error::Error;
use std::path::PathBuf;
-pub fn get_cache_dir() -> Result> {
+pub(crate) fn get_cache_dir() -> Result> {
let cache_dir =
if let Some(cache_dir) = AppDirs::new(Some("librashader"), false).map(|a| a.cache_dir) {
cache_dir
@@ -20,7 +20,7 @@ pub fn get_cache_dir() -> Result> {
Ok(cache_dir)
}
-pub fn get_cache() -> Result> {
+pub(crate) fn get_cache() -> Result> {
let cache_dir = get_cache_dir()?;
let mut conn = Connection::open(&cache_dir.join("librashader.db"))?;
@@ -62,55 +62,29 @@ pub(crate) fn set_blob(conn: &Connection, index: &str, key: &[u8], value: &[u8])
}
}
-pub fn get_cached_blob(
- index: &str,
- key: &[H; KEY_SIZE],
- transform: impl FnOnce(Vec) -> T,
-) -> Option
-where
- H: CacheKey,
-{
- let cache = get_cache();
-
- let Ok(cache) = cache else {
- return None
- };
-
- let key = {
- let mut hasher = blake3::Hasher::new();
- for subkeys in key {
- hasher.update(subkeys.hash_bytes());
- }
- let hash = hasher.finalize();
- hash
- };
-
- let Ok(blob) = get_blob(&cache, index, key.as_bytes()) else {
- return None;
- };
-
- Some(transform(blob))
-}
-
-pub fn cache_object(
+/// Cache a shader object (usually bytecode) created by the keyed objects.
+///
+/// - `factory` is the function that compiles the values passed as keys to a shader object.
+/// - `load` tries to load a compiled shader object to a driver-specialized result.
+pub fn cache_shader_object(
index: &str,
keys: &[H; KEY_SIZE],
factory: impl FnOnce(&[H; KEY_SIZE]) -> Result,
- attempt: impl Fn(T) -> Result,
- do_cache: bool,
+ load: impl Fn(T) -> Result,
+ bypass_cache: bool,
) -> Result
where
H: CacheKey,
T: Cacheable,
{
- if !do_cache {
- return Ok(attempt(factory(keys)?)?);
+ if bypass_cache {
+ return Ok(load(factory(keys)?)?);
}
let cache = get_cache();
let Ok(cache) = cache else {
- return Ok(attempt(factory(keys)?)?);
+ return Ok(load(factory(keys)?)?);
};
let hashkey = {
@@ -124,7 +98,7 @@ where
'attempt: {
if let Ok(blob) = get_blob(&cache, index, hashkey.as_bytes()) {
- let cached = T::from_bytes(&blob).map(&attempt);
+ let cached = T::from_bytes(&blob).map(&load);
match cached {
None => break 'attempt,
@@ -139,27 +113,34 @@ where
if let Some(slice) = T::to_bytes(&blob) {
set_blob(&cache, index, hashkey.as_bytes(), &slice);
}
- Ok(attempt(blob)?)
+ Ok(load(blob)?)
}
+/// Cache a pipeline state object.
+///
+/// Keys are not used to create the object and are only used to uniquely identify the pipeline state.
+///
+/// - `restore_pipeline` tries to restore the pipeline with either a cached binary pipeline state
+/// cache, or create a new pipeline if no cached value is available.
+/// - `fetch_pipeline_state` fetches the new pipeline state cache after the pipeline was created.
pub fn cache_pipeline(
index: &str,
keys: &[&dyn CacheKey; KEY_SIZE],
- attempt: impl Fn(Option>) -> Result,
- factory: impl FnOnce(&R) -> Result,
- do_cache: bool,
+ restore_pipeline: impl Fn(Option>) -> Result,
+ fetch_pipeline_state: impl FnOnce(&R) -> Result,
+ bypass_cache: bool,
) -> Result
where
T: Cacheable,
{
- if !do_cache {
- return Ok(attempt(None)?);
+ if bypass_cache {
+ return Ok(restore_pipeline(None)?);
}
let cache = get_cache();
let Ok(cache) = cache else {
- return Ok(attempt(None)?);
+ return Ok(restore_pipeline(None)?);
};
let hashkey = {
@@ -173,7 +154,7 @@ where
let pipeline = 'attempt: {
if let Ok(blob) = get_blob(&cache, index, hashkey.as_bytes()) {
- let cached = attempt(Some(blob));
+ let cached = restore_pipeline(Some(blob));
match cached {
Ok(res) => {
break 'attempt res;
@@ -182,11 +163,11 @@ where
}
}
- attempt(None)?
+ restore_pipeline(None)?
};
// update the pso every time just in case.
- if let Ok(state) = factory(&pipeline) {
+ if let Ok(state) = fetch_pipeline_state(&pipeline) {
if let Some(slice) = T::to_bytes(&state) {
set_blob(&cache, index, hashkey.as_bytes(), &slice);
}
diff --git a/librashader-cache/src/cacheable.rs b/librashader-cache/src/cacheable.rs
index 55ca531..45acf53 100644
--- a/librashader-cache/src/cacheable.rs
+++ b/librashader-cache/src/cacheable.rs
@@ -1,3 +1,4 @@
+/// Trait for objects that are cacheable.
pub trait Cacheable {
fn from_bytes(bytes: &[u8]) -> Option
where
diff --git a/librashader-cache/src/compilation.rs b/librashader-cache/src/compilation.rs
index 8247c24..65ea665 100644
--- a/librashader-cache/src/compilation.rs
+++ b/librashader-cache/src/compilation.rs
@@ -1,3 +1,4 @@
+//! Cache helpers for `ShaderCompilation` objects to cache compiled SPIRV.
use crate::cache::{get_blob, get_cache, set_blob};
use librashader_preprocess::ShaderSource;
use librashader_reflect::back::targets::{DXIL, GLSL, HLSL, SPIRV};
diff --git a/librashader-cache/src/error.rs b/librashader-cache/src/error.rs
deleted file mode 100644
index 8d291c7..0000000
--- a/librashader-cache/src/error.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use std::error::Error;
-use thiserror::Error;
-
-#[derive(Debug, Error)]
-pub enum CacheError {
- #[error("serde error")]
- SerdeError,
- #[error("unknown error")]
- UnknownError(#[from] Box),
-}
diff --git a/librashader-cache/src/lib.rs b/librashader-cache/src/lib.rs
index 3b61ba7..ff2c41c 100644
--- a/librashader-cache/src/lib.rs
+++ b/librashader-cache/src/lib.rs
@@ -2,20 +2,18 @@
//!
//! This crate is exempt from semantic versioning guarantees and is an implementation
//! detail of librashader runtimes.
-#![feature(try_blocks)]
-#![feature(once_cell)]
-pub mod cache;
-pub mod compilation;
-pub mod error;
+mod cache;
+mod compilation;
mod key;
mod cacheable;
-#[cfg(test)]
-mod tests {}
-
pub use cacheable::Cacheable;
pub use key::CacheKey;
+pub use compilation::CachedCompilation;
+pub use cache::cache_pipeline;
+pub use cache::cache_shader_object;
+
#[cfg(all(target_os = "windows", feature = "d3d"))]
mod d3d;
diff --git a/librashader-preprocess/Cargo.toml b/librashader-preprocess/Cargo.toml
index d1aab03..af13d32 100644
--- a/librashader-preprocess/Cargo.toml
+++ b/librashader-preprocess/Cargo.toml
@@ -23,6 +23,6 @@ default = [ "line_directives" ]
line_directives = []
[dev-dependencies]
-librashader-presets = "0.1.0-beta.16"
+librashader-presets = "0.1.0-rc.3"
glob = "0.3.1"
rayon = "1.6.1"
diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs
index 080d34c..912078f 100644
--- a/librashader-runtime-d3d11/src/filter_chain.rs
+++ b/librashader-runtime-d3d11/src/filter_chain.rs
@@ -22,8 +22,8 @@ use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
use crate::samplers::SamplerSet;
use crate::util::d3d11_compile_bound_shader;
use crate::{error, util, D3D11OutputView};
-use librashader_cache::cache::cache_object;
-use librashader_cache::compilation::CachedCompilation;
+use librashader_cache::cache_shader_object;
+use librashader_cache::CachedCompilation;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_runtime::binding::{BindingUtil, TextureInput};
use librashader_runtime::framebuffer::FramebufferInit;
@@ -230,7 +230,7 @@ impl FilterChainD3D11 {
let reflection = reflect.reflect(index, semantics)?;
let hlsl = reflect.compile(None)?;
- let (vs, vertex_dxbc) = cache_object(
+ let (vs, vertex_dxbc) = cache_shader_object(
"dxbc",
&[hlsl.vertex.as_bytes()],
|&[bytes]| util::d3d_compile_shader(bytes, b"main\0", b"vs_5_0\0"),
@@ -245,20 +245,20 @@ impl FilterChainD3D11 {
blob,
))
},
- !disable_cache,
+ disable_cache,
)?;
let ia_desc = DrawQuad::get_spirv_cross_vbo_desc();
let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxbc)?;
- let ps = cache_object(
+ let ps = cache_shader_object(
"dxbc",
&[hlsl.fragment.as_bytes()],
|&[bytes]| util::d3d_compile_shader(bytes, b"main\0", b"ps_5_0\0"),
|blob| {
d3d11_compile_bound_shader(device, &blob, None, ID3D11Device::CreatePixelShader)
},
- !disable_cache,
+ disable_cache,
)?;
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs
index 89533f8..0d81a8c 100644
--- a/librashader-runtime-d3d12/src/filter_chain.rs
+++ b/librashader-runtime-d3d12/src/filter_chain.rs
@@ -46,7 +46,7 @@ use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN;
use windows::Win32::System::Threading::{CreateEventA, WaitForSingleObject};
use windows::Win32::System::WindowsProgramming::INFINITE;
-use librashader_cache::compilation::CachedCompilation;
+use librashader_cache::CachedCompilation;
use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer;
diff --git a/librashader-runtime-d3d12/src/graphics_pipeline.rs b/librashader-runtime-d3d12/src/graphics_pipeline.rs
index 908ae26..944a58e 100644
--- a/librashader-runtime-d3d12/src/graphics_pipeline.rs
+++ b/librashader-runtime-d3d12/src/graphics_pipeline.rs
@@ -2,7 +2,7 @@ use crate::error::assume_d3d12_init;
use crate::error::FilterChainError::Direct3DOperationError;
use crate::quad_render::DrawQuad;
use crate::{error, util};
-use librashader_cache::cache::{cache_object, cache_pipeline};
+use librashader_cache::{cache_shader_object, cache_pipeline};
use librashader_reflect::back::cross::CrossHlslContext;
use librashader_reflect::back::dxil::DxilObject;
use librashader_reflect::back::ShaderCompilerOutput;
@@ -248,7 +248,7 @@ impl D3D12GraphicsPipeline {
let cached_pso = pso.GetCachedBlob()?;
Ok(cached_pso)
},
- !disable_cache,
+ disable_cache,
)?
};
@@ -324,20 +324,20 @@ impl D3D12GraphicsPipeline {
));
}
- let vertex_dxil = cache_object(
+ let vertex_dxil = cache_shader_object(
"dxil",
&[shader_assembly.vertex.deref()],
|&[source]| util::dxc_validate_shader(library, validator, source),
|f| Ok(f),
- !disable_cache,
+ disable_cache,
)?;
- let fragment_dxil = cache_object(
+ let fragment_dxil = cache_shader_object(
"dxil",
&[shader_assembly.fragment.deref()],
|&[source]| util::dxc_validate_shader(library, validator, source),
|f| Ok(f),
- !disable_cache,
+ disable_cache,
)?;
Self::new_from_blobs(
@@ -359,20 +359,20 @@ impl D3D12GraphicsPipeline {
render_format: DXGI_FORMAT,
disable_cache: bool,
) -> error::Result {
- let vertex_dxil = cache_object(
+ let vertex_dxil = cache_shader_object(
"dxil",
&[shader_assembly.vertex.as_bytes()],
|&[source]| util::dxc_compile_shader(library, dxc, source, u16cstr!("vs_6_0")),
|f| Ok(f),
- !disable_cache,
+ disable_cache,
)?;
- let fragment_dxil = cache_object(
+ let fragment_dxil = cache_shader_object(
"dxil",
&[shader_assembly.fragment.as_bytes()],
|&[source]| util::dxc_compile_shader(library, dxc, source, u16cstr!("ps_6_0")),
|f| Ok(f),
- !disable_cache,
+ disable_cache,
)?;
Self::new_from_blobs(
diff --git a/librashader-runtime-gl/src/filter_chain/filter_impl.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs
index 6db4bfa..8ce15c0 100644
--- a/librashader-runtime-gl/src/filter_chain/filter_impl.rs
+++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs
@@ -19,7 +19,7 @@ use librashader_reflect::back::{CompileReflectShader, CompileShader};
use librashader_reflect::front::GlslangCompilation;
use librashader_reflect::reflect::semantics::{ShaderSemantics, UniformMeta};
-use librashader_cache::compilation::CachedCompilation;
+use librashader_cache::CachedCompilation;
use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact};
use librashader_reflect::reflect::ReflectShader;
use librashader_runtime::binding::BindingUtil;
diff --git a/librashader-runtime-gl/src/gl/gl46/compile_program.rs b/librashader-runtime-gl/src/gl/gl46/compile_program.rs
index 6ada90b..971c39c 100644
--- a/librashader-runtime-gl/src/gl/gl46/compile_program.rs
+++ b/librashader-runtime-gl/src/gl/gl46/compile_program.rs
@@ -47,7 +47,7 @@ impl CompileProgram for Gl4CompileProgram {
) -> crate::error::Result<(GLuint, UniformLocation)> {
let vertex_resources = glsl.context.artifact.vertex.get_shader_resources()?;
- let program = librashader_cache::cache::cache_object(
+ let program = librashader_cache::cache_shader_object(
"opengl4",
&[glsl.vertex.as_str(), glsl.fragment.as_str()],
|&[vertex, fragment]| unsafe {
@@ -120,7 +120,7 @@ impl CompileProgram for Gl4CompileProgram {
}
return Ok(program);
},
- cache,
+ !cache,
)?;
let ubo_location = unsafe {
diff --git a/librashader-runtime-gl/src/options.rs b/librashader-runtime-gl/src/options.rs
index 4bf1e67..493f6f0 100644
--- a/librashader-runtime-gl/src/options.rs
+++ b/librashader-runtime-gl/src/options.rs
@@ -18,11 +18,10 @@ pub struct FilterChainOptionsGL {
/// The GLSL version. Should be at least `330`.
pub glsl_version: u16,
/// Whether or not to use the Direct State Access APIs. Only available on OpenGL 4.5+.
- /// This is required to use shader caching.
+ /// If this is off, compiled program caching will not be available.
pub use_dsa: bool,
/// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
pub force_no_mipmaps: bool,
- /// Disable the shader object cache. Shaders will be
- /// recompiled rather than loaded from the cache.
+ /// Disable the shader object cache. Shaders will be recompiled rather than loaded from the cache.
pub disable_cache: bool,
}
diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs
index c888e43..a4417ef 100644
--- a/librashader-runtime-vk/src/filter_chain.rs
+++ b/librashader-runtime-vk/src/filter_chain.rs
@@ -32,7 +32,7 @@ use std::convert::Infallible;
use std::path::Path;
use std::sync::Arc;
-use librashader_cache::compilation::CachedCompilation;
+use librashader_cache::CachedCompilation;
use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer;
@@ -442,7 +442,7 @@ impl FilterChainVulkan {
&reflection,
frames_in_flight,
render_pass_format,
- !disable_cache,
+ disable_cache,
)?;
Ok(FilterPass {
diff --git a/librashader-runtime-vk/src/graphics_pipeline.rs b/librashader-runtime-vk/src/graphics_pipeline.rs
index 19fd93b..3e0b258 100644
--- a/librashader-runtime-vk/src/graphics_pipeline.rs
+++ b/librashader-runtime-vk/src/graphics_pipeline.rs
@@ -4,7 +4,7 @@ use ash::vk;
use crate::error::FilterChainError;
use crate::framebuffer::OutputImage;
use crate::render_pass::VulkanRenderPass;
-use librashader_cache::cache::cache_pipeline;
+use librashader_cache::cache_pipeline;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
use librashader_reflect::reflect::ShaderReflection;
@@ -314,7 +314,7 @@ impl VulkanGraphicsPipeline {
reflection: &ShaderReflection,
replicas: u32,
render_pass_format: vk::Format,
- cache_objects: bool,
+ bypass_cache: bool,
) -> error::Result {
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
@@ -359,7 +359,7 @@ impl VulkanGraphicsPipeline {
Ok::<_, FilterChainError>((pipeline, pipeline_cache))
},
|(_pipeline, cache)| unsafe { Ok(device.get_pipeline_cache_data(*cache)?) },
- cache_objects,
+ bypass_cache,
)?;
Ok(VulkanGraphicsPipeline {