fmt: run cargo fmt

This commit is contained in:
chyyran 2023-02-05 16:17:23 -05:00
parent 7d8c137083
commit 2d2ed22e9a
28 changed files with 680 additions and 486 deletions

View file

@ -1,10 +1,10 @@
use crate::back::spirv::WriteSpirV;
use crate::back::{CompileShader, CompilerBackend, FromCompilation, ShaderCompilerOutput};
pub use spirv_to_dxil::DxilObject; pub use spirv_to_dxil::DxilObject;
pub use spirv_to_dxil::ShaderModel; pub use spirv_to_dxil::ShaderModel;
use spirv_to_dxil::{ConstantBufferConfig, RuntimeConfig, ShaderStage, ValidatorVersion}; use spirv_to_dxil::{ConstantBufferConfig, RuntimeConfig, ShaderStage, ValidatorVersion};
use crate::back::{CompilerBackend, CompileShader, FromCompilation, ShaderCompilerOutput};
use crate::back::spirv::WriteSpirV;
use crate::back::targets::{DXIL, OutputTarget}; use crate::back::targets::{OutputTarget, DXIL};
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::front::GlslangCompilation; use crate::front::GlslangCompilation;
use crate::reflect::cross::GlslReflect; use crate::reflect::cross::GlslReflect;
@ -19,7 +19,7 @@ impl FromCompilation<GlslangCompilation> for DXIL {
type Options = Option<ShaderModel>; type Options = Option<ShaderModel>;
type Context = (); type Context = ();
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context> type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
+ ReflectShader; + ReflectShader;
fn from_compilation( fn from_compilation(
compile: GlslangCompilation, compile: GlslangCompilation,
@ -60,26 +60,28 @@ impl CompileShader<DXIL> for WriteSpirV {
..RuntimeConfig::default() ..RuntimeConfig::default()
}; };
// todo: do we want to allow other entry point names? // todo: do we want to allow other entry point names?
let vertex = let vertex = spirv_to_dxil::spirv_to_dxil(
spirv_to_dxil::spirv_to_dxil(&self.vertex, &self.vertex,
None, "main", None,
ShaderStage::Vertex, "main",
sm, ShaderStage::Vertex,
ValidatorVersion::None, sm,
config.clone()) ValidatorVersion::None,
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?; config.clone(),
)
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
let fragment = spirv_to_dxil::spirv_to_dxil(
let fragment = &self.fragment,
spirv_to_dxil::spirv_to_dxil(&self.fragment, None,
None, "main", "main",
ShaderStage::Fragment, ShaderStage::Fragment,
sm, sm,
ValidatorVersion::None, ValidatorVersion::None,
config) config,
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?; )
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
Ok(ShaderCompilerOutput { Ok(ShaderCompilerOutput {
vertex, vertex,

View file

@ -1,7 +1,7 @@
pub mod cross; pub mod cross;
pub mod dxil;
mod spirv; mod spirv;
pub mod targets; pub mod targets;
pub mod dxil;
use crate::back::targets::OutputTarget; use crate::back::targets::OutputTarget;
use crate::error::{ShaderCompileError, ShaderReflectError}; use crate::error::{ShaderCompileError, ShaderReflectError};

View file

@ -1,6 +1,6 @@
use crate::error::{SemanticsErrorKind, ShaderReflectError}; use crate::error::{SemanticsErrorKind, ShaderReflectError};
use crate::front::NagaCompilation;
use crate::front::GlslangCompilation; use crate::front::GlslangCompilation;
use crate::front::NagaCompilation;
use crate::reflect::helper::SemanticErrorBlame; use crate::reflect::helper::SemanticErrorBlame;
use crate::reflect::semantics::MAX_BINDINGS_COUNT; use crate::reflect::semantics::MAX_BINDINGS_COUNT;
use naga::front::spv::Options; use naga::front::spv::Options;
@ -105,9 +105,9 @@ impl NagaReflect {
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use librashader_preprocess::ShaderSource;
use rspirv::dr::Instruction; use rspirv::dr::Instruction;
use rspirv::spirv::Op; use rspirv::spirv::Op;
use librashader_preprocess::ShaderSource;
#[test] #[test]
pub fn test_into() { pub fn test_into() {
@ -118,7 +118,9 @@ mod test {
rspirv::binary::parse_words(&compilation.vertex.as_binary(), &mut loader).unwrap(); rspirv::binary::parse_words(&compilation.vertex.as_binary(), &mut loader).unwrap();
let module = loader.module(); let module = loader.module();
let outputs: Vec<&Instruction> = module.types_global_values.iter() let outputs: Vec<&Instruction> = module
.types_global_values
.iter()
.filter(|i| i.class.opcode == Op::Variable) .filter(|i| i.class.opcode == Op::Variable)
.collect(); .collect();

View file

@ -12,12 +12,12 @@ use librashader_reflect::reflect::ShaderReflection;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use librashader_runtime::binding::{BindSemantics, TextureInput}; use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::quad::QuadType;
use windows::Win32::Graphics::Direct3D11::{ use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState, ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAPPED_SUBRESOURCE, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAPPED_SUBRESOURCE,
D3D11_MAP_WRITE_DISCARD, D3D11_MAP_WRITE_DISCARD,
}; };
use librashader_runtime::quad::QuadType;
use crate::render_target::RenderTarget; use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;

View file

@ -1,6 +1,6 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init; use crate::error::assume_d3d11_init;
use crate::texture::{D3D11InputView}; use crate::texture::D3D11InputView;
use crate::util::d3d11_get_closest_format; use crate::util::d3d11_get_closest_format;
use librashader_common::{ImageFormat, Size}; use librashader_common::{ImageFormat, Size};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;

View file

@ -242,7 +242,7 @@ pub mod d3d11_hello_triangle {
use crate::filter_chain::FilterChainD3D11; use crate::filter_chain::FilterChainD3D11;
use crate::options::{FilterChainOptionsD3D11}; use crate::options::FilterChainOptionsD3D11;
use crate::texture::{D3D11InputView, LutTexture}; use crate::texture::{D3D11InputView, LutTexture};
use crate::D3D11OutputView; use crate::D3D11OutputView;
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};

View file

@ -27,10 +27,10 @@ pub use texture::D3D11OutputView;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::env;
use super::*; use super::*;
use crate::options::FilterChainOptionsD3D11; use crate::options::FilterChainOptionsD3D11;
use librashader_runtime::image::{Image, UVDirection}; use librashader_runtime::image::{Image, UVDirection};
use std::env;
// "../test/slang-shaders/scalefx/scalefx-9x.slangp", // "../test/slang-shaders/scalefx/scalefx-9x.slangp",
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp", // "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
@ -46,7 +46,8 @@ mod tests {
let _ = args.next(); let _ = args.next();
let _ = args.next(); let _ = args.next();
let filter = args.next(); let filter = args.next();
let image = args.next() let image = args
.next()
.and_then(|f| Image::load(f, UVDirection::TopLeft).ok()) .and_then(|f| Image::load(f, UVDirection::TopLeft).ok())
.or_else(|| Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap())) .or_else(|| Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap()))
.unwrap(); .unwrap();
@ -58,7 +59,7 @@ mod tests {
force_no_mipmaps: false, force_no_mipmaps: false,
}), }),
// 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(
@ -83,9 +84,9 @@ mod tests {
force_no_mipmaps: false, force_no_mipmaps: false,
}), }),
// replace below with 'None' for the triangle // replace below with 'None' for the triangle
None None,
) )
.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 {

View file

@ -1,6 +1,7 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init; use crate::error::assume_d3d11_init;
use bytemuck::offset_of; use bytemuck::offset_of;
use librashader_runtime::quad::QuadType;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
use windows::Win32::Graphics::Direct3D11::{ use windows::Win32::Graphics::Direct3D11::{
@ -9,7 +10,6 @@ use windows::Win32::Graphics::Direct3D11::{
D3D11_USAGE_IMMUTABLE, D3D11_USAGE_IMMUTABLE,
}; };
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
use librashader_runtime::quad::QuadType;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone, Default)] #[derive(Debug, Copy, Clone, Default)]

View file

