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:
chyyran 2023-02-16 17:33:47 -05:00
parent f8de1fa2ee
commit 0adf3505ec
49 changed files with 312 additions and 368 deletions

View file

@ -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)?;

View file

@ -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;

View file

@ -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())?;
}
} }
} }

View file

@ -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())?;
}
} }
} }

View file

@ -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())?;
}
} }
} }

View file

@ -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())?;
}
} }
} }

View file

@ -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,

View file

@ -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.

View file

@ -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,

View file

@ -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;

View file

@ -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();
} }

View file

@ -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,

View file

@ -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])
} }

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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,
); );
}
} }
} }
} }

View file

@ -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 };

View file

@ -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;

View file

@ -19,4 +19,4 @@ fn triangle_d3d12() {
) )
.unwrap(); .unwrap();
hello_triangle::main(sample).unwrap() hello_triangle::main(sample).unwrap()
} }

View file

@ -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>,

View file

@ -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)
},
} }
} }
} }

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -1,2 +1,2 @@
pub mod gl3;
pub mod gl46; pub mod gl46;
pub mod gl3;

View file

@ -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);
} }

View file

@ -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)?

View file

@ -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()

View file

@ -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)? };

View file

@ -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);

View file

@ -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;

View file

@ -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(

View file

@ -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(())
} }

View file

@ -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)?;

View file

@ -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)? };

View file

@ -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(

View file

@ -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(

View file

@ -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 {

View file

@ -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)?;

View file

@ -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)?;

View file

@ -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

View file

@ -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];

View file

@ -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 {

View file

@ -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 {

View file

@ -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))
} }

View file

@ -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)

View file

@ -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);
} }