Compare commits

...

14 commits

Author SHA1 Message Date
Alex Janka be4c634614 clippy fixes 2024-08-02 13:14:17 +10:00
Alex Janka b2de1697d7 fix shaderstorage in tests 2024-08-02 13:14:17 +10:00
Alex Janka 60d9f0766e nightly rust-toolchain.toml 2024-08-02 13:14:17 +10:00
Alex Janka f3a5712a8c shaders can be either a path or a string 2024-08-02 13:14:17 +10:00
chyyran 35f499f5e1 wgpu: enable pipeline caching 2024-08-01 08:37:40 -04:00
chyyran 6ce711db26 ci: don't build Arch 2024-08-01 08:37:40 -04:00
chyyran d4b4366836 dep: update ash to 0.38 2024-08-01 08:37:40 -04:00
chyyran c646086df4 dep: update wgpu
need to support caching
2024-08-01 08:37:40 -04:00
chyyran f6cf642e50 chore: Release 2024-07-29 00:44:51 -04:00
chyyran 98958dfb5e dep: update rustc_hash 2024-07-29 00:40:59 -04:00
chyyran b5d523e9f3 rt(mtl): move icrate definitions to objc2-metal 2024-07-29 00:40:59 -04:00
chyyran 5e9ce1207c Revert "ci: temporarily remove deny-deprecated on ctypes to unblock ares"
This reverts commit a8d2d1d2ada8fd7e18ee55c53ce5115ef19d6154.
2024-07-29 00:40:59 -04:00
Hubert Hirtz 1b0574c140 presets: show file name and details on io error 2024-07-29 00:40:30 -04:00
Stefan Schlosser b84e104212 capi: fix malformed vulkan include 2024-07-29 00:40:21 -04:00
85 changed files with 846 additions and 762 deletions

View file

@ -27,10 +27,6 @@ jobs:
spec: librashader.spec spec: librashader.spec
can_fail: true can_fail: true
name: Ubuntu 23.10 (.deb) name: Ubuntu 23.10 (.deb)
- repo: Arch
spec: PKGBUILD
can_fail: false
name: Arch (PKGBUILD)
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [approve-obs-build] needs: [approve-obs-build]
continue-on-error: ${{ matrix.can_fail }} continue-on-error: ${{ matrix.can_fail }}

View file

@ -18,9 +18,6 @@ jobs:
- repo: xUbuntu_23.10 - repo: xUbuntu_23.10
spec: librashader.spec spec: librashader.spec
can_fail: true can_fail: true
- repo: Arch
spec: PKGBUILD
can_fail: false
runs-on: ubuntu-latest runs-on: ubuntu-latest
continue-on-error: ${{ matrix.can_fail }} continue-on-error: ${{ matrix.can_fail }}
container: container:

365
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -47,7 +47,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import <Metal/Metal.h> #import <Metal/Metal.h>
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_VULKAN)
#include <vulkan\vulkan.h> #include <vulkan/vulkan.h>
#endif #endif

View file

@ -120,5 +120,5 @@ pub fn main() -> ExitCode {
} }
} }
return ExitCode::SUCCESS; ExitCode::SUCCESS
} }

View file

@ -2,7 +2,7 @@
name = "librashader-cache" name = "librashader-cache"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,8 +12,8 @@ description = "RetroArch shaders for all."
[dependencies] [dependencies]
serde = { version = "1.0" } serde = { version = "1.0" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7", features = ["serialize"] } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8", features = ["serialize"] }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
platform-dirs = "0.3.0" platform-dirs = "0.3.0"
blake3 = { version = "1.3.3" } blake3 = { version = "1.3.3" }
thiserror = "1.0.38" thiserror = "1.0.38"

View file

@ -46,7 +46,7 @@ pub(crate) mod internal {
pub(crate) fn get_cache() -> Result<Persy, Box<dyn Error>> { pub(crate) fn get_cache() -> Result<Persy, Box<dyn Error>> {
let cache_dir = get_cache_dir()?; let cache_dir = get_cache_dir()?;
match Persy::open_or_create_with( match Persy::open_or_create_with(
&cache_dir.join("librashader.db.1"), cache_dir.join("librashader.db.1"),
Config::new(), Config::new(),
|persy| { |persy| {
let tx = persy.begin()?; let tx = persy.begin()?;
@ -110,13 +110,13 @@ where
T: Cacheable, T: Cacheable,
{ {
if bypass_cache { if bypass_cache {
return Ok(load(factory(keys)?)?); return load(factory(keys)?);
} }
let cache = internal::get_cache(); let cache = internal::get_cache();
let Ok(cache) = cache else { let Ok(cache) = cache else {
return Ok(load(factory(keys)?)?); return load(factory(keys)?);
}; };
let hashkey = { let hashkey = {
@ -124,8 +124,8 @@ where
for subkeys in keys { for subkeys in keys {
hasher.update(subkeys.hash_bytes()); hasher.update(subkeys.hash_bytes());
} }
let hash = hasher.finalize();
hash hasher.finalize()
}; };
'attempt: { 'attempt: {
@ -145,7 +145,7 @@ where
if let Some(slice) = T::to_bytes(&blob) { if let Some(slice) = T::to_bytes(&blob) {
let _ = internal::set_blob(&cache, index, hashkey.as_bytes(), &slice); let _ = internal::set_blob(&cache, index, hashkey.as_bytes(), &slice);
} }
Ok(load(blob)?) load(blob)
} }
/// Cache a pipeline state object. /// Cache a pipeline state object.
@ -166,13 +166,13 @@ where
T: Cacheable, T: Cacheable,
{ {
if bypass_cache { if bypass_cache {
return Ok(restore_pipeline(None)?); return restore_pipeline(None);
} }
let cache = internal::get_cache(); let cache = internal::get_cache();
let Ok(cache) = cache else { let Ok(cache) = cache else {
return Ok(restore_pipeline(None)?); return restore_pipeline(None);
}; };
let hashkey = { let hashkey = {
@ -180,18 +180,15 @@ where
for subkeys in keys { for subkeys in keys {
hasher.update(subkeys.hash_bytes()); hasher.update(subkeys.hash_bytes());
} }
let hash = hasher.finalize();
hash hasher.finalize()
}; };
let pipeline = 'attempt: { let pipeline = 'attempt: {
if let Ok(Some(blob)) = internal::get_blob(&cache, index, hashkey.as_bytes()) { if let Ok(Some(blob)) = internal::get_blob(&cache, index, hashkey.as_bytes()) {
let cached = restore_pipeline(Some(blob)); let cached = restore_pipeline(Some(blob));
match cached { if let Ok(res) = cached {
Ok(res) => { break 'attempt res;
break 'attempt res;
}
_ => (),
} }
} }

View file

@ -16,3 +16,13 @@ impl Cacheable for Vec<u8> {
Some(self.to_vec()) Some(self.to_vec())
} }
} }
impl Cacheable for Option<Vec<u8>> {
fn from_bytes(bytes: &[u8]) -> Option<Self> {
Some(Some(Vec::from(bytes)))
}
fn to_bytes(&self) -> Option<Vec<u8>> {
self.clone()
}
}

View file

@ -36,8 +36,8 @@ where
let mut hasher = blake3::Hasher::new(); let mut hasher = blake3::Hasher::new();
hasher.update(source.vertex.as_bytes()); hasher.update(source.vertex.as_bytes());
hasher.update(source.fragment.as_bytes()); hasher.update(source.fragment.as_bytes());
let hash = hasher.finalize();
hash hasher.finalize()
}; };
let compilation = 'cached: { let compilation = 'cached: {

View file

@ -7,13 +7,13 @@ pub trait CacheKey {
impl CacheKey for u32 { impl CacheKey for u32 {
fn hash_bytes(&self) -> &[u8] { fn hash_bytes(&self) -> &[u8] {
&bytemuck::bytes_of(&*self) bytemuck::bytes_of(self)
} }
} }
impl CacheKey for i32 { impl CacheKey for i32 {
fn hash_bytes(&self) -> &[u8] { fn hash_bytes(&self) -> &[u8] {
&bytemuck::bytes_of(&*self) bytemuck::bytes_of(self)
} }
} }
@ -25,13 +25,13 @@ impl CacheKey for &[u8] {
impl CacheKey for Vec<u8> { impl CacheKey for Vec<u8> {
fn hash_bytes(&self) -> &[u8] { fn hash_bytes(&self) -> &[u8] {
&self self
} }
} }
impl CacheKey for Vec<u32> { impl CacheKey for Vec<u32> {
fn hash_bytes(&self) -> &[u8] { fn hash_bytes(&self) -> &[u8] {
bytemuck::cast_slice(&self) bytemuck::cast_slice(self)
} }
} }

View file

@ -3,7 +3,7 @@ name = "librashader-capi"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -29,20 +29,20 @@ __cbindgen_internal = ["runtime-all"]
# make runtime-metal depend on this, so its automatically implied. # make runtime-metal depend on this, so its automatically implied.
# this will make cbindgen generate __OBJC__ ifdefs for metal functions. # this will make cbindgen generate __OBJC__ ifdefs for metal functions.
__cbindgen_internal_objc = ["icrate", "objc2"] __cbindgen_internal_objc = ["objc2-metal", "objc2"]
[dependencies] [dependencies]
thiserror = "1.0.37" thiserror = "1.0.37"
paste = "1.0.9" paste = "1.0.9"
gl = { version = "0.14.0", optional = true } gl = { version = "0.14.0", optional = true }
rustc-hash = "1.1.0" rustc-hash = "2.0.0"
ash = { version = "0.37", optional = true } ash = { version = "0.38", optional = true }
spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1" } spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1" }
sptr = "0.3.2" sptr = "0.3.2"
[dependencies.librashader] [dependencies.librashader]
path = "../librashader" path = "../librashader"
version = "0.2.7" version = "0.2.8"
default-features = false default-features = false
features = ["reflect", "presets", "preprocess"] features = ["reflect", "presets", "preprocess"]
@ -51,7 +51,7 @@ workspace = true
optional = true optional = true
[target.'cfg(target_vendor="apple")'.dependencies] [target.'cfg(target_vendor="apple")'.dependencies]
icrate = { version = "0.1.0" , features = [ "Metal", "Metal_all" ], optional = true } objc2-metal = { version = "0.2.0" , features = [ "all" ], optional = true }
objc2 = { version = "0.5.0", features = ["apple"] , optional = true } objc2 = { version = "0.5.0", features = ["apple"] , optional = true }
[package.metadata.docs.rs] [package.metadata.docs.rs]

View file

@ -45,7 +45,7 @@ after_includes = """
#import <Metal/Metal.h> #import <Metal/Metal.h>
#endif #endif
#if defined(LIBRA_RUNTIME_VULKAN) #if defined(LIBRA_RUNTIME_VULKAN)
#include <vulkan\\vulkan.h> #include <vulkan/vulkan.h>
#endif #endif
""" """

View file

@ -181,6 +181,7 @@ pub(crate) use config_struct;
pub(crate) use config_version_set; pub(crate) use config_version_set;
#[doc(hidden)] #[doc(hidden)]
#[deny(deprecated)]
#[deprecated = "Forward declarations for cbindgen, do not use."] #[deprecated = "Forward declarations for cbindgen, do not use."]
mod __cbindgen_opaque_forward_declarations { mod __cbindgen_opaque_forward_declarations {
macro_rules! typedef_struct { macro_rules! typedef_struct {
@ -188,6 +189,7 @@ mod __cbindgen_opaque_forward_declarations {
$($(#[$($attrss)*])* $($(#[$($attrss)*])*
#[allow(unused)] #[allow(unused)]
#[doc(hidden)] #[doc(hidden)]
#[deny(deprecated)]
#[deprecated] #[deprecated]
pub struct $name; pub struct $name;
)* )*

View file

@ -66,6 +66,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#![deny(deprecated)]
extern crate alloc; extern crate alloc;

View file

@ -13,8 +13,8 @@ use std::slice;
use librashader::runtime::FilterChainParameters; use librashader::runtime::FilterChainParameters;
use librashader::runtime::{Size, Viewport}; use librashader::runtime::{Size, Viewport};
use icrate::Metal::{MTLCommandBuffer, MTLCommandQueue, MTLTexture};
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_metal::{MTLCommandBuffer, MTLCommandQueue, MTLTexture};
use crate::LIBRASHADER_API_VERSION; use crate::LIBRASHADER_API_VERSION;

View file

@ -3,7 +3,7 @@ name = "librashader-common"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -20,14 +20,14 @@ d3d12 = ["windows", "dxgi"]
dxgi = ["windows"] dxgi = ["windows"]
vulkan = ["ash"] vulkan = ["ash"]
wgpu = ["wgpu-types"] wgpu = ["wgpu-types"]
metal = ["icrate"] metal = ["objc2-metal"]
[dependencies] [dependencies]
gl = { version = "0.14.0", optional = true } gl = { version = "0.14.0", optional = true }
ash = { version = "0.37", optional = true } ash = { version = "0.38", optional = true }
wgpu-types = { version = "0.20.0", optional = true } wgpu-types = { version = "22", optional = true }
num-traits = "0.2.15" num-traits = "0.2.15"
rustc-hash = "1.1.0" rustc-hash = "2.0.0"
halfbrown = "0.2.4" halfbrown = "0.2.4"
[target.'cfg(windows)'.dependencies.windows] [target.'cfg(windows)'.dependencies.windows]
@ -42,7 +42,7 @@ features = [
"Win32_Graphics_Direct3D12", "Win32_Graphics_Direct3D12",
] ]
[target.'cfg(target_vendor="apple")'.dependencies.icrate] [target.'cfg(target_vendor="apple")'.dependencies.objc2-metal]
optional = true optional = true
version = "0.1.0" version = "0.2.0"
features = ["Metal", "Metal_all"] features = ["MTLPixelFormat", "MTLRenderCommandEncoder", "MTLSampler"]

View file

@ -42,6 +42,12 @@ use num_traits::AsPrimitive;
use std::convert::Infallible; use std::convert::Infallible;
use std::str::FromStr; use std::str::FromStr;
#[derive(Debug, Clone)]
pub enum ShaderStorage {
Path(std::path::PathBuf),
String(String),
}
#[repr(u32)] #[repr(u32)]
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
/// Supported image formats for textures. /// Supported image formats for textures.

View file

@ -1,46 +1,48 @@
use crate::{FilterMode, ImageFormat, Size, WrapMode}; use crate::{FilterMode, ImageFormat, Size, WrapMode};
use icrate::Metal; use objc2_metal::{
MTLPixelFormat, MTLSamplerAddressMode, MTLSamplerMinMagFilter, MTLSamplerMipFilter, MTLViewport,
};
impl From<ImageFormat> for Metal::MTLPixelFormat { impl From<ImageFormat> for MTLPixelFormat {
fn from(format: ImageFormat) -> Self { fn from(format: ImageFormat) -> Self {
match format { match format {
ImageFormat::Unknown => 0 as Metal::MTLPixelFormat, ImageFormat::Unknown => MTLPixelFormat(0),
ImageFormat::R8Unorm => Metal::MTLPixelFormatR8Unorm, ImageFormat::R8Unorm => MTLPixelFormat::R8Unorm,
ImageFormat::R8Uint => Metal::MTLPixelFormatR8Uint, ImageFormat::R8Uint => MTLPixelFormat::R8Uint,
ImageFormat::R8Sint => Metal::MTLPixelFormatR8Sint, ImageFormat::R8Sint => MTLPixelFormat::R8Sint,
ImageFormat::R8G8Unorm => Metal::MTLPixelFormatRG8Unorm, ImageFormat::R8G8Unorm => MTLPixelFormat::RG8Unorm,
ImageFormat::R8G8Uint => Metal::MTLPixelFormatRG8Uint, ImageFormat::R8G8Uint => MTLPixelFormat::RG8Uint,
ImageFormat::R8G8Sint => Metal::MTLPixelFormatRG8Sint, ImageFormat::R8G8Sint => MTLPixelFormat::RG8Sint,
ImageFormat::R8G8B8A8Unorm => Metal::MTLPixelFormatRGBA8Unorm, ImageFormat::R8G8B8A8Unorm => MTLPixelFormat::RGBA8Unorm,
ImageFormat::R8G8B8A8Uint => Metal::MTLPixelFormatRGBA8Uint, ImageFormat::R8G8B8A8Uint => MTLPixelFormat::RGBA8Uint,
ImageFormat::R8G8B8A8Sint => Metal::MTLPixelFormatRGBA8Sint, ImageFormat::R8G8B8A8Sint => MTLPixelFormat::RGBA8Sint,
ImageFormat::R8G8B8A8Srgb => Metal::MTLPixelFormatRGBA8Unorm_sRGB, ImageFormat::R8G8B8A8Srgb => MTLPixelFormat::RGBA8Unorm_sRGB,
ImageFormat::A2B10G10R10UnormPack32 => Metal::MTLPixelFormatRGB10A2Unorm, ImageFormat::A2B10G10R10UnormPack32 => MTLPixelFormat::RGB10A2Unorm,
ImageFormat::A2B10G10R10UintPack32 => Metal::MTLPixelFormatRGB10A2Uint, ImageFormat::A2B10G10R10UintPack32 => MTLPixelFormat::RGB10A2Uint,
ImageFormat::R16Uint => Metal::MTLPixelFormatR16Uint, ImageFormat::R16Uint => MTLPixelFormat::R16Uint,
ImageFormat::R16Sint => Metal::MTLPixelFormatR16Sint, ImageFormat::R16Sint => MTLPixelFormat::R16Sint,
ImageFormat::R16Sfloat => Metal::MTLPixelFormatR16Float, ImageFormat::R16Sfloat => MTLPixelFormat::R16Float,
ImageFormat::R16G16Uint => Metal::MTLPixelFormatRG16Uint, ImageFormat::R16G16Uint => MTLPixelFormat::RG16Uint,
ImageFormat::R16G16Sint => Metal::MTLPixelFormatRG16Sint, ImageFormat::R16G16Sint => MTLPixelFormat::RG16Sint,
ImageFormat::R16G16Sfloat => Metal::MTLPixelFormatRG16Float, ImageFormat::R16G16Sfloat => MTLPixelFormat::RG16Float,
ImageFormat::R16G16B16A16Uint => Metal::MTLPixelFormatRGBA16Uint, ImageFormat::R16G16B16A16Uint => MTLPixelFormat::RGBA16Uint,
ImageFormat::R16G16B16A16Sint => Metal::MTLPixelFormatRGBA16Sint, ImageFormat::R16G16B16A16Sint => MTLPixelFormat::RGBA16Sint,
ImageFormat::R16G16B16A16Sfloat => Metal::MTLPixelFormatRGBA16Float, ImageFormat::R16G16B16A16Sfloat => MTLPixelFormat::RGBA16Float,
ImageFormat::R32Uint => Metal::MTLPixelFormatR32Uint, ImageFormat::R32Uint => MTLPixelFormat::R32Uint,
ImageFormat::R32Sint => Metal::MTLPixelFormatR32Sint, ImageFormat::R32Sint => MTLPixelFormat::R32Sint,
ImageFormat::R32Sfloat => Metal::MTLPixelFormatR32Float, ImageFormat::R32Sfloat => MTLPixelFormat::R32Float,
ImageFormat::R32G32Uint => Metal::MTLPixelFormatRG32Uint, ImageFormat::R32G32Uint => MTLPixelFormat::RG32Uint,
ImageFormat::R32G32Sint => Metal::MTLPixelFormatRG32Sint, ImageFormat::R32G32Sint => MTLPixelFormat::RG32Sint,
ImageFormat::R32G32Sfloat => Metal::MTLPixelFormatRG32Float, ImageFormat::R32G32Sfloat => MTLPixelFormat::RG32Float,
ImageFormat::R32G32B32A32Uint => Metal::MTLPixelFormatRGBA32Uint, ImageFormat::R32G32B32A32Uint => MTLPixelFormat::RGBA32Uint,
ImageFormat::R32G32B32A32Sint => Metal::MTLPixelFormatRGBA32Sint, ImageFormat::R32G32B32A32Sint => MTLPixelFormat::RGBA32Sint,
ImageFormat::R32G32B32A32Sfloat => Metal::MTLPixelFormatRGBA32Float, ImageFormat::R32G32B32A32Sfloat => MTLPixelFormat::RGBA32Float,
} }
} }
} }
impl From<Metal::MTLViewport> for Size<u32> { impl From<MTLViewport> for Size<u32> {
fn from(value: Metal::MTLViewport) -> Self { fn from(value: MTLViewport) -> Self {
Size { Size {
width: value.width as u32, width: value.width as u32,
height: value.height as u32, height: value.height as u32,
@ -48,9 +50,9 @@ impl From<Metal::MTLViewport> for Size<u32> {
} }
} }
impl From<Size<u32>> for Metal::MTLViewport { impl From<Size<u32>> for MTLViewport {
fn from(value: Size<u32>) -> Self { fn from(value: Size<u32>) -> Self {
Metal::MTLViewport { MTLViewport {
originX: 0.0, originX: 0.0,
originY: 0.0, originY: 0.0,
width: value.width as f64, width: value.width as f64,
@ -61,32 +63,32 @@ impl From<Size<u32>> for Metal::MTLViewport {
} }
} }
impl From<WrapMode> for Metal::MTLSamplerAddressMode { impl From<WrapMode> for MTLSamplerAddressMode {
fn from(value: WrapMode) -> Self { fn from(value: WrapMode) -> Self {
match value { match value {
WrapMode::ClampToBorder => Metal::MTLSamplerAddressModeClampToBorderColor, WrapMode::ClampToBorder => MTLSamplerAddressMode::ClampToBorderColor,
WrapMode::ClampToEdge => Metal::MTLSamplerAddressModeClampToEdge, WrapMode::ClampToEdge => MTLSamplerAddressMode::ClampToEdge,
WrapMode::Repeat => Metal::MTLSamplerAddressModeRepeat, WrapMode::Repeat => MTLSamplerAddressMode::Repeat,
WrapMode::MirroredRepeat => Metal::MTLSamplerAddressModeMirrorRepeat, WrapMode::MirroredRepeat => MTLSamplerAddressMode::MirrorRepeat,
} }
} }
} }
impl From<FilterMode> for Metal::MTLSamplerMinMagFilter { impl From<FilterMode> for MTLSamplerMinMagFilter {
fn from(value: FilterMode) -> Self { fn from(value: FilterMode) -> Self {
match value { match value {
FilterMode::Linear => Metal::MTLSamplerMinMagFilterLinear, FilterMode::Linear => MTLSamplerMinMagFilter::Linear,
_ => Metal::MTLSamplerMipFilterNearest, _ => MTLSamplerMinMagFilter::Nearest,
} }
} }
} }
impl FilterMode { impl FilterMode {
/// Get the mipmap filtering mode for the given combination. /// Get the mipmap filtering mode for the given combination.
pub fn mtl_mip(&self, mip: FilterMode) -> Metal::MTLSamplerMipFilter { pub fn mtl_mip(&self, _mip: FilterMode) -> MTLSamplerMipFilter {
match self { match self {
FilterMode::Linear => Metal::MTLSamplerMipFilterLinear, FilterMode::Linear => MTLSamplerMipFilter::Linear,
FilterMode::Nearest => Metal::MTLSamplerMipFilterNearest, FilterMode::Nearest => MTLSamplerMipFilter::Nearest,
} }
} }
} }

View file

@ -3,7 +3,7 @@ name = "librashader-preprocess"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -14,7 +14,7 @@ description = "RetroArch shaders for all."
[dependencies] [dependencies]
thiserror = "1.0.37" thiserror = "1.0.37"
nom = "7.1.1" nom = "7.1.1"
librashader-common = { path = "../librashader-common", version = "0.2.7" } librashader-common = { path = "../librashader-common", version = "0.2.8" }
encoding_rs = "0.8.31" encoding_rs = "0.8.31"
[features] [features]

View file

@ -17,7 +17,6 @@ use crate::include::read_source;
pub use error::*; pub use error::*;
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_common::ImageFormat; use librashader_common::ImageFormat;
use std::path::Path;
/// The source file for a single shader pass. /// The source file for a single shader pass.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -58,8 +57,8 @@ pub struct ShaderParameter {
impl ShaderSource { impl ShaderSource {
/// Load the source file at the given path, resolving includes relative to the location of the /// Load the source file at the given path, resolving includes relative to the location of the
/// source file. /// source file.
pub fn load(path: impl AsRef<Path>) -> Result<ShaderSource, PreprocessError> { pub fn load(file: &librashader_common::ShaderStorage) -> Result<ShaderSource, PreprocessError> {
load_shader_source(path) load_shader_source(file)
} }
} }
@ -78,8 +77,14 @@ impl SourceOutput for String {
} }
} }
pub(crate) fn load_shader_source(path: impl AsRef<Path>) -> Result<ShaderSource, PreprocessError> { pub(crate) fn load_shader_source(
let source = read_source(path)?; file: &librashader_common::ShaderStorage,
) -> Result<ShaderSource, PreprocessError> {
let source = match file {
librashader_common::ShaderStorage::Path(path) => read_source(path)?,
librashader_common::ShaderStorage::String(s) => s.to_string(),
};
let meta = pragma::parse_pragma_meta(&source)?; let meta = pragma::parse_pragma_meta(&source)?;
let text = stage::process_stages(&source)?; let text = stage::process_stages(&source)?;
let parameters = FastHashMap::from_iter(meta.parameters.into_iter().map(|p| (p.id.clone(), p))); let parameters = FastHashMap::from_iter(meta.parameters.into_iter().map(|p| (p.id.clone(), p)));
@ -100,9 +105,9 @@ mod test {
#[test] #[test]
pub fn load_file() { pub fn load_file() {
let result = load_shader_source( let result = load_shader_source(&librashader_common::ShaderStorage::Path(
"../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang", "../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang".into(),
) ))
.unwrap(); .unwrap();
eprintln!("{:#}", result.vertex) eprintln!("{:#}", result.vertex)
} }

View file

@ -3,7 +3,7 @@ name = "librashader-presets"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -15,7 +15,7 @@ description = "RetroArch shaders for all."
thiserror = "1.0.37" thiserror = "1.0.37"
nom = "7.1.1" nom = "7.1.1"
nom_locate = "4.0.0" nom_locate = "4.0.0"
librashader-common = { path = "../librashader-common", version = "0.2.7" } librashader-common = { path = "../librashader-common", version = "0.2.8" }
num-traits = "0.2" num-traits = "0.2"
once_cell = "1" once_cell = "1"
# we don't need unicode # we don't need unicode

View file

@ -275,6 +275,12 @@ impl Display for ContextItem {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct WildcardContext(VecDeque<ContextItem>); pub struct WildcardContext(VecDeque<ContextItem>);
impl Default for WildcardContext {
fn default() -> Self {
Self::new()
}
}
impl WildcardContext { impl WildcardContext {
/// Create a new wildcard context. /// Create a new wildcard context.
pub fn new() -> Self { pub fn new() -> Self {
@ -391,12 +397,12 @@ pub(crate) fn apply_context(path: &mut PathBuf, context: &FastHashMap<String, St
if let Some(replacement) = context.get(key) { if let Some(replacement) = context.get(key) {
return OsString::from(replacement.to_string()).into_encoded_bytes(); return OsString::from(replacement.to_string()).into_encoded_bytes();
} }
return caps[0].to_vec(); caps[0].to_vec()
}); });
// SAFETY: The original source is valid encoded bytes, and our replacement is // SAFETY: The original source is valid encoded bytes, and our replacement is
// valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`. // valid encoded bytes. This upholds the safety requirements of `from_encoded_bytes_unchecked`.
new_path.push(unsafe { OsStr::from_encoded_bytes_unchecked(&replaced.as_ref()) }) new_path.push(unsafe { OsStr::from_encoded_bytes_unchecked(replaced.as_ref()) })
} }
_ => new_path.push(component), _ => new_path.push(component),
} }

View file

@ -25,7 +25,7 @@ pub enum ParsePresetError {
#[error("shader presets must be resolved against an absolute path")] #[error("shader presets must be resolved against an absolute path")]
RootPathWasNotAbsolute, RootPathWasNotAbsolute,
/// An IO error occurred when reading the shader preset. /// An IO error occurred when reading the shader preset.
#[error("the file was not found during resolution")] #[error("io error on file {0:?}: {1}")]
IOError(PathBuf, std::io::Error), IOError(PathBuf, std::io::Error),
/// The shader preset did not contain valid UTF-8 bytes. /// The shader preset did not contain valid UTF-8 bytes.
#[error("expected utf8 bytes but got invalid utf8")] #[error("expected utf8 bytes but got invalid utf8")]

View file

@ -115,7 +115,7 @@ pub fn resolve_values(mut values: Vec<Value>) -> ShaderPreset {
let shader = ShaderPassConfig { let shader = ShaderPassConfig {
id, id,
name, name: librashader_common::ShaderStorage::Path(name),
alias: shader_values.iter().find_map(|f| match f { alias: shader_values.iter().find_map(|f| match f {
Value::Alias(_, value) => Some(value.to_string()), Value::Alias(_, value) => Some(value.to_string()),
_ => None, _ => None,

View file

@ -23,6 +23,7 @@ use crate::extract_if::MakeExtractIf;
#[derive(Debug)] #[derive(Debug)]
pub enum Value { pub enum Value {
ShaderCount(i32), ShaderCount(i32),
#[allow(dead_code)]
FeedbackPass(i32), FeedbackPass(i32),
Shader(i32, PathBuf), Shader(i32, PathBuf),
ScaleX(i32, ScaleFactor), ScaleX(i32, ScaleFactor),
@ -376,8 +377,7 @@ pub fn parse_values(
&& t.key.ends_with(*texture) && t.key.ends_with(*texture)
&& t.key.len() == "filter_".len() + texture.len() && t.key.len() == "filter_".len() + texture.len()
}) })
// NOPANIC: infallible .map(|(_, v)| FilterMode::from_str(&v.value).unwrap());
.map_or(None, |(_, v)| Some(FilterMode::from_str(&v.value).unwrap()));
values.push(Value::Texture { values.push(Value::Texture {
name: texture.to_string(), name: texture.to_string(),

View file

@ -10,7 +10,7 @@ pub struct ShaderPassConfig {
/// The index of the shader pass relative to its parent preset. /// The index of the shader pass relative to its parent preset.
pub id: i32, pub id: i32,
/// The fully qualified path to the shader pass source file. /// The fully qualified path to the shader pass source file.
pub name: PathBuf, pub name: librashader_common::ShaderStorage,
/// The alias of the shader pass if available. /// The alias of the shader pass if available.
pub alias: Option<String>, pub alias: Option<String>,
/// The filtering mode that this shader pass should expect. /// The filtering mode that this shader pass should expect.

View file

@ -16,7 +16,7 @@ fn parses_all_slang_presets() {
#[test] #[test]
fn parses_problematic() { fn parses_problematic() {
let path = "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_NDS_DREZ/NDS-[DREZ]-[Native]-[ADV]-[Guest]-[Night].slangp"; let path = "../test/Mega_Bezel_Packs/Duimon-Mega-Bezel/Presets/Advanced/Nintendo_NDS_DREZ/NDS-[DREZ]-[Native]-[ADV]-[Guest]-[Night].slangp";
ShaderPreset::try_parse(path).expect(&format!("Failed to parse {}", path)); ShaderPreset::try_parse(path).unwrap_or_else(|_| panic!("Failed to parse {}", path));
} }
#[test] #[test]
@ -30,5 +30,5 @@ fn parses_wildcard() {
context.append_item(ContextItem::CoreName(String::from("image display"))); context.append_item(ContextItem::CoreName(String::from("image display")));
ShaderPreset::try_parse_with_context(path, context) ShaderPreset::try_parse_with_context(path, context)
.expect(&format!("Failed to parse {}", path)); .unwrap_or_else(|_| panic!("Failed to parse {}", path));
} }

View file

@ -3,7 +3,7 @@ name = "librashader-reflect"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -18,13 +18,13 @@ bytemuck = "1.13.0"
thiserror = "1.0.37" thiserror = "1.0.37"
bitflags = "2.4.2" bitflags = "2.4.2"
librashader-common = { path = "../librashader-common", version = "0.2.7" } librashader-common = { path = "../librashader-common", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1", optional = true } spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1", optional = true }
naga = { version = "0.20.0", optional = true } naga = { version = "22", optional = true }
rspirv = { version = "0.12.0", optional = true } rspirv = { version = "0.12.0", optional = true }
spirv = { version = "0.3.0", optional = true} spirv = { version = "0.3.0", optional = true}
@ -32,7 +32,7 @@ serde = { version = "1.0", features = ["derive"], optional = true }
indexmap = { version = "2.1.0", features = [] } indexmap = { version = "2.1.0", features = [] }
matches = { version = "0.1.10", features = [] } matches = { version = "0.1.10", features = [] }
rustc-hash = "1.1.0" rustc-hash = "2.0.0"
[target.'cfg(windows)'.dependencies.spirv-to-dxil] [target.'cfg(windows)'.dependencies.spirv-to-dxil]
version = "0.4.7" version = "0.4.7"

View file

@ -47,7 +47,7 @@ impl HlslBufferAssignments {
{ {
return true; return true;
} }
return false; false
} }
// Check if the mangled name matches. // Check if the mangled name matches.
@ -87,7 +87,7 @@ impl HlslBufferAssignments {
} }
} }
return false; false
} }
} }

View file

@ -18,7 +18,7 @@ impl<'a> LinkInputs<'a> {
return None; return None;
}; };
let Some(&Operand::IdRef(target)) = op.operands.get(0) else { let Some(&Operand::IdRef(target)) = op.operands.first() else {
return None; return None;
}; };
@ -29,7 +29,7 @@ impl<'a> LinkInputs<'a> {
let Some(&Operand::LiteralBit32(binding)) = op.operands.get(2) else { let Some(&Operand::LiteralBit32(binding)) = op.operands.get(2) else {
return None; return None;
}; };
return Some(binding); Some(binding)
}) })
} }
@ -62,7 +62,7 @@ impl<'a> LinkInputs<'a> {
if let Some(frag_ref) = bindings.get(&location) { if let Some(frag_ref) = bindings.get(&location) {
// if something is bound to the same location in the vertex shader, // if something is bound to the same location in the vertex shader,
// we're good. // we're good.
inputs.remove(&frag_ref); inputs.remove(frag_ref);
} }
} }
} }
@ -112,7 +112,7 @@ impl<'a> LinkInputs<'a> {
} }
} }
} }
return true; true
}); });
self.frag_builder.module_mut().annotations.retain(|instr| { self.frag_builder.module_mut().annotations.retain(|instr| {
@ -123,7 +123,7 @@ impl<'a> LinkInputs<'a> {
} }
} }
} }
return true; true
}); });
for entry_point in self.frag_builder.module_mut().entry_points.iter_mut() { for entry_point in self.frag_builder.module_mut().entry_points.iter_mut() {
@ -133,7 +133,7 @@ impl<'a> LinkInputs<'a> {
return false; return false;
} }
} }
return true; true
}) })
} }

View file

@ -33,12 +33,12 @@ struct OpAccessChain<'a> {
impl<'a> LowerCombinedImageSamplerPass<'a> { impl<'a> LowerCombinedImageSamplerPass<'a> {
pub fn new(builder: &'a mut Builder) -> Self { pub fn new(builder: &'a mut Builder) -> Self {
let val = Self {
Self {
builder, builder,
seen_functions: FxHashSet::default(), seen_functions: FxHashSet::default(),
}; }
val
} }
pub(crate) fn do_pass(&mut self) { pub(crate) fn do_pass(&mut self) {
@ -109,7 +109,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
return None; return None;
} }
let Some(&Operand::IdRef(target)) = &i.operands.get(0) else { let Some(&Operand::IdRef(target)) = &i.operands.first() else {
return None; return None;
}; };
@ -121,7 +121,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
return None; return None;
}; };
return Some(format!("_{string}_sampler")); Some(format!("_{string}_sampler"))
}) })
} }
@ -130,7 +130,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
return None; return None;
} }
let Some(&Operand::IdRef(referand)) = inst.operands.get(0) else { let Some(&Operand::IdRef(referand)) = inst.operands.first() else {
return None; return None;
}; };
@ -183,7 +183,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
self.builder.decorate( self.builder.decorate(
sampler_uniform, sampler_uniform,
decoration_type, decoration_type,
decoration.operands[2..].iter().map(|f| f.clone()), decoration.operands[2..].iter().cloned(),
) )
} }
@ -264,7 +264,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
} }
if uniform_type.class.opcode == spirv::Op::TypeArray { if uniform_type.class.opcode == spirv::Op::TypeArray {
let Some(&Operand::IdRef(array_base_type)) = uniform_type.operands.get(0) let Some(&Operand::IdRef(array_base_type)) = uniform_type.operands.first()
else { else {
continue; continue;
}; };
@ -402,7 +402,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
} }
// This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass. // This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass.
let Some(Operand::IdRef(op_variable_id)) = &instr.operands.get(0) else { let Some(Operand::IdRef(op_variable_id)) = &instr.operands.first() else {
instructions.push(instr); instructions.push(instr);
continue; continue;
}; };
@ -474,7 +474,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
} }
// This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass. // This doesn't affect array loads because array loads load the result of the OpAccessChain which can be done in a separate pass.
let Some(Operand::IdRef(op_variable)) = &instr.operands.get(0) else { let Some(Operand::IdRef(op_variable)) = &instr.operands.first() else {
instructions.push(instr); instructions.push(instr);
continue; continue;
}; };
@ -565,7 +565,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
continue; continue;
} }
let Some(Operand::IdRef(op_variable)) = &instr.operands.get(0) else { let Some(Operand::IdRef(op_variable)) = &instr.operands.first() else {
instructions.push(instr); instructions.push(instr);
continue; continue;
}; };
@ -656,7 +656,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
continue; continue;
} }
let Some(&Operand::IdRef(function_id)) = instr.operands.get(0) else { let Some(&Operand::IdRef(function_id)) = instr.operands.first() else {
continue; continue;
}; };
@ -729,7 +729,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
continue; continue;
} }
let Some(&Operand::IdRef(function_id)) = instr.operands.get(0) else { let Some(&Operand::IdRef(function_id)) = instr.operands.first() else {
instructions.push(instr); instructions.push(instr);
continue; continue;
}; };
@ -742,7 +742,7 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
return false; return false;
}; };
op_access_chains.contains_key(&op_ref_id) op_access_chains.contains_key(op_ref_id)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -861,9 +861,9 @@ impl<'a> LowerCombinedImageSamplerPass<'a> {
seen_functions seen_functions
} }
fn rewrite_functions_definitions<'b>( fn rewrite_functions_definitions(
&mut self, &mut self,
mappings: &FxHashMap<spirv::Word, FxHashMap<spirv::Word, Cow<'b, CombinedImageSampler>>>, mappings: &FxHashMap<spirv::Word, FxHashMap<spirv::Word, Cow<'_, CombinedImageSampler>>>,
) -> FxHashMap<spirv::Word, CombinedImageSampler> { ) -> FxHashMap<spirv::Word, CombinedImageSampler> {
let mut sampled_refs = FxHashMap::default(); let mut sampled_refs = FxHashMap::default();
let mut functions = self.builder.module_ref().functions.clone(); let mut functions = self.builder.module_ref().functions.clone();

View file

@ -5,6 +5,6 @@ pub mod lower_samplers;
pub(crate) fn load_module(words: &[u32]) -> rspirv::dr::Module { pub(crate) fn load_module(words: &[u32]) -> rspirv::dr::Module {
let mut loader = rspirv::dr::Loader::new(); let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(words, &mut loader).unwrap(); rspirv::binary::parse_words(words, &mut loader).unwrap();
let module = loader.module();
module loader.module()
} }

View file

@ -754,7 +754,10 @@ mod test {
#[test] #[test]
pub fn test_into() { pub fn test_into() {
let result = ShaderSource::load("../test/basic.slang").unwrap(); let result = ShaderSource::load(&librashader_common::ShaderStorage::Path(
"../test/basic.slang".into(),
))
.unwrap();
let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default(); let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default();
for (_index, param) in result.parameters.iter().enumerate() { for (_index, param) in result.parameters.iter().enumerate() {

View file

@ -120,7 +120,10 @@ mod test {
pub fn test_into() { pub fn test_into() {
// let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap(); // let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
// let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap(); // let result = ShaderSource::load("../test/shaders_slang/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
let result = ShaderSource::load("../test/basic.slang").unwrap(); let result = ShaderSource::load(&librashader_common::ShaderStorage::Path(
"../test/basic.slang".into(),
))
.unwrap();
let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default(); let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default();

View file

@ -205,7 +205,7 @@ impl ValidateTypeSemantics<&TypeInner> for UniqueSemantics {
} }
}; };
return None; None
} }
} }
@ -426,13 +426,13 @@ impl NagaReflect {
// Verify types // Verify types
if self.vertex.global_variables.iter().any(|(_, gv)| { if self.vertex.global_variables.iter().any(|(_, gv)| {
let ty = &self.vertex.types[gv.ty]; let ty = &self.vertex.types[gv.ty];
match ty.inner { !matches!(
ty.inner,
TypeInner::Scalar { .. } TypeInner::Scalar { .. }
| TypeInner::Vector { .. } | TypeInner::Vector { .. }
| TypeInner::Matrix { .. } | TypeInner::Matrix { .. }
| TypeInner::Struct { .. } => false, | TypeInner::Struct { .. }
_ => true, )
}
}) { }) {
return Err(ShaderReflectError::VertexSemanticError( return Err(ShaderReflectError::VertexSemanticError(
SemanticsErrorKind::InvalidResourceType, SemanticsErrorKind::InvalidResourceType,
@ -483,7 +483,7 @@ impl NagaReflect {
SemanticsErrorKind::InvalidInputCount(vert_inputs), SemanticsErrorKind::InvalidInputCount(vert_inputs),
)); ));
} }
for input in &vertex_entry_point.function.arguments { if let Some(input) = &vertex_entry_point.function.arguments.first() {
let &Some(Binding::Location { location, .. }) = &input.binding else { let &Some(Binding::Location { location, .. }) = &input.binding else {
return Err(ShaderReflectError::VertexSemanticError( return Err(ShaderReflectError::VertexSemanticError(
SemanticsErrorKind::MissingBinding, SemanticsErrorKind::MissingBinding,
@ -644,7 +644,7 @@ impl NagaReflect {
offset_type: UniformMemberBlock, offset_type: UniformMemberBlock,
blame: SemanticErrorBlame, blame: SemanticErrorBlame,
) -> Result<(), ShaderReflectError> { ) -> Result<(), ShaderReflectError> {
let reachable = Self::collect_uniform_names(&module, resource, blame)?; let reachable = Self::collect_uniform_names(module, resource, blame)?;
let resource = &module.global_variables[resource]; let resource = &module.global_variables[resource];
@ -824,7 +824,7 @@ impl NagaReflect {
Ok(TextureData { Ok(TextureData {
// id: texture.id, // id: texture.id,
// descriptor_set, // descriptor_set,
name: &name, name,
binding: binding.binding, binding: binding.binding,
}) })
} }
@ -1002,44 +1002,3 @@ impl ReflectShader for NagaReflect {
}) })
} }
} }
#[cfg(test)]
mod test {
use crate::reflect::semantics::{Semantic, TextureSemantics, UniformSemantic};
use librashader_common::map::FastHashMap;
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPreset;
// #[test]
// pub fn test_into() {
// let result = ShaderSource::load("../test/slang-shaders/crt/shaders/crt-royale/src/crt-royale-scanlines-horizontal-apply-mask.slang").unwrap();
// let compilation = crate::front::GlslangCompilation::try_from(&result).unwrap();
//
// let mut loader = rspirv::dr::Loader::new();
// rspirv::binary::parse_words(compilation.vertex.as_binary(), &mut loader).unwrap();
// let module = loader.module();
//
// let outputs: Vec<&Instruction> = module
// .types_global_values
// .iter()
// .filter(|i| i.class.opcode == Op::Variable)
// .collect();
//
// println!("{outputs:#?}");
// }
// #[test]
// pub fn mega_bezel_reflect() {
// let preset = ShaderPreset::try_parse(
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
// )
// .unwrap();
//
// let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default();
// let mut texture_semantics: FastHashMap<String, Semantic<TextureSemantics>> = Default::default();
//
//
//
//
// }
}

View file

@ -53,13 +53,15 @@ impl CompileShader<MSL> for NagaReflect {
) -> Result<(String, TranslationInfo), ShaderCompileError> { ) -> Result<(String, TranslationInfo), ShaderCompileError> {
let mut valid = let mut valid =
naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty()); naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty());
let info = valid.validate(&module)?; let info = valid.validate(module)?;
let pipeline_options = PipelineOptions { let pipeline_options = PipelineOptions {
allow_and_force_point_size: false, allow_and_force_point_size: false,
vertex_pulling_transform: false,
vertex_buffer_mappings: vec![],
}; };
let msl = naga::back::msl::write_string(&module, &info, &options, &pipeline_options)?; let msl = naga::back::msl::write_string(module, &info, &options, &pipeline_options)?;
Ok(msl) Ok(msl)
} }
@ -170,7 +172,10 @@ mod test {
#[test] #[test]
pub fn test_into() { pub fn test_into() {
let result = ShaderSource::load("../test/basic.slang").unwrap(); let result = ShaderSource::load(&librashader_common::ShaderStorage::Path(
"../test/basic.slang".into(),
))
.unwrap();
let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default(); let mut uniform_semantics: FastHashMap<String, UniformSemantic> = Default::default();

View file

@ -22,12 +22,14 @@ impl CompileShader<SPIRV> for NagaReflect {
) -> Result<Vec<u32>, ShaderCompileError> { ) -> Result<Vec<u32>, ShaderCompileError> {
let mut valid = let mut valid =
naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty()); naga::valid::Validator::new(ValidationFlags::all(), Capabilities::empty());
let info = valid.validate(&module)?; let info = valid.validate(module)?;
let mut options = naga::back::spv::Options::default(); let options = naga::back::spv::Options {
options.lang_version = version; lang_version: version,
..Default::default()
};
let spv = naga::back::spv::write_vec( let spv = naga::back::spv::write_vec(
&module, module,
&info, &info,
&options, &options,
Some(&PipelineOptions { Some(&PipelineOptions {

View file

@ -16,7 +16,7 @@ impl CompileShader<WGSL> for NagaReflect {
options: Self::Options, options: Self::Options,
) -> Result<ShaderCompilerOutput<String, Self::Context>, ShaderCompileError> { ) -> Result<ShaderCompilerOutput<String, Self::Context>, ShaderCompileError> {
fn write_wgsl(module: &Module, info: &ModuleInfo) -> Result<String, ShaderCompileError> { fn write_wgsl(module: &Module, info: &ModuleInfo) -> Result<String, ShaderCompileError> {
let wgsl = naga::back::wgsl::write_string(&module, &info, WriterFlags::empty())?; let wgsl = naga::back::wgsl::write_string(module, info, WriterFlags::empty())?;
Ok(wgsl) Ok(wgsl)
} }

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-d3d11"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["d3d11"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.8", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"
bytemuck = "1.12.3" bytemuck = "1.12.3"

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-d3d12"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["d3d12"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["d3d12"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7", features = ["dxil"] } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8", features = ["dxil"] }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.8", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-d3d9"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["d3d9", "d3d11"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["d3d9", "d3d11"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7", features = ["d3d"] } librashader-cache = { path = "../librashader-cache", version = "0.2.8", features = ["d3d"] }
thiserror = "1.0.37" thiserror = "1.0.37"
bytemuck = "1.12.3" bytemuck = "1.12.3"

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-gl"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,12 +12,12 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["opengl"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["opengl"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.8" }
spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1" } spirv_cross = { package = "librashader-spirv-cross", version = "0.25.1" }
gl = "0.14.0" gl = "0.14.0"

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-mtl"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -14,11 +14,11 @@ description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["metal"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["metal"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.8" }
thiserror = "1.0" thiserror = "1.0"
array-concat = "0.5.2" array-concat = "0.5.2"
@ -34,12 +34,14 @@ harness = false
targets = ["x86_64-apple-darwin", "aarch64-apple-darwin", "aarch64-apple-ios"] targets = ["x86_64-apple-darwin", "aarch64-apple-darwin", "aarch64-apple-ios"]
[target.'cfg(target_vendor="apple")'.dependencies] [target.'cfg(target_vendor="apple")'.dependencies]
icrate = { version = "0.1.0" , features = [ "Metal", "Metal_all" ] } objc2-metal = { version = "0.2", features = ["all"] }
objc2-foundation = { version = "0.2", features = ["NSError"] }
objc2 = { version = "0.5.0", features = ["apple"] } objc2 = { version = "0.5.0", features = ["apple"] }
[features] [features]
run_test = ["icrate/AppKit", "icrate/AppKit_all", "icrate/Foundation", "icrate/Foundation_all", "icrate/MetalKit", "icrate/MetalKit_all"] # run_test = ["icrate/AppKit", "i "icrate/Foundation_all", "icrate/MetalKit", "icrate/MetalKit_all"]
#[lib] #[lib]
#crate-type = ["lib", "staticlib"] #crate-type = ["lib", "staticlib"]

View file

@ -1,16 +1,13 @@
use crate::error; use crate::error;
use crate::error::FilterChainError; use crate::error::FilterChainError;
use icrate::Foundation::{NSRange, NSString}; use objc2::rc::Retained;
use icrate::Metal::{
MTLBuffer, MTLDevice, MTLResource, MTLResourceOptions, MTLResourceStorageModeManaged,
MTLResourceStorageModeShared,
};
use objc2::rc::Id;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_foundation::{NSRange, NSString};
use objc2_metal::{MTLBuffer, MTLDevice, MTLResource, MTLResourceOptions};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
pub struct MetalBuffer { pub struct MetalBuffer {
buffer: Id<ProtocolObject<dyn MTLBuffer>>, buffer: Retained<ProtocolObject<dyn MTLBuffer>>,
size: usize, size: usize,
storage_mode: MTLResourceOptions, storage_mode: MTLResourceOptions,
} }
@ -28,9 +25,9 @@ impl MetalBuffer {
label: &str, label: &str,
) -> error::Result<Self> { ) -> error::Result<Self> {
let storage_mode = if cfg!(all(target_arch = "aarch64", target_vendor = "apple")) { let storage_mode = if cfg!(all(target_arch = "aarch64", target_vendor = "apple")) {
MTLResourceStorageModeShared MTLResourceOptions::MTLResourceStorageModeShared
} else { } else {
MTLResourceStorageModeManaged MTLResourceOptions::MTLResourceStorageModeManaged
}; };
// Can't create buffer of size 0. // Can't create buffer of size 0.
@ -53,7 +50,7 @@ impl MetalBuffer {
pub fn flush(&self) { pub fn flush(&self) {
// We don't know what was actually written to so... // We don't know what was actually written to so...
if self.storage_mode == MTLResourceStorageModeManaged { if self.storage_mode == MTLResourceOptions::MTLResourceStorageModeManaged {
self.buffer.didModifyRange(NSRange { self.buffer.didModifyRange(NSRange {
location: 0, location: 0,
length: self.size, length: self.size,

View file

@ -1,11 +1,10 @@
use array_concat::concat_arrays; use array_concat::concat_arrays;
use icrate::Metal::{
MTLBuffer, MTLDevice, MTLPrimitiveTypeTriangleStrip, MTLRenderCommandEncoder,
MTLResourceStorageModeManaged, MTLResourceStorageModeShared,
};
use librashader_runtime::quad::{QuadType, VertexInput}; use librashader_runtime::quad::{QuadType, VertexInput};
use objc2::rc::Id; use objc2::rc::Retained;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_metal::{
MTLBuffer, MTLDevice, MTLPrimitiveType, MTLRenderCommandEncoder, MTLResourceOptions,
};
use std::ffi::c_void; use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -53,7 +52,7 @@ const FINAL_VBO_DATA: [VertexInput; 4] = [
const VBO_DATA: [VertexInput; 8] = concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA); const VBO_DATA: [VertexInput; 8] = concat_arrays!(OFFSCREEN_VBO_DATA, FINAL_VBO_DATA);
pub struct DrawQuad { pub struct DrawQuad {
buffer: Id<ProtocolObject<dyn MTLBuffer>>, buffer: Retained<ProtocolObject<dyn MTLBuffer>>,
} }
impl DrawQuad { impl DrawQuad {
@ -83,9 +82,9 @@ impl DrawQuad {
NonNull::new_unchecked(vbo_data.as_ptr() as *mut c_void), NonNull::new_unchecked(vbo_data.as_ptr() as *mut c_void),
vbo_data.len(), vbo_data.len(),
if cfg!(target_os = "ios") { if cfg!(target_os = "ios") {
MTLResourceStorageModeShared MTLResourceOptions::MTLResourceStorageModeShared
} else { } else {
MTLResourceStorageModeManaged MTLResourceOptions::MTLResourceStorageModeManaged
}, },
) )
.ok_or(FilterChainError::BufferError)? .ok_or(FilterChainError::BufferError)?
@ -103,7 +102,7 @@ impl DrawQuad {
unsafe { unsafe {
cmd.setVertexBuffer_offset_atIndex(Some(&self.buffer), 0, VERTEX_BUFFER_INDEX); cmd.setVertexBuffer_offset_atIndex(Some(&self.buffer), 0, VERTEX_BUFFER_INDEX);
cmd.drawPrimitives_vertexStart_vertexCount(MTLPrimitiveTypeTriangleStrip, offset, 4); cmd.drawPrimitives_vertexStart_vertexCount(MTLPrimitiveType::TriangleStrip, offset, 4);
} }
} }
} }

View file

@ -1,11 +1,11 @@
//! Metal shader runtime errors. //! Metal shader runtime errors.
use icrate::Foundation::NSError;
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use librashader_preprocess::PreprocessError; use librashader_preprocess::PreprocessError;
use librashader_presets::ParsePresetError; use librashader_presets::ParsePresetError;
use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; use librashader_reflect::error::{ShaderCompileError, ShaderReflectError};
use librashader_runtime::image::ImageError; use librashader_runtime::image::ImageError;
use objc2::rc::Id; use objc2::rc::Retained;
use objc2_foundation::NSError;
use thiserror::Error; use thiserror::Error;
/// Cumulative error type for Metal filter chains. /// Cumulative error type for Metal filter chains.
@ -26,7 +26,7 @@ pub enum FilterChainError {
#[error("buffer creation error")] #[error("buffer creation error")]
BufferError, BufferError,
#[error("metal error")] #[error("metal error")]
MetalError(#[from] Id<NSError>), MetalError(#[from] Retained<NSError>),
#[error("couldn't find entry for shader")] #[error("couldn't find entry for shader")]
ShaderWrongEntryName, ShaderWrongEntryName,
#[error("couldn't create render pass")] #[error("couldn't create render pass")]

View file

@ -8,12 +8,6 @@ use crate::luts::LutTexture;
use crate::options::{FilterChainOptionsMetal, FrameOptionsMetal}; use crate::options::{FilterChainOptionsMetal, FrameOptionsMetal};
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::{get_texture_size, InputTexture, MetalTextureRef, OwnedTexture}; use crate::texture::{get_texture_size, InputTexture, MetalTextureRef, OwnedTexture};
use icrate::Foundation::NSString;
use icrate::Metal::{
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLLoadActionClear,
MTLPixelFormat, MTLPixelFormatRGBA8Unorm, MTLRenderPassDescriptor, MTLResource,
MTLStoreActionDontCare, MTLStoreActionStore, MTLTexture,
};
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;
@ -35,6 +29,11 @@ use librashader_runtime::scaling::ScaleFramebuffer;
use librashader_runtime::uniforms::UniformStorage; use librashader_runtime::uniforms::UniformStorage;
use objc2::rc::Id; use objc2::rc::Id;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_foundation::NSString;
use objc2_metal::{
MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLLoadAction, MTLPixelFormat,
MTLRenderPassDescriptor, MTLResource, MTLStoreAction, MTLTexture,
};
use rayon::prelude::*; use rayon::prelude::*;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
@ -184,8 +183,8 @@ impl FilterChainMetal {
let graphics_pipeline = MetalGraphicsPipeline::new( let graphics_pipeline = MetalGraphicsPipeline::new(
&device, &device,
&msl, &msl,
if render_pass_format == 0 { if render_pass_format == MTLPixelFormat(0) {
MTLPixelFormatRGBA8Unorm MTLPixelFormat::RGBA8Unorm
} else { } else {
render_pass_format render_pass_format
}, },
@ -344,11 +343,11 @@ impl FilterChainMetal {
let desc = MTLRenderPassDescriptor::new(); let desc = MTLRenderPassDescriptor::new();
desc.colorAttachments() desc.colorAttachments()
.objectAtIndexedSubscript(0) .objectAtIndexedSubscript(0)
.setLoadAction(MTLLoadActionClear); .setLoadAction(MTLLoadAction::Clear);
desc.colorAttachments() desc.colorAttachments()
.objectAtIndexedSubscript(0) .objectAtIndexedSubscript(0)
.setStoreAction(MTLStoreActionDontCare); .setStoreAction(MTLStoreAction::DontCare);
desc desc
}; };
@ -360,8 +359,8 @@ impl FilterChainMetal {
.colorAttachments() .colorAttachments()
.objectAtIndexedSubscript(index); .objectAtIndexedSubscript(index);
ca.setTexture(Some(&history.texture)); ca.setTexture(Some(&history.texture));
ca.setLoadAction(MTLLoadActionClear); ca.setLoadAction(MTLLoadAction::Clear);
ca.setStoreAction(MTLStoreActionStore); ca.setStoreAction(MTLStoreAction::Store);
} }
} }
} }

View file

@ -5,7 +5,6 @@ use crate::graphics_pipeline::MetalGraphicsPipeline;
use crate::options::FrameOptionsMetal; use crate::options::FrameOptionsMetal;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::{get_texture_size, InputTexture}; use crate::texture::{get_texture_size, InputTexture};
use icrate::Metal::{MTLCommandBuffer, MTLCommandEncoder, MTLRenderCommandEncoder, MTLTexture};
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_common::{ImageFormat, Size, Viewport}; use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
@ -18,6 +17,7 @@ use librashader_runtime::quad::QuadType;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage}; use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage};
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_metal::{MTLCommandBuffer, MTLCommandEncoder, MTLRenderCommandEncoder, MTLTexture};
impl TextureInput for InputTexture { impl TextureInput for InputTexture {
fn size(&self) -> Size<u32> { fn size(&self) -> Size<u32> {

View file

@ -1,22 +1,21 @@
use crate::error::{FilterChainError, Result}; use crate::error::{FilterChainError, Result};
use crate::select_optimal_pixel_format; use crate::select_optimal_pixel_format;
use bytemuck::offset_of; use bytemuck::offset_of;
use icrate::Foundation::NSString;
use icrate::Metal::{
MTLBlendFactorOneMinusSourceAlpha, MTLBlendFactorSourceAlpha, MTLCommandBuffer,
MTLCommandEncoder, MTLDevice, MTLFunction, MTLLibrary, MTLLoadActionDontCare, MTLPixelFormat,
MTLPrimitiveTopologyClassTriangle, MTLRenderCommandEncoder, MTLRenderPassDescriptor,
MTLRenderPipelineColorAttachmentDescriptor, MTLRenderPipelineDescriptor,
MTLRenderPipelineState, MTLScissorRect, MTLStoreActionStore, MTLTexture,
MTLVertexAttributeDescriptor, MTLVertexBufferLayoutDescriptor, MTLVertexDescriptor,
MTLVertexFormatFloat2, MTLVertexFormatFloat4, MTLVertexStepFunctionPerVertex, MTLViewport,
};
use librashader_reflect::back::msl::{CrossMslContext, NagaMslContext}; use librashader_reflect::back::msl::{CrossMslContext, NagaMslContext};
use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::back::ShaderCompilerOutput;
use librashader_runtime::quad::VertexInput; use librashader_runtime::quad::VertexInput;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use objc2_foundation::NSString;
use objc2_metal::{
MTLBlendFactor, MTLCommandBuffer, MTLCommandEncoder, MTLDevice, MTLFunction, MTLLibrary,
MTLLoadAction, MTLPixelFormat, MTLPrimitiveTopologyClass, MTLRenderCommandEncoder,
MTLRenderPassDescriptor, MTLRenderPipelineColorAttachmentDescriptor,
MTLRenderPipelineDescriptor, MTLRenderPipelineState, MTLScissorRect, MTLStoreAction,
MTLTexture, MTLVertexAttributeDescriptor, MTLVertexBufferLayoutDescriptor, MTLVertexDescriptor,
MTLVertexFormat, MTLVertexStepFunction, MTLViewport,
};
use objc2::rc::Id; use objc2::rc::Retained;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
/// This is only really plausible for SPIRV-Cross, for Naga we need to supply the next plausible binding. /// This is only really plausible for SPIRV-Cross, for Naga we need to supply the next plausible binding.
@ -24,29 +23,29 @@ pub const VERTEX_BUFFER_INDEX: usize = 4;
pub struct MetalGraphicsPipeline { pub struct MetalGraphicsPipeline {
pub layout: PipelineLayoutObjects, pub layout: PipelineLayoutObjects,
render_pipeline: Id<ProtocolObject<dyn MTLRenderPipelineState>>, render_pipeline: Retained<ProtocolObject<dyn MTLRenderPipelineState>>,
pub render_pass_format: MTLPixelFormat, pub render_pass_format: MTLPixelFormat,
} }
pub struct PipelineLayoutObjects { pub struct PipelineLayoutObjects {
_vertex_lib: Id<ProtocolObject<dyn MTLLibrary>>, _vertex_lib: Retained<ProtocolObject<dyn MTLLibrary>>,
_fragment_lib: Id<ProtocolObject<dyn MTLLibrary>>, _fragment_lib: Retained<ProtocolObject<dyn MTLLibrary>>,
vertex_entry: Id<ProtocolObject<dyn MTLFunction>>, vertex_entry: Retained<ProtocolObject<dyn MTLFunction>>,
fragment_entry: Id<ProtocolObject<dyn MTLFunction>>, fragment_entry: Retained<ProtocolObject<dyn MTLFunction>>,
} }
pub(crate) trait MslEntryPoint { pub(crate) trait MslEntryPoint {
fn entry_point() -> Id<NSString>; fn entry_point() -> Retained<NSString>;
} }
impl MslEntryPoint for CrossMslContext { impl MslEntryPoint for CrossMslContext {
fn entry_point() -> Id<NSString> { fn entry_point() -> Retained<NSString> {
NSString::from_str("main0") NSString::from_str("main0")
} }
} }
impl MslEntryPoint for NagaMslContext { impl MslEntryPoint for NagaMslContext {
fn entry_point() -> Id<NSString> { fn entry_point() -> Retained<NSString> {
NSString::from_str("main_") NSString::from_str("main_")
} }
} }
@ -78,7 +77,7 @@ impl PipelineLayoutObjects {
}) })
} }
unsafe fn create_vertex_descriptor() -> Id<MTLVertexDescriptor> { unsafe fn create_vertex_descriptor() -> Retained<MTLVertexDescriptor> {
let descriptor = MTLVertexDescriptor::new(); let descriptor = MTLVertexDescriptor::new();
let attributes = descriptor.attributes(); let attributes = descriptor.attributes();
let layouts = descriptor.layouts(); let layouts = descriptor.layouts();
@ -89,11 +88,11 @@ impl PipelineLayoutObjects {
let texcoord = MTLVertexAttributeDescriptor::new(); let texcoord = MTLVertexAttributeDescriptor::new();
// hopefully metal fills in vertices otherwise we'll need to use the vec4 stuff. // hopefully metal fills in vertices otherwise we'll need to use the vec4 stuff.
position.setFormat(MTLVertexFormatFloat4); position.setFormat(MTLVertexFormat::Float4);
position.setBufferIndex(VERTEX_BUFFER_INDEX); position.setBufferIndex(VERTEX_BUFFER_INDEX);
position.setOffset(offset_of!(VertexInput, position)); position.setOffset(offset_of!(VertexInput, position));
texcoord.setFormat(MTLVertexFormatFloat2); texcoord.setFormat(MTLVertexFormat::Float2);
texcoord.setBufferIndex(VERTEX_BUFFER_INDEX); texcoord.setBufferIndex(VERTEX_BUFFER_INDEX);
texcoord.setOffset(offset_of!(VertexInput, texcoord)); texcoord.setOffset(offset_of!(VertexInput, texcoord));
@ -101,7 +100,7 @@ impl PipelineLayoutObjects {
attributes.setObject_atIndexedSubscript(Some(&texcoord), 1); attributes.setObject_atIndexedSubscript(Some(&texcoord), 1);
binding.setStepFunction(MTLVertexStepFunctionPerVertex); binding.setStepFunction(MTLVertexStepFunction::PerVertex);
binding.setStride(std::mem::size_of::<VertexInput>()); binding.setStride(std::mem::size_of::<VertexInput>());
layouts.setObject_atIndexedSubscript(Some(&binding), VERTEX_BUFFER_INDEX); layouts.setObject_atIndexedSubscript(Some(&binding), VERTEX_BUFFER_INDEX);
@ -109,15 +108,15 @@ impl PipelineLayoutObjects {
} }
unsafe fn create_color_attachments( unsafe fn create_color_attachments(
ca: Id<MTLRenderPipelineColorAttachmentDescriptor>, ca: Retained<MTLRenderPipelineColorAttachmentDescriptor>,
format: MTLPixelFormat, format: MTLPixelFormat,
) -> Id<MTLRenderPipelineColorAttachmentDescriptor> { ) -> Retained<MTLRenderPipelineColorAttachmentDescriptor> {
ca.setPixelFormat(select_optimal_pixel_format(format)); ca.setPixelFormat(select_optimal_pixel_format(format));
ca.setBlendingEnabled(false); ca.setBlendingEnabled(false);
ca.setSourceAlphaBlendFactor(MTLBlendFactorSourceAlpha); ca.setSourceAlphaBlendFactor(MTLBlendFactor::SourceAlpha);
ca.setSourceRGBBlendFactor(MTLBlendFactorSourceAlpha); ca.setSourceRGBBlendFactor(MTLBlendFactor::SourceAlpha);
ca.setDestinationAlphaBlendFactor(MTLBlendFactorOneMinusSourceAlpha); ca.setDestinationAlphaBlendFactor(MTLBlendFactor::OneMinusSourceAlpha);
ca.setDestinationRGBBlendFactor(MTLBlendFactorOneMinusSourceAlpha); ca.setDestinationRGBBlendFactor(MTLBlendFactor::OneMinusSourceAlpha);
ca ca
} }
@ -126,12 +125,12 @@ impl PipelineLayoutObjects {
&self, &self,
device: &ProtocolObject<dyn MTLDevice>, device: &ProtocolObject<dyn MTLDevice>,
format: MTLPixelFormat, format: MTLPixelFormat,
) -> Result<Id<ProtocolObject<dyn MTLRenderPipelineState>>> { ) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>> {
let descriptor = MTLRenderPipelineDescriptor::new(); let descriptor = MTLRenderPipelineDescriptor::new();
unsafe { unsafe {
let vertex = Self::create_vertex_descriptor(); let vertex = Self::create_vertex_descriptor();
descriptor.setInputPrimitiveTopology(MTLPrimitiveTopologyClassTriangle); descriptor.setInputPrimitiveTopology(MTLPrimitiveTopologyClass::Triangle);
descriptor.setVertexDescriptor(Some(&vertex)); descriptor.setVertexDescriptor(Some(&vertex));
let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0); let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0);
@ -176,12 +175,12 @@ impl MetalGraphicsPipeline {
&self, &self,
output: &RenderTarget<ProtocolObject<dyn MTLTexture>>, output: &RenderTarget<ProtocolObject<dyn MTLTexture>>,
buffer: &ProtocolObject<dyn MTLCommandBuffer>, buffer: &ProtocolObject<dyn MTLCommandBuffer>,
) -> Result<Id<ProtocolObject<dyn MTLRenderCommandEncoder>>> { ) -> Result<Retained<ProtocolObject<dyn MTLRenderCommandEncoder>>> {
unsafe { unsafe {
let descriptor = MTLRenderPassDescriptor::new(); let descriptor = MTLRenderPassDescriptor::new();
let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0); let ca = descriptor.colorAttachments().objectAtIndexedSubscript(0);
ca.setLoadAction(MTLLoadActionDontCare); ca.setLoadAction(MTLLoadAction::DontCare);
ca.setStoreAction(MTLStoreActionStore); ca.setStoreAction(MTLStoreAction::Store);
ca.setTexture(Some(output.output)); ca.setTexture(Some(output.output));
let rpass = buffer let rpass = buffer

View file

@ -11,10 +11,7 @@ mod samplers;
mod texture; mod texture;
pub use filter_chain::FilterChainMetal; pub use filter_chain::FilterChainMetal;
use icrate::Metal::{ use objc2_metal::MTLPixelFormat;
MTLPixelFormat, MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB,
MTLPixelFormatRGBA8Unorm, MTLPixelFormatRGBA8Unorm_sRGB,
};
pub mod error; pub mod error;
pub mod options; pub mod options;
@ -24,12 +21,12 @@ impl_filter_chain_parameters!(FilterChainMetal);
pub use texture::MetalTextureRef; pub use texture::MetalTextureRef;
fn select_optimal_pixel_format(format: MTLPixelFormat) -> MTLPixelFormat { fn select_optimal_pixel_format(format: MTLPixelFormat) -> MTLPixelFormat {
if format == MTLPixelFormatRGBA8Unorm { if format == MTLPixelFormat::RGBA8Unorm {
return MTLPixelFormatBGRA8Unorm; return MTLPixelFormat::BGRA8Unorm;
} }
if format == MTLPixelFormatRGBA8Unorm_sRGB { if format == MTLPixelFormat::RGBA8Unorm_sRGB {
return MTLPixelFormatBGRA8Unorm_sRGB; return MTLPixelFormat::BGRA8Unorm_sRGB;
} }
return format; return format;
} }

View file

@ -1,14 +1,13 @@
use crate::error::{FilterChainError, Result}; use crate::error::{FilterChainError, Result};
use crate::texture::InputTexture; use crate::texture::InputTexture;
use icrate::Metal::{
MTLBlitCommandEncoder, MTLDevice, MTLOrigin, MTLPixelFormatBGRA8Unorm, MTLRegion,
MTLResourceStorageModeManaged, MTLResourceStorageModeShared, MTLSize, MTLTexture,
MTLTextureDescriptor, MTLTextureUsageShaderRead,
};
use librashader_presets::TextureConfig; use librashader_presets::TextureConfig;
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;
use objc2_metal::{
MTLBlitCommandEncoder, MTLDevice, MTLOrigin, MTLPixelFormat, MTLRegion, MTLSize,
MTLStorageMode, MTLTexture, MTLTextureDescriptor, MTLTextureUsage,
};
use std::ffi::c_void; use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -30,7 +29,7 @@ impl LutTexture {
let descriptor = unsafe { let descriptor = unsafe {
let descriptor = let descriptor =
MTLTextureDescriptor::texture2DDescriptorWithPixelFormat_width_height_mipmapped( MTLTextureDescriptor::texture2DDescriptorWithPixelFormat_width_height_mipmapped(
MTLPixelFormatBGRA8Unorm, MTLPixelFormat::BGRA8Unorm,
image.size.width as usize, image.size.width as usize,
image.size.height as usize, image.size.height as usize,
config.mipmap, config.mipmap,
@ -45,13 +44,13 @@ impl LutTexture {
descriptor.setStorageMode( descriptor.setStorageMode(
if cfg!(all(target_arch = "aarch64", target_vendor = "apple")) { if cfg!(all(target_arch = "aarch64", target_vendor = "apple")) {
MTLResourceStorageModeShared MTLStorageMode::Shared
} else { } else {
MTLResourceStorageModeManaged MTLStorageMode::Managed
}, },
); );
descriptor.setUsage(MTLTextureUsageShaderRead); descriptor.setUsage(MTLTextureUsage::ShaderRead);
descriptor descriptor
}; };

View file

@ -1,19 +1,20 @@
use icrate::Metal::{
MTLCompareFunctionNever, MTLDevice, MTLSamplerAddressMode,
MTLSamplerBorderColorTransparentBlack, MTLSamplerDescriptor, MTLSamplerMinMagFilter,
MTLSamplerState,
};
use librashader_common::map::FastHashMap; use librashader_common::map::FastHashMap;
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use objc2::rc::Id; use objc2::rc::Retained;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_metal::{
MTLCompareFunction, MTLDevice, MTLSamplerAddressMode, MTLSamplerBorderColor,
MTLSamplerDescriptor, MTLSamplerMinMagFilter, MTLSamplerState,
};
use crate::error::{FilterChainError, Result}; use crate::error::{FilterChainError, Result};
pub struct SamplerSet { pub struct SamplerSet {
// todo: may need to deal with differences in mip filter. // todo: may need to deal with differences in mip filter.
samplers: samplers: FastHashMap<
FastHashMap<(WrapMode, FilterMode, FilterMode), Id<ProtocolObject<dyn MTLSamplerState>>>, (WrapMode, FilterMode, FilterMode),
Retained<ProtocolObject<dyn MTLSamplerState>>,
>,
} }
impl SamplerSet { impl SamplerSet {
@ -27,7 +28,7 @@ impl SamplerSet {
// eprintln!("{wrap}, {filter}, {mip}"); // eprintln!("{wrap}, {filter}, {mip}");
// SAFETY: the sampler set is complete for the matrix // SAFETY: the sampler set is complete for the matrix
// wrap x filter x mipmap // wrap x filter x mipmap
let id: &Id<ProtocolObject<dyn MTLSamplerState>> = unsafe { let id: &Retained<ProtocolObject<dyn MTLSamplerState>> = unsafe {
self.samplers self.samplers
.get(&(wrap, filter, mipmap)) .get(&(wrap, filter, mipmap))
.unwrap_unchecked() .unwrap_unchecked()
@ -58,9 +59,9 @@ impl SamplerSet {
descriptor.setMipFilter(filter_mode.mtl_mip(*mipmap_filter)); descriptor.setMipFilter(filter_mode.mtl_mip(*mipmap_filter));
descriptor.setLodMinClamp(0.0); descriptor.setLodMinClamp(0.0);
descriptor.setLodMaxClamp(1000.0); descriptor.setLodMaxClamp(1000.0);
descriptor.setCompareFunction(MTLCompareFunctionNever); descriptor.setCompareFunction(MTLCompareFunction::Never);
descriptor.setMaxAnisotropy(1); descriptor.setMaxAnisotropy(1);
descriptor.setBorderColor(MTLSamplerBorderColorTransparentBlack); descriptor.setBorderColor(MTLSamplerBorderColor::TransparentBlack);
descriptor.setNormalizedCoordinates(true); descriptor.setNormalizedCoordinates(true);
let Some(sampler_state) = device.newSamplerStateWithDescriptor(&descriptor) let Some(sampler_state) = device.newSamplerStateWithDescriptor(&descriptor)

View file

@ -1,17 +1,16 @@
use crate::error::{FilterChainError, Result}; use crate::error::{FilterChainError, Result};
use crate::select_optimal_pixel_format; use crate::select_optimal_pixel_format;
use icrate::Metal::{
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLDevice, MTLPixelFormat,
MTLStorageModePrivate, MTLTexture, MTLTextureDescriptor, MTLTextureUsageRenderTarget,
MTLTextureUsageShaderRead, MTLTextureUsageShaderWrite,
};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize};
use objc2::rc::Id; use objc2::rc::Retained;
use objc2::runtime::ProtocolObject; use objc2::runtime::ProtocolObject;
use objc2_metal::{
MTLBlitCommandEncoder, MTLCommandBuffer, MTLCommandEncoder, MTLDevice, MTLPixelFormat,
MTLStorageMode, MTLTexture, MTLTextureDescriptor, MTLTextureUsage,
};
pub type MetalTexture = Id<ProtocolObject<dyn MTLTexture>>; pub type MetalTexture = Retained<ProtocolObject<dyn MTLTexture>>;
/// Alias to an `id<MTLTexture>`. /// Alias to an `id<MTLTexture>`.
pub type MetalTextureRef<'a> = &'a ProtocolObject<dyn MTLTexture>; pub type MetalTextureRef<'a> = &'a ProtocolObject<dyn MTLTexture>;
@ -71,11 +70,11 @@ impl OwnedTexture {
1 1
}); });
descriptor.setStorageMode(MTLStorageModePrivate); descriptor.setStorageMode(MTLStorageMode::Private);
descriptor.setUsage( descriptor.setUsage(
MTLTextureUsageShaderRead MTLTextureUsage::ShaderRead
| MTLTextureUsageShaderWrite | MTLTextureUsage::ShaderWrite
| MTLTextureUsageRenderTarget, | MTLTextureUsage::RenderTarget,
); );
descriptor descriptor

View file

@ -3,7 +3,7 @@ name = "librashader-runtime-vk"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -14,17 +14,17 @@ description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["vulkan"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.8" }
bytemuck = { version = "1.12.3", features = ["derive"] } bytemuck = { version = "1.12.3", features = ["derive"] }
thiserror = "1.0.37" thiserror = "1.0.37"
ash = { version = "0.37", features = ["debug"] } ash = { version = "0.38", features = ["debug"] }
gpu-allocator = { version = "0.25.0", default-features = false, features = ["vulkan"] } gpu-allocator = { version = "0.27.0", default-features = false, features = ["vulkan"] }
parking_lot = "0.12.1" parking_lot = "0.12.1"
rayon = "1.6.1" rayon = "1.6.1"
array-concat = "0.5.2" array-concat = "0.5.2"
@ -32,9 +32,9 @@ array-concat = "0.5.2"
[dev-dependencies] [dev-dependencies]
num = "0.4.0" num = "0.4.0"
glfw = "0.49.0" glfw = "0.49.0"
winit = { version = "0.29.10", features = ["rwh_05"] } winit = { version = "0.29.10", features = ["rwh_06"] }
raw-window-handle = "0.5" raw-window-handle = "0.6.2"
ash-window = "0.12.0" ash-window = "0.13.0"
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["librashader-cache/docsrs"] features = ["librashader-cache/docsrs"]

View file

@ -67,7 +67,7 @@ impl TryFrom<VulkanInstance> for VulkanObjects {
fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> { fn try_from(vulkan: VulkanInstance) -> Result<Self, FilterChainError> {
unsafe { unsafe {
let instance = ash::Instance::load( let instance = ash::Instance::load(
&vk::StaticFn { &ash::StaticFn {
get_instance_proc_addr: vulkan.get_instance_proc_addr, get_instance_proc_addr: vulkan.get_instance_proc_addr,
}, },
vulkan.instance, vulkan.instance,
@ -270,7 +270,7 @@ impl FilterChainVulkan {
let command_pool = unsafe { let command_pool = unsafe {
device.create_command_pool( device.create_command_pool(
&vk::CommandPoolCreateInfo::builder() &vk::CommandPoolCreateInfo::default()
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER), .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER),
None, None,
)? )?
@ -279,7 +279,7 @@ impl FilterChainVulkan {
let command_buffer = unsafe { let command_buffer = unsafe {
// panic safety: command buffer count = 1 // panic safety: command buffer count = 1
device.allocate_command_buffers( device.allocate_command_buffers(
&vk::CommandBufferAllocateInfo::builder() &vk::CommandBufferAllocateInfo::default()
.command_pool(command_pool) .command_pool(command_pool)
.level(vk::CommandBufferLevel::PRIMARY) .level(vk::CommandBufferLevel::PRIMARY)
.command_buffer_count(1), .command_buffer_count(1),
@ -289,7 +289,7 @@ impl FilterChainVulkan {
unsafe { unsafe {
device.begin_command_buffer( device.begin_command_buffer(
command_buffer, command_buffer,
&vk::CommandBufferBeginInfo::builder() &vk::CommandBufferBeginInfo::default()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT), .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT),
)? )?
} }
@ -307,9 +307,9 @@ impl FilterChainVulkan {
device.end_command_buffer(command_buffer)?; device.end_command_buffer(command_buffer)?;
let buffers = [command_buffer]; let buffers = [command_buffer];
let submit_info = vk::SubmitInfo::builder().command_buffers(&buffers); let submit_info = vk::SubmitInfo::default().command_buffers(&buffers);
device.queue_submit(queue, &[*submit_info], vk::Fence::null())?; device.queue_submit(queue, &[submit_info], vk::Fence::null())?;
device.queue_wait_idle(queue)?; device.queue_wait_idle(queue)?;
device.free_command_buffers(command_pool, &buffers); device.free_command_buffers(command_pool, &buffers);
device.destroy_command_pool(command_pool, None); device.destroy_command_pool(command_pool, None);
@ -592,18 +592,18 @@ impl FilterChainVulkan {
} }
let original_image_view = unsafe { let original_image_view = unsafe {
let create_info = vk::ImageViewCreateInfo::builder() let create_info = vk::ImageViewCreateInfo::default()
.image(input.image) .image(input.image)
.format(input.format) .format(input.format)
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.subresource_range( .subresource_range(
*vk::ImageSubresourceRange::builder() vk::ImageSubresourceRange::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.level_count(1) .level_count(1)
.layer_count(1), .layer_count(1),
) )
.components( .components(
*vk::ComponentMapping::builder() vk::ComponentMapping::default()
.r(vk::ComponentSwizzle::R) .r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G) .g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B) .b(vk::ComponentSwizzle::B)

View file

@ -55,20 +55,20 @@ impl BindSemantics<NoUniformBinder, Option<()>, RawVulkanBuffer> for FilterPass
device: &Self::DeviceContext, device: &Self::DeviceContext,
) { ) {
let sampler = samplers.get(texture.wrap_mode, texture.filter_mode, texture.mip_filter); let sampler = samplers.get(texture.wrap_mode, texture.filter_mode, texture.mip_filter);
let image_info = vk::DescriptorImageInfo::builder() let image_info = vk::DescriptorImageInfo::default()
.sampler(sampler.handle) .sampler(sampler.handle)
.image_view(texture.image_view) .image_view(texture.image_view)
.image_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL); .image_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL);
let image_info = [*image_info]; let image_info = [image_info];
let write_desc = vk::WriteDescriptorSet::builder() let write_desc = vk::WriteDescriptorSet::default()
.dst_set(*descriptors) .dst_set(*descriptors)
.dst_binding(binding.binding) .dst_binding(binding.binding)
.dst_array_element(0) .dst_array_element(0)
.descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER) .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.image_info(&image_info); .image_info(&image_info);
unsafe { unsafe {
device.update_descriptor_sets(&[*write_desc], &[]); device.update_descriptor_sets(&[write_desc], &[]);
} }
} }
} }

View file

@ -12,25 +12,25 @@ pub(crate) struct OutputImage {
impl OutputImage { impl OutputImage {
pub fn new(device: &ash::Device, image: VulkanImage) -> error::Result<OutputImage> { pub fn new(device: &ash::Device, image: VulkanImage) -> error::Result<OutputImage> {
let image_subresource = vk::ImageSubresourceRange::builder() let image_subresource = vk::ImageSubresourceRange::default()
.base_mip_level(0) .base_mip_level(0)
.base_array_layer(0) .base_array_layer(0)
.level_count(1) .level_count(1)
.layer_count(1) .layer_count(1)
.aspect_mask(vk::ImageAspectFlags::COLOR); .aspect_mask(vk::ImageAspectFlags::COLOR);
let swizzle_components = vk::ComponentMapping::builder() let swizzle_components = vk::ComponentMapping::default()
.r(vk::ComponentSwizzle::R) .r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G) .g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B) .b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A); .a(vk::ComponentSwizzle::A);
let view_info = vk::ImageViewCreateInfo::builder() let view_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.format(image.format) .format(image.format)
.image(image.image) .image(image.image)
.subresource_range(*image_subresource) .subresource_range(image_subresource)
.components(*swizzle_components); .components(swizzle_components);
let image_view = unsafe { device.create_image_view(&view_info, None)? }; let image_view = unsafe { device.create_image_view(&view_info, None)? };

View file

@ -16,13 +16,13 @@ use std::ffi::CStr;
use std::sync::Arc; use std::sync::Arc;
const ENTRY_POINT: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") }; const ENTRY_POINT: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") };
pub struct PipelineDescriptors { pub struct PipelineDescriptors<'a> {
pub replicas: u32, pub replicas: u32,
pub layout_bindings: Vec<vk::DescriptorSetLayoutBinding>, pub layout_bindings: Vec<vk::DescriptorSetLayoutBinding<'a>>,
pub pool_sizes: Vec<vk::DescriptorPoolSize>, pub pool_sizes: Vec<vk::DescriptorPoolSize>,
} }
impl PipelineDescriptors { impl PipelineDescriptors<'_> {
pub fn new(duplicates: u32) -> Self { pub fn new(duplicates: u32) -> Self {
Self { Self {
replicas: duplicates, replicas: duplicates,
@ -43,6 +43,7 @@ impl PipelineDescriptors {
descriptor_count: 1, descriptor_count: 1,
stage_flags: ubo_mask, stage_flags: ubo_mask,
p_immutable_samplers: std::ptr::null(), p_immutable_samplers: std::ptr::null(),
_marker: Default::default(),
}); });
self.pool_sizes.push(vk::DescriptorPoolSize { self.pool_sizes.push(vk::DescriptorPoolSize {
@ -61,6 +62,7 @@ impl PipelineDescriptors {
descriptor_count: 1, descriptor_count: 1,
stage_flags: texture_mask, stage_flags: texture_mask,
p_immutable_samplers: std::ptr::null(), p_immutable_samplers: std::ptr::null(),
_marker: Default::default(),
}); });
self.pool_sizes.push(vk::DescriptorPoolSize { self.pool_sizes.push(vk::DescriptorPoolSize {
@ -80,7 +82,7 @@ impl PipelineDescriptors {
) -> error::Result<vk::DescriptorSetLayout> { ) -> error::Result<vk::DescriptorSetLayout> {
unsafe { unsafe {
let layout = device.create_descriptor_set_layout( let layout = device.create_descriptor_set_layout(
&vk::DescriptorSetLayoutCreateInfo::builder().bindings(self.bindings()), &vk::DescriptorSetLayoutCreateInfo::default().bindings(self.bindings()),
None, None,
)?; )?;
Ok(layout) Ok(layout)
@ -90,9 +92,9 @@ impl PipelineDescriptors {
pub struct PipelineLayoutObjects { pub struct PipelineLayoutObjects {
pub layout: vk::PipelineLayout, pub layout: vk::PipelineLayout,
pub pool: vk::DescriptorPool,
pub descriptor_sets: Vec<vk::DescriptorSet>, pub descriptor_sets: Vec<vk::DescriptorSet>,
pub descriptor_set_layout: [vk::DescriptorSetLayout; 1], pub _pool: vk::DescriptorPool,
pub _descriptor_set_layout: [vk::DescriptorSetLayout; 1],
} }
impl PipelineLayoutObjects { impl PipelineLayoutObjects {
@ -108,11 +110,11 @@ impl PipelineLayoutObjects {
let descriptor_set_layout = [descriptors.create_descriptor_set_layout(device)?]; let descriptor_set_layout = [descriptors.create_descriptor_set_layout(device)?];
let pipeline_create_info = let pipeline_create_info =
vk::PipelineLayoutCreateInfo::builder().set_layouts(&descriptor_set_layout); vk::PipelineLayoutCreateInfo::default().set_layouts(&descriptor_set_layout);
let push_constant_range = reflection.push_constant.as_ref().map(|push_constant| { let push_constant_range = reflection.push_constant.as_ref().map(|push_constant| {
let stage_mask = util::binding_stage_to_vulkan_stage(push_constant.stage_mask); let stage_mask = util::binding_stage_to_vulkan_stage(push_constant.stage_mask);
[*vk::PushConstantRange::builder() [vk::PushConstantRange::default()
.stage_flags(stage_mask) .stage_flags(stage_mask)
.size(push_constant.size)] .size(push_constant.size)]
}); });
@ -124,14 +126,14 @@ impl PipelineLayoutObjects {
let layout = unsafe { device.create_pipeline_layout(&pipeline_create_info, None)? }; let layout = unsafe { device.create_pipeline_layout(&pipeline_create_info, None)? };
let pool_info = vk::DescriptorPoolCreateInfo::builder() let pool_info = vk::DescriptorPoolCreateInfo::default()
.max_sets(replicas) .max_sets(replicas)
.pool_sizes(&descriptors.pool_sizes); .pool_sizes(&descriptors.pool_sizes);
let pool = unsafe { device.create_descriptor_pool(&pool_info, None)? }; let pool = unsafe { device.create_descriptor_pool(&pool_info, None)? };
let mut descriptor_sets = Vec::new(); let mut descriptor_sets = Vec::new();
let alloc_info = vk::DescriptorSetAllocateInfo::builder() let alloc_info = vk::DescriptorSetAllocateInfo::default()
.descriptor_pool(pool) .descriptor_pool(pool)
.set_layouts(&descriptor_set_layout); .set_layouts(&descriptor_set_layout);
@ -145,9 +147,9 @@ impl PipelineLayoutObjects {
Ok(PipelineLayoutObjects { Ok(PipelineLayoutObjects {
layout, layout,
descriptor_set_layout, _descriptor_set_layout: descriptor_set_layout,
descriptor_sets, descriptor_sets,
pool, _pool: pool,
}) })
} }
} }
@ -194,7 +196,7 @@ impl VulkanGraphicsPipeline {
fragment_module: &VulkanShaderModule, fragment_module: &VulkanShaderModule,
render_pass: Option<&VulkanRenderPass>, render_pass: Option<&VulkanRenderPass>,
) -> error::Result<vk::Pipeline> { ) -> error::Result<vk::Pipeline> {
let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::builder() let input_assembly = vk::PipelineInputAssemblyStateCreateInfo::default()
.topology(vk::PrimitiveTopology::TRIANGLE_STRIP); .topology(vk::PrimitiveTopology::TRIANGLE_STRIP);
let vao_state = [ let vao_state = [
@ -212,17 +214,17 @@ impl VulkanGraphicsPipeline {
}, },
]; ];
let input_binding = vk::VertexInputBindingDescription::builder() let input_binding = vk::VertexInputBindingDescription::default()
.binding(0) .binding(0)
.stride(std::mem::size_of::<VertexInput>() as u32) .stride(std::mem::size_of::<VertexInput>() as u32)
.input_rate(vk::VertexInputRate::VERTEX); .input_rate(vk::VertexInputRate::VERTEX);
let input_binding = [*input_binding]; let input_binding = [input_binding];
let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder() let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::default()
.vertex_binding_descriptions(&input_binding) .vertex_binding_descriptions(&input_binding)
.vertex_attribute_descriptions(&vao_state); .vertex_attribute_descriptions(&vao_state);
let raster_state = vk::PipelineRasterizationStateCreateInfo::builder() let raster_state = vk::PipelineRasterizationStateCreateInfo::default()
.polygon_mode(vk::PolygonMode::FILL) .polygon_mode(vk::PolygonMode::FILL)
.cull_mode(vk::CullModeFlags::NONE) .cull_mode(vk::CullModeFlags::NONE)
.front_face(vk::FrontFace::COUNTER_CLOCKWISE) .front_face(vk::FrontFace::COUNTER_CLOCKWISE)
@ -231,19 +233,19 @@ impl VulkanGraphicsPipeline {
.depth_bias_enable(false) .depth_bias_enable(false)
.line_width(1.0); .line_width(1.0);
let attachments = vk::PipelineColorBlendAttachmentState::builder() let attachments = vk::PipelineColorBlendAttachmentState::default()
.blend_enable(false) .blend_enable(false)
.color_write_mask(vk::ColorComponentFlags::from_raw(0xf)); .color_write_mask(vk::ColorComponentFlags::from_raw(0xf));
let attachments = [*attachments]; let attachments = [attachments];
let blend_state = let blend_state =
vk::PipelineColorBlendStateCreateInfo::builder().attachments(&attachments); vk::PipelineColorBlendStateCreateInfo::default().attachments(&attachments);
let viewport_state = vk::PipelineViewportStateCreateInfo::builder() let viewport_state = vk::PipelineViewportStateCreateInfo::default()
.viewport_count(1) .viewport_count(1)
.scissor_count(1); .scissor_count(1);
let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::builder() let depth_stencil_state = vk::PipelineDepthStencilStateCreateInfo::default()
.depth_test_enable(false) .depth_test_enable(false)
.depth_write_enable(false) .depth_write_enable(false)
.stencil_test_enable(false) .stencil_test_enable(false)
@ -251,25 +253,24 @@ impl VulkanGraphicsPipeline {
.min_depth_bounds(1.0) .min_depth_bounds(1.0)
.max_depth_bounds(1.0); .max_depth_bounds(1.0);
let multisample_state = vk::PipelineMultisampleStateCreateInfo::builder() let multisample_state = vk::PipelineMultisampleStateCreateInfo::default()
.rasterization_samples(vk::SampleCountFlags::TYPE_1); .rasterization_samples(vk::SampleCountFlags::TYPE_1);
let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder().dynamic_states(&states); let dynamic_state = vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&states);
let shader_stages = [ let shader_stages = [
vk::PipelineShaderStageCreateInfo::builder() vk::PipelineShaderStageCreateInfo::default()
.stage(vk::ShaderStageFlags::VERTEX) .stage(vk::ShaderStageFlags::VERTEX)
.name(ENTRY_POINT) .name(ENTRY_POINT)
.module(vertex_module.shader), .module(vertex_module.shader),
vk::PipelineShaderStageCreateInfo::builder() vk::PipelineShaderStageCreateInfo::default()
.stage(vk::ShaderStageFlags::FRAGMENT) .stage(vk::ShaderStageFlags::FRAGMENT)
.name(ENTRY_POINT) .name(ENTRY_POINT)
.module(fragment_module.shader), .module(fragment_module.shader),
]; ];
let shader_stages = [*shader_stages[0], *shader_stages[1]]; let mut pipeline_info = vk::GraphicsPipelineCreateInfo::default()
let mut pipeline_info = vk::GraphicsPipelineCreateInfo::builder()
.stages(&shader_stages) .stages(&shader_stages)
.vertex_input_state(&pipeline_input_state) .vertex_input_state(&pipeline_input_state)
.input_assembly_state(&input_assembly) .input_assembly_state(&input_assembly)
@ -288,7 +289,7 @@ impl VulkanGraphicsPipeline {
let pipeline = unsafe { let pipeline = unsafe {
// panic_safety: if this is successful this should return 1 pipelines. // panic_safety: if this is successful this should return 1 pipelines.
device device
.create_graphics_pipelines(*cache, &[*pipeline_info], None) .create_graphics_pipelines(*cache, &[pipeline_info], None)
.map_err(|e| e.1)?[0] .map_err(|e| e.1)?[0]
}; };
@ -306,9 +307,9 @@ impl VulkanGraphicsPipeline {
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?; let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
let vertex_info = let vertex_info =
vk::ShaderModuleCreateInfo::builder().code(shader_assembly.vertex.as_ref()); vk::ShaderModuleCreateInfo::default().code(shader_assembly.vertex.as_ref());
let fragment_info = let fragment_info =
vk::ShaderModuleCreateInfo::builder().code(shader_assembly.fragment.as_ref()); vk::ShaderModuleCreateInfo::default().code(shader_assembly.fragment.as_ref());
let vertex_module = VulkanShaderModule::new(device, &vertex_info)?; let vertex_module = VulkanShaderModule::new(device, &vertex_info)?;
let fragment_module = VulkanShaderModule::new(device, &fragment_info)?; let fragment_module = VulkanShaderModule::new(device, &fragment_info)?;
@ -325,7 +326,7 @@ impl VulkanGraphicsPipeline {
"vulkan", "vulkan",
&[&shader_assembly.vertex, &shader_assembly.fragment], &[&shader_assembly.vertex, &shader_assembly.fragment],
|pipeline_data| { |pipeline_data| {
let mut cache_info = vk::PipelineCacheCreateInfo::builder(); let mut cache_info = vk::PipelineCacheCreateInfo::default();
if let Some(pipeline_data) = pipeline_data.as_ref() { if let Some(pipeline_data) = pipeline_data.as_ref() {
cache_info = cache_info.initial_data(pipeline_data); cache_info = cache_info.initial_data(pipeline_data);
} }
@ -394,7 +395,7 @@ impl VulkanGraphicsPipeline {
let attachments = [output.output.image_view]; let attachments = [output.output.image_view];
let framebuffer = unsafe { let framebuffer = unsafe {
self.device.create_framebuffer( self.device.create_framebuffer(
&vk::FramebufferCreateInfo::builder() &vk::FramebufferCreateInfo::default()
.render_pass(render_pass.handle) .render_pass(render_pass.handle)
.attachments(&attachments) .attachments(&attachments)
.width(output.output.size.width) .width(output.output.size.width)
@ -410,7 +411,7 @@ impl VulkanGraphicsPipeline {
}, },
}]; }];
let render_pass_info = vk::RenderPassBeginInfo::builder() let render_pass_info = vk::RenderPassBeginInfo::default()
.framebuffer(framebuffer) .framebuffer(framebuffer)
.render_pass(render_pass.handle) .render_pass(render_pass.handle)
.clear_values(&clear_values) .clear_values(&clear_values)
@ -428,14 +429,13 @@ impl VulkanGraphicsPipeline {
} }
Ok(Some(framebuffer)) Ok(Some(framebuffer))
} else { } else {
let attachments = vk::RenderingAttachmentInfo::builder() let attachments = [vk::RenderingAttachmentInfo::default()
.load_op(vk::AttachmentLoadOp::DONT_CARE) .load_op(vk::AttachmentLoadOp::DONT_CARE)
.store_op(vk::AttachmentStoreOp::STORE) .store_op(vk::AttachmentStoreOp::STORE)
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL) .image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.image_view(output.output.image_view); .image_view(output.output.image_view)];
let attachments = [*attachments];
let rendering_info = vk::RenderingInfo::builder() let rendering_info = vk::RenderingInfo::default()
.layer_count(1) .layer_count(1)
.render_area(vk::Rect2D { .render_area(vk::Rect2D {
offset: vk::Offset2D { x: 0, y: 0 }, offset: vk::Offset2D { x: 0, y: 0 },

View file

@ -20,7 +20,7 @@ impl LutTexture {
image: Image<BGRA8>, image: Image<BGRA8>,
config: &TextureConfig, config: &TextureConfig,
) -> error::Result<LutTexture> { ) -> error::Result<LutTexture> {
let image_info = vk::ImageCreateInfo::builder() let image_info = vk::ImageCreateInfo::default()
.image_type(vk::ImageType::TYPE_2D) .image_type(vk::ImageType::TYPE_2D)
.format(vk::Format::B8G8R8A8_UNORM) .format(vk::Format::B8G8R8A8_UNORM)
.extent(image.size.into()) .extent(image.size.into())
@ -46,23 +46,23 @@ impl LutTexture {
VulkanImageMemory::new(&vulkan.device, &vulkan.alloc, mem_reqs, &texture)? VulkanImageMemory::new(&vulkan.device, &vulkan.alloc, mem_reqs, &texture)?
}; };
let image_subresource = vk::ImageSubresourceRange::builder() let image_subresource = vk::ImageSubresourceRange::default()
.level_count(image_info.mip_levels) .level_count(image_info.mip_levels)
.layer_count(1) .layer_count(1)
.aspect_mask(vk::ImageAspectFlags::COLOR); .aspect_mask(vk::ImageAspectFlags::COLOR);
let swizzle_components = vk::ComponentMapping::builder() let swizzle_components = vk::ComponentMapping::default()
.r(vk::ComponentSwizzle::R) .r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G) .g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B) .b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A); .a(vk::ComponentSwizzle::A);
let view_info = vk::ImageViewCreateInfo::builder() let view_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.format(vk::Format::B8G8R8A8_UNORM) .format(vk::Format::B8G8R8A8_UNORM)
.image(texture) .image(texture)
.subresource_range(*image_subresource) .subresource_range(image_subresource)
.components(*swizzle_components); .components(swizzle_components);
let texture_view = unsafe { vulkan.device.create_image_view(&view_info, None)? }; let texture_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
@ -95,9 +95,9 @@ impl LutTexture {
vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED,
); );
let builder = vk::BufferImageCopy::builder() let builder = vk::BufferImageCopy::default()
.image_subresource( .image_subresource(
*vk::ImageSubresourceLayers::builder() vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0) .mip_level(0)
.base_array_layer(0) .base_array_layer(0)
@ -114,7 +114,7 @@ impl LutTexture {
} else { } else {
vk::ImageLayout::TRANSFER_DST_OPTIMAL vk::ImageLayout::TRANSFER_DST_OPTIMAL
}, },
&[*builder], &[builder],
) )
} }
@ -140,22 +140,22 @@ impl LutTexture {
z: 1, z: 1,
}, },
]; ];
let src_subresource = vk::ImageSubresourceLayers::builder() let src_subresource = vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(level - 1) .mip_level(level - 1)
.base_array_layer(0) .base_array_layer(0)
.layer_count(1); .layer_count(1);
let dst_subresource = vk::ImageSubresourceLayers::builder() let dst_subresource = vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(level) .mip_level(level)
.base_array_layer(0) .base_array_layer(0)
.layer_count(1); .layer_count(1);
let image_blit = vk::ImageBlit::builder() let image_blit = vk::ImageBlit::default()
.src_subresource(*src_subresource) .src_subresource(src_subresource)
.src_offsets(src_offsets) .src_offsets(src_offsets)
.dst_subresource(*dst_subresource) .dst_subresource(dst_subresource)
.dst_offsets(dst_offsets); .dst_offsets(dst_offsets);
unsafe { unsafe {
@ -181,7 +181,7 @@ impl LutTexture {
vk::ImageLayout::GENERAL, vk::ImageLayout::GENERAL,
texture, texture,
vk::ImageLayout::GENERAL, vk::ImageLayout::GENERAL,
&[*image_blit], &[image_blit],
config.filter_mode.into(), config.filter_mode.into(),
); );
} }

View file

@ -69,7 +69,7 @@ impl VulkanBuffer {
size: usize, size: usize,
) -> error::Result<VulkanBuffer> { ) -> error::Result<VulkanBuffer> {
unsafe { unsafe {
let buffer_info = vk::BufferCreateInfo::builder() let buffer_info = vk::BufferCreateInfo::default()
.size(size as vk::DeviceSize) .size(size as vk::DeviceSize)
.usage(usage) .usage(usage)
.sharing_mode(vk::SharingMode::EXCLUSIVE); .sharing_mode(vk::SharingMode::EXCLUSIVE);
@ -161,13 +161,12 @@ impl RawVulkanBuffer {
storage: &impl UniformStorageAccess, storage: &impl UniformStorageAccess,
) -> error::Result<()> { ) -> error::Result<()> {
unsafe { unsafe {
let buffer_info = vk::DescriptorBufferInfo::builder() let buffer_info = [vk::DescriptorBufferInfo::default()
.buffer(self.buffer.handle) .buffer(self.buffer.handle)
.offset(0) .offset(0)
.range(storage.ubo_slice().len() as vk::DeviceSize); .range(storage.ubo_slice().len() as vk::DeviceSize)];
let buffer_info = [*buffer_info]; let write_info = vk::WriteDescriptorSet::default()
let write_info = vk::WriteDescriptorSet::builder()
.descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
.dst_set(descriptor_set) .dst_set(descriptor_set)
.dst_binding(binding) .dst_binding(binding)
@ -176,7 +175,7 @@ impl RawVulkanBuffer {
self.buffer self.buffer
.device .device
.update_descriptor_sets(&[*write_info], &[]) .update_descriptor_sets(&[write_info], &[])
} }
Ok(()) Ok(())
} }

View file

@ -12,7 +12,7 @@ pub struct VulkanRenderPass {
impl VulkanRenderPass { impl VulkanRenderPass {
pub fn create_render_pass(device: &ash::Device, format: vk::Format) -> error::Result<Self> { pub fn create_render_pass(device: &ash::Device, format: vk::Format) -> error::Result<Self> {
// format should never be undefined. // format should never be undefined.
let attachment = vk::AttachmentDescription::builder() let attachment = [vk::AttachmentDescription::default()
.flags(vk::AttachmentDescriptionFlags::empty()) .flags(vk::AttachmentDescriptionFlags::empty())
.format(format) .format(format)
.samples(SampleCountFlags::TYPE_1) .samples(SampleCountFlags::TYPE_1)
@ -21,20 +21,17 @@ impl VulkanRenderPass {
.stencil_load_op(AttachmentLoadOp::DONT_CARE) .stencil_load_op(AttachmentLoadOp::DONT_CARE)
.stencil_store_op(AttachmentStoreOp::DONT_CARE) .stencil_store_op(AttachmentStoreOp::DONT_CARE)
.initial_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL) .initial_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.final_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL); .final_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)];
let attachment = [*attachment];
let attachment_ref = vk::AttachmentReference::builder() let attachment_ref = [vk::AttachmentReference::default()
.attachment(0) .attachment(0)
.layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL); .layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)];
let attachment_ref = [*attachment_ref];
let subpass = vk::SubpassDescription::builder() let subpass = [vk::SubpassDescription::default()
.pipeline_bind_point(PipelineBindPoint::GRAPHICS) .pipeline_bind_point(PipelineBindPoint::GRAPHICS)
.color_attachments(&attachment_ref); .color_attachments(&attachment_ref)];
let subpass = [*subpass];
let renderpass_info = vk::RenderPassCreateInfo::builder() let renderpass_info = vk::RenderPassCreateInfo::default()
.flags(vk::RenderPassCreateFlags::empty()) .flags(vk::RenderPassCreateFlags::empty())
.attachments(&attachment) .attachments(&attachment)
.subpasses(&subpass); .subpasses(&subpass);

View file

@ -16,7 +16,7 @@ impl VulkanSampler {
filter: FilterMode, filter: FilterMode,
mipmap: FilterMode, mipmap: FilterMode,
) -> error::Result<VulkanSampler> { ) -> error::Result<VulkanSampler> {
let create_info = vk::SamplerCreateInfo::builder() let create_info = vk::SamplerCreateInfo::default()
.mip_lod_bias(0.0) .mip_lod_bias(0.0)
.max_anisotropy(1.0) .max_anisotropy(1.0)
.compare_enable(false) .compare_enable(false)

View file

@ -16,9 +16,9 @@ pub struct OwnedImage {
pub allocator: Arc<Mutex<Allocator>>, pub allocator: Arc<Mutex<Allocator>>,
pub image_view: vk::ImageView, pub image_view: vk::ImageView,
pub image: VulkanImage, pub image: VulkanImage,
pub memory: VulkanImageMemory,
pub max_miplevels: u32, pub max_miplevels: u32,
pub levels: u32, pub levels: u32,
pub _memory: VulkanImageMemory,
} }
#[derive(Clone)] #[derive(Clone)]
@ -42,7 +42,7 @@ impl OwnedImage {
if format == ImageFormat::Unknown { if format == ImageFormat::Unknown {
format = ImageFormat::R8G8B8A8Unorm format = ImageFormat::R8G8B8A8Unorm
} }
let image_create_info = vk::ImageCreateInfo::builder() let image_create_info = vk::ImageCreateInfo::default()
.image_type(vk::ImageType::TYPE_2D) .image_type(vk::ImageType::TYPE_2D)
.format(format.into()) .format(format.into())
.extent(size.into()) .extent(size.into())
@ -64,25 +64,25 @@ impl OwnedImage {
let mem_reqs = unsafe { device.get_image_memory_requirements(image) }; let mem_reqs = unsafe { device.get_image_memory_requirements(image) };
let memory = VulkanImageMemory::new(&device, alloc, mem_reqs, &image)?; let memory = VulkanImageMemory::new(&device, alloc, mem_reqs, &image)?;
let image_subresource = vk::ImageSubresourceRange::builder() let image_subresource = vk::ImageSubresourceRange::default()
.base_mip_level(0) .base_mip_level(0)
.base_array_layer(0) .base_array_layer(0)
.level_count(image_create_info.mip_levels) .level_count(image_create_info.mip_levels)
.layer_count(1) .layer_count(1)
.aspect_mask(vk::ImageAspectFlags::COLOR); .aspect_mask(vk::ImageAspectFlags::COLOR);
let swizzle_components = vk::ComponentMapping::builder() let swizzle_components = vk::ComponentMapping::default()
.r(vk::ComponentSwizzle::R) .r(vk::ComponentSwizzle::R)
.g(vk::ComponentSwizzle::G) .g(vk::ComponentSwizzle::G)
.b(vk::ComponentSwizzle::B) .b(vk::ComponentSwizzle::B)
.a(vk::ComponentSwizzle::A); .a(vk::ComponentSwizzle::A);
let view_info = vk::ImageViewCreateInfo::builder() let view_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.format(format.into()) .format(format.into())
.image(image) .image(image)
.subresource_range(*image_subresource) .subresource_range(image_subresource)
.components(*swizzle_components); .components(swizzle_components);
let image_view = unsafe { device.create_image_view(&view_info, None)? }; let image_view = unsafe { device.create_image_view(&view_info, None)? };
@ -95,7 +95,7 @@ impl OwnedImage {
size, size,
format: format.into(), format: format.into(),
}, },
memory, _memory: memory,
max_miplevels, max_miplevels,
levels: std::cmp::min(max_miplevels, size.calculate_miplevels()), levels: std::cmp::min(max_miplevels, size.calculate_miplevels()),
}) })
@ -182,7 +182,7 @@ impl OwnedImage {
} }
pub fn generate_mipmaps_and_end_pass(&self, cmd: vk::CommandBuffer) { pub fn generate_mipmaps_and_end_pass(&self, cmd: vk::CommandBuffer) {
let input_barrier = vk::ImageMemoryBarrier::builder() let input_barrier = vk::ImageMemoryBarrier::default()
.src_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE) .src_access_mask(vk::AccessFlags::COLOR_ATTACHMENT_WRITE)
.dst_access_mask(vk::AccessFlags::TRANSFER_READ) .dst_access_mask(vk::AccessFlags::TRANSFER_READ)
.old_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL) .old_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
@ -198,7 +198,7 @@ impl OwnedImage {
layer_count: vk::REMAINING_ARRAY_LAYERS, layer_count: vk::REMAINING_ARRAY_LAYERS,
}); });
let mipchain_barrier = vk::ImageMemoryBarrier::builder() let mipchain_barrier = vk::ImageMemoryBarrier::default()
.src_access_mask(vk::AccessFlags::empty()) .src_access_mask(vk::AccessFlags::empty())
.dst_access_mask(vk::AccessFlags::TRANSFER_WRITE) .dst_access_mask(vk::AccessFlags::TRANSFER_WRITE)
.old_layout(vk::ImageLayout::UNDEFINED) .old_layout(vk::ImageLayout::UNDEFINED)
@ -222,13 +222,13 @@ impl OwnedImage {
vk::DependencyFlags::empty(), vk::DependencyFlags::empty(),
&[], &[],
&[], &[],
&[*input_barrier, *mipchain_barrier], &[input_barrier, mipchain_barrier],
); );
for level in 1..self.levels { for level in 1..self.levels {
// need to transition from DST to SRC, one level at a time. // need to transition from DST to SRC, one level at a time.
if level > 1 { if level > 1 {
let next_barrier = vk::ImageMemoryBarrier::builder() let next_barrier = vk::ImageMemoryBarrier::default()
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE) .src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
.dst_access_mask(vk::AccessFlags::TRANSFER_READ) .dst_access_mask(vk::AccessFlags::TRANSFER_READ)
.old_layout(vk::ImageLayout::TRANSFER_DST_OPTIMAL) .old_layout(vk::ImageLayout::TRANSFER_DST_OPTIMAL)
@ -251,7 +251,7 @@ impl OwnedImage {
vk::DependencyFlags::empty(), vk::DependencyFlags::empty(),
&[], &[],
&[], &[],
&[*next_barrier], &[next_barrier],
); );
} }
@ -276,22 +276,22 @@ impl OwnedImage {
}, },
]; ];
let src_subresource = vk::ImageSubresourceLayers::builder() let src_subresource = vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(level - 1) .mip_level(level - 1)
.base_array_layer(0) .base_array_layer(0)
.layer_count(1); .layer_count(1);
let dst_subresource = vk::ImageSubresourceLayers::builder() let dst_subresource = vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(level) .mip_level(level)
.base_array_layer(0) .base_array_layer(0)
.layer_count(1); .layer_count(1);
let image_blit = vk::ImageBlit::builder() let image_blit = vk::ImageBlit::default()
.src_subresource(*src_subresource) .src_subresource(src_subresource)
.src_offsets(src_offsets) .src_offsets(src_offsets)
.dst_subresource(*dst_subresource) .dst_subresource(dst_subresource)
.dst_offsets(dst_offsets); .dst_offsets(dst_offsets);
self.device.cmd_blit_image( self.device.cmd_blit_image(
@ -300,14 +300,14 @@ impl OwnedImage {
vk::ImageLayout::TRANSFER_SRC_OPTIMAL, vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
self.image.image, self.image.image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL, vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[*image_blit], &[image_blit],
vk::Filter::LINEAR, vk::Filter::LINEAR,
); );
} }
// move everything to SHADER_READ_ONLY_OPTIMAL // move everything to SHADER_READ_ONLY_OPTIMAL
let input_barrier = vk::ImageMemoryBarrier::builder() let input_barrier = vk::ImageMemoryBarrier::default()
.src_access_mask(vk::AccessFlags::TRANSFER_READ) .src_access_mask(vk::AccessFlags::TRANSFER_READ)
.dst_access_mask(vk::AccessFlags::SHADER_READ) .dst_access_mask(vk::AccessFlags::SHADER_READ)
.old_layout(vk::ImageLayout::TRANSFER_SRC_OPTIMAL) .old_layout(vk::ImageLayout::TRANSFER_SRC_OPTIMAL)
@ -323,7 +323,7 @@ impl OwnedImage {
layer_count: vk::REMAINING_ARRAY_LAYERS, layer_count: vk::REMAINING_ARRAY_LAYERS,
}); });
let mipchain_barrier = vk::ImageMemoryBarrier::builder() let mipchain_barrier = vk::ImageMemoryBarrier::default()
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE) .src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
.dst_access_mask(vk::AccessFlags::SHADER_READ) .dst_access_mask(vk::AccessFlags::SHADER_READ)
.old_layout(vk::ImageLayout::TRANSFER_DST_OPTIMAL) .old_layout(vk::ImageLayout::TRANSFER_DST_OPTIMAL)
@ -348,7 +348,7 @@ impl OwnedImage {
vk::DependencyFlags::empty(), vk::DependencyFlags::empty(),
&[], &[],
&[], &[],
&[*input_barrier, *mipchain_barrier], &[input_barrier, mipchain_barrier],
); );
} }
} }
@ -360,16 +360,16 @@ impl OwnedImage {
source: &VulkanImage, source: &VulkanImage,
source_layout: vk::ImageLayout, source_layout: vk::ImageLayout,
) { ) {
let region = vk::ImageCopy::builder() let region = vk::ImageCopy::default()
.src_subresource( .src_subresource(
*vk::ImageSubresourceLayers::builder() vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0) .mip_level(0)
.base_array_layer(0) .base_array_layer(0)
.layer_count(1), .layer_count(1),
) )
.dst_subresource( .dst_subresource(
*vk::ImageSubresourceLayers::builder() vk::ImageSubresourceLayers::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0) .mip_level(0)
.base_array_layer(0) .base_array_layer(0)
@ -401,7 +401,7 @@ impl OwnedImage {
source_layout, source_layout,
self.image.image, self.image.image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL, vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[*region], &[region],
); );
util::vulkan_image_layout_transition_levels( util::vulkan_image_layout_transition_levels(
&self.device, &self.device,
@ -443,7 +443,7 @@ impl OwnedImage {
&vk::ClearColorValue { &vk::ClearColorValue {
float32: [0.0, 0.0, 0.0, 0.0], float32: [0.0, 0.0, 0.0, 0.0],
}, },
&[*vk::ImageSubresourceRange::builder() &[vk::ImageSubresourceRange::default()
.aspect_mask(vk::ImageAspectFlags::COLOR) .aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0) .base_mip_level(0)
.level_count(1) .level_count(1)

View file

@ -14,13 +14,13 @@ impl VulkanCommandPool {
pub fn new(base: &VulkanBase, frames_in_flight: u32) -> VkResult<VulkanCommandPool> { pub fn new(base: &VulkanBase, frames_in_flight: u32) -> VkResult<VulkanCommandPool> {
let indices = find_queue_family(&base.instance, base.physical_device); let indices = find_queue_family(&base.instance, base.physical_device);
let create_info = vk::CommandPoolCreateInfo::builder() let create_info = vk::CommandPoolCreateInfo::default()
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER) .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
.queue_family_index(indices.graphics_family()); .queue_family_index(indices.graphics_family());
unsafe { unsafe {
let pool = base.device.create_command_pool(&create_info, None)?; let pool = base.device.create_command_pool(&create_info, None)?;
let buffer_info = vk::CommandBufferAllocateInfo::builder() let buffer_info = vk::CommandBufferAllocateInfo::default()
.command_pool(pool) .command_pool(pool)
.level(vk::CommandBufferLevel::PRIMARY) .level(vk::CommandBufferLevel::PRIMARY)
.command_buffer_count(frames_in_flight); .command_buffer_count(frames_in_flight);

View file

@ -1,10 +1,10 @@
use ash::extensions::ext::DebugUtils; use ash::ext::debug_utils::Instance;
use ash::prelude::VkResult; use ash::prelude::VkResult;
use ash::vk; use ash::vk;
use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT}; use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT};
pub struct VulkanDebug { pub struct VulkanDebug {
pub loader: DebugUtils, pub loader: Instance,
messenger: DebugUtilsMessengerEXT, messenger: DebugUtilsMessengerEXT,
} }
@ -15,7 +15,7 @@ impl VulkanDebug {
instance: &ash::Instance, instance: &ash::Instance,
callback: PFN_vkDebugUtilsMessengerCallbackEXT, callback: PFN_vkDebugUtilsMessengerCallbackEXT,
) -> VkResult<VulkanDebug> { ) -> VkResult<VulkanDebug> {
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::builder() let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
.message_severity( .message_severity(
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING | vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
@ -28,7 +28,7 @@ impl VulkanDebug {
) )
.pfn_user_callback(callback); .pfn_user_callback(callback);
let debug_utils_loader = DebugUtils::new(entry, instance); let debug_utils_loader = Instance::new(entry, instance);
dbg!("got to dbg"); dbg!("got to dbg");
unsafe { unsafe {

View file

@ -14,7 +14,7 @@ impl VulkanFramebuffer {
height: u32, height: u32,
) -> VkResult<VulkanFramebuffer> { ) -> VkResult<VulkanFramebuffer> {
let attachments = &[*image_view]; let attachments = &[*image_view];
let framebuffer_info = vk::FramebufferCreateInfo::builder() let framebuffer_info = vk::FramebufferCreateInfo::default()
.render_pass(*render_pass) .render_pass(*render_pass)
.attachments(attachments) .attachments(attachments)
.width(width) .width(width)

View file

@ -91,7 +91,7 @@ impl VulkanWindow {
}, },
}]; }];
let render_pass_begin = vk::RenderPassBeginInfo::builder() let render_pass_begin = vk::RenderPassBeginInfo::default()
.render_pass(vulkan.pipeline.renderpass) .render_pass(vulkan.pipeline.renderpass)
.framebuffer(framebuffer) .framebuffer(framebuffer)
.render_area(vk::Rect2D { .render_area(vk::Rect2D {
@ -284,7 +284,7 @@ impl VulkanWindow {
// vk::QUEUE_FAMILY_IGNORED, // vk::QUEUE_FAMILY_IGNORED,
// ); // );
// //
// let blit_subresource = vk::ImageSubresourceLayers::builder() // let blit_subresource = vk::ImageSubresourceLayers::default()
// .layer_count(1) // .layer_count(1)
// .aspect_mask(vk::ImageAspectFlags::COLOR) // .aspect_mask(vk::ImageAspectFlags::COLOR)
// ; // ;
@ -344,7 +344,7 @@ impl VulkanWindow {
let stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; let stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
let cmd = [cmd]; let cmd = [cmd];
let submit_info = [*vk::SubmitInfo::builder() let submit_info = [vk::SubmitInfo::default()
.wait_dst_stage_mask(&stage_mask) .wait_dst_stage_mask(&stage_mask)
.wait_semaphores(&image_available) .wait_semaphores(&image_available)
.signal_semaphores(&render_finished) .signal_semaphores(&render_finished)
@ -358,7 +358,7 @@ impl VulkanWindow {
let swapchain_index = [swapchain_index]; let swapchain_index = [swapchain_index];
let swapchain = [vulkan.swapchain.swapchain]; let swapchain = [vulkan.swapchain.swapchain];
let present_info = vk::PresentInfoKHR::builder() let present_info = vk::PresentInfoKHR::default()
.wait_semaphores(&render_finished) .wait_semaphores(&render_finished)
.swapchains(&swapchain) .swapchains(&swapchain)
.image_indices(&swapchain_index); .image_indices(&swapchain_index);

View file

@ -29,7 +29,7 @@ impl VulkanPipeline {
pub unsafe fn new(base: &VulkanBase, swapchain: &VulkanSwapchain) -> VkResult<VulkanPipeline> { pub unsafe fn new(base: &VulkanBase, swapchain: &VulkanSwapchain) -> VkResult<VulkanPipeline> {
// upload buffers // upload buffers
let index_buffer_data = [0u32, 1, 2]; let index_buffer_data = [0u32, 1, 2];
let index_buffer_info = vk::BufferCreateInfo::builder() let index_buffer_info = vk::BufferCreateInfo::default()
.size(std::mem::size_of_val(&index_buffer_data) as u64) .size(std::mem::size_of_val(&index_buffer_data) as u64)
.usage(vk::BufferUsageFlags::INDEX_BUFFER) .usage(vk::BufferUsageFlags::INDEX_BUFFER)
.sharing_mode(vk::SharingMode::EXCLUSIVE); .sharing_mode(vk::SharingMode::EXCLUSIVE);
@ -150,7 +150,7 @@ impl VulkanPipeline {
let vertex_code = let vertex_code =
read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file"); read_spv(&mut vertex_spv_file).expect("Failed to read vertex shader spv file");
let vertex_shader_info = ShaderModule::new(&base.device, vertex_code)?; let vertex_shader_info = ShaderModule::new(&base.device, vertex_code)?;
let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder() let vertex_stage_info = vk::PipelineShaderStageCreateInfo::default()
.module(vertex_shader_info.module) .module(vertex_shader_info.module)
.stage(vk::ShaderStageFlags::VERTEX) .stage(vk::ShaderStageFlags::VERTEX)
.name(ENTRY_POINT); .name(ENTRY_POINT);
@ -160,16 +160,16 @@ impl VulkanPipeline {
let frag_code = let frag_code =
read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file"); read_spv(&mut frag_spv_file).expect("Failed to read fragment shader spv file");
let frag_shader_info = ShaderModule::new(&base.device, frag_code)?; let frag_shader_info = ShaderModule::new(&base.device, frag_code)?;
let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder() let frag_stage_info = vk::PipelineShaderStageCreateInfo::default()
.module(frag_shader_info.module) .module(frag_shader_info.module)
.stage(vk::ShaderStageFlags::FRAGMENT) .stage(vk::ShaderStageFlags::FRAGMENT)
.name(ENTRY_POINT); .name(ENTRY_POINT);
let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::builder() let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::default()
.vertex_attribute_descriptions(&[]) .vertex_attribute_descriptions(&[])
.vertex_binding_descriptions(&[]); .vertex_binding_descriptions(&[]);
let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo::builder() let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo::default()
.primitive_restart_enable(false) .primitive_restart_enable(false)
.topology(vk::PrimitiveTopology::TRIANGLE_LIST); .topology(vk::PrimitiveTopology::TRIANGLE_LIST);
@ -194,13 +194,13 @@ impl VulkanPipeline {
.unwrap(); .unwrap();
let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder().dynamic_states(&states); let dynamic_state = vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&states);
let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() let viewport_state_info = vk::PipelineViewportStateCreateInfo::default()
.scissors(&scissors) .scissors(&scissors)
.viewports(&viewports); .viewports(&viewports);
let rs_state_info = vk::PipelineRasterizationStateCreateInfo::builder() let rs_state_info = vk::PipelineRasterizationStateCreateInfo::default()
.depth_clamp_enable(false) .depth_clamp_enable(false)
.depth_bias_enable(false) .depth_bias_enable(false)
.rasterizer_discard_enable(false) .rasterizer_discard_enable(false)
@ -209,12 +209,12 @@ impl VulkanPipeline {
.cull_mode(vk::CullModeFlags::BACK) .cull_mode(vk::CullModeFlags::BACK)
.front_face(vk::FrontFace::CLOCKWISE); .front_face(vk::FrontFace::CLOCKWISE);
let multisample = vk::PipelineMultisampleStateCreateInfo::builder() let multisample = vk::PipelineMultisampleStateCreateInfo::default()
.rasterization_samples(vk::SampleCountFlags::TYPE_1) .rasterization_samples(vk::SampleCountFlags::TYPE_1)
.min_sample_shading(1.0f32) .min_sample_shading(1.0f32)
.sample_shading_enable(false); .sample_shading_enable(false);
let color_blend_attachment = [*vk::PipelineColorBlendAttachmentState::builder() let color_blend_attachment = [vk::PipelineColorBlendAttachmentState::default()
.blend_enable(false) .blend_enable(false)
.color_write_mask(vk::ColorComponentFlags::RGBA) .color_write_mask(vk::ColorComponentFlags::RGBA)
.src_color_blend_factor(vk::BlendFactor::ONE) .src_color_blend_factor(vk::BlendFactor::ONE)
@ -224,7 +224,7 @@ impl VulkanPipeline {
.dst_alpha_blend_factor(vk::BlendFactor::ZERO) .dst_alpha_blend_factor(vk::BlendFactor::ZERO)
.alpha_blend_op(vk::BlendOp::ADD)]; .alpha_blend_op(vk::BlendOp::ADD)];
let color_blend_state = vk::PipelineColorBlendStateCreateInfo::builder() let color_blend_state = vk::PipelineColorBlendStateCreateInfo::default()
.logic_op(vk::LogicOp::COPY) .logic_op(vk::LogicOp::COPY)
.attachments(&color_blend_attachment); .attachments(&color_blend_attachment);
@ -252,11 +252,11 @@ impl VulkanPipeline {
// ..Default::default() // ..Default::default()
// }]; // }];
let subpass = vk::SubpassDescription::builder() let subpass = vk::SubpassDescription::default()
.color_attachments(&color_attachment_refs) .color_attachments(&color_attachment_refs)
.pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS); .pipeline_bind_point(vk::PipelineBindPoint::GRAPHICS);
let renderpass_create_info = vk::RenderPassCreateInfo::builder() let renderpass_create_info = vk::RenderPassCreateInfo::default()
.attachments(&renderpass_attachments) .attachments(&renderpass_attachments)
.subpasses(std::slice::from_ref(&subpass)) .subpasses(std::slice::from_ref(&subpass))
.dependencies(&[]); .dependencies(&[]);
@ -266,8 +266,8 @@ impl VulkanPipeline {
.create_render_pass(&renderpass_create_info, None) .create_render_pass(&renderpass_create_info, None)
.unwrap(); .unwrap();
let infos = [*vertex_stage_info, *frag_stage_info]; let infos = [vertex_stage_info, frag_stage_info];
let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::builder() let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::default()
.stages(&infos) .stages(&infos)
.vertex_input_state(&vertex_input_state_info) .vertex_input_state(&vertex_input_state_info)
.input_assembly_state(&vertex_input_assembly_state_info) .input_assembly_state(&vertex_input_assembly_state_info)
@ -278,7 +278,7 @@ impl VulkanPipeline {
.dynamic_state(&dynamic_state) .dynamic_state(&dynamic_state)
.layout(pipeline_layout) .layout(pipeline_layout)
.render_pass(renderpass); .render_pass(renderpass);
let graphic_pipeline_info = [*graphic_pipeline_info]; let graphic_pipeline_info = [graphic_pipeline_info];
let graphics_pipelines = base let graphics_pipelines = base
.device .device
@ -302,7 +302,7 @@ pub struct ShaderModule {
impl ShaderModule { impl ShaderModule {
pub fn new(device: &ash::Device, spirv: Vec<u32>) -> VkResult<ShaderModule> { pub fn new(device: &ash::Device, spirv: Vec<u32>) -> VkResult<ShaderModule> {
let create_info = vk::ShaderModuleCreateInfo::builder().code(&spirv); let create_info = vk::ShaderModuleCreateInfo::default().code(&spirv);
let module = unsafe { device.create_shader_module(&create_info, None)? }; let module = unsafe { device.create_shader_module(&create_info, None)? };

View file

@ -4,7 +4,7 @@ use ash::vk;
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
pub struct VulkanSurface { pub struct VulkanSurface {
surface_loader: ash::extensions::khr::Surface, surface_loader: ash::khr::surface::Instance,
pub surface: vk::SurfaceKHR, pub surface: vk::SurfaceKHR,
pub present_queue: vk::Queue, pub present_queue: vk::Queue,
} }
@ -15,13 +15,13 @@ impl VulkanSurface {
ash_window::create_surface( ash_window::create_surface(
&base.entry, &base.entry,
&base.instance, &base.instance,
window.raw_display_handle(), window.raw_display_handle().unwrap(),
window.raw_window_handle(), window.raw_window_handle().unwrap(),
None, None,
)? )?
}; };
let surface_loader = ash::extensions::khr::Surface::new(&base.entry, &base.instance); let surface_loader = ash::khr::surface::Instance::new(&base.entry, &base.instance);
let present_queue = unsafe { let present_queue = unsafe {
let queue_family = base let queue_family = base

View file

@ -9,7 +9,7 @@ use std::sync::Arc;
pub struct VulkanSwapchain { pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR, pub swapchain: vk::SwapchainKHR,
pub loader: ash::extensions::khr::Swapchain, pub loader: ash::khr::swapchain::Device,
pub format: vk::SurfaceFormatKHR, pub format: vk::SurfaceFormatKHR,
pub extent: vk::Extent2D, pub extent: vk::Extent2D,
pub mode: vk::PresentModeKHR, pub mode: vk::PresentModeKHR,
@ -44,7 +44,7 @@ impl VulkanSwapchain {
panic!("exclusive mode only") panic!("exclusive mode only")
} }
let create_info = vk::SwapchainCreateInfoKHR::builder() let create_info = vk::SwapchainCreateInfoKHR::default()
.surface(surface.surface) .surface(surface.surface)
.present_mode(mode) .present_mode(mode)
.min_image_count(image_count) .min_image_count(image_count)
@ -59,7 +59,7 @@ impl VulkanSwapchain {
// todo: switch to IMAGE_USAGE_TRANSFER_DST // todo: switch to IMAGE_USAGE_TRANSFER_DST
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT); .image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT);
let loader = ash::extensions::khr::Swapchain::new(&base.instance, &base.device); let loader = ash::khr::swapchain::Device::new(&base.instance, &base.device);
let swapchain = unsafe { loader.create_swapchain(&create_info, None)? }; let swapchain = unsafe { loader.create_swapchain(&create_info, None)? };
@ -69,7 +69,7 @@ impl VulkanSwapchain {
// create render imaghes // create render imaghes
for _ in 0..swapchain_images.len() { for _ in 0..swapchain_images.len() {
let create_info = vk::ImageCreateInfo::builder() let create_info = vk::ImageCreateInfo::default()
.extent(Extent3D { .extent(Extent3D {
width, width,
height, height,
@ -104,7 +104,7 @@ impl VulkanSwapchain {
let swapchain_image_views: VkResult<Vec<vk::ImageView>> = swapchain_images let swapchain_image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
.iter() .iter()
.map(|image| { .map(|image| {
let create_info = vk::ImageViewCreateInfo::builder() let create_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.format(format.format) .format(format.format)
.components(vk::ComponentMapping { .components(vk::ComponentMapping {
@ -128,7 +128,7 @@ impl VulkanSwapchain {
// .loader // .loader
// .set_debug_utils_object_name( // .set_debug_utils_object_name(
// base.device.handle(), // base.device.handle(),
// &vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::default()
// .object_handle(image.as_raw()) // .object_handle(image.as_raw())
// .object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
// b"SwapchainImage\0", // b"SwapchainImage\0",
@ -141,7 +141,7 @@ impl VulkanSwapchain {
// .loader // .loader
// .set_debug_utils_object_name( // .set_debug_utils_object_name(
// base.device.handle(), // base.device.handle(),
// &vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::default()
// .object_handle(view.as_raw()) // .object_handle(view.as_raw())
// .object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
// b"SwapchainImageView\0", // b"SwapchainImageView\0",
@ -158,7 +158,7 @@ impl VulkanSwapchain {
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
.iter() .iter()
.map(|(image, _)| { .map(|(image, _)| {
let create_info = vk::ImageViewCreateInfo::builder() let create_info = vk::ImageViewCreateInfo::default()
.view_type(vk::ImageViewType::TYPE_2D) .view_type(vk::ImageViewType::TYPE_2D)
.format(format.format) .format(format.format)
.components(vk::ComponentMapping { .components(vk::ComponentMapping {
@ -182,7 +182,7 @@ impl VulkanSwapchain {
// .loader // .loader
// .set_debug_utils_object_name( // .set_debug_utils_object_name(
// base.device.handle(), // base.device.handle(),
// &vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::default()
// .object_handle(view.as_raw()) // .object_handle(view.as_raw())
// .object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
// b"RenderImageView\0", // b"RenderImageView\0",

View file

@ -20,7 +20,7 @@ impl SyncObjects {
render_finished render_finished
.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?); .push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
in_flight.push(device.create_fence( in_flight.push(device.create_fence(
&vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED), &vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED),
None, None,
)?) )?)
} }

View file

@ -27,7 +27,7 @@ pub struct VulkanBase {
impl VulkanBase { impl VulkanBase {
pub fn new(entry: ash::Entry) -> VkResult<VulkanBase> { pub fn new(entry: ash::Entry) -> VkResult<VulkanBase> {
let app_info = vk::ApplicationInfo::builder() let app_info = vk::ApplicationInfo::default()
.application_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) }) .application_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) }) .engine_name(unsafe { CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_version(0) .engine_version(0)
@ -37,14 +37,14 @@ impl VulkanBase {
dbg!("entry"); dbg!("entry");
// todo: make this xplat // todo: make this xplat
let extensions = [ let extensions = [
ash::extensions::khr::Surface::name().as_ptr(), ash::khr::surface::NAME.as_ptr(),
ash::extensions::khr::Win32Surface::name().as_ptr(), ash::khr::win32_surface::NAME.as_ptr(),
ash::extensions::ext::DebugUtils::name().as_ptr(), ash::ext::debug_utils::NAME.as_ptr(),
]; ];
let layers = [KHRONOS_VALIDATION.as_ptr().cast()]; let layers = [KHRONOS_VALIDATION.as_ptr().cast()];
let create_info = vk::InstanceCreateInfo::builder() let create_info = vk::InstanceCreateInfo::default()
.application_info(&app_info) .application_info(&app_info)
.enabled_layer_names(&layers) .enabled_layer_names(&layers)
.enabled_extension_names(&extensions); .enabled_extension_names(&extensions);
@ -84,25 +84,25 @@ impl VulkanBase {
let _debug = [unsafe { CStr::from_bytes_with_nul_unchecked(KHRONOS_VALIDATION).as_ptr() }]; let _debug = [unsafe { CStr::from_bytes_with_nul_unchecked(KHRONOS_VALIDATION).as_ptr() }];
let indices = find_queue_family(instance, *physical_device); let indices = find_queue_family(instance, *physical_device);
let queue_info = [*vk::DeviceQueueCreateInfo::builder() let queue_info = [vk::DeviceQueueCreateInfo::default()
.queue_family_index(indices.graphics_family()) .queue_family_index(indices.graphics_family())
.queue_priorities(&[1.0f32])]; .queue_priorities(&[1.0f32])];
// let physical_device_features = vk::PhysicalDeviceFeatures::default(); // let physical_device_features = vk::PhysicalDeviceFeatures::default();
let mut physical_device_features = let mut physical_device_features =
vk::PhysicalDeviceVulkan13Features::builder().dynamic_rendering(true); vk::PhysicalDeviceVulkan13Features::default().dynamic_rendering(true);
// let mut physical_device_features = // let mut physical_device_features =
// vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features) // vk::PhysicalDeviceFeatures2::default().push_next(&mut physical_device_features)
// ; // ;
let extensions = [ let extensions = [
ash::extensions::khr::Swapchain::name().as_ptr(), ash::khr::swapchain::NAME.as_ptr(),
ash::extensions::khr::DynamicRendering::name().as_ptr(), ash::khr::dynamic_rendering::NAME.as_ptr(),
]; ];
let device_create_info = vk::DeviceCreateInfo::builder() let device_create_info = vk::DeviceCreateInfo::default()
.queue_create_infos(&queue_info) .queue_create_infos(&queue_info)
// .enabled_layer_names(&debug) // .enabled_layer_names(&debug)
.enabled_extension_names(&extensions) .enabled_extension_names(&extensions)

View file

@ -2,7 +2,7 @@
name = "librashader-runtime-wgpu" name = "librashader-runtime-wgpu"
edition = "2021" edition = "2021"
version = "0.2.7" version = "0.2.8"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
@ -14,13 +14,14 @@ description = "RetroArch shaders for all."
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.2.7" } librashader-common = { path = "../librashader-common", features = ["wgpu"], version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7", features = ["wgsl"], default-features = false } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8", features = ["wgsl"], default-features = false }
librashader-runtime = { path = "../librashader-runtime" , version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime" , version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.8" }
wgpu = { version = "0.20.0", default-features = false, features = ["wgsl"] } wgpu = { version = "22.0", default-features = false, features = ["wgsl"] }
image = "0.25.1" image = "0.25.1"
thiserror = "1.0.50" thiserror = "1.0.50"
bytemuck = { version = "1.14.0", features = ["derive"] } bytemuck = { version = "1.14.0", features = ["derive"] }

View file

@ -25,7 +25,7 @@ use librashader_reflect::reflect::naga::{Naga, NagaLoweringOptions};
use librashader_runtime::framebuffer::FramebufferInit; use librashader_runtime::framebuffer::FramebufferInit;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use librashader_runtime::scaling::ScaleFramebuffer; use librashader_runtime::scaling::ScaleFramebuffer;
use wgpu::{Device, TextureFormat}; use wgpu::{AdapterInfo, Device, TextureFormat};
use crate::error; use crate::error;
use crate::error::FilterChainError; use crate::error::FilterChainError;
@ -144,8 +144,17 @@ impl FilterChainWgpu {
) -> error::Result<FilterChainWgpu> { ) -> error::Result<FilterChainWgpu> {
let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?; let (passes, semantics) = compile_passes(preset.shaders, &preset.textures)?;
// // initialize passes // cache is opt-in for wgpu, not opt-out because of feature requirements.
let filters = Self::init_passes(Arc::clone(&device), passes, &semantics)?; let disable_cache = options.map_or(true, |o| !o.enable_cache);
// initialize passes
let filters = Self::init_passes(
Arc::clone(&device),
passes,
&semantics,
options.and_then(|o| o.adapter_info.as_ref()),
disable_cache,
)?;
let samplers = SamplerSet::new(&device); let samplers = SamplerSet::new(&device);
let mut mipmapper = MipmapGen::new(Arc::clone(&device)); let mut mipmapper = MipmapGen::new(Arc::clone(&device));
@ -268,6 +277,8 @@ impl FilterChainWgpu {
device: Arc<Device>, device: Arc<Device>,
passes: Vec<ShaderPassMeta>, passes: Vec<ShaderPassMeta>,
semantics: &ShaderSemantics, semantics: &ShaderSemantics,
adapter_info: Option<&wgpu::AdapterInfo>,
disable_cache: bool,
) -> error::Result<Box<[FilterPass]>> { ) -> error::Result<Box<[FilterPass]>> {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let filter_creation_fn = || { let filter_creation_fn = || {
@ -320,6 +331,8 @@ impl FilterChainWgpu {
&wgsl, &wgsl,
&reflection, &reflection,
render_pass_format.unwrap_or(TextureFormat::Rgba8Unorm), render_pass_format.unwrap_or(TextureFormat::Rgba8Unorm),
adapter_info,
disable_cache,
); );
Ok(FilterPass { Ok(FilterPass {

View file

@ -1,11 +1,14 @@
use crate::error::FilterChainError;
use crate::framebuffer::WgpuOutputView; use crate::framebuffer::WgpuOutputView;
use crate::util; use crate::util;
use librashader_cache::cache_pipeline;
use librashader_reflect::back::wgsl::NagaWgslContext; use librashader_reflect::back::wgsl::NagaWgslContext;
use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::ShaderReflection; use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::quad::VertexInput; use librashader_runtime::quad::VertexInput;
use librashader_runtime::render_target::RenderTarget; use librashader_runtime::render_target::RenderTarget;
use std::borrow::Cow; use std::borrow::Cow;
use std::convert::Infallible;
use std::sync::Arc; use std::sync::Arc;
use wgpu::{ use wgpu::{
BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
@ -18,6 +21,7 @@ use wgpu::{
pub struct WgpuGraphicsPipeline { pub struct WgpuGraphicsPipeline {
pub layout: PipelineLayoutObjects, pub layout: PipelineLayoutObjects,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
cache: Option<wgpu::PipelineCache>,
pub format: wgpu::TextureFormat, pub format: wgpu::TextureFormat,
} }
@ -144,7 +148,11 @@ impl PipelineLayoutObjects {
} }
} }
pub fn create_pipeline(&self, framebuffer_format: TextureFormat) -> wgpu::RenderPipeline { pub fn create_pipeline(
&self,
framebuffer_format: TextureFormat,
cache: Option<&wgpu::PipelineCache>,
) -> wgpu::RenderPipeline {
self.device self.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor { .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"), label: Some("Render Pipeline"),
@ -198,6 +206,7 @@ impl PipelineLayoutObjects {
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
}, },
multiview: None, multiview: None,
cache,
}) })
} }
} }
@ -208,18 +217,50 @@ impl WgpuGraphicsPipeline {
shader_assembly: &ShaderCompilerOutput<String, NagaWgslContext>, shader_assembly: &ShaderCompilerOutput<String, NagaWgslContext>,
reflection: &ShaderReflection, reflection: &ShaderReflection,
render_pass_format: TextureFormat, render_pass_format: TextureFormat,
adapter_info: Option<&wgpu::AdapterInfo>,
bypass_cache: bool,
) -> Self { ) -> Self {
let cache = if bypass_cache {
None
} else {
let name = adapter_info
.and_then(|o| wgpu::util::pipeline_cache_key(o))
.unwrap_or_else(|| String::from("wgpu"));
cache_pipeline(
&name,
&[
&shader_assembly.vertex.as_str(),
&shader_assembly.fragment.as_str(),
],
|pipeline_data| {
let descriptor = wgpu::PipelineCacheDescriptor {
label: Some("librashader-wgpu"),
data: pipeline_data.as_deref(),
fallback: true,
};
let cache = unsafe { device.create_pipeline_cache(&descriptor) };
Ok::<_, Infallible>(cache)
},
|cache| Ok(cache.get_data()),
bypass_cache,
)
.ok()
};
let layout = PipelineLayoutObjects::new(reflection, shader_assembly, device); let layout = PipelineLayoutObjects::new(reflection, shader_assembly, device);
let render_pipeline = layout.create_pipeline(render_pass_format); let render_pipeline = layout.create_pipeline(render_pass_format, cache.as_ref());
Self { Self {
layout, layout,
render_pipeline, render_pipeline,
format: render_pass_format, format: render_pass_format,
cache,
} }
} }
pub fn recompile(&mut self, format: TextureFormat) { pub fn recompile(&mut self, format: TextureFormat) {
let render_pipeline = self.layout.create_pipeline(format); let render_pipeline = self.layout.create_pipeline(format, self.cache.as_ref());
self.render_pipeline = render_pipeline; self.render_pipeline = render_pipeline;
} }

View file

@ -36,6 +36,7 @@ impl MipmapGen {
depth_stencil: None, depth_stencil: None,
multisample: wgpu::MultisampleState::default(), multisample: wgpu::MultisampleState::default(),
multiview: None, multiview: None,
cache: None,
}); });
pipeline pipeline

View file

@ -9,4 +9,11 @@ impl_default_frame_options!(FrameOptionsWgpu);
pub struct FilterChainOptionsWgpu { pub struct FilterChainOptionsWgpu {
/// Whether or not to explicitly disable mipmap generation regardless of shader preset settings. /// Whether or not to explicitly disable mipmap generation regardless of shader preset settings.
pub force_no_mipmaps: bool, pub force_no_mipmaps: bool,
/// Enable the shader object cache. Shaders will be loaded from the cache
/// if this is enabled.
pub enable_cache: bool,
/// WGPU adapter info for use to determine the name of the pipeline cache index.
/// If this is not provided, then it will fallback to a default "wgpu" index, which
/// may clobber the cache for a different device using WGPU.
pub adapter_info: Option<wgpu::AdapterInfo>,
} }

View file

@ -93,9 +93,13 @@ impl<'a> State<'a> {
let (device, queue) = adapter let (device, queue) = adapter
.request_device( .request_device(
&wgpu::DeviceDescriptor { &wgpu::DeviceDescriptor {
required_features: wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER, required_features: wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER
| wgpu::Features::PIPELINE_CACHE
| wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES
| wgpu::Features::FLOAT32_FILTERABLE,
required_limits: wgpu::Limits::default(), required_limits: wgpu::Limits::default(),
label: None, label: None,
memory_hints: Default::default(),
}, },
None, None,
) )
@ -118,17 +122,14 @@ impl<'a> State<'a> {
let device = Arc::new(device); let device = Arc::new(device);
let queue = Arc::new(queue); let queue = Arc::new(queue);
// //
// let preset = ShaderPreset::try_parse( // let preset = ShaderPreset::try_parse("../test/basic.slangp").unwrap();
// "../test/basic.slangp",
// )
// .unwrap();
// //
let preset = ShaderPreset::try_parse("../test/shaders_slang/test/history.slangp").unwrap(); // let preset = ShaderPreset::try_parse("../test/shaders_slang/test/history.slangp").unwrap();
// let preset = ShaderPreset::try_parse( let preset = ShaderPreset::try_parse(
// "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", "../test/shaders_slang/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
// ) )
// .unwrap(); .unwrap();
let chain = FilterChainWgpu::load_from_preset( let chain = FilterChainWgpu::load_from_preset(
preset, preset,
@ -154,11 +155,13 @@ impl<'a> State<'a> {
vertex: wgpu::VertexState { vertex: wgpu::VertexState {
module: &shader, module: &shader,
entry_point: "vs_main", entry_point: "vs_main",
compilation_options: Default::default(),
buffers: &[Vertex::desc()], buffers: &[Vertex::desc()],
}, },
fragment: Some(wgpu::FragmentState { fragment: Some(wgpu::FragmentState {
module: &shader, module: &shader,
entry_point: "fs_main", entry_point: "fs_main",
compilation_options: Default::default(),
targets: &[Some(wgpu::ColorTargetState { targets: &[Some(wgpu::ColorTargetState {
format: config.format, format: config.format,
blend: Some(wgpu::BlendState::REPLACE), blend: Some(wgpu::BlendState::REPLACE),
@ -181,6 +184,7 @@ impl<'a> State<'a> {
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
}, },
multiview: None, multiview: None,
cache: None,
}); });
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {

View file

@ -3,7 +3,7 @@ name = "librashader-runtime"
edition = "2021" edition = "2021"
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -12,10 +12,10 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", version = "0.2.7" } librashader-common = { path = "../librashader-common", version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
bytemuck = { version = "1.12.3", features = ["derive"] } bytemuck = { version = "1.12.3", features = ["derive"] }
num-traits = "0.2.15" num-traits = "0.2.15"
array-concat = "0.5.2" array-concat = "0.5.2"

View file

@ -95,8 +95,8 @@ where
type UniformOffset: ContextOffset<H, C, Self::DeviceContext>; type UniformOffset: ContextOffset<H, C, Self::DeviceContext>;
/// Bind a texture to the input descriptor set /// Bind a texture to the input descriptor set
fn bind_texture<'a>( fn bind_texture(
descriptors: &mut Self::DescriptorSet<'a>, descriptors: &mut Self::DescriptorSet<'_>,
samplers: &Self::SamplerSet, samplers: &Self::SamplerSet,
binding: &TextureBinding, binding: &TextureBinding,
texture: &Self::InputTexture, texture: &Self::InputTexture,
@ -105,11 +105,11 @@ where
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
/// Write uniform and texture semantics to the provided storages. /// Write uniform and texture semantics to the provided storages.
fn bind_semantics<'a>( fn bind_semantics(
device: &Self::DeviceContext, device: &Self::DeviceContext,
sampler_set: &Self::SamplerSet, sampler_set: &Self::SamplerSet,
uniform_storage: &mut UniformStorage<H, C, U, P, Self::DeviceContext>, uniform_storage: &mut UniformStorage<H, C, U, P, Self::DeviceContext>,
descriptor_set: &mut Self::DescriptorSet<'a>, descriptor_set: &mut Self::DescriptorSet<'_>,
uniform_inputs: UniformInputs<'_>, uniform_inputs: UniformInputs<'_>,
original: &Self::InputTexture, original: &Self::InputTexture,
source: &Self::InputTexture, source: &Self::InputTexture,

View file

@ -14,7 +14,7 @@ impl<'a, F, I, E> FramebufferInit<'a, F, I, E> {
/// Create a new framebuffer initializer with the given /// Create a new framebuffer initializer with the given
/// closures to create owned framebuffers and image views. /// closures to create owned framebuffers and image views.
pub fn new( pub fn new(
filters: impl Iterator<Item = &'a BindingMeta> + ExactSizeIterator, filters: impl ExactSizeIterator<Item = &'a BindingMeta>,
owned_generator: &'a dyn Fn() -> Result<F, E>, owned_generator: &'a dyn Fn() -> Result<F, E>,
input_generator: &'a dyn Fn() -> I, input_generator: &'a dyn Fn() -> I,
) -> Self { ) -> Self {

View file

@ -7,8 +7,8 @@ pub trait FilterChainParameters {
fn set_enabled_pass_count(&mut self, count: usize); fn set_enabled_pass_count(&mut self, count: usize);
/// Enumerates the active parameters as well as their values in the current filter chain. /// Enumerates the active parameters as well as their values in the current filter chain.
fn enumerate_parameters<'a>( fn enumerate_parameters(
&'a self, &self,
) -> ::librashader_common::map::halfbrown::Iter<String, f32>; ) -> ::librashader_common::map::halfbrown::Iter<String, f32>;
/// Get the value of the given parameter if present. /// Get the value of the given parameter if present.

View file

@ -39,6 +39,16 @@ pub struct InlineRingBuffer<T, const SIZE: usize> {
index: usize, index: usize,
} }
impl<T, const SIZE: usize> Default for InlineRingBuffer<T, SIZE>
where
T: Copy,
T: Default,
{
fn default() -> Self {
Self::new()
}
}
impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE> impl<T, const SIZE: usize> InlineRingBuffer<T, SIZE>
where where
T: Copy, T: Copy,

View file

@ -4,7 +4,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
license = "MPL-2.0 OR GPL-3.0-only" license = "MPL-2.0 OR GPL-3.0-only"
version = "0.2.7" version = "0.2.8"
authors = ["Ronny Chan <ronny@ronnychan.ca>"] authors = ["Ronny Chan <ronny@ronnychan.ca>"]
repository = "https://github.com/SnowflakePowered/librashader" repository = "https://github.com/SnowflakePowered/librashader"
readme = "../README.md" readme = "../README.md"
@ -13,33 +13,33 @@ keywords = ["shader", "retroarch", "SPIR-V"]
description = "RetroArch shaders for all." description = "RetroArch shaders for all."
[dependencies] [dependencies]
librashader-common = { path = "../librashader-common", version = "0.2.7" } librashader-common = { path = "../librashader-common", version = "0.2.8" }
librashader-presets = { path = "../librashader-presets", version = "0.2.7" } librashader-presets = { path = "../librashader-presets", version = "0.2.8" }
librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.7" } librashader-preprocess = { path = "../librashader-preprocess", version = "0.2.8" }
librashader-reflect = { path = "../librashader-reflect", version = "0.2.7" } librashader-reflect = { path = "../librashader-reflect", version = "0.2.8" }
librashader-cache = { path = "../librashader-cache", version = "0.2.7" } librashader-cache = { path = "../librashader-cache", version = "0.2.8" }
librashader-runtime = { path = "../librashader-runtime", version = "0.2.7" } librashader-runtime = { path = "../librashader-runtime", version = "0.2.8" }
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11", version = "0.2.7", optional = true } librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11", version = "0.2.8", optional = true }
librashader-runtime-d3d12 = { path = "../librashader-runtime-d3d12", version = "0.2.7", optional = true } librashader-runtime-d3d12 = { path = "../librashader-runtime-d3d12", version = "0.2.8", optional = true }
librashader-runtime-d3d9 = { path = "../librashader-runtime-d3d9", version = "0.2.7", optional = true } librashader-runtime-d3d9 = { path = "../librashader-runtime-d3d9", version = "0.2.8", optional = true }
librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.2.7", optional = true } librashader-runtime-gl = { path = "../librashader-runtime-gl", version = "0.2.8", optional = true }
librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.2.7", optional = true } librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.2.8", optional = true }
librashader-runtime-mtl = { path = "../librashader-runtime-mtl", version = "0.2.7", optional = true } librashader-runtime-mtl = { path = "../librashader-runtime-mtl", version = "0.2.8", optional = true }
ash = { version = "0.37", optional = true } ash = { version = "0.38", optional = true }
halfbrown = "0.2.4" halfbrown = "0.2.4"
[target.'cfg(not(all(target_vendor="apple", docsrs)))'.dependencies] [target.'cfg(not(all(target_vendor="apple", docsrs)))'.dependencies]
wgpu = { version = "0.20", default-features = false, optional = true } wgpu = { version = "22", default-features = false, optional = true }
librashader-runtime-wgpu = { path = "../librashader-runtime-wgpu", version = "0.2.7", optional = true } librashader-runtime-wgpu = { path = "../librashader-runtime-wgpu", version = "0.2.8", optional = true }
wgpu-types = { version = "0.20", optional = true } wgpu-types = { version = "22", optional = true }
[target.'cfg(windows)'.dependencies.windows] [target.'cfg(windows)'.dependencies.windows]
workspace = true workspace = true
optional = true optional = true
[target.'cfg(target_vendor="apple")'.dependencies] [target.'cfg(target_vendor="apple")'.dependencies]
icrate = { version = "0.1.0" , features = [ "Metal", "Metal_all" ], optional = true} objc2-metal = { version = "0.2.0" , features = [ "all" ], optional = true}
objc2 = { version = "0.5.0", features = ["apple"] , optional = true } objc2 = { version = "0.5.0", features = ["apple"] , optional = true }
[features] [features]
@ -58,7 +58,7 @@ runtime-d3d9 = [ "runtime", "reflect-cross", "librashader-common/d3d9", "librash
runtime-vk = ["runtime", "reflect-cross", "librashader-common/vulkan", "librashader-runtime-vk", "ash" ] runtime-vk = ["runtime", "reflect-cross", "librashader-common/vulkan", "librashader-runtime-vk", "ash" ]
runtime-wgpu = [ "runtime", "reflect-naga", "librashader-common/wgpu", "librashader-runtime-wgpu", "wgpu", "wgpu-types" ] runtime-wgpu = [ "runtime", "reflect-naga", "librashader-common/wgpu", "librashader-runtime-wgpu", "wgpu", "wgpu-types" ]
runtime-metal = [ "runtime", "reflect-naga", "reflect-cross", "librashader-common/metal", "librashader-runtime-mtl", "icrate", "objc2" ] runtime-metal = [ "runtime", "reflect-naga", "reflect-cross", "librashader-common/metal", "librashader-runtime-mtl", "objc2-metal", "objc2" ]
# reflection # reflection
reflect-cross = ["reflect", "librashader-reflect/cross"] reflect-cross = ["reflect", "librashader-reflect/cross"]
@ -75,7 +75,7 @@ internal = []
full = ["runtime-all", "reflect-all", "preprocess", "presets"] full = ["runtime-all", "reflect-all", "preprocess", "presets"]
# cache hack # cache hack
docsrs = ["librashader-cache/docsrs", "objc2/unstable-docsrs"] docsrs = ["librashader-cache/docsrs"]
# emits warning messages in tests # emits warning messages in tests
github-ci = [] github-ci = []

2
rust-toolchain.toml Normal file
View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"