@ -1,8 +1,8 @@
use crate::framebuffer::OutputFramebuffer; use crate::framebuffer::OutputFramebuffer;
use crate::D3D11OutputView; use crate::D3D11OutputView;
use librashader_common::Viewport; use librashader_common::Viewport;
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
use librashader_runtime::quad::DEFAULT_MVP; use librashader_runtime::quad::DEFAULT_MVP;
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct RenderTarget<'a> { pub(crate) struct RenderTarget<'a> {

View file

@ -1,8 +1,13 @@
use std::ops::Range;
use windows::Win32::Graphics::Direct3D12::{D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, ID3D12Device, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use std::ops::Range;
use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, ID3D12Resource, D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN,
D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER,
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
pub struct D3D12ConstantBuffer { pub struct D3D12ConstantBuffer {
pub buffer: D3D12Buffer, pub buffer: D3D12Buffer,
@ -11,7 +16,7 @@ pub struct D3D12ConstantBuffer {
pub struct D3D12Buffer { pub struct D3D12Buffer {
handle: ID3D12Resource, handle: ID3D12Resource,
size: usize size: usize,
} }
pub struct D3D12BufferMapHandle<'a> { pub struct D3D12BufferMapHandle<'a> {
@ -21,9 +26,7 @@ pub struct D3D12BufferMapHandle<'a> {
impl<'a> Drop for D3D12BufferMapHandle<'a> { impl<'a> Drop for D3D12BufferMapHandle<'a> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe { self.handle.Unmap(0, None) }
self.handle.Unmap(0, None)
}
} }
} }
@ -48,28 +51,26 @@ impl D3D12Buffer {
Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR, Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
SampleDesc: DXGI_SAMPLE_DESC { SampleDesc: DXGI_SAMPLE_DESC {
Count: 1, Count: 1,
Quality: 0 Quality: 0,
}, },
..Default::default() ..Default::default()
}, },
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_GENERIC_READ,
None, None,
&mut buffer &mut buffer,
)?; )?;
assume_d3d12_init!(buffer, "CreateCommittedResource"); assume_d3d12_init!(buffer, "CreateCommittedResource");
Ok(D3D12Buffer { Ok(D3D12Buffer {
handle: buffer, handle: buffer,
size size,
}) })
} }
} }
pub fn gpu_address(&self) -> u64 { pub fn gpu_address(&self) -> u64 {
unsafe { unsafe { self.handle.GetGPUVirtualAddress() }
self.handle.GetGPUVirtualAddress()
}
} }
pub fn into_raw(self) -> ID3D12Resource { pub fn into_raw(self) -> ID3D12Resource {
@ -77,15 +78,17 @@ impl D3D12Buffer {
} }
pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> { pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> {
let (range, size) = range.map(|range| { let (range, size) = range
(D3D12_RANGE { .map(|range| {
Begin: range.start, (
End: range.end D3D12_RANGE {
}, range.end - range.start) Begin: range.start,
}).unwrap_or((D3D12_RANGE { End: range.end,
Begin: 0, },
End: 0 range.end - range.start,
}, self.size)); )
})
.unwrap_or((D3D12_RANGE { Begin: 0, End: 0 }, self.size));
unsafe { unsafe {
let mut ptr = std::ptr::null_mut(); let mut ptr = std::ptr::null_mut();
@ -99,7 +102,6 @@ impl D3D12Buffer {
} }
} }
impl D3D12ConstantBuffer { impl D3D12ConstantBuffer {
pub fn new(buffer: D3D12Buffer) -> D3D12ConstantBuffer { pub fn new(buffer: D3D12Buffer) -> D3D12ConstantBuffer {
unsafe { unsafe {
@ -108,10 +110,7 @@ impl D3D12ConstantBuffer {
SizeInBytes: buffer.size as u32, SizeInBytes: buffer.size as u32,
}; };
D3D12ConstantBuffer { D3D12ConstantBuffer { buffer, desc }
buffer,
desc,
}
} }
} }
} }

View file

@ -4,7 +4,13 @@ use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_RTV}; use windows::Win32::Graphics::Direct3D12::{
ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC,
D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
D3D12_GPU_DESCRIPTOR_HANDLE,
};
#[const_trait] #[const_trait]
pub trait D3D12HeapType { pub trait D3D12HeapType {
@ -108,15 +114,10 @@ impl<T> D3D12DescriptorHeapSlotInner<T> {
/// unsafe because type must match /// unsafe because type must match
pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) { pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
unsafe { unsafe {
let heap = self.heap.deref() let heap = self.heap.deref().borrow();
.borrow();
heap.device.CopyDescriptorsSimple( heap.device
1, .CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty)
self.cpu_handle,
source,
heap.ty
)
} }
} }
} }
@ -208,10 +209,16 @@ impl<T> D3D12DescriptorHeap<T> {
/// descriptors allocated for it. /// descriptors allocated for it.
/// ///
/// size must also divide equally into the size of the heap. /// size must also divide equally into the size of the heap.
pub unsafe fn suballocate(self, size: usize) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) { pub unsafe fn suballocate(
self,
size: usize,
) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
// has to be called right after creation. // has to be called right after creation.
assert_eq!(Rc::strong_count(&self.0), 1, assert_eq!(
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation."); Rc::strong_count(&self.0),
1,
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation."
);
let inner = Rc::try_unwrap(self.0) let inner = Rc::try_unwrap(self.0)
.expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.") .expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.")
@ -221,8 +228,11 @@ impl<T> D3D12DescriptorHeap<T> {
let num_heaps = inner.num_descriptors / size; let num_heaps = inner.num_descriptors / size;
let remainder = inner.num_descriptors % size; let remainder = inner.num_descriptors % size;
assert_eq!(remainder, 0, "D3D12DescriptorHeap::suballocate \ assert_eq!(
must be called with a size that equally divides the number of descriptors"); remainder, 0,
"D3D12DescriptorHeap::suballocate \
must be called with a size that equally divides the number of descriptors"
);
let mut heaps = Vec::new(); let mut heaps = Vec::new();
@ -231,19 +241,16 @@ impl<T> D3D12DescriptorHeap<T> {
let root_gpu_ptr = inner.gpu_start.map(|p| p.ptr); let root_gpu_ptr = inner.gpu_start.map(|p| p.ptr);
for _ in 0..num_heaps { for _ in 0..num_heaps {
let new_cpu_start = root_cpu_ptr + (start * inner.handle_size); let new_cpu_start = root_cpu_ptr + (start * inner.handle_size);
let new_gpu_start = root_gpu_ptr let new_gpu_start = root_gpu_ptr.map(|r| D3D12_GPU_DESCRIPTOR_HANDLE {
.map(|r| D3D12_GPU_DESCRIPTOR_HANDLE { ptr: r + (start as u64 * inner.handle_size as u64),
ptr: r + (start as u64 * inner.handle_size as u64) });
});
heaps.push(D3D12DescriptorHeapInner { heaps.push(D3D12DescriptorHeapInner {
device: inner.device.clone(), device: inner.device.clone(),
heap: inner.heap.clone(), heap: inner.heap.clone(),
ty: inner.ty, ty: inner.ty,
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start },
ptr: new_cpu_start
},
gpu_start: new_gpu_start, gpu_start: new_gpu_start,
handle_size: inner.handle_size, handle_size: inner.handle_size,
start: 0, start: 0,
@ -254,11 +261,15 @@ impl<T> D3D12DescriptorHeap<T> {
start += size; start += size;
} }
(heaps.into_iter() (
.map(|inner| D3D12DescriptorHeap( heaps
Rc::new(RefCell::new(inner)), .into_iter()
PhantomData::default())) .map(|inner| {
.collect(), inner.heap) D3D12DescriptorHeap(Rc::new(RefCell::new(inner)), PhantomData::default())
})
.collect(),
inner.heap,
)
} }
pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> { pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> {
@ -290,7 +301,9 @@ impl<T> D3D12DescriptorHeap<T> {
todo!("error need to fail"); todo!("error need to fail");
} }
pub fn alloc_range<const NUM_DESC: usize>(&mut self)-> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> { pub fn alloc_range<const NUM_DESC: usize>(
&mut self,
) -> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> {
let dest = array_init::try_array_init(|_| self.alloc_slot())?; let dest = array_init::try_array_init(|_| self.alloc_slot())?;
Ok(dest) Ok(dest)
} }

View file

@ -1,9 +1,13 @@
use std::ops::Deref; use crate::buffer::D3D12ConstantBuffer;
use rustc_hash::FxHashMap; use crate::descriptor_heap::{
use windows::core::Interface; D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap,
use windows::Win32::Foundation::RECT; };
use windows::Win32::Graphics::Direct3D11::ID3D11Device; use crate::filter_chain::FilterCommon;
use windows::Win32::Graphics::Direct3D12::{D3D12_RENDER_PASS_BEGINNING_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD, D3D12_RENDER_PASS_ENDING_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE, D3D12_RENDER_PASS_FLAG_NONE, D3D12_RENDER_PASS_RENDER_TARGET_DESC, D3D12_VIEWPORT, ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4}; use crate::graphics_pipeline::D3D12GraphicsPipeline;
use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use crate::texture::{InputTexture, OutputTexture};
use crate::{error, util};
use librashader_common::{ImageFormat, Size, Viewport}; use librashader_common::{ImageFormat, Size, Viewport};
use librashader_preprocess::ShaderSource; use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig; use librashader_presets::ShaderPassConfig;
@ -12,14 +16,17 @@ use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::binding::{BindSemantics, TextureInput}; use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::quad::QuadType; use librashader_runtime::quad::QuadType;
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess}; use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
use crate::buffer::D3D12ConstantBuffer; use rustc_hash::FxHashMap;
use crate::{error, util}; use std::ops::Deref;
use crate::filter_chain::FilterCommon; use windows::core::Interface;
use crate::graphics_pipeline::D3D12GraphicsPipeline; use windows::Win32::Foundation::RECT;
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap}; use windows::Win32::Graphics::Direct3D11::ID3D11Device;
use crate::render_target::RenderTarget; use windows::Win32::Graphics::Direct3D12::{
use crate::samplers::SamplerSet; ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4,
use crate::texture::{InputTexture, OutputTexture}; D3D12_RENDER_PASS_BEGINNING_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,
D3D12_RENDER_PASS_ENDING_ACCESS, D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE,
D3D12_RENDER_PASS_FLAG_NONE, D3D12_RENDER_PASS_RENDER_TARGET_DESC, D3D12_VIEWPORT,
};
pub(crate) struct FilterPass { pub(crate) struct FilterPass {
pub(crate) pipeline: D3D12GraphicsPipeline, pub(crate) pipeline: D3D12GraphicsPipeline,
@ -32,7 +39,6 @@ pub(crate) struct FilterPass {
pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16], pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16], pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
pub source: ShaderSource, pub source: ShaderSource,
} }
impl TextureInput for InputTexture { impl TextureInput for InputTexture {
@ -44,8 +50,7 @@ impl TextureInput for InputTexture {
impl BindSemantics for FilterPass { impl BindSemantics for FilterPass {
type InputTexture = InputTexture; type InputTexture = InputTexture;
type SamplerSet = SamplerSet; type SamplerSet = SamplerSet;
type DescriptorSet<'a> = type DescriptorSet<'a> = (
(
&'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16], &'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
&'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16], &'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
); );
@ -59,14 +64,16 @@ impl BindSemantics for FilterPass {
texture: &Self::InputTexture, texture: &Self::InputTexture,
_device: &Self::DeviceContext, _device: &Self::DeviceContext,
) { ) {
let (texture_binding, let (texture_binding, sampler_binding) = descriptors;
sampler_binding) = descriptors;
unsafe { unsafe {
texture_binding[binding.binding as usize] texture_binding[binding.binding as usize].copy_descriptor(*texture.descriptor.as_ref());
.copy_descriptor(*texture.descriptor.as_ref()); sampler_binding[binding.binding as usize].copy_descriptor(
sampler_binding[binding.binding as usize] *samplers
.copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).deref().as_ref()) .get(texture.wrap_mode, texture.filter)
.deref()
.as_ref(),
)
} }
} }
} }
@ -96,7 +103,6 @@ impl FilterPass {
original: &InputTexture, original: &InputTexture,
source: &InputTexture, source: &InputTexture,
) { ) {
Self::bind_semantics( Self::bind_semantics(
&(), &(),
&parent.samplers, &parent.samplers,
@ -140,7 +146,6 @@ impl FilterPass {
output: &RenderTarget, output: &RenderTarget,
vbo_type: QuadType, vbo_type: QuadType,
) -> error::Result<()> { ) -> error::Result<()> {
parent.draw_quad.bind_vertices(cmd, vbo_type); parent.draw_quad.bind_vertices(cmd, vbo_type);
unsafe { unsafe {
cmd.SetPipelineState(&self.pipeline.handle); cmd.SetPipelineState(&self.pipeline.handle);
@ -207,7 +212,7 @@ impl FilterPass {
Anonymous: Default::default(), Anonymous: Default::default(),
}, },
}]; }];
cmd.BeginRenderPass(Some(&pass), None, D3D12_RENDER_PASS_FLAG_NONE) cmd.BeginRenderPass(Some(&pass), None, D3D12_RENDER_PASS_FLAG_NONE)
} }
@ -220,7 +225,7 @@ impl FilterPass {
MinDepth: 0.0, MinDepth: 0.0,
MaxDepth: 1.0, MaxDepth: 1.0,
}]); }]);
cmd.RSSetScissorRects(&[RECT { cmd.RSSetScissorRects(&[RECT {
left: 0, left: 0,
top: 0, top: 0,
@ -232,10 +237,8 @@ impl FilterPass {
cmd.DrawInstanced(4, 1, 0, 0) cmd.DrawInstanced(4, 1, 0, 0)
} }
unsafe { unsafe { cmd.EndRenderPass() }
cmd.EndRenderPass()
}
Ok(()) Ok(())
} }
} }

View file

@ -1,25 +1,36 @@
use std::ops::Deref; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, ID3D12Device, ID3D12Resource}; use crate::error;
use windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC}; use crate::error::assume_d3d12_init;
use crate::texture::{InputTexture, OutputTexture};
use crate::util::d3d12_get_closest_format;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D; use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ViewportSize};
use crate::error; use std::ops::Deref;
use crate::error::assume_d3d12_init; use windows::Win32::Graphics::Direct3D12::{
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap}; ID3D12Device, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
use crate::texture::{InputTexture, OutputTexture}; D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
use crate::util::d3d12_get_closest_format; D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET,
D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D,
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES,
D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC,
D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RTV_DIMENSION_TEXTURE2D,
D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0,
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct OwnedImage { pub(crate) struct OwnedImage {
pub(crate)handle: ID3D12Resource, pub(crate) handle: ID3D12Resource,
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
format: ImageFormat, format: ImageFormat,
device: ID3D12Device, device: ID3D12Device,
max_mipmap: u16, max_mipmap: u16,
} }
impl OwnedImage { impl OwnedImage {
pub fn new( pub fn new(
device: &ID3D12Device, device: &ID3D12Device,
@ -28,7 +39,11 @@ impl OwnedImage {
mipmap: bool, mipmap: bool,
) -> error::Result<OwnedImage> { ) -> error::Result<OwnedImage> {
unsafe { unsafe {
let miplevels = if mipmap { size.calculate_miplevels() } else { 1 }; let miplevels = if mipmap {
size.calculate_miplevels()
} else {
1
};
let mut desc = D3D12_RESOURCE_DESC { let mut desc = D3D12_RESOURCE_DESC {
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D, Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
Alignment: 0, Alignment: 0,
@ -88,10 +103,12 @@ impl OwnedImage {
} }
} }
pub(crate) fn create_shader_resource_view(
pub(crate) fn create_shader_resource_view(&self, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>, &self,
filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputTexture> { heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
filter: FilterMode,
wrap_mode: WrapMode,
) -> error::Result<InputTexture> {
let descriptor = heap.alloc_slot()?; let descriptor = heap.alloc_slot()?;
unsafe { unsafe {
@ -107,15 +124,26 @@ impl OwnedImage {
}, },
}; };
self.device.CreateShaderResourceView(&self.handle, Some(&srv_desc), *descriptor.deref().as_ref()); self.device.CreateShaderResourceView(
&self.handle,
Some(&srv_desc),
*descriptor.deref().as_ref(),
);
} }
Ok(InputTexture::new(descriptor, self.size, self.format, wrap_mode, filter)) Ok(InputTexture::new(
descriptor,
self.size,
self.format,
wrap_mode,
filter,
))
} }
pub(crate) fn create_render_target_view(&self, heap: &mut D3D12DescriptorHeap<RenderTargetHeap> pub(crate) fn create_render_target_view(
&self,
heap: &mut D3D12DescriptorHeap<RenderTargetHeap>,
) -> error::Result<OutputTexture> { ) -> error::Result<OutputTexture> {
let descriptor = heap.alloc_slot()?; let descriptor = heap.alloc_slot()?;
unsafe { unsafe {
@ -130,35 +158,34 @@ impl OwnedImage {
}, },
}; };
self.device.CreateRenderTargetView(&self.handle, Some(&rtv_desc), *descriptor.deref().as_ref()); self.device.CreateRenderTargetView(
&self.handle,
Some(&rtv_desc),
*descriptor.deref().as_ref(),
);
} }
Ok(OutputTexture::new(descriptor, self.size)) Ok(OutputTexture::new(descriptor, self.size))
} }
pub fn scale(&mut self, pub fn scale(
scaling: Scale2D, &mut self,
format: ImageFormat, scaling: Scale2D,
viewport_size: &Size<u32>, format: ImageFormat,
source_size: &Size<u32>, viewport_size: &Size<u32>,
mipmap: bool, source_size: &Size<u32>,
) -> error::Result<Size<u32>> mipmap: bool,
{ ) -> error::Result<Size<u32>> {
let size = source_size.scale_viewport(scaling, *viewport_size); let size = source_size.scale_viewport(scaling, *viewport_size);
if self.size != size if self.size != size
|| (mipmap && self.max_mipmap == 1) || (mipmap && self.max_mipmap == 1)
|| (!mipmap && self.max_mipmap != 1) || (!mipmap && self.max_mipmap != 1)
|| format != self.format || format != self.format
{ {
let mut new = OwnedImage::new( let mut new = OwnedImage::new(&self.device, size, format, mipmap)?;
&self.device,
size,
format,
mipmap
)?;
std::mem::swap(self, &mut new); std::mem::swap(self, &mut new);
} }
Ok(size) Ok(size)
} }
} }

