rt: mark frame and create APIs unsafe
This doesn't cause an API break in the C API but we don't actually make an attempt to verify that it's safe to access any of the device contexts.
This commit is contained in:
parent
f8de1fa2ee
commit
0adf3505ec
|
@ -4,18 +4,19 @@ use crate::key::CacheKey;
|
||||||
pub(crate) mod internal {
|
pub(crate) mod internal {
|
||||||
use platform_dirs::AppDirs;
|
use platform_dirs::AppDirs;
|
||||||
use rusqlite::{Connection, DatabaseName};
|
use rusqlite::{Connection, DatabaseName};
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub(crate) fn get_cache_dir() -> Result<PathBuf, Box<dyn Error>> {
|
pub(crate) fn get_cache_dir() -> Result<PathBuf, Box<dyn Error>> {
|
||||||
let cache_dir =
|
let cache_dir = if let Some(cache_dir) =
|
||||||
if let Some(cache_dir) = AppDirs::new(Some("librashader"), false).map(|a| a.cache_dir) {
|
AppDirs::new(Some("librashader"), false).map(|a| a.cache_dir)
|
||||||
cache_dir
|
{
|
||||||
} else {
|
cache_dir
|
||||||
let mut current_dir = std::env::current_dir()?;
|
} else {
|
||||||
current_dir.push("librashader");
|
let mut current_dir = std::env::current_dir()?;
|
||||||
current_dir
|
current_dir.push("librashader");
|
||||||
};
|
current_dir
|
||||||
|
};
|
||||||
|
|
||||||
std::fs::create_dir_all(&cache_dir)?;
|
std::fs::create_dir_all(&cache_dir)?;
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,10 @@
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
|
|
||||||
|
|
||||||
mod compilation;
|
mod compilation;
|
||||||
|
|
||||||
mod key;
|
|
||||||
mod cacheable;
|
mod cacheable;
|
||||||
|
mod key;
|
||||||
|
|
||||||
pub use cacheable::Cacheable;
|
pub use cacheable::Cacheable;
|
||||||
pub use key::CacheKey;
|
pub use key::CacheKey;
|
||||||
|
@ -19,6 +18,5 @@ pub use compilation::CachedCompilation;
|
||||||
pub use cache::cache_pipeline;
|
pub use cache::cache_pipeline;
|
||||||
pub use cache::cache_shader_object;
|
pub use cache::cache_shader_object;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(all(target_os = "windows", feature = "d3d"))]
|
#[cfg(all(target_os = "windows", feature = "d3d"))]
|
||||||
mod d3d;
|
mod d3d;
|
||||||
|
|
|
@ -113,13 +113,13 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset(
|
|
||||||
*preset,
|
|
||||||
&device,
|
|
||||||
options.as_ref(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset(
|
||||||
|
*preset,
|
||||||
|
&device,
|
||||||
|
options.as_ref(),
|
||||||
|
)?;
|
||||||
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -173,17 +173,15 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = unsafe {
|
unsafe {
|
||||||
librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset_deferred(
|
let chain = librashader::runtime::d3d11::capi::FilterChainD3D11::load_from_preset_deferred(
|
||||||
*preset,
|
*preset,
|
||||||
&device,
|
&device,
|
||||||
&device_context,
|
&device_context,
|
||||||
options.as_ref(),
|
options.as_ref(),
|
||||||
)?
|
)?;
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
}
|
}
|
||||||
|
@ -257,7 +255,10 @@ extern_fn! {
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let image = image.try_into()?;
|
let image = image.try_into()?;
|
||||||
chain.frame(device_context.as_deref(), image, &viewport, frame_count, options.as_ref())?;
|
|
||||||
|
unsafe {
|
||||||
|
chain.frame(device_context.as_deref(), image, &viewport, frame_count, options.as_ref())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,13 +135,13 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset(
|
|
||||||
*preset,
|
|
||||||
&device,
|
|
||||||
options.as_ref(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset(
|
||||||
|
*preset,
|
||||||
|
&device,
|
||||||
|
options.as_ref(),
|
||||||
|
)?;
|
||||||
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -187,16 +187,14 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = unsafe {
|
unsafe {
|
||||||
librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset_deferred(
|
let chain = librashader::runtime::d3d12::capi::FilterChainD3D12::load_from_preset_deferred(
|
||||||
*preset,
|
*preset,
|
||||||
&device,
|
&device,
|
||||||
&command_list,
|
&command_list,
|
||||||
options.as_ref(),
|
options.as_ref(),
|
||||||
)?
|
)?;
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -261,7 +259,9 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let image = image.try_into()?;
|
let image = image.try_into()?;
|
||||||
chain.frame(&command_list, image, &viewport, frame_count, options.as_ref())?;
|
unsafe {
|
||||||
|
chain.frame(&command_list, image, &viewport, frame_count, options.as_ref())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,9 +147,10 @@ extern_fn! {
|
||||||
};
|
};
|
||||||
|
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
let chain = librashader::runtime::gl::capi::FilterChainGL::load_from_preset(*preset, options.as_ref())?;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let chain = librashader::runtime::gl::capi::FilterChainGL::load_from_preset(*preset, options.as_ref())?;
|
||||||
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -201,7 +202,10 @@ extern_fn! {
|
||||||
output: &framebuffer,
|
output: &framebuffer,
|
||||||
mvp,
|
mvp,
|
||||||
};
|
};
|
||||||
chain.frame(&image, &viewport, frame_count, opt.as_ref())?;
|
|
||||||
|
unsafe {
|
||||||
|
chain.frame(&image, &viewport, frame_count, opt.as_ref())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,9 +160,9 @@ extern_fn! {
|
||||||
let vulkan: VulkanInstance = vulkan.into();
|
let vulkan: VulkanInstance = vulkan.into();
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(*preset, vulkan, options.as_ref())?;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset(*preset, vulkan, options.as_ref())?;
|
||||||
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -211,14 +211,12 @@ extern_fn! {
|
||||||
let vulkan: VulkanInstance = vulkan.into();
|
let vulkan: VulkanInstance = vulkan.into();
|
||||||
let options = options.map(FromUninit::from_uninit);
|
let options = options.map(FromUninit::from_uninit);
|
||||||
|
|
||||||
let chain = unsafe {
|
unsafe {
|
||||||
librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset_deferred(*preset,
|
let chain = librashader::runtime::vk::capi::FilterChainVulkan::load_from_preset_deferred(*preset,
|
||||||
vulkan,
|
vulkan,
|
||||||
command_buffer,
|
command_buffer,
|
||||||
options.as_ref())?
|
options.as_ref())?;
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
out.write(MaybeUninit::new(NonNull::new(Box::into_raw(Box::new(
|
||||||
chain,
|
chain,
|
||||||
)))))
|
)))))
|
||||||
|
@ -282,7 +280,10 @@ extern_fn! {
|
||||||
output,
|
output,
|
||||||
mvp,
|
mvp,
|
||||||
};
|
};
|
||||||
chain.frame(&image, &viewport, command_buffer, frame_count, opt.as_ref())?;
|
|
||||||
|
unsafe {
|
||||||
|
chain.frame(&image, &viewport, command_buffer, frame_count, opt.as_ref())?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,18 +77,19 @@ pub(crate) struct FilterCommon {
|
||||||
|
|
||||||
impl FilterChainD3D11 {
|
impl FilterChainD3D11 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub unsafe fn load_from_path(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
) -> error::Result<FilterChainD3D11> {
|
) -> error::Result<FilterChainD3D11> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset, device, options)
|
|
||||||
|
unsafe { Self::load_from_preset(preset, device, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
options: Option<&FilterChainOptionsD3D11>,
|
options: Option<&FilterChainOptionsD3D11>,
|
||||||
|
@ -374,7 +375,7 @@ impl FilterChainD3D11 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
pub fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: Option<&ID3D11DeviceContext>,
|
ctx: Option<&ID3D11DeviceContext>,
|
||||||
input: D3D11InputView,
|
input: D3D11InputView,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![cfg(target_os = "windows")]
|
#![cfg(target_os = "windows")]
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
//! librashader Direct3D 11 runtime
|
//! librashader Direct3D 11 runtime
|
||||||
//!
|
//!
|
||||||
//! This crate should not be used directly.
|
//! This crate should not be used directly.
|
||||||
|
|
|
@ -242,15 +242,14 @@ pub mod d3d11_hello_triangle {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
||||||
use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
|
|
||||||
use librashader_runtime_d3d11::{D3D11InputView, D3D11OutputView};
|
|
||||||
use texture::ExampleTexture;
|
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};
|
||||||
use librashader_runtime::image::Image;
|
use librashader_runtime::image::Image;
|
||||||
|
use librashader_runtime_d3d11::options::FilterChainOptionsD3D11;
|
||||||
|
use librashader_runtime_d3d11::FilterChainD3D11;
|
||||||
|
use librashader_runtime_d3d11::{D3D11InputView, D3D11OutputView};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use librashader_runtime_d3d11::FilterChainD3D11;
|
use texture::ExampleTexture;
|
||||||
|
|
||||||
pub struct Sample {
|
pub struct Sample {
|
||||||
pub dxgi_factory: IDXGIFactory4,
|
pub dxgi_factory: IDXGIFactory4,
|
||||||
|
|
|
@ -3,12 +3,11 @@ use librashader_runtime::image::Image;
|
||||||
use librashader_runtime::scaling::MipmapSize;
|
use librashader_runtime::scaling::MipmapSize;
|
||||||
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
use windows::Win32::Graphics::Direct3D11::{
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
ID3D11Device, ID3D11DeviceContext, ID3D11ShaderResourceView,
|
ID3D11Device, ID3D11DeviceContext, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_FLAG,
|
||||||
ID3D11Texture2D, D3D11_BIND_FLAG, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE,
|
D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_FLAG,
|
||||||
D3D11_BOX, D3D11_CPU_ACCESS_FLAG, D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG,
|
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
||||||
D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SHADER_RESOURCE_VIEW_DESC,
|
D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_SUBRESOURCE_DATA,
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_SUBRESOURCE_DATA, D3D11_TEX2D_SRV,
|
D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_USAGE_STAGING,
|
||||||
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_USAGE_STAGING,
|
|
||||||
};
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ fn triangle_d3d11_args() {
|
||||||
// replace below with 'None' for the triangle
|
// replace below with 'None' for the triangle
|
||||||
Some(image),
|
Some(image),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
||||||
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
// Some(&FilterChainOptions {
|
// Some(&FilterChainOptions {
|
||||||
|
@ -64,7 +64,7 @@ fn triangle_d3d11() {
|
||||||
// None,
|
// None,
|
||||||
Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap()),
|
Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
||||||
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||||
// Some(&FilterChainOptions {
|
// Some(&FilterChainOptions {
|
||||||
|
@ -76,4 +76,4 @@ fn triangle_d3d11() {
|
||||||
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
||||||
|
|
||||||
hello_triangle::main(sample).unwrap();
|
hello_triangle::main(sample).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,18 +141,19 @@ impl Drop for FrameResiduals {
|
||||||
|
|
||||||
impl FilterChainD3D12 {
|
impl FilterChainD3D12 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub unsafe fn load_from_path(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset, device, options)
|
|
||||||
|
unsafe { Self::load_from_preset(preset, device, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
options: Option<&FilterChainOptionsD3D12>,
|
options: Option<&FilterChainOptionsD3D12>,
|
||||||
|
@ -545,7 +546,7 @@ impl FilterChainD3D12 {
|
||||||
/// librashader **will not** create a resource barrier for the final pass. The output image will
|
/// librashader **will not** create a resource barrier for the final pass. The output image will
|
||||||
/// remain in `D3D12_RESOURCE_STATE_RENDER_TARGET` after all shader passes. The caller must transition
|
/// remain in `D3D12_RESOURCE_STATE_RENDER_TARGET` after all shader passes. The caller must transition
|
||||||
/// the output image to the final resource state.
|
/// the output image to the final resource state.
|
||||||
pub fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
cmd: &ID3D12GraphicsCommandList,
|
cmd: &ID3D12GraphicsCommandList,
|
||||||
input: D3D12InputImage,
|
input: D3D12InputImage,
|
||||||
|
|
|
@ -154,9 +154,9 @@ impl OwnedImage {
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
cmd.ResourceBarrier(&barriers);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
cmd.ResourceBarrier(&barriers);
|
||||||
|
|
||||||
cmd.CopyTextureRegion(
|
cmd.CopyTextureRegion(
|
||||||
&D3D12_TEXTURE_COPY_LOCATION {
|
&D3D12_TEXTURE_COPY_LOCATION {
|
||||||
pResource: windows::core::ManuallyDrop::new(&self.handle),
|
pResource: windows::core::ManuallyDrop::new(&self.handle),
|
||||||
|
@ -200,8 +200,10 @@ impl OwnedImage {
|
||||||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
cmd.ResourceBarrier(&barriers);
|
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
cmd.ResourceBarrier(&barriers);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +229,7 @@ impl OwnedImage {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// more efficient if we don't pass the rect but
|
// todo: more efficient if we don't pass the rect but.. waiting on windows-rs updates
|
||||||
cmd.ClearRenderTargetView(*rtv.descriptor.as_ref(), CLEAR.as_ptr(), &[rect])
|
cmd.ClearRenderTargetView(*rtv.descriptor.as_ref(), CLEAR.as_ptr(), &[rect])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::assume_d3d12_init;
|
||||||
use crate::error::FilterChainError::Direct3DOperationError;
|
use crate::error::FilterChainError::Direct3DOperationError;
|
||||||
use crate::quad_render::DrawQuad;
|
use crate::quad_render::DrawQuad;
|
||||||
use crate::{error, util};
|
use crate::{error, util};
|
||||||
use librashader_cache::{cache_shader_object, cache_pipeline};
|
use librashader_cache::{cache_pipeline, cache_shader_object};
|
||||||
use librashader_reflect::back::cross::CrossHlslContext;
|
use librashader_reflect::back::cross::CrossHlslContext;
|
||||||
use librashader_reflect::back::dxil::DxilObject;
|
use librashader_reflect::back::dxil::DxilObject;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(int_roundings)]
|
#![feature(int_roundings)]
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod descriptor_heap;
|
mod descriptor_heap;
|
||||||
|
@ -18,8 +19,8 @@ mod samplers;
|
||||||
mod texture;
|
mod texture;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub mod options;
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub mod options;
|
||||||
|
|
||||||
pub use filter_chain::FilterChainD3D12;
|
pub use filter_chain::FilterChainD3D12;
|
||||||
pub use texture::D3D12InputImage;
|
pub use texture::D3D12InputImage;
|
||||||
|
|
|
@ -217,7 +217,7 @@ impl D3D12MipmapGen {
|
||||||
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> {
|
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> {
|
||||||
// create views for mipmap generation
|
// create views for mipmap generation
|
||||||
let srv = work_heap.alloc_slot()?;
|
let srv = work_heap.alloc_slot()?;
|
||||||
{
|
unsafe {
|
||||||
let srv_desc = D3D12_SHADER_RESOURCE_VIEW_DESC {
|
let srv_desc = D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||||
Format: format,
|
Format: format,
|
||||||
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
|
||||||
|
@ -250,16 +250,20 @@ impl D3D12MipmapGen {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
self.device.CreateUnorderedAccessView(
|
unsafe {
|
||||||
resource,
|
self.device.CreateUnorderedAccessView(
|
||||||
None,
|
resource,
|
||||||
Some(&desc),
|
None,
|
||||||
*descriptor.deref().as_ref(),
|
Some(&desc),
|
||||||
);
|
*descriptor.deref().as_ref(),
|
||||||
|
);
|
||||||
|
}
|
||||||
heap_slots.push(descriptor);
|
heap_slots.push(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.SetComputeRootDescriptorTable(0, *heap_slots[0].deref().as_ref());
|
unsafe {
|
||||||
|
cmd.SetComputeRootDescriptorTable(0, *heap_slots[0].deref().as_ref());
|
||||||
|
}
|
||||||
|
|
||||||
for i in 1..miplevels as u32 {
|
for i in 1..miplevels as u32 {
|
||||||
let scaled = size.scale_mipmap(i);
|
let scaled = size.scale_mipmap(i);
|
||||||
|
@ -285,21 +289,23 @@ impl D3D12MipmapGen {
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
cmd.ResourceBarrier(&barriers);
|
unsafe {
|
||||||
|
cmd.ResourceBarrier(&barriers);
|
||||||
|
|
||||||
cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref());
|
cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref());
|
||||||
cmd.SetComputeRoot32BitConstants(
|
cmd.SetComputeRoot32BitConstants(
|
||||||
2,
|
2,
|
||||||
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
|
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
|
||||||
mipmap_params.as_ptr().cast(),
|
mipmap_params.as_ptr().cast(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
cmd.Dispatch(
|
cmd.Dispatch(
|
||||||
std::cmp::max(scaled.width.div_ceil(8), 1),
|
std::cmp::max(scaled.width.div_ceil(8), 1),
|
||||||
std::cmp::max(scaled.height.div_ceil(8), 1),
|
std::cmp::max(scaled.height.div_ceil(8), 1),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// todo: handle manuallyDrop properly.
|
// todo: handle manuallyDrop properly.
|
||||||
|
|
||||||
|
@ -327,7 +333,9 @@ impl D3D12MipmapGen {
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
cmd.ResourceBarrier(&barriers);
|
unsafe {
|
||||||
|
cmd.ResourceBarrier(&barriers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(heap_slots)
|
Ok(heap_slots)
|
||||||
|
|
|
@ -356,16 +356,18 @@ unsafe fn memcpy_subresource(
|
||||||
num_rows: u32,
|
num_rows: u32,
|
||||||
num_slices: u32,
|
num_slices: u32,
|
||||||
) {
|
) {
|
||||||
for z in 0..num_slices as usize {
|
unsafe {
|
||||||
let dest_slice = dest.pData.add(dest.SlicePitch * z);
|
for z in 0..num_slices as usize {
|
||||||
let src_slice = src.pData.offset(src.SlicePitch * z as isize);
|
let dest_slice = dest.pData.add(dest.SlicePitch * z);
|
||||||
|
let src_slice = src.pData.offset(src.SlicePitch * z as isize);
|
||||||
|
|
||||||
for y in 0..num_rows as usize {
|
for y in 0..num_rows as usize {
|
||||||
std::ptr::copy_nonoverlapping(
|
std::ptr::copy_nonoverlapping(
|
||||||
src_slice.offset(src.RowPitch * y as isize),
|
src_slice.offset(src.RowPitch * y as isize),
|
||||||
dest_slice.add(dest.RowPitch * y),
|
dest_slice.add(dest.RowPitch * y),
|
||||||
row_sizes_in_bytes as usize,
|
row_sizes_in_bytes as usize,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,10 @@ struct D3D12DescriptorHeapInner {
|
||||||
pub struct D3D12DescriptorHeap<T>(Arc<RwLock<D3D12DescriptorHeapInner>>, PhantomData<T>);
|
pub struct D3D12DescriptorHeap<T>(Arc<RwLock<D3D12DescriptorHeapInner>>, PhantomData<T>);
|
||||||
|
|
||||||
impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
|
impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
|
||||||
pub fn new(device: &ID3D12Device, size: usize) -> Result<D3D12DescriptorHeap<T>, windows::core::Error> {
|
pub fn new(
|
||||||
|
device: &ID3D12Device,
|
||||||
|
size: usize,
|
||||||
|
) -> Result<D3D12DescriptorHeap<T>, windows::core::Error> {
|
||||||
let desc = T::get_desc(size);
|
let desc = T::get_desc(size);
|
||||||
unsafe { D3D12DescriptorHeap::new_with_desc(device, desc) }
|
unsafe { D3D12DescriptorHeap::new_with_desc(device, desc) }
|
||||||
}
|
}
|
||||||
|
@ -141,7 +144,6 @@ impl<T> D3D12DescriptorHeap<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn alloc_slot(&mut self) -> D3D12DescriptorHeapSlot<T> {
|
pub fn alloc_slot(&mut self) -> D3D12DescriptorHeapSlot<T> {
|
||||||
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
|
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ use windows::{
|
||||||
|
|
||||||
mod descriptor_heap;
|
mod descriptor_heap;
|
||||||
|
|
||||||
|
|
||||||
static SHADER: &[u8] = b"struct PSInput
|
static SHADER: &[u8] = b"struct PSInput
|
||||||
{
|
{
|
||||||
float4 position : SV_POSITION;
|
float4 position : SV_POSITION;
|
||||||
|
@ -230,11 +229,11 @@ unsafe extern "system" fn debug_log(
|
||||||
|
|
||||||
pub mod d3d12_hello_triangle {
|
pub mod d3d12_hello_triangle {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::hello_triangle::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
||||||
use librashader_common::{Size, Viewport};
|
use librashader_common::{Size, Viewport};
|
||||||
|
use librashader_runtime_d3d12::{D3D12InputImage, D3D12OutputView, FilterChainD3D12};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use librashader_runtime_d3d12::{FilterChainD3D12, D3D12InputImage, D3D12OutputView};
|
|
||||||
use crate::hello_triangle::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
|
|
||||||
|
|
||||||
const FRAME_COUNT: u32 = 2;
|
const FRAME_COUNT: u32 = 2;
|
||||||
|
|
||||||
|
|
|
@ -19,4 +19,4 @@ fn triangle_d3d12() {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::main(sample).unwrap()
|
hello_triangle::main(sample).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<GLSL, Glslang
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChainImpl<T> {
|
impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub(crate) fn load_from_preset(
|
pub(crate) unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> error::Result<Self> {
|
) -> error::Result<Self> {
|
||||||
|
@ -256,7 +256,7 @@ impl<T: GLInterface> FilterChainImpl<T> {
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
///
|
///
|
||||||
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
||||||
pub fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLFramebuffer>,
|
||||||
|
|
|
@ -22,20 +22,22 @@ pub struct FilterChainGL {
|
||||||
|
|
||||||
impl FilterChainGL {
|
impl FilterChainGL {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub unsafe fn load_from_preset(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let result = catch_unwind(|| {
|
let result = catch_unwind(|| {
|
||||||
if let Some(options) = options && options.use_dsa {
|
if let Some(options) = options && options.use_dsa {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
filter: FilterChainDispatch::DirectStateAccess(FilterChainImpl::load_from_preset(preset, Some(options))?)
|
filter: FilterChainDispatch::DirectStateAccess(unsafe {
|
||||||
|
FilterChainImpl::load_from_preset(preset, Some(options))?
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
filter: FilterChainDispatch::Compatibility(FilterChainImpl::load_from_preset(
|
filter: FilterChainDispatch::Compatibility(unsafe {
|
||||||
preset, options,
|
FilterChainImpl::load_from_preset(preset, options)?
|
||||||
)?),
|
}),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
match result {
|
match result {
|
||||||
|
@ -45,20 +47,20 @@ impl FilterChainGL {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub unsafe fn load_from_path(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
options: Option<&FilterChainOptionsGL>,
|
options: Option<&FilterChainOptionsGL>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset, options)
|
unsafe { Self::load_from_preset(preset, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
///
|
///
|
||||||
/// When this frame returns, `GL_FRAMEBUFFER` is bound to 0 if not using Direct State Access.
|
/// When this frame returns, `GL_FRAMEBUFFER` is bound to 0 if not using Direct State Access.
|
||||||
/// Otherwise, it is untouched.
|
/// Otherwise, it is untouched.
|
||||||
pub fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &GLImage,
|
input: &GLImage,
|
||||||
viewport: &Viewport<&GLFramebuffer>,
|
viewport: &Viewport<&GLFramebuffer>,
|
||||||
|
@ -66,10 +68,12 @@ impl FilterChainGL {
|
||||||
options: Option<&FrameOptionsGL>,
|
options: Option<&FrameOptionsGL>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match &mut self.filter {
|
match &mut self.filter {
|
||||||
FilterChainDispatch::DirectStateAccess(p) => {
|
FilterChainDispatch::DirectStateAccess(p) => unsafe {
|
||||||
p.frame(frame_count, viewport, input, options)
|
p.frame(frame_count, viewport, input, options)
|
||||||
}
|
},
|
||||||
FilterChainDispatch::Compatibility(p) => p.frame(frame_count, viewport, input, options),
|
FilterChainDispatch::Compatibility(p) => unsafe {
|
||||||
|
p.frame(frame_count, viewport, input, options)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! This crate should not be used directly.
|
//! This crate should not be used directly.
|
||||||
//! See [`librashader::runtime::gl`](https://docs.rs/librashader/latest/librashader/runtime/gl/index.html) instead.
|
//! See [`librashader::runtime::gl`](https://docs.rs/librashader/latest/librashader/runtime/gl/index.html) instead.
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
@ -24,4 +24,3 @@ pub mod options;
|
||||||
pub use crate::gl::GLFramebuffer;
|
pub use crate::gl::GLFramebuffer;
|
||||||
pub use filter_chain::FilterChainGL;
|
pub use filter_chain::FilterChainGL;
|
||||||
pub use framebuffer::GLImage;
|
pub use framebuffer::GLImage;
|
||||||
|
|
||||||
|
|
|
@ -5,16 +5,19 @@ use crate::error::FilterChainError;
|
||||||
use librashader_reflect::back::cross::GlslVersion;
|
use librashader_reflect::back::cross::GlslVersion;
|
||||||
|
|
||||||
pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> error::Result<GLuint> {
|
pub unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> error::Result<GLuint> {
|
||||||
let shader = gl::CreateShader(stage);
|
let (shader, compile_status) = unsafe {
|
||||||
gl::ShaderSource(
|
let shader = gl::CreateShader(stage);
|
||||||
shader,
|
gl::ShaderSource(
|
||||||
1,
|
shader,
|
||||||
&source.as_bytes().as_ptr().cast(),
|
1,
|
||||||
std::ptr::null(),
|
&source.as_bytes().as_ptr().cast(),
|
||||||
);
|
std::ptr::null(),
|
||||||
gl::CompileShader(shader);
|
);
|
||||||
let mut compile_status = 0;
|
gl::CompileShader(shader);
|
||||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);
|
let mut compile_status = 0;
|
||||||
|
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);
|
||||||
|
(shader, compile_status)
|
||||||
|
};
|
||||||
|
|
||||||
if compile_status == 0 {
|
if compile_status == 0 {
|
||||||
Err(FilterChainError::GlCompileError)
|
Err(FilterChainError::GlCompileError)
|
||||||
|
|
|
@ -7,7 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
||||||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||||
use librashader_common::{Size, Viewport};
|
use librashader_common::{Size, Viewport};
|
||||||
|
|
||||||
use librashader_runtime_gl::{FilterChainGL, GLImage, GLFramebuffer};
|
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
|
||||||
|
|
||||||
const WIDTH: u32 = 800;
|
const WIDTH: u32 = 800;
|
||||||
const HEIGHT: u32 = 600;
|
const HEIGHT: u32 = 600;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use glfw::{Context, Glfw, Window, WindowEvent};
|
||||||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||||
use librashader_common::{Size, Viewport};
|
use librashader_common::{Size, Viewport};
|
||||||
|
|
||||||
use librashader_runtime_gl::{FilterChainGL, GLImage, GLFramebuffer};
|
use librashader_runtime_gl::{FilterChainGL, GLFramebuffer, GLImage};
|
||||||
|
|
||||||
const WIDTH: u32 = 800;
|
const WIDTH: u32 = 800;
|
||||||
const HEIGHT: u32 = 600;
|
const HEIGHT: u32 = 600;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|
pub mod gl3;
|
||||||
pub mod gl46;
|
pub mod gl46;
|
||||||
pub mod gl3;
|
|
|
@ -1,8 +1,7 @@
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
|
||||||
|
|
||||||
use librashader_runtime_gl::FilterChainGL;
|
|
||||||
use librashader_runtime_gl::options::FilterChainOptionsGL;
|
use librashader_runtime_gl::options::FilterChainOptionsGL;
|
||||||
|
use librashader_runtime_gl::FilterChainGL;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_gl() {
|
fn triangle_gl() {
|
||||||
|
@ -16,9 +15,9 @@ fn triangle_gl() {
|
||||||
disable_cache: false,
|
disable_cache: false,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::gl3::do_loop(glfw, window, events, shader, vao, &mut filter);
|
hello_triangle::gl3::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -36,7 +35,7 @@ fn triangle_gl46() {
|
||||||
disable_cache: false,
|
disable_cache: false,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
hello_triangle::gl46::do_loop(glfw, window, events, shader, vao, &mut filter);
|
hello_triangle::gl46::do_loop(glfw, window, events, shader, vao, &mut filter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl Drop for FrameResiduals {
|
||||||
|
|
||||||
impl FilterChainVulkan {
|
impl FilterChainVulkan {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path<V, E>(
|
pub unsafe fn load_from_path<V, E>(
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
vulkan: V,
|
vulkan: V,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
@ -220,11 +220,12 @@ impl FilterChainVulkan {
|
||||||
{
|
{
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset, vulkan, options)
|
|
||||||
|
unsafe { Self::load_from_preset(preset, vulkan, options) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset<V, E>(
|
pub unsafe fn load_from_preset<V, E>(
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
vulkan: V,
|
vulkan: V,
|
||||||
options: Option<&FilterChainOptionsVulkan>,
|
options: Option<&FilterChainOptionsVulkan>,
|
||||||
|
@ -240,8 +241,7 @@ impl FilterChainVulkan {
|
||||||
let command_pool = unsafe {
|
let command_pool = unsafe {
|
||||||
device.create_command_pool(
|
device.create_command_pool(
|
||||||
&vk::CommandPoolCreateInfo::builder()
|
&vk::CommandPoolCreateInfo::builder()
|
||||||
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
|
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER),
|
||||||
,
|
|
||||||
None,
|
None,
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
@ -252,8 +252,7 @@ impl FilterChainVulkan {
|
||||||
&vk::CommandBufferAllocateInfo::builder()
|
&vk::CommandBufferAllocateInfo::builder()
|
||||||
.command_pool(command_pool)
|
.command_pool(command_pool)
|
||||||
.level(vk::CommandBufferLevel::PRIMARY)
|
.level(vk::CommandBufferLevel::PRIMARY)
|
||||||
.command_buffer_count(1)
|
.command_buffer_count(1),
|
||||||
,
|
|
||||||
)?[0]
|
)?[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -261,8 +260,7 @@ impl FilterChainVulkan {
|
||||||
device.begin_command_buffer(
|
device.begin_command_buffer(
|
||||||
command_buffer,
|
command_buffer,
|
||||||
&vk::CommandBufferBeginInfo::builder()
|
&vk::CommandBufferBeginInfo::builder()
|
||||||
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT)
|
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT),
|
||||||
,
|
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,8 +277,7 @@ 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()
|
let submit_info = vk::SubmitInfo::builder().command_buffers(&buffers);
|
||||||
.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)?;
|
||||||
|
@ -551,7 +548,7 @@ impl FilterChainVulkan {
|
||||||
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
|
/// librashader **will not** create a pipeline barrier for the final pass. The output image will
|
||||||
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
|
/// remain in `VK_COLOR_ATTACHMENT_OPTIMAL` after all shader passes. The caller must transition
|
||||||
/// the output image to the final layout.
|
/// the output image to the final layout.
|
||||||
pub fn frame(
|
pub unsafe fn frame(
|
||||||
&mut self,
|
&mut self,
|
||||||
input: &VulkanImage,
|
input: &VulkanImage,
|
||||||
viewport: &Viewport<VulkanImage>,
|
viewport: &Viewport<VulkanImage>,
|
||||||
|
@ -587,15 +584,14 @@ impl FilterChainVulkan {
|
||||||
*vk::ImageSubresourceRange::builder()
|
*vk::ImageSubresourceRange::builder()
|
||||||
.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::builder()
|
||||||
.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),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.vulkan.device.create_image_view(&create_info, None)?
|
self.vulkan.device.create_image_view(&create_info, None)?
|
||||||
|
|
|
@ -60,8 +60,7 @@ impl BindSemantics<NoUniformBinder, Option<()>, RawVulkanBuffer> for FilterPass
|
||||||
let image_info = vk::DescriptorImageInfo::builder()
|
let image_info = vk::DescriptorImageInfo::builder()
|
||||||
.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::builder()
|
||||||
|
|
|
@ -20,23 +20,20 @@ impl OutputImage {
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.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 { vulkan.device.create_image_view(&view_info, None)? };
|
let image_view = unsafe { vulkan.device.create_image_view(&view_info, None)? };
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use ash::vk;
|
||||||
use crate::error::FilterChainError;
|
use crate::error::FilterChainError;
|
||||||
use crate::framebuffer::OutputImage;
|
use crate::framebuffer::OutputImage;
|
||||||
use crate::render_pass::VulkanRenderPass;
|
use crate::render_pass::VulkanRenderPass;
|
||||||
|
use ash::vk::PushConstantRange;
|
||||||
use librashader_cache::cache_pipeline;
|
use librashader_cache::cache_pipeline;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
|
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
|
||||||
|
@ -11,7 +12,6 @@ use librashader_reflect::reflect::ShaderReflection;
|
||||||
use librashader_runtime::render_target::RenderTarget;
|
use librashader_runtime::render_target::RenderTarget;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ash::vk::PushConstantRange;
|
|
||||||
|
|
||||||
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") };
|
||||||
|
|
||||||
|
@ -77,8 +77,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()
|
&vk::DescriptorSetLayoutCreateInfo::builder().bindings(self.bindings()),
|
||||||
.bindings(self.bindings()),
|
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
Ok(layout)
|
Ok(layout)
|
||||||
|
@ -108,20 +107,17 @@ impl PipelineLayoutObjects {
|
||||||
let pipeline_create_info =
|
let pipeline_create_info =
|
||||||
vk::PipelineLayoutCreateInfo::builder().set_layouts(&descriptor_set_layout);
|
vk::PipelineLayoutCreateInfo::builder().set_layouts(&descriptor_set_layout);
|
||||||
|
|
||||||
let push_constant_range = reflection.push_constant.as_ref()
|
let push_constant_range = reflection.push_constant.as_ref().map(|push_constant| {
|
||||||
.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::builder()
|
.stage_flags(stage_mask)
|
||||||
.stage_flags(stage_mask)
|
.size(push_constant.size)]
|
||||||
.size(push_constant.size)]
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let push_constant_range: &[PushConstantRange] = push_constant_range
|
let push_constant_range: &[PushConstantRange] =
|
||||||
.as_ref()
|
push_constant_range.as_ref().map_or(&[], |o| o);
|
||||||
.map_or(&[], |o| o);
|
|
||||||
|
|
||||||
let pipeline_create_info = pipeline_create_info
|
let pipeline_create_info = pipeline_create_info.push_constant_ranges(push_constant_range);
|
||||||
.push_constant_ranges(push_constant_range);
|
|
||||||
|
|
||||||
// let pipeline_create_info = if let Some(push_constant) = &reflection.push_constant {
|
// let pipeline_create_info = if let Some(push_constant) = &reflection.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);
|
||||||
|
@ -139,16 +135,14 @@ impl PipelineLayoutObjects {
|
||||||
|
|
||||||
let pool_info = vk::DescriptorPoolCreateInfo::builder()
|
let pool_info = vk::DescriptorPoolCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.descriptor_pool(pool)
|
.descriptor_pool(pool)
|
||||||
.set_layouts(&descriptor_set_layout)
|
.set_layouts(&descriptor_set_layout);
|
||||||
;
|
|
||||||
|
|
||||||
for _ in 0..replicas {
|
for _ in 0..replicas {
|
||||||
let set = unsafe { device.allocate_descriptor_sets(&alloc_info)? };
|
let set = unsafe { device.allocate_descriptor_sets(&alloc_info)? };
|
||||||
|
@ -210,8 +204,7 @@ impl VulkanGraphicsPipeline {
|
||||||
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::builder()
|
||||||
.topology(vk::PrimitiveTopology::TRIANGLE_STRIP)
|
.topology(vk::PrimitiveTopology::TRIANGLE_STRIP);
|
||||||
;
|
|
||||||
|
|
||||||
let vao_state = [
|
let vao_state = [
|
||||||
vk::VertexInputAttributeDescription {
|
vk::VertexInputAttributeDescription {
|
||||||
|
@ -236,8 +229,7 @@ impl VulkanGraphicsPipeline {
|
||||||
let input_binding = [*input_binding];
|
let input_binding = [*input_binding];
|
||||||
let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder()
|
let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.polygon_mode(vk::PolygonMode::FILL)
|
.polygon_mode(vk::PolygonMode::FILL)
|
||||||
|
@ -246,22 +238,19 @@ impl VulkanGraphicsPipeline {
|
||||||
.depth_clamp_enable(false)
|
.depth_clamp_enable(false)
|
||||||
.rasterizer_discard_enable(false)
|
.rasterizer_discard_enable(false)
|
||||||
.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::builder()
|
||||||
.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 = vk::PipelineColorBlendStateCreateInfo::builder()
|
let blend_state =
|
||||||
.attachments(&attachments)
|
vk::PipelineColorBlendStateCreateInfo::builder().attachments(&attachments);
|
||||||
;
|
|
||||||
|
|
||||||
let viewport_state = vk::PipelineViewportStateCreateInfo::builder()
|
let viewport_state = vk::PipelineViewportStateCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.depth_test_enable(false)
|
.depth_test_enable(false)
|
||||||
|
@ -269,29 +258,23 @@ impl VulkanGraphicsPipeline {
|
||||||
.stencil_test_enable(false)
|
.stencil_test_enable(false)
|
||||||
.depth_bounds_test_enable(false)
|
.depth_bounds_test_enable(false)
|
||||||
.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::builder()
|
||||||
.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()
|
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder().dynamic_states(&states);
|
||||||
.dynamic_states(&states)
|
|
||||||
;
|
|
||||||
|
|
||||||
let shader_stages = [
|
let shader_stages = [
|
||||||
vk::PipelineShaderStageCreateInfo::builder()
|
vk::PipelineShaderStageCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.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 shader_stages = [*shader_stages[0], *shader_stages[1]];
|
||||||
|
@ -311,7 +294,6 @@ impl VulkanGraphicsPipeline {
|
||||||
pipeline_info = pipeline_info.render_pass(render_pass.handle)
|
pipeline_info = pipeline_info.render_pass(render_pass.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -332,12 +314,10 @@ impl VulkanGraphicsPipeline {
|
||||||
) -> error::Result<VulkanGraphicsPipeline> {
|
) -> error::Result<VulkanGraphicsPipeline> {
|
||||||
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
|
let pipeline_layout = PipelineLayoutObjects::new(reflection, replicas, device)?;
|
||||||
|
|
||||||
let vertex_info = vk::ShaderModuleCreateInfo::builder()
|
let vertex_info =
|
||||||
.code(shader_assembly.vertex.as_ref())
|
vk::ShaderModuleCreateInfo::builder().code(shader_assembly.vertex.as_ref());
|
||||||
;
|
let fragment_info =
|
||||||
let fragment_info = vk::ShaderModuleCreateInfo::builder()
|
vk::ShaderModuleCreateInfo::builder().code(shader_assembly.fragment.as_ref());
|
||||||
.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)?;
|
||||||
|
@ -429,8 +409,7 @@ impl VulkanGraphicsPipeline {
|
||||||
.attachments(&attachments)
|
.attachments(&attachments)
|
||||||
.width(output.output.size.width)
|
.width(output.output.size.width)
|
||||||
.height(output.output.size.height)
|
.height(output.output.size.height)
|
||||||
.layers(1)
|
.layers(1),
|
||||||
,
|
|
||||||
None,
|
None,
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
@ -449,8 +428,7 @@ impl VulkanGraphicsPipeline {
|
||||||
.render_area(vk::Rect2D {
|
.render_area(vk::Rect2D {
|
||||||
offset: vk::Offset2D { x: 0, y: 0 },
|
offset: vk::Offset2D { x: 0, y: 0 },
|
||||||
extent: output.output.size.into(),
|
extent: output.output.size.into(),
|
||||||
})
|
});
|
||||||
;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
device.cmd_begin_render_pass(cmd, &render_pass_info, vk::SubpassContents::INLINE);
|
device.cmd_begin_render_pass(cmd, &render_pass_info, vk::SubpassContents::INLINE);
|
||||||
}
|
}
|
||||||
|
@ -469,8 +447,7 @@ impl VulkanGraphicsPipeline {
|
||||||
offset: vk::Offset2D { x: 0, y: 0 },
|
offset: vk::Offset2D { x: 0, y: 0 },
|
||||||
extent: output.output.size.into(),
|
extent: output.output.size.into(),
|
||||||
})
|
})
|
||||||
.color_attachments(&attachments)
|
.color_attachments(&attachments);
|
||||||
;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
device.cmd_begin_rendering(cmd, &rendering_info);
|
device.cmd_begin_rendering(cmd, &rendering_info);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! This crate should not be used directly.
|
//! This crate should not be used directly.
|
||||||
//! See [`librashader::runtime::vk`](https://docs.rs/librashader/latest/librashader/runtime/vk/index.html) instead.
|
//! See [`librashader::runtime::vk`](https://docs.rs/librashader/latest/librashader/runtime/vk/index.html) instead.
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
@ -28,4 +28,3 @@ pub use texture::VulkanImage;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
mod render_pass;
|
mod render_pass;
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,7 @@ impl LutTexture {
|
||||||
| vk::ImageUsageFlags::TRANSFER_SRC
|
| vk::ImageUsageFlags::TRANSFER_SRC
|
||||||
| vk::ImageUsageFlags::TRANSFER_DST,
|
| vk::ImageUsageFlags::TRANSFER_DST,
|
||||||
)
|
)
|
||||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
.initial_layout(vk::ImageLayout::UNDEFINED);
|
||||||
;
|
|
||||||
|
|
||||||
let texture = unsafe { vulkan.device.create_image(&image_info, None)? };
|
let texture = unsafe { vulkan.device.create_image(&image_info, None)? };
|
||||||
|
|
||||||
|
@ -50,23 +49,20 @@ impl LutTexture {
|
||||||
let image_subresource = vk::ImageSubresourceRange::builder()
|
let image_subresource = vk::ImageSubresourceRange::builder()
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.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)? };
|
||||||
|
|
||||||
|
@ -105,8 +101,7 @@ impl LutTexture {
|
||||||
.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),
|
||||||
,
|
|
||||||
)
|
)
|
||||||
.image_extent(image.size.into());
|
.image_extent(image.size.into());
|
||||||
|
|
||||||
|
@ -149,22 +144,19 @@ impl LutTexture {
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.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 {
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
|
|
|
@ -72,8 +72,7 @@ impl VulkanBuffer {
|
||||||
let buffer_info = vk::BufferCreateInfo::builder()
|
let buffer_info = vk::BufferCreateInfo::builder()
|
||||||
.size(size as vk::DeviceSize)
|
.size(size as vk::DeviceSize)
|
||||||
.usage(usage)
|
.usage(usage)
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
.sharing_mode(vk::SharingMode::EXCLUSIVE);
|
||||||
;
|
|
||||||
let buffer = device.create_buffer(&buffer_info, None)?;
|
let buffer = device.create_buffer(&buffer_info, None)?;
|
||||||
|
|
||||||
let memory_reqs = device.get_buffer_memory_requirements(buffer);
|
let memory_reqs = device.get_buffer_memory_requirements(buffer);
|
||||||
|
@ -176,10 +175,11 @@ impl RawVulkanBuffer {
|
||||||
.dst_set(descriptor_set)
|
.dst_set(descriptor_set)
|
||||||
.dst_binding(binding)
|
.dst_binding(binding)
|
||||||
.dst_array_element(0)
|
.dst_array_element(0)
|
||||||
.buffer_info(&buffer_info)
|
.buffer_info(&buffer_info);
|
||||||
;
|
|
||||||
|
|
||||||
self.buffer.device.update_descriptor_sets(&[*write_info], &[])
|
self.buffer
|
||||||
|
.device
|
||||||
|
.update_descriptor_sets(&[*write_info], &[])
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,7 @@ impl VulkanRenderPass {
|
||||||
let renderpass_info = vk::RenderPassCreateInfo::builder()
|
let renderpass_info = vk::RenderPassCreateInfo::builder()
|
||||||
.flags(vk::RenderPassCreateFlags::empty())
|
.flags(vk::RenderPassCreateFlags::empty())
|
||||||
.attachments(&attachment)
|
.attachments(&attachment)
|
||||||
.subpasses(&subpass)
|
.subpasses(&subpass);
|
||||||
;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let rp = device.create_render_pass(&renderpass_info, None)?;
|
let rp = device.create_render_pass(&renderpass_info, None)?;
|
||||||
|
|
|
@ -29,8 +29,7 @@ impl VulkanSampler {
|
||||||
.mipmap_mode(mipmap.into())
|
.mipmap_mode(mipmap.into())
|
||||||
.address_mode_u(wrap.into())
|
.address_mode_u(wrap.into())
|
||||||
.address_mode_v(wrap.into())
|
.address_mode_v(wrap.into())
|
||||||
.address_mode_w(wrap.into())
|
.address_mode_w(wrap.into());
|
||||||
;
|
|
||||||
|
|
||||||
let sampler = unsafe { device.create_sampler(&create_info, None)? };
|
let sampler = unsafe { device.create_sampler(&create_info, None)? };
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,7 @@ impl OwnedImage {
|
||||||
| vk::ImageUsageFlags::TRANSFER_SRC,
|
| vk::ImageUsageFlags::TRANSFER_SRC,
|
||||||
)
|
)
|
||||||
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
.sharing_mode(vk::SharingMode::EXCLUSIVE)
|
||||||
.initial_layout(vk::ImageLayout::UNDEFINED)
|
.initial_layout(vk::ImageLayout::UNDEFINED);
|
||||||
;
|
|
||||||
|
|
||||||
let image = unsafe { device.create_image(&image_create_info, None)? };
|
let image = unsafe { device.create_image(&image_create_info, None)? };
|
||||||
let mem_reqs = unsafe { device.get_image_memory_requirements(image) };
|
let mem_reqs = unsafe { device.get_image_memory_requirements(image) };
|
||||||
|
@ -70,23 +69,20 @@ impl OwnedImage {
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.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)? };
|
||||||
|
|
||||||
|
@ -199,8 +195,7 @@ impl OwnedImage {
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
|
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
|
||||||
.src_access_mask(vk::AccessFlags::empty())
|
.src_access_mask(vk::AccessFlags::empty())
|
||||||
|
@ -216,8 +211,7 @@ impl OwnedImage {
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
level_count: vk::REMAINING_MIP_LEVELS,
|
level_count: vk::REMAINING_MIP_LEVELS,
|
||||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device.cmd_pipeline_barrier(
|
self.device.cmd_pipeline_barrier(
|
||||||
|
@ -247,8 +241,7 @@ impl OwnedImage {
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
self.device.cmd_pipeline_barrier(
|
self.device.cmd_pipeline_barrier(
|
||||||
cmd,
|
cmd,
|
||||||
|
@ -286,15 +279,13 @@ impl OwnedImage {
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.src_subresource(*src_subresource)
|
.src_subresource(*src_subresource)
|
||||||
|
@ -329,8 +320,7 @@ impl OwnedImage {
|
||||||
level_count: self.levels - 1,
|
level_count: self.levels - 1,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
|
let mipchain_barrier = vk::ImageMemoryBarrier::builder()
|
||||||
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
|
.src_access_mask(vk::AccessFlags::TRANSFER_WRITE)
|
||||||
|
@ -346,8 +336,7 @@ impl OwnedImage {
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
layer_count: vk::REMAINING_ARRAY_LAYERS,
|
||||||
})
|
});
|
||||||
;
|
|
||||||
|
|
||||||
// next past waits for ALL_GRAPHICS, use dependency chain and FRAGMENT_SHADER dst stage
|
// next past waits for ALL_GRAPHICS, use dependency chain and FRAGMENT_SHADER dst stage
|
||||||
// to ensure that next pass doesn't start until mipchain is complete.
|
// to ensure that next pass doesn't start until mipchain is complete.
|
||||||
|
@ -376,21 +365,18 @@ impl OwnedImage {
|
||||||
.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::builder()
|
||||||
.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),
|
||||||
,
|
|
||||||
)
|
)
|
||||||
.src_offset(Default::default())
|
.src_offset(Default::default())
|
||||||
.dst_offset(Default::default())
|
.dst_offset(Default::default())
|
||||||
.extent(source.size.into())
|
.extent(source.size.into());
|
||||||
;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
|
@ -461,8 +447,7 @@ impl OwnedImage {
|
||||||
.base_mip_level(0)
|
.base_mip_level(0)
|
||||||
.level_count(1)
|
.level_count(1)
|
||||||
.base_array_layer(0)
|
.base_array_layer(0)
|
||||||
.layer_count(1)
|
.layer_count(1)],
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
util::vulkan_image_layout_transition_levels(
|
util::vulkan_image_layout_transition_levels(
|
||||||
|
|
|
@ -76,15 +76,18 @@ pub unsafe fn vulkan_image_layout_transition_levels(
|
||||||
barrier.subresource_range.base_array_layer = 0;
|
barrier.subresource_range.base_array_layer = 0;
|
||||||
barrier.subresource_range.level_count = levels;
|
barrier.subresource_range.level_count = levels;
|
||||||
barrier.subresource_range.layer_count = vk::REMAINING_ARRAY_LAYERS;
|
barrier.subresource_range.layer_count = vk::REMAINING_ARRAY_LAYERS;
|
||||||
device.cmd_pipeline_barrier(
|
|
||||||
cmd,
|
unsafe {
|
||||||
src_stage,
|
device.cmd_pipeline_barrier(
|
||||||
dst_stage,
|
cmd,
|
||||||
vk::DependencyFlags::empty(),
|
src_stage,
|
||||||
&[],
|
dst_stage,
|
||||||
&[],
|
vk::DependencyFlags::empty(),
|
||||||
&[barrier],
|
&[],
|
||||||
)
|
&[],
|
||||||
|
&[barrier],
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_allocator(
|
pub fn create_allocator(
|
||||||
|
|
|
@ -16,16 +16,14 @@ impl VulkanCommandPool {
|
||||||
|
|
||||||
let create_info = vk::CommandPoolCreateInfo::builder()
|
let create_info = vk::CommandPoolCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.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);
|
||||||
;
|
|
||||||
|
|
||||||
let buffers = base.device.allocate_command_buffers(&buffer_info)?;
|
let buffers = base.device.allocate_command_buffers(&buffer_info)?;
|
||||||
Ok(VulkanCommandPool {
|
Ok(VulkanCommandPool {
|
||||||
|
|
|
@ -19,8 +19,7 @@ impl VulkanFramebuffer {
|
||||||
.attachments(attachments)
|
.attachments(attachments)
|
||||||
.width(width)
|
.width(width)
|
||||||
.height(height)
|
.height(height)
|
||||||
.layers(1)
|
.layers(1);
|
||||||
;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let framebuffer = device.create_framebuffer(&framebuffer_info, None)?;
|
let framebuffer = device.create_framebuffer(&framebuffer_info, None)?;
|
||||||
|
|
|
@ -4,12 +4,12 @@ use gpu_allocator::MemoryLocation;
|
||||||
use librashader_runtime::uniforms::UniformStorageAccess;
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
use ash::prelude::VkResult;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ash::prelude::VkResult;
|
|
||||||
|
|
||||||
pub struct VulkanImageMemory {
|
pub struct VulkanImageMemory {
|
||||||
allocation: Option<Allocation>,
|
allocation: Option<Allocation>,
|
||||||
|
@ -23,13 +23,16 @@ impl VulkanImageMemory {
|
||||||
requirements: vk::MemoryRequirements,
|
requirements: vk::MemoryRequirements,
|
||||||
image: &vk::Image,
|
image: &vk::Image,
|
||||||
) -> VkResult<VulkanImageMemory> {
|
) -> VkResult<VulkanImageMemory> {
|
||||||
let allocation = allocator.write().allocate(&AllocationCreateDesc {
|
let allocation = allocator
|
||||||
name: "imagemem",
|
.write()
|
||||||
requirements,
|
.allocate(&AllocationCreateDesc {
|
||||||
location: MemoryLocation::GpuOnly,
|
name: "imagemem",
|
||||||
linear: false,
|
requirements,
|
||||||
allocation_scheme: AllocationScheme::DedicatedImage(*image),
|
location: MemoryLocation::GpuOnly,
|
||||||
}).unwrap();
|
linear: false,
|
||||||
|
allocation_scheme: AllocationScheme::DedicatedImage(*image),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
device.bind_image_memory(*image, allocation.memory(), 0)?;
|
device.bind_image_memory(*image, allocation.memory(), 0)?;
|
||||||
|
|
|
@ -3,32 +3,32 @@
|
||||||
mod command;
|
mod command;
|
||||||
mod debug;
|
mod debug;
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
mod memory;
|
||||||
mod physicaldevice;
|
mod physicaldevice;
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
mod surface;
|
mod surface;
|
||||||
mod swapchain;
|
mod swapchain;
|
||||||
mod syncobjects;
|
mod syncobjects;
|
||||||
mod util;
|
mod util;
|
||||||
mod memory;
|
|
||||||
|
|
||||||
pub(crate) mod vulkan_base;
|
pub(crate) mod vulkan_base;
|
||||||
|
|
||||||
use librashader_runtime_vk::{FilterChainVulkan, VulkanImage};
|
use ash::vk;
|
||||||
use command::VulkanCommandPool;
|
use command::VulkanCommandPool;
|
||||||
use framebuffer::VulkanFramebuffer;
|
use framebuffer::VulkanFramebuffer;
|
||||||
|
use librashader_runtime_vk::{FilterChainVulkan, VulkanImage};
|
||||||
use pipeline::VulkanPipeline;
|
use pipeline::VulkanPipeline;
|
||||||
use surface::VulkanSurface;
|
use surface::VulkanSurface;
|
||||||
use swapchain::VulkanSwapchain;
|
use swapchain::VulkanSwapchain;
|
||||||
use syncobjects::SyncObjects;
|
use syncobjects::SyncObjects;
|
||||||
use vulkan_base::VulkanBase;
|
use vulkan_base::VulkanBase;
|
||||||
use ash::vk;
|
|
||||||
|
|
||||||
use librashader_common::Viewport;
|
use librashader_common::Viewport;
|
||||||
|
|
||||||
|
use librashader_runtime_vk::options::FrameOptionsVulkan;
|
||||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
||||||
use winit::platform::windows::EventLoopBuilderExtWindows;
|
use winit::platform::windows::EventLoopBuilderExtWindows;
|
||||||
use librashader_runtime_vk::options::FrameOptionsVulkan;
|
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const WINDOW_TITLE: &str = "librashader Vulkan";
|
const WINDOW_TITLE: &str = "librashader Vulkan";
|
||||||
|
@ -101,8 +101,7 @@ impl VulkanWindow {
|
||||||
extent: vulkan.swapchain.extent,
|
extent: vulkan.swapchain.extent,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
.clear_values(&clear_values)
|
.clear_values(&clear_values);
|
||||||
;
|
|
||||||
|
|
||||||
vulkan.base.device.cmd_begin_render_pass(
|
vulkan.base.device.cmd_begin_render_pass(
|
||||||
cmd,
|
cmd,
|
||||||
|
@ -349,8 +348,7 @@ impl VulkanWindow {
|
||||||
.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)
|
||||||
.command_buffers(&cmd)
|
.command_buffers(&cmd)];
|
||||||
];
|
|
||||||
|
|
||||||
vulkan
|
vulkan
|
||||||
.base
|
.base
|
||||||
|
@ -363,8 +361,7 @@ impl VulkanWindow {
|
||||||
let present_info = vk::PresentInfoKHR::builder()
|
let present_info = vk::PresentInfoKHR::builder()
|
||||||
.wait_semaphores(&render_finished)
|
.wait_semaphores(&render_finished)
|
||||||
.swapchains(&swapchain)
|
.swapchains(&swapchain)
|
||||||
.image_indices(&swapchain_index)
|
.image_indices(&swapchain_index);
|
||||||
;
|
|
||||||
|
|
||||||
vulkan
|
vulkan
|
||||||
.swapchain
|
.swapchain
|
||||||
|
|
|
@ -153,8 +153,7 @@ impl VulkanPipeline {
|
||||||
let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder()
|
let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder()
|
||||||
.module(vertex_shader_info.module)
|
.module(vertex_shader_info.module)
|
||||||
.stage(vk::ShaderStageFlags::VERTEX)
|
.stage(vk::ShaderStageFlags::VERTEX)
|
||||||
.name(ENTRY_POINT)
|
.name(ENTRY_POINT);
|
||||||
;
|
|
||||||
|
|
||||||
let mut frag_spv_file =
|
let mut frag_spv_file =
|
||||||
Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]);
|
Cursor::new(&include_bytes!("../../shader/triangle_simple/frag.spv")[..]);
|
||||||
|
@ -164,18 +163,15 @@ impl VulkanPipeline {
|
||||||
let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder()
|
let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder()
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.primitive_restart_enable(false)
|
.primitive_restart_enable(false)
|
||||||
.topology(vk::PrimitiveTopology::TRIANGLE_LIST)
|
.topology(vk::PrimitiveTopology::TRIANGLE_LIST);
|
||||||
;
|
|
||||||
|
|
||||||
let viewports = [vk::Viewport {
|
let viewports = [vk::Viewport {
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
|
@ -198,9 +194,7 @@ 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()
|
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder().dynamic_states(&states);
|
||||||
.dynamic_states(&states)
|
|
||||||
;
|
|
||||||
|
|
||||||
let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder()
|
let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder()
|
||||||
.scissors(&scissors)
|
.scissors(&scissors)
|
||||||
|
@ -213,14 +207,12 @@ impl VulkanPipeline {
|
||||||
.polygon_mode(vk::PolygonMode::FILL)
|
.polygon_mode(vk::PolygonMode::FILL)
|
||||||
.line_width(1.0f32)
|
.line_width(1.0f32)
|
||||||
.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::builder()
|
||||||
.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::builder()
|
||||||
.blend_enable(false)
|
.blend_enable(false)
|
||||||
|
@ -230,8 +222,7 @@ impl VulkanPipeline {
|
||||||
.color_blend_op(vk::BlendOp::ADD)
|
.color_blend_op(vk::BlendOp::ADD)
|
||||||
.src_alpha_blend_factor(vk::BlendFactor::ONE)
|
.src_alpha_blend_factor(vk::BlendFactor::ONE)
|
||||||
.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::builder()
|
||||||
.logic_op(vk::LogicOp::COPY)
|
.logic_op(vk::LogicOp::COPY)
|
||||||
|
@ -291,11 +282,7 @@ impl VulkanPipeline {
|
||||||
|
|
||||||
let graphics_pipelines = base
|
let graphics_pipelines = base
|
||||||
.device
|
.device
|
||||||
.create_graphics_pipelines(
|
.create_graphics_pipelines(vk::PipelineCache::null(), &graphic_pipeline_info, None)
|
||||||
vk::PipelineCache::null(),
|
|
||||||
&graphic_pipeline_info,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.expect("Unable to create graphics pipeline");
|
.expect("Unable to create graphics pipeline");
|
||||||
|
|
||||||
let graphic_pipeline = graphics_pipelines[0];
|
let graphic_pipeline = graphics_pipelines[0];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use crate::hello_triangle::memory::VulkanImageMemory;
|
||||||
use crate::hello_triangle::surface::VulkanSurface;
|
use crate::hello_triangle::surface::VulkanSurface;
|
||||||
use crate::hello_triangle::vulkan_base::VulkanBase;
|
use crate::hello_triangle::vulkan_base::VulkanBase;
|
||||||
use crate::hello_triangle::memory::VulkanImageMemory;
|
|
||||||
use ash::prelude::VkResult;
|
use ash::prelude::VkResult;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use ash::vk::Extent3D;
|
use ash::vk::Extent3D;
|
||||||
|
@ -57,8 +57,7 @@ impl VulkanSwapchain {
|
||||||
.clipped(true)
|
.clipped(true)
|
||||||
.image_array_layers(1)
|
.image_array_layers(1)
|
||||||
// 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::extensions::khr::Swapchain::new(&base.instance, &base.device);
|
||||||
|
|
||||||
|
@ -121,8 +120,7 @@ impl VulkanSwapchain {
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
layer_count: 1,
|
layer_count: 1,
|
||||||
})
|
})
|
||||||
.image(*image)
|
.image(*image);
|
||||||
;
|
|
||||||
|
|
||||||
let view = unsafe { base.device.create_image_view(&create_info, None)? };
|
let view = unsafe { base.device.create_image_view(&create_info, None)? };
|
||||||
// unsafe {
|
// unsafe {
|
||||||
|
@ -176,8 +174,7 @@ impl VulkanSwapchain {
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
layer_count: 1,
|
layer_count: 1,
|
||||||
})
|
})
|
||||||
.image(*image)
|
.image(*image);
|
||||||
;
|
|
||||||
|
|
||||||
let view = unsafe { base.device.create_image_view(&create_info, None)? };
|
let view = unsafe { base.device.create_image_view(&create_info, None)? };
|
||||||
// unsafe {
|
// unsafe {
|
||||||
|
|
|
@ -19,14 +19,10 @@ impl SyncObjects {
|
||||||
.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
|
.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
|
||||||
render_finished
|
render_finished
|
||||||
.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
|
.push(device.create_semaphore(&vk::SemaphoreCreateInfo::default(), None)?);
|
||||||
in_flight.push(
|
in_flight.push(device.create_fence(
|
||||||
device.create_fence(
|
&vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED),
|
||||||
&vk::FenceCreateInfo::builder()
|
None,
|
||||||
.flags(vk::FenceCreateFlags::SIGNALED)
|
)?)
|
||||||
,
|
|
||||||
None,
|
|
||||||
)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SyncObjects {
|
Ok(SyncObjects {
|
||||||
|
|
|
@ -4,7 +4,6 @@ use gpu_allocator::vulkan::{Allocator, AllocatorCreateDesc};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
||||||
use librashader_reflect::reflect::semantics::BindingStage;
|
use librashader_reflect::reflect::semantics::BindingStage;
|
||||||
|
|
||||||
pub fn binding_stage_to_vulkan_stage(stage_mask: BindingStage) -> vk::ShaderStageFlags {
|
pub fn binding_stage_to_vulkan_stage(stage_mask: BindingStage) -> vk::ShaderStageFlags {
|
||||||
|
@ -72,6 +71,7 @@ pub fn create_allocator(
|
||||||
physical_device,
|
physical_device,
|
||||||
debug_settings: Default::default(),
|
debug_settings: Default::default(),
|
||||||
buffer_device_address: false,
|
buffer_device_address: false,
|
||||||
}).unwrap();
|
})
|
||||||
|
.unwrap();
|
||||||
Arc::new(RwLock::new(alloc))
|
Arc::new(RwLock::new(alloc))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@ use ash::vk;
|
||||||
|
|
||||||
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
|
use crate::hello_triangle::physicaldevice::{find_queue_family, pick_physical_device};
|
||||||
|
|
||||||
|
use crate::hello_triangle::util;
|
||||||
use ash::prelude::VkResult;
|
use ash::prelude::VkResult;
|
||||||
use gpu_allocator::vulkan::Allocator;
|
use gpu_allocator::vulkan::Allocator;
|
||||||
|
use librashader_runtime_vk::error::FilterChainError;
|
||||||
|
use librashader_runtime_vk::VulkanObjects;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use librashader_runtime_vk::error::FilterChainError;
|
|
||||||
use librashader_runtime_vk::VulkanObjects;
|
|
||||||
use crate::hello_triangle::util;
|
|
||||||
|
|
||||||
const WINDOW_TITLE: &[u8] = b"librashader Vulkan\0";
|
const WINDOW_TITLE: &[u8] = b"librashader Vulkan\0";
|
||||||
const KHRONOS_VALIDATION: &[u8] = b"VK_LAYER_KHRONOS_validation\0";
|
const KHRONOS_VALIDATION: &[u8] = b"VK_LAYER_KHRONOS_validation\0";
|
||||||
|
@ -32,8 +32,7 @@ impl VulkanBase {
|
||||||
.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)
|
||||||
.application_version(0)
|
.application_version(0)
|
||||||
.api_version(vk::make_api_version(0, 1, 3, 0))
|
.api_version(vk::make_api_version(0, 1, 3, 0));
|
||||||
;
|
|
||||||
|
|
||||||
dbg!("entry");
|
dbg!("entry");
|
||||||
// todo: make this xplat
|
// todo: make this xplat
|
||||||
|
@ -48,8 +47,7 @@ impl VulkanBase {
|
||||||
let create_info = vk::InstanceCreateInfo::builder()
|
let create_info = vk::InstanceCreateInfo::builder()
|
||||||
.application_info(&app_info)
|
.application_info(&app_info)
|
||||||
.enabled_layer_names(&layers)
|
.enabled_layer_names(&layers)
|
||||||
.enabled_extension_names(&extensions)
|
.enabled_extension_names(&extensions);
|
||||||
;
|
|
||||||
|
|
||||||
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
||||||
|
|
||||||
|
@ -88,14 +86,12 @@ impl VulkanBase {
|
||||||
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::builder()
|
||||||
.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 = vk::PhysicalDeviceVulkan13Features::builder()
|
let mut physical_device_features =
|
||||||
.dynamic_rendering(true)
|
vk::PhysicalDeviceVulkan13Features::builder().dynamic_rendering(true);
|
||||||
;
|
|
||||||
|
|
||||||
// let mut physical_device_features =
|
// let mut physical_device_features =
|
||||||
// vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features)
|
// vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
|
||||||
use librashader_runtime_vk::FilterChainVulkan;
|
|
||||||
use hello_triangle::vulkan_base::VulkanBase;
|
use hello_triangle::vulkan_base::VulkanBase;
|
||||||
use librashader_runtime_vk::options::FilterChainOptionsVulkan;
|
use librashader_runtime_vk::options::FilterChainOptionsVulkan;
|
||||||
|
use librashader_runtime_vk::FilterChainVulkan;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_vk() {
|
fn triangle_vk() {
|
||||||
|
@ -44,4 +44,4 @@ fn triangle_vk() {
|
||||||
// // FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
// // FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
|
||||||
// .unwrap();
|
// .unwrap();
|
||||||
// hello_triangle_old::main(base, filter);
|
// hello_triangle_old::main(base, filter);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue