capi: basic capi for presets and gl
This commit is contained in:
parent
f92dc5cae6
commit
b569de1522
292
Cargo.lock
generated
292
Cargo.lock
generated
|
@ -8,6 +8,17 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto_ops"
|
||||
version = "0.3.0"
|
||||
|
@ -71,6 +82,25 @@ version = "1.4.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cbindgen"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn",
|
||||
"tempfile",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
|
@ -86,6 +116,30 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.48"
|
||||
|
@ -159,6 +213,16 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
|
@ -186,6 +250,15 @@ dependencies = [
|
|||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
|
@ -258,6 +331,17 @@ dependencies = [
|
|||
"auto_ops",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghost"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb19fe8de3ea0920d282f7b77dd4227aea6b8b999b42cdf0ca41b2472b14443a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.11.4"
|
||||
|
@ -325,6 +409,12 @@ version = "0.12.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -363,6 +453,43 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inventory"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0eb5160c60ba1e809707918ee329adb99d222888155835c6feedba19f6c3fd4"
|
||||
dependencies = [
|
||||
"ctor",
|
||||
"ghost",
|
||||
"inventory-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inventory-impl"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e41b53715c6f0c4be49510bb82dee2c1e51c8586d885abe65396e82ed518548"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.25"
|
||||
|
@ -421,6 +548,18 @@ dependencies = [
|
|||
"librashader-runtime-gl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librashader-capi"
|
||||
version = "0.1.0-alpha.1"
|
||||
dependencies = [
|
||||
"cbindgen",
|
||||
"gl",
|
||||
"librashader",
|
||||
"paste",
|
||||
"safer-ffi",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librashader-common"
|
||||
version = "0.1.0-alpha.1"
|
||||
|
@ -557,6 +696,21 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mini_paste"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2499b7bd9834270bf24cfc4dd96be59020ba6fd7f3276b772aee2de66e82b63"
|
||||
dependencies = [
|
||||
"mini_paste-proc_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mini_paste-proc_macro"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c5f1f52e39b728e73af4b454f1b29173d4544607bd395dafe1918fd149db67"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -684,6 +838,18 @@ version = "1.15.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.2"
|
||||
|
@ -786,6 +952,24 @@ dependencies = [
|
|||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.14.1"
|
||||
|
@ -821,6 +1005,30 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "safer-ffi"
|
||||
version = "0.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c710243617290d86a49a30564d94d0b646eacf6d7b67035e20d6e8a21f1193"
|
||||
dependencies = [
|
||||
"inventory",
|
||||
"libc",
|
||||
"mini_paste",
|
||||
"safer_ffi-proc_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safer_ffi-proc_macro"
|
||||
version = "0.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc02dc034daa0944eb133b448f261ef7422ccae768e30f30ce5cdeb4ae4e506c"
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
|
@ -833,6 +1041,37 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shaderc"
|
||||
version = "0.8.0"
|
||||
|
@ -890,6 +1129,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.102"
|
||||
|
@ -901,6 +1146,35 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.37"
|
||||
|
@ -941,6 +1215,15 @@ dependencies = [
|
|||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
|
@ -1035,6 +1318,15 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
|
|
@ -8,6 +8,7 @@ members = [
|
|||
"librashader-runtime",
|
||||
"librashader-runtime-d3d11",
|
||||
"librashader-runtime-gl",
|
||||
"librashader-capi",
|
||||
]
|
||||
|
||||
[workspace.metadata.release]
|
||||
|
|
30
librashader-capi/Cargo.toml
Normal file
30
librashader-capi/Cargo.toml
Normal file
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
name = "librashader-capi"
|
||||
edition = "2021"
|
||||
|
||||
license = "MPL-2.0 OR GPL-3.0-only"
|
||||
version = "0.1.0-alpha.1"
|
||||
authors = ["Ronny Chan <ronny@ronnychan.ca>"]
|
||||
repository = "https://github.com/SnowflakePowered/librashader"
|
||||
readme = "../README.md"
|
||||
categories = ["emulators", "compilers", "graphics"]
|
||||
keywords = ["shader", "retroarch", "SPIR-V"]
|
||||
description = "RetroArch shaders for all."
|
||||
|
||||
[lib]
|
||||
crate-type = [ "cdylib", "staticlib", "lib" ]
|
||||
|
||||
[features]
|
||||
#default = ["runtime-opengl"]
|
||||
#runtime-opengl = ["gl", "librashader/gl"]
|
||||
headers = ["safer-ffi/headers"]
|
||||
|
||||
[dependencies]
|
||||
librashader = { path = "../librashader", version = "0.1.0-alpha.1", features = ["gl"] }
|
||||
thiserror = "1.0.37"
|
||||
paste = "1.0.9"
|
||||
gl = { version = "0.14.0" }
|
||||
safer-ffi = { version = "0.0.10", repository = "https://github.com/getditto/safer_ffi" }
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.24.3"
|
19
librashader-capi/build.rs
Normal file
19
librashader-capi/build.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
|
||||
pub fn main() {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let mut buf = BufWriter::new(Vec::new());
|
||||
cbindgen::generate(crate_dir)
|
||||
.expect("Unable to generate bindings")
|
||||
.write(&mut buf);
|
||||
|
||||
let bytes = buf.into_inner().expect("Unable to extract bytes");
|
||||
let string = String::from_utf8(bytes).expect("Unable to create string");
|
||||
// let string = string.replace("CHD_ERROR_", "CHDERR_");
|
||||
File::create("librashader.h")
|
||||
.expect("Unable to open file")
|
||||
.write_all(string.as_bytes())
|
||||
.expect("Unable to write bindings.")
|
||||
}
|
41
librashader-capi/cbindgen.toml
Normal file
41
librashader-capi/cbindgen.toml
Normal file
|
@ -0,0 +1,41 @@
|
|||
language = "C"
|
||||
cpp_compat = true
|
||||
include_guard = "__LIBRASHADER_H__"
|
||||
pragma_once = true
|
||||
usize_is_size_t = true
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
include = ["librashader",
|
||||
"librashader-presets",
|
||||
"librashader-preprocess",
|
||||
"librashader-reflect",
|
||||
"librashader-runtime-gl"
|
||||
]
|
||||
|
||||
|
||||
[struct]
|
||||
|
||||
[enum]
|
||||
rename_variants = "ScreamingSnakeCase"
|
||||
prefix_with_name = true
|
||||
|
||||
[export]
|
||||
include = [
|
||||
"PFN_lbr_load_preset",
|
||||
"PFN_lbr_preset_free",
|
||||
"PFN_lbr_preset_set_param",
|
||||
"PFN_lbr_preset_get_param",
|
||||
"PFN_lbr_preset_print",
|
||||
"PFN_lbr_preset_get_runtime_param_names",
|
||||
"GLFilterChain"
|
||||
|
||||
]
|
||||
|
||||
#exclude = ["LibrashaderError"]
|
||||
#
|
||||
[export.rename]
|
||||
"LibrashaderError" = "_libra_error"
|
||||
"ShaderPreset" = "_shader_preset"
|
||||
"GLFilterChain" = "_filter_chain_gl"
|
||||
"GLFilterChainOptions" = "filter_chain_gl_opt_t"
|
3
librashader-capi/examples/generate-headers.rs
Normal file
3
librashader-capi/examples/generate-headers.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() -> ::std::io::Result<()> {
|
||||
::librashader_capi::generate_headers()
|
||||
}
|
116
librashader-capi/librashader.h
Normal file
116
librashader-capi/librashader.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
#ifndef __LIBRASHADER_H__
|
||||
#define __LIBRASHADER_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct FilterChain FilterChain;
|
||||
|
||||
typedef struct _libra_error _libra_error;
|
||||
|
||||
/**
|
||||
* A shader preset including all specified parameters, textures, and paths to specified shaders.
|
||||
*
|
||||
* A shader preset can be used to create a filter chain runtime instance, or reflected to get
|
||||
* parameter metadata.
|
||||
*/
|
||||
typedef struct _shader_preset _shader_preset;
|
||||
|
||||
typedef const struct _libra_error *libra_error_t;
|
||||
|
||||
typedef struct _shader_preset *libra_shader_preset_t;
|
||||
|
||||
typedef const void *(*gl_loader_t)(const char*);
|
||||
|
||||
typedef struct FilterChainOptions {
|
||||
uint16_t gl_version;
|
||||
bool use_dsa;
|
||||
} FilterChainOptions;
|
||||
|
||||
typedef struct FilterChain *libra_gl_filter_chain_t;
|
||||
|
||||
/**
|
||||
* Load a preset.
|
||||
*/
|
||||
typedef libra_error_t (*PFN_lbr_load_preset)(const char*, libra_shader_preset_t*);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_free)(libra_shader_preset_t*);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_set_param)(libra_shader_preset_t*, const char*, float);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_get_param)(libra_shader_preset_t*, const char*, float*);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_print)(libra_shader_preset_t*);
|
||||
|
||||
typedef libra_error_t (*PFN_lbr_preset_get_runtime_param_names)(libra_shader_preset_t*, float*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
libra_error_t libra_load_preset(const char *filename, libra_shader_preset_t *out);
|
||||
|
||||
/**
|
||||
* Free the preset.
|
||||
*/
|
||||
libra_error_t libra_preset_free(libra_shader_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Set the value of the parameter in the preset.
|
||||
*/
|
||||
libra_error_t libra_preset_set_param(libra_shader_preset_t *preset, const char *name, float value);
|
||||
|
||||
/**
|
||||
* Get the value of the parameter as set in the preset.
|
||||
*/
|
||||
libra_error_t libra_preset_get_param(libra_shader_preset_t *preset, const char *name, float *value);
|
||||
|
||||
/**
|
||||
* Pretty print the shader preset.
|
||||
*/
|
||||
libra_error_t libra_preset_print(libra_shader_preset_t *preset);
|
||||
|
||||
/**
|
||||
* Get a list of runtime parameter names.
|
||||
*
|
||||
* The returned value can not currently be freed.
|
||||
*/
|
||||
libra_error_t libra_preset_get_runtime_param_names(libra_shader_preset_t *preset,
|
||||
const char **value);
|
||||
|
||||
/**
|
||||
* Initialize the OpenGL Context for librashader.
|
||||
*
|
||||
* ## Safety
|
||||
* Attempting to create a filter chain before initializing the GL context is undefined behaviour.
|
||||
*
|
||||
* Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
* chain objects, and drawing with them causes immediate undefined behaviour.
|
||||
*/
|
||||
libra_error_t libra_gl_init_context(gl_loader_t loader);
|
||||
|
||||
/**
|
||||
* Create the filter chain given the shader preset.
|
||||
*
|
||||
* The shader preset is immediately invalidated and must be recreated after
|
||||
* the filter chain is created.
|
||||
*
|
||||
* ## Safety:
|
||||
* - `preset` must be either null, or valid and aligned.
|
||||
* - `options` must be either null, or valid and aligned.
|
||||
* - `out` may be either null or uninitialized, but must be aligned.
|
||||
*/
|
||||
libra_error_t libra_gl_create_filter_chain(libra_shader_preset_t *preset,
|
||||
const struct FilterChainOptions *options,
|
||||
libra_gl_filter_chain_t *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* __LIBRASHADER_H__ */
|
9
librashader-capi/src/ctypes.rs
Normal file
9
librashader-capi/src/ctypes.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use std::mem::ManuallyDrop;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use crate::error::LibrashaderError;
|
||||
|
||||
pub type libra_shader_preset_t = ManuallyDrop<Option<Box<ShaderPreset>>>;
|
||||
pub type libra_error_t = *const LibrashaderError;
|
||||
|
||||
// #[cfg(feature = "runtime-opengl")]
|
||||
pub type libra_gl_filter_chain_t = ManuallyDrop<Option<Box<librashader::runtime::gl::FilterChainGL>>>;
|
54
librashader-capi/src/error.rs
Normal file
54
librashader-capi/src/error.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use std::any::Any;
|
||||
use thiserror::Error;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Error, Debug)]
|
||||
pub enum LibrashaderError {
|
||||
#[error("The parameter was null or invalid.")]
|
||||
InvalidParameter(&'static str),
|
||||
#[error("The path was invalid.")]
|
||||
InvalidPath(#[from] std::str::Utf8Error),
|
||||
#[error("There was an error parsing the preset.")]
|
||||
PresetError(#[from] librashader::presets::ParsePresetError),
|
||||
#[error("There was an error preprocessing the shader source.")]
|
||||
PreprocessError(#[from] librashader::preprocess::PreprocessError),
|
||||
|
||||
// #[cfg(feature = "runtime-opengl")]
|
||||
#[error("There was an error in the OpenGL filter chain.")]
|
||||
OpenGlFilterError(#[from] librashader::runtime::gl::error::FilterChainError),
|
||||
#[error("There was an unknown error.")]
|
||||
UnknownError(Box<dyn Any + Send + 'static>)
|
||||
}
|
||||
|
||||
impl LibrashaderError {
|
||||
pub const fn ok() -> libra_error_t {
|
||||
std::ptr::null()
|
||||
}
|
||||
|
||||
pub fn panic(panic: Box<dyn Any + Send + 'static>) -> libra_error_t {
|
||||
LibrashaderError::UnknownError(panic).export()
|
||||
}
|
||||
|
||||
pub fn export(self) -> libra_error_t {
|
||||
Box::into_raw(Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! assert_non_null {
|
||||
($value:ident) => {
|
||||
if $value.is_null() {
|
||||
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
|
||||
}
|
||||
}
|
||||
}
|
||||
macro_rules! assert_some {
|
||||
($value:ident) => {
|
||||
if $value.is_none() {
|
||||
return $crate::error::LibrashaderError::InvalidParameter(stringify!($value)).export()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use assert_non_null;
|
||||
pub(crate) use assert_some;
|
||||
use crate::ctypes::libra_error_t;
|
77
librashader-capi/src/ffi.rs
Normal file
77
librashader-capi/src/ffi.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
|
||||
macro_rules! ffi_body {
|
||||
($body:block) => {
|
||||
{
|
||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||
$body
|
||||
};
|
||||
|
||||
let Err(e) = result else {
|
||||
return $crate::error::LibrashaderError::ok()
|
||||
};
|
||||
e.export()
|
||||
}
|
||||
};
|
||||
(|$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||
{
|
||||
$($crate::error::assert_non_null!($ref_capture);)*
|
||||
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
||||
$($crate::error::assert_non_null!($mut_capture);)*
|
||||
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||
$body
|
||||
};
|
||||
|
||||
let Err(e) = result else {
|
||||
return $crate::error::LibrashaderError::ok()
|
||||
};
|
||||
e.export()
|
||||
}
|
||||
};
|
||||
(mut |$($mut_capture:ident),*| $body:block) => {
|
||||
{
|
||||
$($crate::error::assert_non_null!($mut_capture);)*
|
||||
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||
$body
|
||||
};
|
||||
|
||||
let Err(e) = result else {
|
||||
return $crate::error::LibrashaderError::ok()
|
||||
};
|
||||
e.export()
|
||||
}
|
||||
};
|
||||
(|$($ref_capture:ident),*| $body:block) => {
|
||||
{
|
||||
$($crate::error::assert_non_null!($ref_capture);)*
|
||||
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||
$body
|
||||
};
|
||||
|
||||
let Err(e) = result else {
|
||||
return $crate::error::LibrashaderError::ok()
|
||||
};
|
||||
e.export()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
macro_rules! extern_fn {
|
||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),*) $body:block) => {
|
||||
paste::paste! {
|
||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
$(#[$($attrss)*])*
|
||||
fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||
$crate::ffi::ffi_body!($body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use extern_fn;
|
||||
pub(crate) use ffi_body;
|
21
librashader-capi/src/lib.rs
Normal file
21
librashader-capi/src/lib.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(vec_into_raw_parts)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use std::os::raw::c_char;
|
||||
|
||||
pub mod presets;
|
||||
pub mod runtime;
|
||||
pub mod error;
|
||||
pub mod ctypes;
|
||||
mod ffi;
|
||||
|
||||
pub type PK_s = unsafe extern "C" fn(filename: *const c_char);
|
||||
|
||||
#[cfg(feature = "headers")] // c.f. the `Cargo.toml` section
|
||||
pub fn generate_headers() -> ::std::io::Result<()> {
|
||||
::safer_ffi::headers::builder()
|
||||
.to_file("librashader.h")?
|
||||
.generate()
|
||||
}
|
149
librashader-capi/src/presets.rs
Normal file
149
librashader-capi/src/presets.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
use std::ffi::{c_char, CStr, CString, OsStr};
|
||||
use std::mem::{ManuallyDrop, MaybeUninit};
|
||||
use std::panic::catch_unwind;
|
||||
use std::path::Path;
|
||||
use librashader::presets::ShaderPreset;
|
||||
use crate::ffi::ffi_body;
|
||||
use crate::ctypes::{libra_error_t, libra_shader_preset_t};
|
||||
use crate::error::{assert_non_null, assert_some, LibrashaderError};
|
||||
use safer_ffi::prelude::*;
|
||||
use safer_ffi::ffi_export;
|
||||
use safer_ffi::char_p::char_p_ref as CStrRef;
|
||||
|
||||
// extern_fn! {
|
||||
// /// SAFETY:
|
||||
// /// - filename is aligned and valid for reads.
|
||||
// fn load_preset(filename: *const c_char, out: *mut MaybeUninit<shader_preset_t>) {
|
||||
// assert_non_null!(filename, "filename");
|
||||
// assert_non_null!(out, "out");
|
||||
//
|
||||
// let filename = unsafe {
|
||||
// CStr::from_ptr(filename)
|
||||
// };
|
||||
//
|
||||
// let filename = filename.to_str()?;
|
||||
//
|
||||
// println!("loading {filename}");
|
||||
// let preset = ShaderPreset::try_parse(filename)?;
|
||||
//
|
||||
// unsafe {
|
||||
// out.write(MaybeUninit::new(ManuallyDrop::new(Box::new(preset))))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Load a preset.
|
||||
pub type PFN_lbr_load_preset = unsafe extern "C" fn (*const c_char, *mut MaybeUninit<libra_shader_preset_t>) -> libra_error_t;
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_load_preset(filename: *const c_char, out: *mut MaybeUninit<libra_shader_preset_t>) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(filename);
|
||||
assert_non_null!(out);
|
||||
|
||||
let filename = unsafe {
|
||||
CStr::from_ptr(filename)
|
||||
};
|
||||
|
||||
let filename = filename.to_str()?;
|
||||
|
||||
println!("loading {filename}");
|
||||
let preset = ShaderPreset::try_parse(filename)?;
|
||||
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(ManuallyDrop::new(Some(Box::new(preset)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_free = unsafe extern "C" fn (*mut libra_shader_preset_t) -> libra_error_t;
|
||||
|
||||
/// Free the preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_free(preset: *mut libra_shader_preset_t) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(preset);
|
||||
unsafe {
|
||||
let preset_ptr = &mut *preset;
|
||||
ManuallyDrop::drop(preset_ptr);
|
||||
preset.write(ManuallyDrop::new(None));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_set_param = unsafe extern "C" fn (*mut libra_shader_preset_t, *const c_char, f32) -> libra_error_t;
|
||||
/// Set the value of the parameter in the preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_set_param(preset: *mut libra_shader_preset_t,
|
||||
name: *const c_char, value: f32) -> libra_error_t {
|
||||
ffi_body!(|name|; mut |preset| {
|
||||
let name = unsafe {
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
|
||||
let name = name.to_str()?;
|
||||
assert_some!(preset);
|
||||
let preset = preset.as_mut().unwrap();
|
||||
|
||||
if let Some(param) = preset.parameters.iter_mut().find(|c| c.name == name) {
|
||||
param.value = value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_get_param = unsafe extern "C" fn (*mut libra_shader_preset_t, *const c_char, *mut MaybeUninit<f32>) -> libra_error_t;
|
||||
|
||||
/// Get the value of the parameter as set in the preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_get_param(preset: *mut libra_shader_preset_t,
|
||||
name: *const c_char, value: *mut MaybeUninit<f32>) -> libra_error_t {
|
||||
ffi_body!(|name, preset | {
|
||||
let name = unsafe {
|
||||
CStr::from_ptr(name)
|
||||
};
|
||||
|
||||
let name = name.to_str()?;
|
||||
assert_some!(preset);
|
||||
let preset = preset.as_ref().unwrap();
|
||||
|
||||
if let Some(param) = preset.parameters.iter().find(|c| c.name == name) {
|
||||
unsafe {
|
||||
value.write(MaybeUninit::new(param.value))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub type PFN_lbr_preset_print = unsafe extern "C" fn (*mut libra_shader_preset_t) -> libra_error_t;
|
||||
|
||||
/// Pretty print the shader preset.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_print(preset: *mut libra_shader_preset_t) -> libra_error_t {
|
||||
ffi_body!(|preset| {
|
||||
assert_some!(preset);
|
||||
println!("{:#?}", preset.as_ref().unwrap());
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
pub type PFN_lbr_preset_get_runtime_param_names = unsafe extern "C" fn (*mut libra_shader_preset_t, *mut MaybeUninit<f32>) -> libra_error_t;
|
||||
|
||||
/// Get a list of runtime parameter names.
|
||||
///
|
||||
/// The returned value can not currently be freed.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_preset_get_runtime_param_names(preset: *mut libra_shader_preset_t, mut value: MaybeUninit<*mut *const c_char>) -> libra_error_t {
|
||||
ffi_body!(|preset | {
|
||||
assert_some!(preset);
|
||||
let preset = preset.as_ref().unwrap();
|
||||
|
||||
let iter = librashader::presets::get_parameter_meta(preset)?;
|
||||
let mut c_strings = Vec::new();
|
||||
for param in iter {
|
||||
let c_string = CString::new(param.id).map_err(|err| LibrashaderError::UnknownError(Box::new(err)))?;
|
||||
c_strings.push(c_string.into_raw().cast_const());
|
||||
}
|
||||
|
||||
let (parts, _len, _cap) = c_strings.into_raw_parts();
|
||||
value.write(parts);
|
||||
})
|
||||
}
|
0
librashader-capi/src/runtime/d3d11.rs
Normal file
0
librashader-capi/src/runtime/d3d11.rs
Normal file
61
librashader-capi/src/runtime/gl.rs
Normal file
61
librashader-capi/src/runtime/gl.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use std::ffi::{c_char, c_void, CString};
|
||||
use std::mem::MaybeUninit;
|
||||
use crate::ctypes::{libra_error_t, libra_gl_filter_chain_t, libra_shader_preset_t};
|
||||
use crate::error::{assert_non_null, assert_some, LibrashaderError};
|
||||
use crate::ffi::ffi_body;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
pub use librashader::runtime::gl::options::FilterChainOptionsGL;
|
||||
|
||||
pub type gl_loader_t = unsafe extern "C" fn (*const c_char) -> *const c_void;
|
||||
/// Initialize the OpenGL Context for librashader.
|
||||
///
|
||||
/// ## Safety
|
||||
/// Attempting to create a filter chain before initializing the GL context is undefined behaviour.
|
||||
///
|
||||
/// Reinitializing the OpenGL context with a different loader immediately invalidates previous filter
|
||||
/// chain objects, and drawing with them causes immediate undefined behaviour.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_gl_init_context(loader: gl_loader_t) -> libra_error_t {
|
||||
gl::load_with(|s| {
|
||||
unsafe {
|
||||
let proc_name = CString::new(s).unwrap_unchecked();
|
||||
loader(proc_name.as_ptr())
|
||||
}
|
||||
});
|
||||
|
||||
LibrashaderError::ok()
|
||||
}
|
||||
|
||||
/// Create the filter chain given the shader preset.
|
||||
///
|
||||
/// The shader preset is immediately invalidated and must be recreated after
|
||||
/// the filter chain is created.
|
||||
///
|
||||
/// ## Safety:
|
||||
/// - `preset` must be either null, or valid and aligned.
|
||||
/// - `options` must be either null, or valid and aligned.
|
||||
/// - `out` may be either null or uninitialized, but must be aligned.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn libra_gl_create_filter_chain(preset: *mut libra_shader_preset_t,
|
||||
options: *const FilterChainOptionsGL,
|
||||
out: *mut MaybeUninit<libra_gl_filter_chain_t>) -> libra_error_t {
|
||||
ffi_body!({
|
||||
assert_non_null!(preset);
|
||||
let preset_ptr = unsafe {
|
||||
&mut *preset
|
||||
};
|
||||
|
||||
assert_some!(preset_ptr);
|
||||
let preset = preset_ptr.take().unwrap();
|
||||
let options = if options.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(unsafe { &*options })
|
||||
};
|
||||
let chain = librashader::runtime::gl::FilterChainGL::load_from_preset(*preset, options)?;
|
||||
unsafe {
|
||||
out.write(MaybeUninit::new(ManuallyDrop::new(Some(Box::new(chain)))))
|
||||
}
|
||||
})
|
||||
}
|
1
librashader-capi/src/runtime/mod.rs
Normal file
1
librashader-capi/src/runtime/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod gl;
|
|
@ -20,7 +20,7 @@ use std::path::Path;
|
|||
use crate::error::FilterChainError;
|
||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||
use crate::framebuffer::OwnedFramebuffer;
|
||||
use crate::options::{FilterChainOptions, FrameOptions};
|
||||
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
|
||||
use crate::quad_render::DrawQuad;
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
|
@ -49,7 +49,7 @@ type ShaderPassMeta = (
|
|||
>,
|
||||
);
|
||||
|
||||
pub struct FilterChain {
|
||||
pub struct FilterChainD3D11 {
|
||||
pub(crate) common: FilterCommon,
|
||||
pub(crate) passes: Vec<FilterPass>,
|
||||
pub(crate) output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||
|
@ -75,13 +75,13 @@ pub(crate) struct FilterCommon {
|
|||
pub config: FilterMutable,
|
||||
}
|
||||
|
||||
impl FilterChain {
|
||||
impl FilterChainD3D11 {
|
||||
/// Load the shader preset at the given path into a filter chain.
|
||||
pub fn load_from_path(
|
||||
device: &ID3D11Device,
|
||||
path: impl AsRef<Path>,
|
||||
options: Option<&FilterChainOptions>,
|
||||
) -> error::Result<FilterChain> {
|
||||
options: Option<&FilterChainOptionsD3D11>,
|
||||
) -> error::Result<FilterChainD3D11> {
|
||||
// load passes from preset
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
Self::load_from_preset(device, preset, options)
|
||||
|
@ -91,16 +91,16 @@ impl FilterChain {
|
|||
pub fn load_from_preset(
|
||||
device: &ID3D11Device,
|
||||
preset: ShaderPreset,
|
||||
options: Option<&FilterChainOptions>,
|
||||
) -> error::Result<FilterChain> {
|
||||
let (passes, semantics) = FilterChain::load_preset(preset.shaders, &preset.textures)?;
|
||||
options: Option<&FilterChainOptionsD3D11>,
|
||||
) -> error::Result<FilterChainD3D11> {
|
||||
let (passes, semantics) = FilterChainD3D11::load_preset(preset.shaders, &preset.textures)?;
|
||||
|
||||
let use_deferred_context = options.map(|f| f.use_deferred_context).unwrap_or(false);
|
||||
|
||||
let samplers = SamplerSet::new(device)?;
|
||||
|
||||
// initialize passes
|
||||
let filters = FilterChain::init_passes(device, passes, &semantics)?;
|
||||
let filters = FilterChainD3D11::init_passes(device, passes, &semantics)?;
|
||||
|
||||
let mut immediate_context = None;
|
||||
unsafe {
|
||||
|
@ -155,17 +155,17 @@ impl FilterChain {
|
|||
feedback_textures.resize_with(filters.len(), || None);
|
||||
|
||||
// load luts
|
||||
let luts = FilterChain::load_luts(device, ¤t_context, &preset.textures)?;
|
||||
let luts = FilterChainD3D11::load_luts(device, ¤t_context, &preset.textures)?;
|
||||
|
||||
let (history_framebuffers, history_textures) =
|
||||
FilterChain::init_history(device,
|
||||
FilterChainD3D11::init_history(device,
|
||||
¤t_context,
|
||||
&filters)?;
|
||||
|
||||
let draw_quad = DrawQuad::new(device, ¤t_context)?;
|
||||
|
||||
// todo: make vbo: d3d11.c 1376
|
||||
Ok(FilterChain {
|
||||
Ok(FilterChainD3D11 {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
|
@ -196,7 +196,7 @@ impl FilterChain {
|
|||
}
|
||||
}
|
||||
|
||||
impl FilterChain {
|
||||
impl FilterChainD3D11 {
|
||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> error::Result<ID3D11Buffer> {
|
||||
unsafe {
|
||||
let buffer = device.CreateBuffer(
|
||||
|
@ -249,7 +249,7 @@ impl FilterChain {
|
|||
)?;
|
||||
|
||||
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
||||
let buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
|
||||
let buffer = FilterChainD3D11::create_constant_buffer(device, ubo.size)?;
|
||||
Some(ConstantBufferBinding {
|
||||
binding: ubo.binding,
|
||||
size: ubo.size,
|
||||
|
@ -261,7 +261,7 @@ impl FilterChain {
|
|||
};
|
||||
|
||||
let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 {
|
||||
let buffer = FilterChain::create_constant_buffer(device, push.size)?;
|
||||
let buffer = FilterChainD3D11::create_constant_buffer(device, push.size)?;
|
||||
Some(ConstantBufferBinding {
|
||||
binding: if ubo_cbuffer.is_some() { 1 } else { 0 },
|
||||
size: push.size,
|
||||
|
@ -470,7 +470,7 @@ impl FilterChain {
|
|||
input: DxImageView,
|
||||
viewport: &Viewport,
|
||||
frame_count: usize,
|
||||
options: Option<&FrameOptions>,
|
||||
options: Option<&FrameOptionsD3D11>,
|
||||
) -> error::Result<()> {
|
||||
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
||||
if let Some(options) = options {
|
||||
|
@ -607,11 +607,11 @@ impl FilterChain {
|
|||
}
|
||||
}
|
||||
|
||||
impl librashader_runtime::filter_chain::FilterChain for FilterChain {
|
||||
impl librashader_runtime::filter_chain::FilterChain for FilterChainD3D11 {
|
||||
type Error = FilterChainError;
|
||||
type Input<'a> = DxImageView;
|
||||
type Viewport<'a> = Viewport<'a>;
|
||||
type FrameOptions = FrameOptions;
|
||||
type FrameOptions = FrameOptionsD3D11;
|
||||
|
||||
fn frame<'a>(&mut self, input: Self::Input<'a>, viewport: &Self::Viewport<'a>, frame_count: usize, options: Option<&Self::FrameOptions>) -> Result<(), Self::Error> {
|
||||
self.frame(input, viewport, frame_count, options)
|
||||
|
|
|
@ -225,9 +225,9 @@ pub mod d3d11_hello_triangle {
|
|||
use super::*;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::filter_chain::FilterChain;
|
||||
use crate::filter_chain::FilterChainD3D11;
|
||||
|
||||
use crate::options::FilterChainOptions;
|
||||
use crate::options::FilterChainOptionsD3D11;
|
||||
use crate::texture::DxImageView;
|
||||
use crate::viewport::Viewport;
|
||||
use librashader_common::Size;
|
||||
|
@ -239,7 +239,7 @@ pub mod d3d11_hello_triangle {
|
|||
pub device: ID3D11Device,
|
||||
pub context: ID3D11DeviceContext,
|
||||
pub resources: Option<Resources>,
|
||||
pub filter: FilterChain,
|
||||
pub filter: FilterChainD3D11,
|
||||
}
|
||||
|
||||
pub struct Resources {
|
||||
|
@ -266,10 +266,10 @@ pub mod d3d11_hello_triangle {
|
|||
impl Sample {
|
||||
pub(crate) fn new(
|
||||
filter: impl AsRef<Path>,
|
||||
filter_options: Option<&FilterChainOptions>,
|
||||
filter_options: Option<&FilterChainOptionsD3D11>,
|
||||
) -> Result<Self> {
|
||||
let (dxgi_factory, device, context) = create_device()?;
|
||||
let filter = FilterChain::load_from_path(&device, filter, filter_options).unwrap();
|
||||
let filter = FilterChainD3D11::load_from_path(&device, filter, filter_options).unwrap();
|
||||
Ok(Sample {
|
||||
filter,
|
||||
dxgi_factory,
|
||||
|
|
|
@ -17,7 +17,7 @@ mod util;
|
|||
mod viewport;
|
||||
mod parameters;
|
||||
|
||||
pub use filter_chain::FilterChain;
|
||||
pub use filter_chain::FilterChainD3D11;
|
||||
pub use viewport::Viewport;
|
||||
pub use texture::DxImageView;
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FrameOptions {
|
||||
pub struct FrameOptionsD3D11 {
|
||||
pub clear_history: bool,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FilterChainOptions {
|
||||
pub struct FilterChainOptionsD3D11 {
|
||||
pub use_deferred_context: bool,
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::collections::hash_map::Iter;
|
||||
use librashader_runtime::parameters::FilterChainParameters;
|
||||
use crate::FilterChain;
|
||||
use crate::FilterChainD3D11;
|
||||
|
||||
impl FilterChainParameters for FilterChain {
|
||||
impl FilterChainParameters for FilterChainD3D11 {
|
||||
fn get_enabled_pass_count(&self) -> usize {
|
||||
self.common.config.passes_enabled
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::binding::{BufferStorage, UniformLocation, VariableLocation};
|
|||
use crate::error::FilterChainError;
|
||||
use crate::filter_pass::FilterPass;
|
||||
use crate::gl::{DrawQuad, Framebuffer, FramebufferInterface, GLInterface, LoadLut, UboRing};
|
||||
use crate::options::{FilterChainOptions, FrameOptions};
|
||||
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::Texture;
|
||||
|
@ -87,7 +87,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
|||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||
pub(crate) fn load_from_preset(
|
||||
preset: ShaderPreset,
|
||||
options: Option<&FilterChainOptions>,
|
||||
options: Option<&FilterChainOptionsGL>,
|
||||
) -> error::Result<Self> {
|
||||
let (passes, semantics) = Self::load_preset(preset.shaders, &preset.textures)?;
|
||||
|
||||
|
@ -415,7 +415,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
|||
count: usize,
|
||||
viewport: &Viewport,
|
||||
input: &GLImage,
|
||||
options: Option<&FrameOptions>,
|
||||
options: Option<&FrameOptionsGL>,
|
||||
) -> error::Result<()> {
|
||||
// limit number of passes to those enabled.
|
||||
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::filter_chain::filter_impl::FilterChainImpl;
|
|||
use crate::filter_chain::inner::FilterChainDispatch;
|
||||
use crate::{GLImage, Viewport};
|
||||
use crate::error::{Result, FilterChainError};
|
||||
use crate::options::{FilterChainOptions, FrameOptions};
|
||||
use crate::options::{FilterChainOptionsGL, FrameOptionsGL};
|
||||
|
||||
mod filter_impl;
|
||||
mod inner;
|
||||
|
@ -13,14 +13,14 @@ mod parameters;
|
|||
|
||||
pub(crate) use filter_impl::FilterCommon;
|
||||
|
||||
pub struct FilterChain {
|
||||
pub struct FilterChainGL {
|
||||
pub(in crate::filter_chain) filter: FilterChainDispatch,
|
||||
}
|
||||
|
||||
impl FilterChain {
|
||||
impl FilterChainGL {
|
||||
pub fn load_from_preset(
|
||||
preset: ShaderPreset,
|
||||
options: Option<&FilterChainOptions>,
|
||||
options: Option<&FilterChainOptionsGL>,
|
||||
) -> Result<Self> {
|
||||
if let Some(options) = options && options.use_dsa {
|
||||
return Ok(Self {
|
||||
|
@ -37,7 +37,7 @@ impl FilterChain {
|
|||
/// Load the shader preset at the given path into a filter chain.
|
||||
pub fn load_from_path(
|
||||
path: impl AsRef<Path>,
|
||||
options: Option<&FilterChainOptions>,
|
||||
options: Option<&FilterChainOptionsGL>,
|
||||
) -> Result<Self> {
|
||||
// load passes from preset
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
|
@ -52,7 +52,7 @@ impl FilterChain {
|
|||
input: &GLImage,
|
||||
viewport: &Viewport,
|
||||
frame_count: usize,
|
||||
options: Option<&FrameOptions>,
|
||||
options: Option<&FrameOptionsGL>,
|
||||
) -> Result<()> {
|
||||
match &mut self.filter {
|
||||
FilterChainDispatch::DirectStateAccess(p) => {
|
||||
|
@ -63,11 +63,11 @@ impl FilterChain {
|
|||
}
|
||||
}
|
||||
|
||||
impl librashader_runtime::filter_chain::FilterChain for FilterChain {
|
||||
impl librashader_runtime::filter_chain::FilterChain for FilterChainGL {
|
||||
type Error = FilterChainError;
|
||||
type Input<'a> = &'a GLImage;
|
||||
type Viewport<'a> = Viewport<'a>;
|
||||
type FrameOptions = FrameOptions;
|
||||
type FrameOptions = FrameOptionsGL;
|
||||
|
||||
fn frame<'a>(
|
||||
&mut self,
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::hash_map::Iter;
|
|||
use librashader_runtime::parameters::FilterChainParameters;
|
||||
use crate::filter_chain::filter_impl::FilterChainImpl;
|
||||
use crate::filter_chain::inner::FilterChainDispatch;
|
||||
use crate::FilterChain;
|
||||
use crate::FilterChainGL;
|
||||
use crate::gl::GLInterface;
|
||||
|
||||
impl AsRef<dyn FilterChainParameters + 'static> for FilterChainDispatch {
|
||||
|
@ -23,7 +23,7 @@ impl AsMut<dyn FilterChainParameters + 'static> for FilterChainDispatch {
|
|||
}
|
||||
}
|
||||
|
||||
impl FilterChainParameters for FilterChain {
|
||||
impl FilterChainParameters for FilterChainGL {
|
||||
fn get_enabled_pass_count(&self) -> usize {
|
||||
self.filter.as_ref().get_enabled_pass_count()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
|||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||
use librashader_common::Size;
|
||||
|
||||
use crate::filter_chain::FilterChain;
|
||||
use crate::filter_chain::FilterChainGL;
|
||||
use crate::framebuffer::GLImage;
|
||||
use crate::gl::gl3::CompatibilityGL;
|
||||
use crate::gl::{FramebufferInterface, GLInterface};
|
||||
|
@ -268,7 +268,7 @@ pub fn do_loop(
|
|||
events: Receiver<(f64, WindowEvent)>,
|
||||
triangle_program: GLuint,
|
||||
triangle_vao: GLuint,
|
||||
filter: &mut FilterChain,
|
||||
filter: &mut FilterChainGL,
|
||||
) {
|
||||
let mut framecount = 0;
|
||||
let mut rendered_framebuffer = 0;
|
||||
|
|
|
@ -7,7 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
|||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||
use librashader_common::Size;
|
||||
|
||||
use crate::filter_chain::FilterChain;
|
||||
use crate::filter_chain::FilterChainGL;
|
||||
use crate::framebuffer::GLImage;
|
||||
use crate::gl::gl46::DirectStateAccessGL;
|
||||
use crate::gl::{FramebufferInterface, GLInterface};
|
||||
|
@ -259,7 +259,7 @@ pub fn do_loop(
|
|||
events: Receiver<(f64, WindowEvent)>,
|
||||
triangle_program: GLuint,
|
||||
triangle_vao: GLuint,
|
||||
filter: &mut FilterChain,
|
||||
filter: &mut FilterChainGL,
|
||||
) {
|
||||
let mut framecount = 0;
|
||||
let mut rendered_framebuffer = 0;
|
||||
|
|
|
@ -17,22 +17,22 @@ pub mod error;
|
|||
pub mod options;
|
||||
mod viewport;
|
||||
|
||||
pub use filter_chain::FilterChain;
|
||||
pub use filter_chain::FilterChainGL;
|
||||
pub use framebuffer::GLImage;
|
||||
pub use viewport::Viewport;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::filter_chain::FilterChain;
|
||||
use crate::options::FilterChainOptions;
|
||||
use crate::filter_chain::FilterChainGL;
|
||||
use crate::options::FilterChainOptionsGL;
|
||||
|
||||
#[test]
|
||||
fn triangle_gl() {
|
||||
let (glfw, window, events, shader, vao) = gl::gl3::hello_triangle::setup();
|
||||
let mut filter = FilterChain::load_from_path(
|
||||
let mut filter = FilterChainGL::load_from_path(
|
||||
"../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp",
|
||||
Some(&FilterChainOptions {
|
||||
Some(&FilterChainOptionsGL {
|
||||
gl_version: 0,
|
||||
use_dsa: false,
|
||||
}),
|
||||
|
@ -45,9 +45,9 @@ mod tests {
|
|||
#[test]
|
||||
fn triangle_gl46() {
|
||||
let (glfw, window, events, shader, vao) = gl::gl46::hello_triangle::setup();
|
||||
let mut filter = FilterChain::load_from_path(
|
||||
let mut filter = FilterChainGL::load_from_path(
|
||||
"../test/slang-shaders/vhs/VHSPro.slangp",
|
||||
Some(&FilterChainOptions {
|
||||
Some(&FilterChainOptionsGL {
|
||||
gl_version: 0,
|
||||
use_dsa: true,
|
||||
}),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FrameOptions {
|
||||
pub struct FrameOptionsGL {
|
||||
pub clear_history: bool,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FilterChainOptions {
|
||||
pub struct FilterChainOptionsGL {
|
||||
pub gl_version: u16,
|
||||
pub use_dsa: bool,
|
||||
}
|
||||
|
|
22
librashader.h
Normal file
22
librashader.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*! \file */
|
||||
/*******************************************
|
||||
* *
|
||||
* File auto-generated by `::safer_ffi`. *
|
||||
* *
|
||||
* Do not manually edit this file. *
|
||||
* *
|
||||
*******************************************/
|
||||
|
||||
#ifndef __RUST_LIBRASHADER_CAPI__
|
||||
#define __RUST_LIBRASHADER_CAPI__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __RUST_LIBRASHADER_CAPI__ */
|
|
@ -23,5 +23,10 @@ librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.1.0-
|
|||
|
||||
|
||||
[features]
|
||||
gl = [ "librashader-common/opengl" ]
|
||||
d3d11 = [ "librashader-common/d3d11" ]
|
||||
default = ["gl", "d3d11", "reflect", "preprocess", "presets" ]
|
||||
gl = [ "runtime", "librashader-common/opengl" ]
|
||||
d3d11 = [ "runtime", "librashader-common/d3d11" ]
|
||||
runtime = []
|
||||
reflect = []
|
||||
preprocess = []
|
||||
presets = []
|
|
@ -3,6 +3,7 @@
|
|||
//! Runtime implementations should depend directly on constituent crates.
|
||||
|
||||
|
||||
#[cfg(feature = "presets")]
|
||||
/// Parsing and usage of shader presets.
|
||||
///
|
||||
/// Shader presets contain shader and texture parameters, and the order in which to apply a set of shaders
|
||||
|
@ -10,7 +11,6 @@
|
|||
pub mod presets {
|
||||
pub use librashader_presets::*;
|
||||
use librashader_preprocess::{PreprocessError, ShaderParameter, ShaderSource};
|
||||
use librashader_presets::ShaderPreset;
|
||||
/// Get full parameter metadata from a shader preset.
|
||||
pub fn get_parameter_meta(
|
||||
preset: &ShaderPreset,
|
||||
|
@ -26,6 +26,7 @@ pub mod presets {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "preprocess")]
|
||||
/// Loading and preprocessing of 'slang' shader source files.
|
||||
///
|
||||
/// Shader sources files must be loaded with imports resolved before being able to be compiled.
|
||||
|
@ -34,6 +35,7 @@ pub mod preprocess {
|
|||
pub use librashader_preprocess::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "reflect")]
|
||||
/// Shader compilation and reflection.
|
||||
pub mod reflect {
|
||||
/// Supported shader compiler targets.
|
||||
|
@ -58,20 +60,24 @@ pub mod reflect {
|
|||
}
|
||||
|
||||
/// Shader runtimes to execute a filter chain on a GPU surface.
|
||||
#[cfg(feature = "runtime")]
|
||||
pub mod runtime {
|
||||
pub use librashader_runtime::parameters::FilterChainParameters;
|
||||
pub use librashader_runtime::filter_chain::FilterChain;
|
||||
|
||||
#[cfg(feature = "gl")]
|
||||
/// Shader runtime for OpenGL 3.3+.
|
||||
pub mod gl {
|
||||
pub use librashader_runtime_gl::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "d3d11")]
|
||||
/// Shader runtime for Direct3D11
|
||||
pub mod d3d11 {
|
||||
pub use librashader_runtime_d3d11::*;
|
||||
}
|
||||
|
||||
#[cfg(feature = "vk")]
|
||||
/// Shader compiler targets and runtime for Vulkan.
|
||||
pub mod vk {
|
||||
|
||||
|
|
Loading…
Reference in a new issue