View file

@ -1,14 +1,27 @@
use crate::quad_render::DrawQuad;
use windows::Win32::Foundation::BOOL; use crate::{error, util};
use windows::Win32::Graphics::Direct3D12::{D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA, D3D12_COLOR_WRITE_ENABLE_ALL, D3D12_CULL_MODE_NONE, D3D12_DESCRIPTOR_RANGE, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_FILL_MODE_SOLID, D3D12_GRAPHICS_PIPELINE_STATE_DESC, D3D12_INPUT_LAYOUT_DESC, D3D12_LOGIC_OP_NOOP, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, D3D12_RASTERIZER_DESC, D3D12_RENDER_TARGET_BLEND_DESC, D3D12_ROOT_DESCRIPTOR, D3D12_ROOT_DESCRIPTOR_TABLE, D3D12_ROOT_PARAMETER, D3D12_ROOT_PARAMETER_0, D3D12_ROOT_PARAMETER_TYPE_CBV, D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, D3D12_ROOT_SIGNATURE_DESC, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT, D3D12_SHADER_BYTECODE, D3D12_SHADER_VISIBILITY_ALL, D3D12_SHADER_VISIBILITY_PIXEL, D3D12SerializeRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature};
use windows::Win32::Graphics::Direct3D::Dxc::{IDxcBlob, IDxcCompiler, IDxcLibrary, IDxcUtils, IDxcValidator};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC};
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;
use librashader_reflect::reflect::semantics::BindingStage; use librashader_reflect::reflect::semantics::BindingStage;
use crate::{error, util}; use windows::Win32::Foundation::BOOL;
use crate::quad_render::DrawQuad; use windows::Win32::Graphics::Direct3D::Dxc::{
IDxcBlob, IDxcCompiler, IDxcLibrary, IDxcUtils, IDxcValidator,
};
use windows::Win32::Graphics::Direct3D12::{
D3D12SerializeRootSignature, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature,
D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA,
D3D12_COLOR_WRITE_ENABLE_ALL, D3D12_CULL_MODE_NONE, D3D12_DESCRIPTOR_RANGE,
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_FILL_MODE_SOLID,
D3D12_GRAPHICS_PIPELINE_STATE_DESC, D3D12_INPUT_LAYOUT_DESC, D3D12_LOGIC_OP_NOOP,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, D3D12_RASTERIZER_DESC, D3D12_RENDER_TARGET_BLEND_DESC,
D3D12_ROOT_DESCRIPTOR, D3D12_ROOT_DESCRIPTOR_TABLE, D3D12_ROOT_PARAMETER,
D3D12_ROOT_PARAMETER_0, D3D12_ROOT_PARAMETER_TYPE_CBV,
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, D3D12_ROOT_SIGNATURE_DESC,
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT, D3D12_SHADER_BYTECODE,
D3D12_SHADER_VISIBILITY_ALL, D3D12_SHADER_VISIBILITY_PIXEL, D3D_ROOT_SIGNATURE_VERSION_1,
};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC};
pub struct D3D12GraphicsPipeline { pub struct D3D12GraphicsPipeline {
pub(crate) handle: ID3D12PipelineState, pub(crate) handle: ID3D12PipelineState,
@ -28,7 +41,7 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
RegisterSpace: 0, RegisterSpace: 0,
OffsetInDescriptorsFromTableStart: 0, OffsetInDescriptorsFromTableStart: 0,
}, },
} },
}, },
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL, ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
}, },
@ -45,11 +58,10 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
RegisterSpace: 0, RegisterSpace: 0,
OffsetInDescriptorsFromTableStart: 0, OffsetInDescriptorsFromTableStart: 0,
}, },
} },
}, },
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL, ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
}, },
// UBO // UBO
D3D12_ROOT_PARAMETER { D3D12_ROOT_PARAMETER {
ParameterType: D3D12_ROOT_PARAMETER_TYPE_CBV, ParameterType: D3D12_ROOT_PARAMETER_TYPE_CBV,
@ -57,7 +69,7 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
Descriptor: D3D12_ROOT_DESCRIPTOR { Descriptor: D3D12_ROOT_DESCRIPTOR {
ShaderRegister: 0, ShaderRegister: 0,
RegisterSpace: 0, RegisterSpace: 0,
} },
}, },
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL, ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
}, },
@ -67,10 +79,10 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
Descriptor: D3D12_ROOT_DESCRIPTOR { Descriptor: D3D12_ROOT_DESCRIPTOR {
ShaderRegister: 1, ShaderRegister: 1,
RegisterSpace: 0, RegisterSpace: 0,
} },
}, },
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL, ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
} },
]; ];
const D3D12_SLANG_ROOT_SIGNATURE: &D3D12_ROOT_SIGNATURE_DESC = &D3D12_ROOT_SIGNATURE_DESC { const D3D12_SLANG_ROOT_SIGNATURE: &D3D12_ROOT_SIGNATURE_DESC = &D3D12_ROOT_SIGNATURE_DESC {
@ -82,36 +94,33 @@ const D3D12_SLANG_ROOT_SIGNATURE: &D3D12_ROOT_SIGNATURE_DESC = &D3D12_ROOT_SIGNA
}; };
pub struct D3D12RootSignature { pub struct D3D12RootSignature {
pub(crate) handle: ID3D12RootSignature pub(crate) handle: ID3D12RootSignature,
} }
impl D3D12RootSignature { impl D3D12RootSignature {
pub fn new(device: &ID3D12Device) pub fn new(device: &ID3D12Device) -> error::Result<D3D12RootSignature> {
-> error::Result<D3D12RootSignature>
{
let signature = unsafe { let signature = unsafe {
let mut rs_blob = None; let mut rs_blob = None;
// todo: D3D12SerializeVersionedRootSignature // todo: D3D12SerializeVersionedRootSignature
// todo: hlsl rootsig tbh // todo: hlsl rootsig tbh
D3D12SerializeRootSignature(D3D12_SLANG_ROOT_SIGNATURE, D3D12SerializeRootSignature(
D3D_ROOT_SIGNATURE_VERSION_1, D3D12_SLANG_ROOT_SIGNATURE,
&mut rs_blob, D3D_ROOT_SIGNATURE_VERSION_1,
None &mut rs_blob,
None,
)?; )?;
// SAFETY: if D3D12SerializeRootSignature succeeds then blob is Some // SAFETY: if D3D12SerializeRootSignature succeeds then blob is Some
let rs_blob = rs_blob.unwrap(); let rs_blob = rs_blob.unwrap();
let blob = std::slice::from_raw_parts(rs_blob.GetBufferPointer().cast(), let blob = std::slice::from_raw_parts(
rs_blob.GetBufferSize()); rs_blob.GetBufferPointer().cast(),
let root_signature: ID3D12RootSignature = device.CreateRootSignature( rs_blob.GetBufferSize(),
0, blob );
)?; let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob)?;
root_signature root_signature
}; };
Ok(D3D12RootSignature { Ok(D3D12RootSignature { handle: signature })
handle: signature,
})
} }
} }
impl D3D12GraphicsPipeline { impl D3D12GraphicsPipeline {
@ -156,7 +165,7 @@ impl D3D12GraphicsPipeline {
Default::default(), Default::default(),
Default::default(), Default::default(),
Default::default(), Default::default(),
Default::default() Default::default(),
], ],
..Default::default() ..Default::default()
}, },
@ -199,12 +208,13 @@ impl D3D12GraphicsPipeline {
}) })
} }
pub fn new_from_dxil(device: &ID3D12Device, pub fn new_from_dxil(
library: &IDxcUtils, device: &ID3D12Device,
validator: &IDxcValidator, library: &IDxcUtils,
shader_assembly: &ShaderCompilerOutput<DxilObject, ()>, validator: &IDxcValidator,
root_signature: &D3D12RootSignature, shader_assembly: &ShaderCompilerOutput<DxilObject, ()>,
render_format: DXGI_FORMAT, root_signature: &D3D12RootSignature,
render_format: DXGI_FORMAT,
) -> error::Result<D3D12GraphicsPipeline> { ) -> error::Result<D3D12GraphicsPipeline> {
if shader_assembly.vertex.requires_runtime_data() { if shader_assembly.vertex.requires_runtime_data() {
panic!("vertex needs rt data??") panic!("vertex needs rt data??")
@ -212,29 +222,48 @@ impl D3D12GraphicsPipeline {
if shader_assembly.fragment.requires_runtime_data() { if shader_assembly.fragment.requires_runtime_data() {
panic!("fragment needs rt data??") panic!("fragment needs rt data??")
} }
let vertex_dxil = let vertex_dxil = util::dxc_validate_shader(library, validator, &shader_assembly.vertex)?;
util::dxc_validate_shader(library, validator, &shader_assembly.vertex)?;
let fragment_dxil = let fragment_dxil =
util::dxc_validate_shader(library, validator, &shader_assembly.fragment)?; util::dxc_validate_shader(library, validator, &shader_assembly.fragment)?;
Self::new_from_blobs(device, vertex_dxil, fragment_dxil, root_signature, render_format) Self::new_from_blobs(
device,
vertex_dxil,
fragment_dxil,
root_signature,
render_format,
)
} }
pub fn new_from_hlsl(device: &ID3D12Device, pub fn new_from_hlsl(
library: &IDxcUtils, device: &ID3D12Device,
dxc: &IDxcCompiler, library: &IDxcUtils,
shader_assembly: &ShaderCompilerOutput<String, CrossHlslContext>, dxc: &IDxcCompiler,
root_signature: &D3D12RootSignature, shader_assembly: &ShaderCompilerOutput<String, CrossHlslContext>,
render_format: DXGI_FORMAT, root_signature: &D3D12RootSignature,
render_format: DXGI_FORMAT,
) -> error::Result<D3D12GraphicsPipeline> { ) -> error::Result<D3D12GraphicsPipeline> {
unsafe { unsafe {
let vertex_dxil = util::dxc_compile_shader(
library,
dxc,
&shader_assembly.vertex,
BindingStage::VERTEX,
)?;
let fragment_dxil = util::dxc_compile_shader(
library,
dxc,
&shader_assembly.fragment,
BindingStage::FRAGMENT,
)?;
let vertex_dxil = util::dxc_compile_shader(library, dxc, &shader_assembly.vertex, BindingStage::VERTEX)?; Self::new_from_blobs(
let fragment_dxil = device,
util::dxc_compile_shader(library, dxc,&shader_assembly.fragment, BindingStage::FRAGMENT)?; vertex_dxil,
fragment_dxil,
Self::new_from_blobs(device, vertex_dxil, fragment_dxil, root_signature, render_format) root_signature,
render_format,
)
} }
} }
} }

View file

@ -237,13 +237,13 @@ unsafe extern "system" fn debug_log(
} }
pub mod d3d12_hello_triangle { pub mod d3d12_hello_triangle {
use std::ops::Deref;
use super::*; use super::*;
use crate::filter_chain::FilterChainD3D12;
use std::path::Path;
use librashader_common::{FilterMode, Size, Viewport, WrapMode};
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap}; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
use crate::filter_chain::FilterChainD3D12;
use crate::texture::{InputTexture, OutputTexture}; use crate::texture::{InputTexture, OutputTexture};
use librashader_common::{FilterMode, Size, Viewport, WrapMode};
use std::ops::Deref;
use std::path::Path;
const FRAME_COUNT: u32 = 2; const FRAME_COUNT: u32 = 2;
@ -252,7 +252,7 @@ pub mod d3d12_hello_triangle {
device: ID3D12Device, device: ID3D12Device,
resources: Option<Resources>, resources: Option<Resources>,
pub filter: FilterChainD3D12, pub filter: FilterChainD3D12,
framecount: usize framecount: usize,
} }
struct Resources { struct Resources {
@ -278,7 +278,7 @@ pub mod d3d12_hello_triangle {
fence: ID3D12Fence, fence: ID3D12Fence,
fence_value: u64, fence_value: u64,
fence_event: HANDLE, fence_event: HANDLE,
frambuffer_heap: D3D12DescriptorHeap<CpuStagingHeap> frambuffer_heap: D3D12DescriptorHeap<CpuStagingHeap>,
} }
impl DXSample for Sample { impl DXSample for Sample {
@ -305,7 +305,7 @@ pub mod d3d12_hello_triangle {
device, device,
resources: None, resources: None,
filter, filter,
framecount: 0 framecount: 0,
}) })
} }
@ -394,9 +394,13 @@ pub mod d3d12_hello_triangle {
render_target.GetHeapProperties(Some(&mut heapprops), Some(&mut heappflags))?; render_target.GetHeapProperties(Some(&mut heapprops), Some(&mut heappflags))?;
desc.Flags &= !D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; desc.Flags &= !D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
let mut fb = None; let mut fb = None;
self.device.CreateCommittedResource(&heapprops, D3D12_HEAP_FLAG_NONE, &desc, self.device.CreateCommittedResource(
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, &heapprops,
None, &mut fb D3D12_HEAP_FLAG_NONE,
&desc,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
None,
&mut fb,
)?; )?;
fb.unwrap() fb.unwrap()
@ -487,24 +491,33 @@ pub mod d3d12_hello_triangle {
fn render(&mut self) { fn render(&mut self) {
if let Some(resources) = &mut self.resources { if let Some(resources) = &mut self.resources {
let srv = resources.frambuffer_heap.alloc_slot() let srv = resources.frambuffer_heap.alloc_slot().unwrap();
.unwrap();
unsafe { unsafe {
self.device.CreateShaderResourceView(&resources.framebuffer, Some(&D3D12_SHADER_RESOURCE_VIEW_DESC { self.device.CreateShaderResourceView(
Format: DXGI_FORMAT_R8G8B8A8_UNORM, &resources.framebuffer,
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D, Some(&D3D12_SHADER_RESOURCE_VIEW_DESC {
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, Format: DXGI_FORMAT_R8G8B8A8_UNORM,
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 { ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
Texture2D: D3D12_TEX2D_SRV { Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
MipLevels: u32::MAX, Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
..Default::default() Texture2D: D3D12_TEX2D_SRV {
} MipLevels: u32::MAX,
}, ..Default::default()
}), *srv.deref().as_ref()) },
},
}),
*srv.deref().as_ref(),
)
} }
populate_command_list(resources, &mut self.filter, self.framecount, *srv.deref().as_ref()).unwrap(); populate_command_list(
resources,
&mut self.filter,
self.framecount,
*srv.deref().as_ref(),
)
.unwrap();
// Execute the command list. // Execute the command list.
let command_list = ID3D12CommandList::from(&resources.command_list); let command_list = ID3D12CommandList::from(&resources.command_list);
@ -519,8 +532,10 @@ pub mod d3d12_hello_triangle {
} }
} }
fn populate_command_list(resources: &mut Resources, filter: &mut FilterChainD3D12, fn populate_command_list(
frame_count: usize, resources: &mut Resources,
filter: &mut FilterChainD3D12,
frame_count: usize,
framebuffer: D3D12_CPU_DESCRIPTOR_HANDLE, framebuffer: D3D12_CPU_DESCRIPTOR_HANDLE,
) -> Result<()> { ) -> Result<()> {
// Command list allocators can only be reset when the associated // Command list allocators can only be reset when the associated
@ -583,8 +598,10 @@ pub mod d3d12_hello_triangle {
} }
unsafe { unsafe {
command_list.CopyResource(&resources.framebuffer, command_list.CopyResource(
&resources.render_targets[resources.frame_index as usize]); &resources.framebuffer,
&resources.render_targets[resources.frame_index as usize],
);
command_list.ResourceBarrier(&[transition_barrier( command_list.ResourceBarrier(&[transition_barrier(
&resources.framebuffer, &resources.framebuffer,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
@ -597,21 +614,35 @@ pub mod d3d12_hello_triangle {
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET,
)]); )]);
filter.frame( filter
command_list, .frame(
InputTexture::new_from_raw(framebuffer, command_list,
Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32), InputTexture::new_from_raw(
DXGI_FORMAT_R8G8B8A8_UNORM, framebuffer,
WrapMode::ClampToEdge, Size::new(
FilterMode::Linear, resources.viewport.Width as u32,
), resources.viewport.Height as u32,
&Viewport { ),
x: 0.0, DXGI_FORMAT_R8G8B8A8_UNORM,
y: 0.0, WrapMode::ClampToEdge,
mvp: None, FilterMode::Linear,
output: OutputTexture::new_from_raw(rtv_handle, ),
Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32)), &Viewport {
}, frame_count, None).unwrap(); x: 0.0,
y: 0.0,
mvp: None,
output: OutputTexture::new_from_raw(
rtv_handle,
Size::new(
resources.viewport.Width as u32,
resources.viewport.Height as u32,
),
),
},
frame_count,
None,
)
.unwrap();
command_list.ResourceBarrier(&[transition_barrier( command_list.ResourceBarrier(&[transition_barrier(
&resources.render_targets[resources.frame_index as usize], &resources.render_targets[resources.frame_index as usize],
@ -620,8 +651,6 @@ pub mod d3d12_hello_triangle {
)]); )]);
} }
unsafe { command_list.Close() } unsafe { command_list.Close() }
} }

View file

@ -1,21 +1,21 @@
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
mod buffer;
mod descriptor_heap;
mod error; mod error;
mod filter_chain; mod filter_chain;
mod descriptor_heap;
mod hello_triangle;
mod samplers;
mod luts;
mod util;
mod mipmap;
mod filter_pass; mod filter_pass;
mod quad_render;
mod graphics_pipeline;
mod buffer;
mod framebuffer; mod framebuffer;
mod texture; mod graphics_pipeline;
mod hello_triangle;
mod luts;
mod mipmap;
mod quad_render;
mod render_target; mod render_target;
mod samplers;
mod texture;
mod util;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -1,15 +1,28 @@
use std::ops::Deref; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, CpuStagingHeap}; use crate::mipmap::MipmapGenContext;
use crate::texture::InputTexture;
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources}; use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::image::Image; use librashader_runtime::image::Image;
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
use crate::mipmap::{MipmapGenContext}; use std::ops::Deref;
use crate::texture::InputTexture; use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE,
D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE,
D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD,
D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC,
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0,
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_SUBRESOURCE_DATA, D3D12_TEX2D_SRV,
D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
pub struct LutTexture { pub struct LutTexture {
resource: ID3D12Resource, resource: ID3D12Resource,
@ -91,7 +104,11 @@ impl LutTexture {
}, },
}; };
device.CreateShaderResourceView(&resource, Some(&srv_desc), *descriptor.deref().as_ref()); device.CreateShaderResourceView(
&resource,
Some(&srv_desc),
*descriptor.deref().as_ref(),
);
} }
let mut buffer_desc = D3D12_RESOURCE_DESC { let mut buffer_desc = D3D12_RESOURCE_DESC {
@ -148,12 +165,21 @@ impl LutTexture {
SlicePitch: (4 * source.size.width * source.size.height) as isize, SlicePitch: (4 * source.size.width * source.size.height) as isize,
}]; }];
d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST); d3d12_resource_transition(
cmd,
&resource,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_COPY_DEST,
);
d3d12_update_subresources(cmd, &resource, d3d12_update_subresources(cmd, &resource, &upload, 0, 0, 1, &subresource)?;
&upload, 0, 0, 1, &subresource)?;
d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) d3d12_resource_transition(
cmd,
&resource,
D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
)
} }
let view = InputTexture::new( let view = InputTexture::new(
@ -163,18 +189,24 @@ impl LutTexture {
wrap_mode, wrap_mode,
filter, filter,
); );
Ok((LutTexture { Ok((
resource, LutTexture {
view, resource,
miplevels: if mipmap { Some(miplevels) } else { None } view,
}, upload)) miplevels: if mipmap { Some(miplevels) } else { None },
},
upload,
))
} }
pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> { pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> {
if let Some(miplevels) = self.miplevels { if let Some(miplevels) = self.miplevels {
gen_mips.generate_mipmaps(&self.resource, gen_mips.generate_mipmaps(
miplevels, &self.resource,
self.view.size, ImageFormat::R8G8B8A8Unorm.into())? miplevels,
self.view.size,
ImageFormat::R8G8B8A8Unorm.into(),
)?
} }
Ok(()) Ok(())
@ -185,4 +217,4 @@ impl AsRef<InputTexture> for LutTexture {
fn as_ref(&self) -> &InputTexture { fn as_ref(&self) -> &InputTexture {
&self.view &self.view
} }
} }

View file

@ -1,14 +1,22 @@
use std::mem::ManuallyDrop;
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::{D3D12_COMPUTE_PIPELINE_STATE_DESC, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_TYPE_UAV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_UAV_BARRIER, D3D12_SHADER_BYTECODE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEX2D_UAV, D3D12_UAV_DIMENSION_TEXTURE2D, D3D12_UNORDERED_ACCESS_VIEW_DESC, D3D12_UNORDERED_ACCESS_VIEW_DESC_0, ID3D12DescriptorHeap, ID3D12Device, ID3D12GraphicsCommandList, ID3D12PipelineState, ID3D12Resource, ID3D12RootSignature};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::Size;
use crate::{error, util};
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap};
use crate::util::fxc_compile_shader; use crate::util::fxc_compile_shader;
use bytemuck::{Zeroable, Pod}; use crate::{error, util};
use bytemuck::{Pod, Zeroable};
use librashader_common::Size;
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
use std::mem::ManuallyDrop;
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::{
ID3D12DescriptorHeap, ID3D12Device, ID3D12GraphicsCommandList, ID3D12PipelineState,
ID3D12Resource, ID3D12RootSignature, D3D12_COMPUTE_PIPELINE_STATE_DESC,
D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0,
D3D12_RESOURCE_BARRIER_TYPE_UAV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_UAV_BARRIER, D3D12_SHADER_BYTECODE,
D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0,
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEX2D_UAV, D3D12_UAV_DIMENSION_TEXTURE2D,
D3D12_UNORDERED_ACCESS_VIEW_DESC, D3D12_UNORDERED_ACCESS_VIEW_DESC_0,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
static GENERATE_MIPS_SRC: &[u8] = b" static GENERATE_MIPS_SRC: &[u8] = b"
// Copyright (c) Microsoft Corporation. // Copyright (c) Microsoft Corporation.
@ -71,23 +79,36 @@ pub struct MipmapGenContext<'a> {
gen: &'a D3D12MipmapGen, gen: &'a D3D12MipmapGen,
cmd: &'a ID3D12GraphicsCommandList, cmd: &'a ID3D12GraphicsCommandList,
heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>, heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>,
residuals: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>> residuals: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>,
} }
impl <'a> MipmapGenContext<'a> { impl<'a> MipmapGenContext<'a> {
fn new(gen: &'a D3D12MipmapGen, cmd: &'a ID3D12GraphicsCommandList, heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>) -> MipmapGenContext<'a> { fn new(
gen: &'a D3D12MipmapGen,
cmd: &'a ID3D12GraphicsCommandList,
heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>,
) -> MipmapGenContext<'a> {
Self { Self {
gen, cmd, heap, residuals: Vec::new() gen,
cmd,
heap,
residuals: Vec::new(),
} }
} }
/// Generate a set of mipmaps for the resource. /// Generate a set of mipmaps for the resource.
/// This is a "cheap" action and only dispatches a compute shader. /// This is a "cheap" action and only dispatches a compute shader.
pub fn generate_mipmaps(&mut self, resource: &ID3D12Resource, miplevels: u16, size: Size<u32>, format: DXGI_FORMAT) pub fn generate_mipmaps(
-> error::Result<()> &mut self,
{ resource: &ID3D12Resource,
miplevels: u16,
size: Size<u32>,
format: DXGI_FORMAT,
) -> error::Result<()> {
unsafe { unsafe {
let residuals = self.gen.generate_mipmaps(self.cmd, resource, miplevels, size, format, self.heap)?; let residuals = self
.gen
.generate_mipmaps(self.cmd, resource, miplevels, size, format, self.heap)?;
self.residuals.extend(residuals) self.residuals.extend(residuals)
} }
@ -103,14 +124,15 @@ impl D3D12MipmapGen {
pub fn new(device: &ID3D12Device) -> error::Result<D3D12MipmapGen> { pub fn new(device: &ID3D12Device) -> error::Result<D3D12MipmapGen> {
unsafe { unsafe {
let blob = fxc_compile_shader(GENERATE_MIPS_SRC, b"main\0", b"cs_5_1\0").unwrap(); let blob = fxc_compile_shader(GENERATE_MIPS_SRC, b"main\0", b"cs_5_1\0").unwrap();
let blob = std::slice::from_raw_parts(blob.GetBufferPointer().cast(), blob.GetBufferSize()); let blob =
std::slice::from_raw_parts(blob.GetBufferPointer().cast(), blob.GetBufferSize());
let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob).unwrap(); let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob).unwrap();
let desc = D3D12_COMPUTE_PIPELINE_STATE_DESC { let desc = D3D12_COMPUTE_PIPELINE_STATE_DESC {
pRootSignature: windows::core::ManuallyDrop::new(&root_signature), pRootSignature: windows::core::ManuallyDrop::new(&root_signature),
CS: D3D12_SHADER_BYTECODE { CS: D3D12_SHADER_BYTECODE {
pShaderBytecode: blob.as_ptr().cast(), pShaderBytecode: blob.as_ptr().cast(),
BytecodeLength: blob.len() BytecodeLength: blob.len(),
}, },
NodeMask: 0, NodeMask: 0,
..Default::default() ..Default::default()
@ -129,10 +151,14 @@ impl D3D12MipmapGen {
/// Enters a mipmapping compute context. /// Enters a mipmapping compute context.
/// This is a relatively expensive operation /// This is a relatively expensive operation
/// and should only be done at most a few times per frame. /// and should only be done at most a few times per frame.
pub fn mipmapping_context<F>(&self, cmd: &ID3D12GraphicsCommandList, work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>, mut f: F) pub fn mipmapping_context<F>(
-> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> &self,
where cmd: &ID3D12GraphicsCommandList,
F: FnMut(&mut MipmapGenContext) work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
mut f: F,
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>>
where
F: FnMut(&mut MipmapGenContext),
{ {
let heap: ID3D12DescriptorHeap = (&(*work_heap)).into(); let heap: ID3D12DescriptorHeap = (&(*work_heap)).into();
unsafe { unsafe {
@ -149,15 +175,16 @@ impl D3D12MipmapGen {
/// SAFETY: /// SAFETY:
/// - handle must be a CPU handle to an SRV /// - handle must be a CPU handle to an SRV
/// - work_heap must have enough descriptors to fit all miplevels. /// - work_heap must have enough descriptors to fit all miplevels.
unsafe fn generate_mipmaps(&self, unsafe fn generate_mipmaps(
cmd: &ID3D12GraphicsCommandList, &self,
resource: &ID3D12Resource, cmd: &ID3D12GraphicsCommandList,
resource: &ID3D12Resource,
miplevels: u16, miplevels: u16,
size: Size<u32>, size: Size<u32>,
format: DXGI_FORMAT, format: DXGI_FORMAT,
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> work_heap: &mut D3D12DescriptorHeap<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()?;
{ {
@ -173,8 +200,8 @@ impl D3D12MipmapGen {
}, },
}; };
self.device.CreateShaderResourceView(resource, self.device
Some(&srv_desc), *srv.deref().as_ref()); .CreateShaderResourceView(resource, Some(&srv_desc), *srv.deref().as_ref());
} }
let mut heap_slots = Vec::with_capacity(miplevels as usize); let mut heap_slots = Vec::with_capacity(miplevels as usize);
@ -189,12 +216,15 @@ impl D3D12MipmapGen {
Texture2D: D3D12_TEX2D_UAV { Texture2D: D3D12_TEX2D_UAV {
MipSlice: i as u32, MipSlice: i as u32,
..Default::default() ..Default::default()
} },
}, },
}; };
self.device.CreateUnorderedAccessView(resource, None, self.device.CreateUnorderedAccessView(
Some(&desc), *descriptor.deref().as_ref() resource,
None,
Some(&desc),
*descriptor.deref().as_ref(),
); );
heap_slots.push(descriptor); heap_slots.push(descriptor);
} }
@ -204,35 +234,41 @@ impl D3D12MipmapGen {
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);
let mipmap_params = MipConstants { let mipmap_params = MipConstants {
inv_out_texel_size: [ inv_out_texel_size: [1.0 / scaled.width as f32, 1.0 / scaled.height as f32],
1.0 / scaled.width as f32,
1.0 / scaled.height as f32
],
src_mip_index: (i - 1), src_mip_index: (i - 1),
}; };
let mipmap_params = bytemuck::bytes_of(&mipmap_params); let mipmap_params = bytemuck::bytes_of(&mipmap_params);
util::d3d12_resource_transition_subresource(
util::d3d12_resource_transition_subresource(cmd, resource, cmd,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, resource,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
i - 1 D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
i - 1,
); );
util::d3d12_resource_transition_subresource(cmd, resource, util::d3d12_resource_transition_subresource(
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, cmd,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, resource,
i D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
i,
); );
cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref()); cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref());
cmd.SetComputeRoot32BitConstants(2, cmd.SetComputeRoot32BitConstants(
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32, 2,
mipmap_params.as_ptr().cast(), (std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
0); mipmap_params.as_ptr().cast(),
0,
);
cmd.Dispatch( std::cmp::max(scaled.width / 8, 1), std::cmp::max(scaled.height / 8, 1), 1); cmd.Dispatch(
std::cmp::max(scaled.width / 8, 1),
std::cmp::max(scaled.height / 8, 1),
1,
);
// todo: handle manuallyDrop properly. // todo: handle manuallyDrop properly.
@ -242,21 +278,21 @@ impl D3D12MipmapGen {
let barrier = [D3D12_RESOURCE_BARRIER { let barrier = [D3D12_RESOURCE_BARRIER {
Type: D3D12_RESOURCE_BARRIER_TYPE_UAV, Type: D3D12_RESOURCE_BARRIER_TYPE_UAV,
Anonymous: D3D12_RESOURCE_BARRIER_0 { Anonymous: D3D12_RESOURCE_BARRIER_0 { UAV: uav_barrier },
UAV: uav_barrier
},
..Default::default() ..Default::default()
}]; }];
cmd.ResourceBarrier(&barrier); cmd.ResourceBarrier(&barrier);
util::d3d12_resource_transition_subresource(cmd, resource, util::d3d12_resource_transition_subresource(
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, cmd,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, resource,
i D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
i,
); );
} }
Ok(heap_slots) Ok(heap_slots)
} }
} }

View file

@ -1,12 +1,15 @@
use crate::buffer::D3D12Buffer;
use crate::error; use crate::error;
use bytemuck::{offset_of, Pod, Zeroable}; use bytemuck::{offset_of, Pod, Zeroable};
use librashader_runtime::quad::QuadType;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::w; use windows::w;
use windows::Win32::Graphics::Direct3D::{D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP}; use windows::Win32::Graphics::Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
use windows::Win32::Graphics::Direct3D12::{D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource}; use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource,
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW,
};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
use librashader_runtime::quad::QuadType;
use crate::buffer::{D3D12Buffer};
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone, Default, Zeroable, Pod)] #[derive(Debug, Copy, Clone, Default, Zeroable, Pod)]
@ -47,13 +50,14 @@ pub(crate) struct DrawQuad {
} }
impl DrawQuad { impl DrawQuad {
pub fn new(device: &ID3D12Device) pub fn new(device: &ID3D12Device) -> error::Result<DrawQuad> {
-> error::Result<DrawQuad> {
let stride = std::mem::size_of::<D3D12Vertex>() as u32; let stride = std::mem::size_of::<D3D12Vertex>() as u32;
let size = std::mem::size_of::<[D3D12Vertex;4]>() as u32; let size = std::mem::size_of::<[D3D12Vertex; 4]>() as u32;
let mut buffer = D3D12Buffer::new(device, size as usize)?; let mut buffer = D3D12Buffer::new(device, size as usize)?;
buffer.map(None)? buffer
.slice.copy_from_slice(bytemuck::cast_slice(QUAD_VBO_DATA)); .map(None)?
.slice
.copy_from_slice(bytemuck::cast_slice(QUAD_VBO_DATA));
let view = D3D12_VERTEX_BUFFER_VIEW { let view = D3D12_VERTEX_BUFFER_VIEW {
BufferLocation: buffer.gpu_address(), BufferLocation: buffer.gpu_address(),
@ -62,13 +66,10 @@ impl DrawQuad {
}; };
let buffer = buffer.into_raw(); let buffer = buffer.into_raw();
unsafe { unsafe {
buffer.SetName(w!("drawquad"))?; buffer.SetName(w!("drawquad"))?;
} }
Ok(DrawQuad { Ok(DrawQuad { buffer, view })
buffer,
view
})
} }
pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList, _vbo_type: QuadType) { pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList, _vbo_type: QuadType) {

View file

@ -6,4 +6,3 @@ pub(crate) struct RenderTarget<'a> {
pub mvp: &'a [f32; 16], pub mvp: &'a [f32; 16],
pub output: OutputTexture, pub output: OutputTexture,
} }

View file

@ -1,8 +1,8 @@
use std::ops::Deref;
use crate::error;
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
use crate::error;
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Direct3D12::{
ID3D12Device, D3D12_COMPARISON_FUNC_NEVER, D3D12_FLOAT32_MAX, D3D12_SAMPLER_DESC, ID3D12Device, D3D12_COMPARISON_FUNC_NEVER, D3D12_FLOAT32_MAX, D3D12_SAMPLER_DESC,
D3D12_TEXTURE_ADDRESS_MODE, D3D12_TEXTURE_ADDRESS_MODE,

View file

@ -1,26 +1,26 @@
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap}; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::D3D12_CPU_DESCRIPTOR_HANDLE;
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum InputDescriptor { pub(crate) enum InputDescriptor {
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>), Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE) Raw(D3D12_CPU_DESCRIPTOR_HANDLE),
} }
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum OutputDescriptor { pub(crate) enum OutputDescriptor {
Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>), Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE) Raw(D3D12_CPU_DESCRIPTOR_HANDLE),
} }
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor { impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self { match self {
InputDescriptor::Owned(h) => h.deref().as_ref(), InputDescriptor::Owned(h) => h.deref().as_ref(),
InputDescriptor::Raw(h) => h InputDescriptor::Raw(h) => h,
} }
} }
} }
@ -29,7 +29,7 @@ impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self { match self {
OutputDescriptor::Owned(h) => h.deref().as_ref(), OutputDescriptor::Owned(h) => h.deref().as_ref(),
OutputDescriptor::Raw(h) => h OutputDescriptor::Raw(h) => h,
} }
} }
} }
@ -41,25 +41,21 @@ pub struct OutputTexture {
} }
impl OutputTexture { impl OutputTexture {
pub fn new(handle: D3D12DescriptorHeapSlot<RenderTargetHeap>, pub fn new(
size: Size<u32>, handle: D3D12DescriptorHeapSlot<RenderTargetHeap>,
) -> OutputTexture { size: Size<u32>,
) -> OutputTexture {
let descriptor = OutputDescriptor::Owned(handle); let descriptor = OutputDescriptor::Owned(handle);
OutputTexture { OutputTexture { descriptor, size }
descriptor,
size,
}
} }
// unsafe since the lifetime of the handle has to survive // unsafe since the lifetime of the handle has to survive
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE, pub unsafe fn new_from_raw(
size: Size<u32>, handle: D3D12_CPU_DESCRIPTOR_HANDLE,
size: Size<u32>,
) -> OutputTexture { ) -> OutputTexture {
let descriptor = OutputDescriptor::Raw(handle); let descriptor = OutputDescriptor::Raw(handle);
OutputTexture { OutputTexture { descriptor, size }
descriptor,
size,
}
} }
} }
@ -69,31 +65,34 @@ pub struct InputTexture {
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
format: DXGI_FORMAT, format: DXGI_FORMAT,
pub(crate) wrap_mode: WrapMode, pub(crate) wrap_mode: WrapMode,
pub(crate) filter: FilterMode pub(crate) filter: FilterMode,
} }
impl InputTexture { impl InputTexture {
pub fn new(handle: D3D12DescriptorHeapSlot<CpuStagingHeap>, pub fn new(
size: Size<u32>, handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
format: ImageFormat, size: Size<u32>,
wrap_mode: WrapMode, format: ImageFormat,
filter: FilterMode) -> InputTexture { wrap_mode: WrapMode,
filter: FilterMode,
) -> InputTexture {
let srv = InputDescriptor::Owned(handle); let srv = InputDescriptor::Owned(handle);
InputTexture { InputTexture {
descriptor: srv, descriptor: srv,
size, size,
format: format.into(), format: format.into(),
wrap_mode, wrap_mode,
filter filter,
} }
} }
// unsafe since the lifetime of the handle has to survive // unsafe since the lifetime of the handle has to survive
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE, pub unsafe fn new_from_raw(
size: Size<u32>, handle: D3D12_CPU_DESCRIPTOR_HANDLE,
format: DXGI_FORMAT, size: Size<u32>,
wrap_mode: WrapMode, format: DXGI_FORMAT,
filter: FilterMode wrap_mode: WrapMode,
filter: FilterMode,
) -> InputTexture { ) -> InputTexture {
let srv = InputDescriptor::Raw(handle); let srv = InputDescriptor::Raw(handle);
InputTexture { InputTexture {
@ -101,7 +100,7 @@ impl InputTexture {
size, size,
format, format,
wrap_mode, wrap_mode,
filter filter,
} }
} }
} }
@ -110,4 +109,4 @@ impl AsRef<InputTexture> for InputTexture {
fn as_ref(&self) -> &InputTexture { fn as_ref(&self) -> &InputTexture {
self self
} }
} }

View file

@ -1,15 +1,29 @@
use crate::error;
use crate::error::assume_d3d12_init;
use librashader_reflect::reflect::semantics::BindingStage;
use std::ffi::CStr; use std::ffi::CStr;
use std::mem::ManuallyDrop; use std::mem::ManuallyDrop;
use std::u64; use std::u64;
use crate::error;
use windows::core::{Interface, PCSTR, PCWSTR}; use windows::core::{Interface, PCSTR, PCWSTR};
use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_SKIP_OPTIMIZATION}; use windows::Win32::Graphics::Direct3D::Dxc::{
DxcValidatorFlags_Default, DxcValidatorFlags_InPlaceEdit, DxcValidatorFlags_ModuleOnly,
DxcValidatorFlags_ValidMask, IDxcBlob, IDxcBlobUtf8, IDxcCompiler, IDxcLibrary, IDxcUtils,
IDxcValidator, DXC_CP, DXC_CP_UTF8,
};
use windows::Win32::Graphics::Direct3D::Fxc::{
D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_SKIP_OPTIMIZATION,
};
use windows::Win32::Graphics::Direct3D::ID3DBlob; use windows::Win32::Graphics::Direct3D::ID3DBlob;
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FEATURE_FORMAT_SUPPORT, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_TRANSITION_BARRIER, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_STATES, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_MEMCPY_DEST, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT}; use windows::Win32::Graphics::Direct3D12::{
use windows::Win32::Graphics::Direct3D::Dxc::{DXC_CP, DXC_CP_UTF8, DxcValidatorFlags_Default, DxcValidatorFlags_InPlaceEdit, DxcValidatorFlags_ModuleOnly, DxcValidatorFlags_ValidMask, IDxcBlob, IDxcBlobUtf8, IDxcCompiler, IDxcLibrary, IDxcUtils, IDxcValidator}; ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_FEATURE_DATA_FORMAT_SUPPORT,
D3D12_FEATURE_FORMAT_SUPPORT, D3D12_MEMCPY_DEST, D3D12_PLACED_SUBRESOURCE_FOOTPRINT,
D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATES, D3D12_RESOURCE_TRANSITION_BARRIER,
D3D12_SUBRESOURCE_DATA, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_LOCATION_0,
D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
};
use windows::Win32::Graphics::Dxgi::Common::*; use windows::Win32::Graphics::Dxgi::Common::*;
use librashader_reflect::reflect::semantics::BindingStage;
use crate::error::assume_d3d12_init;
/// wtf retroarch? /// wtf retroarch?
const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000); const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000);
@ -130,7 +144,7 @@ pub fn fxc_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> error:
None, None,
PCSTR(entry.as_ptr()), PCSTR(entry.as_ptr()),
PCSTR(version.as_ptr()), PCSTR(version.as_ptr()),
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
// if cfg!(feature = "debug-shader") { // if cfg!(feature = "debug-shader") {
// D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION // D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
// } else { // } else {
@ -146,20 +160,22 @@ pub fn fxc_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> error:
} }
} }
pub fn dxc_compile_shader(
pub fn dxc_compile_shader(library: &IDxcUtils, compiler: &IDxcCompiler, source: &String, profile: BindingStage) -> error::Result<IDxcBlob> { library: &IDxcUtils,
compiler: &IDxcCompiler,
source: &String,
profile: BindingStage,
) -> error::Result<IDxcBlob> {
// todo: compile with dxc // todo: compile with dxc
// let mut source = source.to_vec(); // let mut source = source.to_vec();
let include = unsafe { let include = unsafe { library.CreateDefaultIncludeHandler()? };
library.CreateDefaultIncludeHandler()?
};
let blob = unsafe { let blob = unsafe {
library.CreateBlobFromPinned( library.CreateBlobFromPinned(
source.as_ptr().cast(), source.as_ptr().cast(),
source.as_bytes().len() as u32, source.as_bytes().len() as u32,
DXC_CP_UTF8 DXC_CP_UTF8,
)? )?
}; };
@ -170,20 +186,21 @@ pub fn dxc_compile_shader(library: &IDxcUtils, compiler: &IDxcCompiler, source:
}; };
unsafe { unsafe {
let result = compiler.Compile(&blob, let result = compiler.Compile(
&blob,
PCWSTR::null(), PCWSTR::null(),
windows::w!("main"), windows::w!("main"),
profile, profile,
None, None,
&[], &[],
&include &include,
)?; )?;
if let Ok(buf) = result.GetErrorBuffer() { if let Ok(buf) = result.GetErrorBuffer() {
unsafe { unsafe {
let buf: IDxcBlobUtf8 = buf.cast().unwrap(); let buf: IDxcBlobUtf8 = buf.cast().unwrap();
let buf = std::slice::from_raw_parts(buf.GetBufferPointer() let buf =
.cast(), buf.GetBufferSize()); std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize());
let str = std::str::from_utf8_unchecked(buf); let str = std::str::from_utf8_unchecked(buf);
if str.len() != 0 { if str.len() != 0 {
eprintln!("{}", str); eprintln!("{}", str);
@ -196,26 +213,27 @@ pub fn dxc_compile_shader(library: &IDxcUtils, compiler: &IDxcCompiler, source:
} }
} }
pub fn dxc_validate_shader(
pub fn dxc_validate_shader(library: &IDxcUtils, validator: &IDxcValidator, source: &[u8]) -> error::Result<IDxcBlob> { library: &IDxcUtils,
validator: &IDxcValidator,
source: &[u8],
) -> error::Result<IDxcBlob> {
// todo: compile with dxc // todo: compile with dxc
// let mut source = source.to_vec(); // let mut source = source.to_vec();
let blob = unsafe { let blob =
library.CreateBlob(source.as_ptr().cast(), unsafe { library.CreateBlob(source.as_ptr().cast(), source.len() as u32, DXC_CP(0))? };
source.len() as u32,
DXC_CP(0))?
};
unsafe { unsafe {
let result = validator let result = validator
.Validate(&blob, DxcValidatorFlags_InPlaceEdit).unwrap(); .Validate(&blob, DxcValidatorFlags_InPlaceEdit)
.unwrap();
if let Ok(buf) = result.GetErrorBuffer() { if let Ok(buf) = result.GetErrorBuffer() {
unsafe { unsafe {
let buf: IDxcBlobUtf8 = buf.cast().unwrap(); let buf: IDxcBlobUtf8 = buf.cast().unwrap();
let buf = std::slice::from_raw_parts(buf.GetBufferPointer() let buf =
.cast(), buf.GetBufferSize()); std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize());
let str = std::str::from_utf8_unchecked(buf); let str = std::str::from_utf8_unchecked(buf);
if str.len() != 0 { if str.len() != 0 {
eprintln!("{}", str); eprintln!("{}", str);
@ -227,21 +245,28 @@ pub fn dxc_validate_shader(library: &IDxcUtils, validator: &IDxcValidator, sourc
} }
#[inline(always)] #[inline(always)]
pub fn d3d12_resource_transition(cmd: &ID3D12GraphicsCommandList, pub fn d3d12_resource_transition(
cmd: &ID3D12GraphicsCommandList,
resource: &ID3D12Resource, resource: &ID3D12Resource,
before: D3D12_RESOURCE_STATES, before: D3D12_RESOURCE_STATES,
after: D3D12_RESOURCE_STATES, after: D3D12_RESOURCE_STATES,
) { ) {
d3d12_resource_transition_subresource(cmd, resource, before, after,D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES); d3d12_resource_transition_subresource(
cmd,
resource,
before,
after,
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
);
} }
#[inline(always)] #[inline(always)]
pub fn d3d12_resource_transition_subresource(cmd: &ID3D12GraphicsCommandList, pub fn d3d12_resource_transition_subresource(
resource: &ID3D12Resource, cmd: &ID3D12GraphicsCommandList,
before: D3D12_RESOURCE_STATES, resource: &ID3D12Resource,
after: D3D12_RESOURCE_STATES, before: D3D12_RESOURCE_STATES,
subresource: u32 after: D3D12_RESOURCE_STATES,
subresource: u32,
) { ) {
let barrier = [D3D12_RESOURCE_BARRIER { let barrier = [D3D12_RESOURCE_BARRIER {
Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
@ -252,24 +277,22 @@ pub fn d3d12_resource_transition_subresource(cmd: &ID3D12GraphicsCommandList,
Subresource: subresource, Subresource: subresource,
StateBefore: before, StateBefore: before,
StateAfter: after, StateAfter: after,
}) }),
}, },
}]; }];
unsafe { unsafe { cmd.ResourceBarrier(&barrier) }
cmd.ResourceBarrier(&barrier)
}
} }
pub fn d3d12_update_subresources(cmd: &ID3D12GraphicsCommandList, pub fn d3d12_update_subresources(
destination_resource: &ID3D12Resource, cmd: &ID3D12GraphicsCommandList,
intermediate_resource: &ID3D12Resource, destination_resource: &ID3D12Resource,
intermediate_offset: u64, intermediate_resource: &ID3D12Resource,
first_subresouce: u32, intermediate_offset: u64,
num_subresources: u32, first_subresouce: u32,
source: &[D3D12_SUBRESOURCE_DATA] num_subresources: u32,
source: &[D3D12_SUBRESOURCE_DATA],
) -> error::Result<u64> { ) -> error::Result<u64> {
// let allocation_size = std::mem::size_of::<D3D12_PLACED_SUBRESOURCE_FOOTPRINT>() // let allocation_size = std::mem::size_of::<D3D12_PLACED_SUBRESOURCE_FOOTPRINT>()
// + std::mem::size_of::<u32>() // + std::mem::size_of::<u32>()
// + std::mem::size_of::<u64>() * num_subresources; // + std::mem::size_of::<u64>() * num_subresources;
@ -280,10 +303,10 @@ pub fn d3d12_update_subresources(cmd: &ID3D12GraphicsCommandList,
destination_resource.GetDevice(&mut device)?; destination_resource.GetDevice(&mut device)?;
assume_d3d12_init!(device, "GetDevice"); assume_d3d12_init!(device, "GetDevice");
let mut layouts =
let mut layouts = vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); num_subresources as usize]; vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); num_subresources as usize];
let mut num_rows = vec![0; num_subresources as usize]; let mut num_rows = vec![0; num_subresources as usize];
let mut row_sizes_in_bytes = vec![0; num_subresources as usize]; let mut row_sizes_in_bytes = vec![0; num_subresources as usize];
let mut required_size = 0; let mut required_size = 0;
// texture upload // texture upload
unsafe { unsafe {
@ -329,18 +352,15 @@ fn update_subresources(
) -> error::Result<u64> { ) -> error::Result<u64> {
// ToDo: implement validation as in the original function // ToDo: implement validation as in the original function
unsafe { unsafe {
let mut data = std::ptr::null_mut(); let mut data = std::ptr::null_mut();
intermediate_resource.Map(0, None, Some(&mut data))?; intermediate_resource.Map(0, None, Some(&mut data))?;
for i in 0..num_subresources as usize { for i in 0..num_subresources as usize {
let dest_data = D3D12_MEMCPY_DEST { let dest_data = D3D12_MEMCPY_DEST {
pData: data.offset(layouts[i].Offset as isize) pData: data.offset(layouts[i].Offset as isize) as *mut std::ffi::c_void,
as *mut std::ffi::c_void,
RowPitch: layouts[i].Footprint.RowPitch as usize, RowPitch: layouts[i].Footprint.RowPitch as usize,
SlicePitch: ((layouts[i].Footprint.RowPitch) SlicePitch: ((layouts[i].Footprint.RowPitch) * num_rows[i]) as usize,
* num_rows[i]) as usize,
}; };
memcpy_subresource( memcpy_subresource(
@ -366,12 +386,11 @@ fn update_subresources(
); );
} else { } else {
for i in 0..num_subresources as usize { for i in 0..num_subresources as usize {
let dest_location = D3D12_TEXTURE_COPY_LOCATION { let dest_location = D3D12_TEXTURE_COPY_LOCATION {
pResource: windows::core::ManuallyDrop::new(destination_resource), pResource: windows::core::ManuallyDrop::new(destination_resource),
Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 { Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
SubresourceIndex: i as u32 + first_subresouce SubresourceIndex: i as u32 + first_subresouce,
}, },
}; };
@ -379,23 +398,15 @@ fn update_subresources(
pResource: windows::core::ManuallyDrop::new(intermediate_resource), pResource: windows::core::ManuallyDrop::new(intermediate_resource),
Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 { Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
PlacedFootprint: layouts[i] PlacedFootprint: layouts[i],
}, },
}; };
cmd.CopyTextureRegion( cmd.CopyTextureRegion(&dest_location, 0, 0, 0, &source_location, None);
&dest_location,
0,
0,
0,
&source_location,
None,
);
} }
} }
Ok(required_size) Ok(required_size)
} }
} }
// this function should not leak to the public API, so // this function should not leak to the public API, so
@ -407,9 +418,8 @@ unsafe fn memcpy_subresource(
num_rows: u32, num_rows: u32,
num_slices: u32, num_slices: u32,
) { ) {
for z in 0..num_slices as usize { for z in 0..num_slices as usize {
let dest_slice = let dest_slice = dest.pData.add(dest.SlicePitch * z);
dest.pData.add(dest.SlicePitch * z);
let src_slice = src.pData.offset(src.SlicePitch * z as isize); 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 {

View file

@ -1,8 +1,8 @@
use std::sync::Arc;
use ash::vk;
use librashader_runtime::quad::QuadType;
use crate::error; use crate::error;
use crate::vulkan_primitives::VulkanBuffer; use crate::vulkan_primitives::VulkanBuffer;
use ash::vk;
use librashader_runtime::quad::QuadType;
use std::sync::Arc;
#[rustfmt::skip] #[rustfmt::skip]
static VBO_OFFSCREEN: &[f32; 16] = &[ static VBO_OFFSCREEN: &[f32; 16] = &[
@ -24,34 +24,50 @@ static VBO_DEFAULT_FINAL: &[f32; 16] = &[
pub struct DrawQuad { pub struct DrawQuad {
buffer: VulkanBuffer, buffer: VulkanBuffer,
device: Arc<ash::Device> device: Arc<ash::Device>,
} }
impl DrawQuad { impl DrawQuad {
pub fn new(device: &Arc<ash::Device>, mem_props: &vk::PhysicalDeviceMemoryProperties) -> error::Result<DrawQuad> { pub fn new(
let mut buffer = VulkanBuffer::new(device, mem_props, vk::BufferUsageFlags::VERTEX_BUFFER, 2 * std::mem::size_of::<[f32; 16]>())?; device: &Arc<ash::Device>,
mem_props: &vk::PhysicalDeviceMemoryProperties,
) -> error::Result<DrawQuad> {
let mut buffer = VulkanBuffer::new(
device,
mem_props,
vk::BufferUsageFlags::VERTEX_BUFFER,
2 * std::mem::size_of::<[f32; 16]>(),
)?;
{ {
let mut map = buffer.map()?; let mut map = buffer.map()?;
unsafe { unsafe {
map.copy_from(0, bytemuck::cast_slice(VBO_OFFSCREEN)); map.copy_from(0, bytemuck::cast_slice(VBO_OFFSCREEN));
map.copy_from(std::mem::size_of::<[f32; 16]>(), bytemuck::cast_slice(VBO_DEFAULT_FINAL)); map.copy_from(
std::mem::size_of::<[f32; 16]>(),
bytemuck::cast_slice(VBO_DEFAULT_FINAL),
);
} }
} }
Ok(DrawQuad { Ok(DrawQuad {
buffer, buffer,
device: device.clone() device: device.clone(),
}) })
} }
pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: QuadType) { pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: QuadType) {
let offset = match vbo { let offset = match vbo {
QuadType::Offscreen => 0, QuadType::Offscreen => 0,
QuadType::Final => std::mem::size_of::<[f32; 16]>() QuadType::Final => std::mem::size_of::<[f32; 16]>(),
}; };
unsafe { unsafe {
self.device.cmd_bind_vertex_buffers(cmd, 0, &[self.buffer.handle], &[offset as vk::DeviceSize]) self.device.cmd_bind_vertex_buffers(
cmd,
0,
&[self.buffer.handle],
&[offset as vk::DeviceSize],
)
} }
} }
} }

View file

@ -14,10 +14,10 @@ use librashader_reflect::reflect::semantics::{
}; };
use librashader_reflect::reflect::ShaderReflection; use librashader_reflect::reflect::ShaderReflection;
use librashader_runtime::binding::{BindSemantics, TextureInput}; use librashader_runtime::binding::{BindSemantics, TextureInput};
use librashader_runtime::quad::QuadType;
use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage, UniformStorageAccess}; use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage, UniformStorageAccess};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::sync::Arc; use std::sync::Arc;
use librashader_runtime::quad::QuadType;
pub struct FilterPass { pub struct FilterPass {
pub device: Arc<ash::Device>, pub device: Arc<ash::Device>,

View file

@ -37,7 +37,6 @@ mod tests {
use crate::filter_chain::FilterChainVulkan; use crate::filter_chain::FilterChainVulkan;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::options::FilterChainOptionsVulkan; use crate::options::FilterChainOptionsVulkan;
#[test] #[test]
fn triangle_vk() { fn triangle_vk() {

View file

@ -1,7 +1,5 @@
//! Vulkan shader runtime options. //! Vulkan shader runtime options.
/// Options for each Vulkan shader frame. /// Options for each Vulkan shader frame.
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -3,7 +3,7 @@ pub enum QuadType {
/// Offscreen, intermediate passes. /// Offscreen, intermediate passes.
Offscreen, Offscreen,
/// Final pass to render target. /// Final pass to render target.
Final Final,
} }
/// Identity MVP for use in intermediate passes. /// Identity MVP for use in intermediate passes.
@ -15,7 +15,6 @@ pub static IDENTITY_MVP: &[f32; 16] = &[
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
]; ];
/// Default MVP for use when rendering to the render target. /// Default MVP for use when rendering to the render target.
#[rustfmt::skip] #[rustfmt::skip]
pub static DEFAULT_MVP: &[f32; 16] = &[ pub static DEFAULT_MVP: &[f32; 16] = &[