fmt: run cargo fmt
This commit is contained in:
parent
7d8c137083
commit
2d2ed22e9a
|
@ -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::ShaderModel;
|
||||
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::front::GlslangCompilation;
|
||||
use crate::reflect::cross::GlslReflect;
|
||||
|
@ -19,7 +19,7 @@ impl FromCompilation<GlslangCompilation> for DXIL {
|
|||
type Options = Option<ShaderModel>;
|
||||
type Context = ();
|
||||
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
|
||||
+ ReflectShader;
|
||||
+ ReflectShader;
|
||||
|
||||
fn from_compilation(
|
||||
compile: GlslangCompilation,
|
||||
|
@ -60,26 +60,28 @@ impl CompileShader<DXIL> for WriteSpirV {
|
|||
..RuntimeConfig::default()
|
||||
};
|
||||
|
||||
|
||||
// todo: do we want to allow other entry point names?
|
||||
let vertex =
|
||||
spirv_to_dxil::spirv_to_dxil(&self.vertex,
|
||||
None, "main",
|
||||
ShaderStage::Vertex,
|
||||
sm,
|
||||
ValidatorVersion::None,
|
||||
config.clone())
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
let vertex = spirv_to_dxil::spirv_to_dxil(
|
||||
&self.vertex,
|
||||
None,
|
||||
"main",
|
||||
ShaderStage::Vertex,
|
||||
sm,
|
||||
ValidatorVersion::None,
|
||||
config.clone(),
|
||||
)
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
|
||||
|
||||
let fragment =
|
||||
spirv_to_dxil::spirv_to_dxil(&self.fragment,
|
||||
None, "main",
|
||||
ShaderStage::Fragment,
|
||||
sm,
|
||||
ValidatorVersion::None,
|
||||
config)
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
let fragment = spirv_to_dxil::spirv_to_dxil(
|
||||
&self.fragment,
|
||||
None,
|
||||
"main",
|
||||
ShaderStage::Fragment,
|
||||
sm,
|
||||
ValidatorVersion::None,
|
||||
config,
|
||||
)
|
||||
.map_err(|s| ShaderCompileError::SpirvToDxilCompileError(s))?;
|
||||
|
||||
Ok(ShaderCompilerOutput {
|
||||
vertex,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub mod cross;
|
||||
pub mod dxil;
|
||||
mod spirv;
|
||||
pub mod targets;
|
||||
pub mod dxil;
|
||||
|
||||
use crate::back::targets::OutputTarget;
|
||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::{SemanticsErrorKind, ShaderReflectError};
|
||||
use crate::front::NagaCompilation;
|
||||
use crate::front::GlslangCompilation;
|
||||
use crate::front::NagaCompilation;
|
||||
use crate::reflect::helper::SemanticErrorBlame;
|
||||
use crate::reflect::semantics::MAX_BINDINGS_COUNT;
|
||||
use naga::front::spv::Options;
|
||||
|
@ -105,9 +105,9 @@ impl NagaReflect {
|
|||
}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use rspirv::dr::Instruction;
|
||||
use rspirv::spirv::Op;
|
||||
use librashader_preprocess::ShaderSource;
|
||||
|
||||
#[test]
|
||||
pub fn test_into() {
|
||||
|
@ -118,7 +118,9 @@ mod test {
|
|||
rspirv::binary::parse_words(&compilation.vertex.as_binary(), &mut loader).unwrap();
|
||||
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)
|
||||
.collect();
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ use librashader_reflect::reflect::ShaderReflection;
|
|||
use rustc_hash::FxHashMap;
|
||||
|
||||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use windows::Win32::Graphics::Direct3D11::{
|
||||
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
|
||||
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAPPED_SUBRESOURCE,
|
||||
D3D11_MAP_WRITE_DISCARD,
|
||||
};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error;
|
||||
use crate::error::assume_d3d11_init;
|
||||
use crate::texture::{D3D11InputView};
|
||||
use crate::texture::D3D11InputView;
|
||||
use crate::util::d3d11_get_closest_format;
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
use librashader_presets::Scale2D;
|
||||
|
|
|
@ -242,7 +242,7 @@ pub mod d3d11_hello_triangle {
|
|||
|
||||
use crate::filter_chain::FilterChainD3D11;
|
||||
|
||||
use crate::options::{FilterChainOptionsD3D11};
|
||||
use crate::options::FilterChainOptionsD3D11;
|
||||
use crate::texture::{D3D11InputView, LutTexture};
|
||||
use crate::D3D11OutputView;
|
||||
use librashader_common::{FilterMode, ImageFormat, Size, Viewport, WrapMode};
|
||||
|
|
|
@ -27,10 +27,10 @@ pub use texture::D3D11OutputView;
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::env;
|
||||
use super::*;
|
||||
use crate::options::FilterChainOptionsD3D11;
|
||||
use librashader_runtime::image::{Image, UVDirection};
|
||||
use std::env;
|
||||
|
||||
// "../test/slang-shaders/scalefx/scalefx-9x.slangp",
|
||||
// "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp",
|
||||
|
@ -46,7 +46,8 @@ mod tests {
|
|||
let _ = args.next();
|
||||
let _ = args.next();
|
||||
let filter = args.next();
|
||||
let image = args.next()
|
||||
let image = args
|
||||
.next()
|
||||
.and_then(|f| Image::load(f, UVDirection::TopLeft).ok())
|
||||
.or_else(|| Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap()))
|
||||
.unwrap();
|
||||
|
@ -58,7 +59,7 @@ mod tests {
|
|||
force_no_mipmaps: false,
|
||||
}),
|
||||
// replace below with 'None' for the triangle
|
||||
Some(image)
|
||||
Some(image),
|
||||
)
|
||||
.unwrap();
|
||||
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
||||
|
@ -83,9 +84,9 @@ mod tests {
|
|||
force_no_mipmaps: false,
|
||||
}),
|
||||
// replace below with 'None' for the triangle
|
||||
None
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
// let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new(
|
||||
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
|
||||
// Some(&FilterChainOptions {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::error;
|
||||
use crate::error::assume_d3d11_init;
|
||||
use bytemuck::offset_of;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use windows::core::PCSTR;
|
||||
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
use windows::Win32::Graphics::Direct3D11::{
|
||||
|
@ -9,7 +10,6 @@ use windows::Win32::Graphics::Direct3D11::{
|
|||
D3D11_USAGE_IMMUTABLE,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::framebuffer::OutputFramebuffer;
|
||||
use crate::D3D11OutputView;
|
||||
use librashader_common::Viewport;
|
||||
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
|
||||
use librashader_runtime::quad::DEFAULT_MVP;
|
||||
use windows::Win32::Graphics::Direct3D11::D3D11_VIEWPORT;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct RenderTarget<'a> {
|
||||
|
|
|
@ -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::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 buffer: D3D12Buffer,
|
||||
|
@ -11,7 +16,7 @@ pub struct D3D12ConstantBuffer {
|
|||
|
||||
pub struct D3D12Buffer {
|
||||
handle: ID3D12Resource,
|
||||
size: usize
|
||||
size: usize,
|
||||
}
|
||||
|
||||
pub struct D3D12BufferMapHandle<'a> {
|
||||
|
@ -21,9 +26,7 @@ pub struct D3D12BufferMapHandle<'a> {
|
|||
|
||||
impl<'a> Drop for D3D12BufferMapHandle<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.handle.Unmap(0, None)
|
||||
}
|
||||
unsafe { self.handle.Unmap(0, None) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,28 +51,26 @@ impl D3D12Buffer {
|
|||
Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||
SampleDesc: DXGI_SAMPLE_DESC {
|
||||
Count: 1,
|
||||
Quality: 0
|
||||
Quality: 0,
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
None,
|
||||
&mut buffer
|
||||
&mut buffer,
|
||||
)?;
|
||||
|
||||
assume_d3d12_init!(buffer, "CreateCommittedResource");
|
||||
|
||||
Ok(D3D12Buffer {
|
||||
handle: buffer,
|
||||
size
|
||||
size,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gpu_address(&self) -> u64 {
|
||||
unsafe {
|
||||
self.handle.GetGPUVirtualAddress()
|
||||
}
|
||||
unsafe { self.handle.GetGPUVirtualAddress() }
|
||||
}
|
||||
|
||||
pub fn into_raw(self) -> ID3D12Resource {
|
||||
|
@ -77,15 +78,17 @@ impl D3D12Buffer {
|
|||
}
|
||||
|
||||
pub fn map(&mut self, range: Option<Range<usize>>) -> error::Result<D3D12BufferMapHandle> {
|
||||
let (range, size) = range.map(|range| {
|
||||
(D3D12_RANGE {
|
||||
Begin: range.start,
|
||||
End: range.end
|
||||
}, range.end - range.start)
|
||||
}).unwrap_or((D3D12_RANGE {
|
||||
Begin: 0,
|
||||
End: 0
|
||||
}, self.size));
|
||||
let (range, size) = range
|
||||
.map(|range| {
|
||||
(
|
||||
D3D12_RANGE {
|
||||
Begin: range.start,
|
||||
End: range.end,
|
||||
},
|
||||
range.end - range.start,
|
||||
)
|
||||
})
|
||||
.unwrap_or((D3D12_RANGE { Begin: 0, End: 0 }, self.size));
|
||||
|
||||
unsafe {
|
||||
let mut ptr = std::ptr::null_mut();
|
||||
|
@ -99,7 +102,6 @@ impl D3D12Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl D3D12ConstantBuffer {
|
||||
pub fn new(buffer: D3D12Buffer) -> D3D12ConstantBuffer {
|
||||
unsafe {
|
||||
|
@ -108,10 +110,7 @@ impl D3D12ConstantBuffer {
|
|||
SizeInBytes: buffer.size as u32,
|
||||
};
|
||||
|
||||
D3D12ConstantBuffer {
|
||||
buffer,
|
||||
desc,
|
||||
}
|
||||
D3D12ConstantBuffer { buffer, desc }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,13 @@ use std::marker::PhantomData;
|
|||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
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]
|
||||
pub trait D3D12HeapType {
|
||||
|
@ -108,15 +114,10 @@ impl<T> D3D12DescriptorHeapSlotInner<T> {
|
|||
/// unsafe because type must match
|
||||
pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
|
||||
unsafe {
|
||||
let heap = self.heap.deref()
|
||||
.borrow();
|
||||
let heap = self.heap.deref().borrow();
|
||||
|
||||
heap.device.CopyDescriptorsSimple(
|
||||
1,
|
||||
self.cpu_handle,
|
||||
source,
|
||||
heap.ty
|
||||
)
|
||||
heap.device
|
||||
.CopyDescriptorsSimple(1, self.cpu_handle, source, heap.ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,10 +209,16 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
/// descriptors allocated for it.
|
||||
///
|
||||
/// 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.
|
||||
assert_eq!(Rc::strong_count(&self.0), 1,
|
||||
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation.");
|
||||
assert_eq!(
|
||||
Rc::strong_count(&self.0),
|
||||
1,
|
||||
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation."
|
||||
);
|
||||
|
||||
let inner = Rc::try_unwrap(self.0)
|
||||
.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 remainder = inner.num_descriptors % size;
|
||||
|
||||
assert_eq!(remainder, 0, "D3D12DescriptorHeap::suballocate \
|
||||
must be called with a size that equally divides the number of descriptors");
|
||||
assert_eq!(
|
||||
remainder, 0,
|
||||
"D3D12DescriptorHeap::suballocate \
|
||||
must be called with a size that equally divides the number of descriptors"
|
||||
);
|
||||
|
||||
let mut heaps = Vec::new();
|
||||
|
||||
|
@ -231,19 +241,16 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
let root_gpu_ptr = inner.gpu_start.map(|p| p.ptr);
|
||||
|
||||
for _ in 0..num_heaps {
|
||||
let new_cpu_start = root_cpu_ptr + (start * inner.handle_size);
|
||||
let new_gpu_start = root_gpu_ptr
|
||||
.map(|r| D3D12_GPU_DESCRIPTOR_HANDLE {
|
||||
ptr: r + (start as u64 * inner.handle_size as u64)
|
||||
});
|
||||
let new_cpu_start = root_cpu_ptr + (start * inner.handle_size);
|
||||
let new_gpu_start = root_gpu_ptr.map(|r| D3D12_GPU_DESCRIPTOR_HANDLE {
|
||||
ptr: r + (start as u64 * inner.handle_size as u64),
|
||||
});
|
||||
|
||||
heaps.push(D3D12DescriptorHeapInner {
|
||||
device: inner.device.clone(),
|
||||
heap: inner.heap.clone(),
|
||||
ty: inner.ty,
|
||||
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE {
|
||||
ptr: new_cpu_start
|
||||
},
|
||||
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start },
|
||||
gpu_start: new_gpu_start,
|
||||
handle_size: inner.handle_size,
|
||||
start: 0,
|
||||
|
@ -254,11 +261,15 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
start += size;
|
||||
}
|
||||
|
||||
(heaps.into_iter()
|
||||
.map(|inner| D3D12DescriptorHeap(
|
||||
Rc::new(RefCell::new(inner)),
|
||||
PhantomData::default()))
|
||||
.collect(), inner.heap)
|
||||
(
|
||||
heaps
|
||||
.into_iter()
|
||||
.map(|inner| {
|
||||
D3D12DescriptorHeap(Rc::new(RefCell::new(inner)), PhantomData::default())
|
||||
})
|
||||
.collect(),
|
||||
inner.heap,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> {
|
||||
|
@ -290,7 +301,9 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
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())?;
|
||||
Ok(dest)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
use std::ops::Deref;
|
||||
use rustc_hash::FxHashMap;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Foundation::RECT;
|
||||
use windows::Win32::Graphics::Direct3D11::ID3D11Device;
|
||||
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::buffer::D3D12ConstantBuffer;
|
||||
use crate::descriptor_heap::{
|
||||
D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap,
|
||||
};
|
||||
use crate::filter_chain::FilterCommon;
|
||||
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_preprocess::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
|
@ -12,14 +16,17 @@ use librashader_reflect::reflect::ShaderReflection;
|
|||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
||||
use crate::buffer::D3D12ConstantBuffer;
|
||||
use crate::{error, util};
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::graphics_pipeline::D3D12GraphicsPipeline;
|
||||
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::{InputTexture, OutputTexture};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::ops::Deref;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Foundation::RECT;
|
||||
use windows::Win32::Graphics::Direct3D11::ID3D11Device;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4,
|
||||
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) pipeline: D3D12GraphicsPipeline,
|
||||
|
@ -32,7 +39,6 @@ pub(crate) struct FilterPass {
|
|||
pub(crate) texture_heap: [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
pub(crate) sampler_heap: [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
pub source: ShaderSource,
|
||||
|
||||
}
|
||||
|
||||
impl TextureInput for InputTexture {
|
||||
|
@ -44,8 +50,7 @@ impl TextureInput for InputTexture {
|
|||
impl BindSemantics for FilterPass {
|
||||
type InputTexture = InputTexture;
|
||||
type SamplerSet = SamplerSet;
|
||||
type DescriptorSet<'a> =
|
||||
(
|
||||
type DescriptorSet<'a> = (
|
||||
&'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
&'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
);
|
||||
|
@ -59,14 +64,16 @@ impl BindSemantics for FilterPass {
|
|||
texture: &Self::InputTexture,
|
||||
_device: &Self::DeviceContext,
|
||||
) {
|
||||
let (texture_binding,
|
||||
sampler_binding) = descriptors;
|
||||
let (texture_binding, sampler_binding) = descriptors;
|
||||
|
||||
unsafe {
|
||||
texture_binding[binding.binding as usize]
|
||||
.copy_descriptor(*texture.descriptor.as_ref());
|
||||
sampler_binding[binding.binding as usize]
|
||||
.copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).deref().as_ref())
|
||||
texture_binding[binding.binding as usize].copy_descriptor(*texture.descriptor.as_ref());
|
||||
sampler_binding[binding.binding as usize].copy_descriptor(
|
||||
*samplers
|
||||
.get(texture.wrap_mode, texture.filter)
|
||||
.deref()
|
||||
.as_ref(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +103,6 @@ impl FilterPass {
|
|||
original: &InputTexture,
|
||||
source: &InputTexture,
|
||||
) {
|
||||
|
||||
Self::bind_semantics(
|
||||
&(),
|
||||
&parent.samplers,
|
||||
|
@ -140,7 +146,6 @@ impl FilterPass {
|
|||
output: &RenderTarget,
|
||||
vbo_type: QuadType,
|
||||
) -> error::Result<()> {
|
||||
|
||||
parent.draw_quad.bind_vertices(cmd, vbo_type);
|
||||
unsafe {
|
||||
cmd.SetPipelineState(&self.pipeline.handle);
|
||||
|
@ -232,9 +237,7 @@ impl FilterPass {
|
|||
cmd.DrawInstanced(4, 1, 0, 0)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
cmd.EndRenderPass()
|
||||
}
|
||||
unsafe { cmd.EndRenderPass() }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,25 +1,36 @@
|
|||
use std::ops::Deref;
|
||||
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 windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC};
|
||||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
|
||||
use crate::error;
|
||||
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_presets::Scale2D;
|
||||
use librashader_runtime::scaling::{MipmapSize, ViewportSize};
|
||||
use crate::error;
|
||||
use crate::error::assume_d3d12_init;
|
||||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
|
||||
use crate::texture::{InputTexture, OutputTexture};
|
||||
use crate::util::d3d12_get_closest_format;
|
||||
use std::ops::Deref;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12Resource, 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,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct OwnedImage {
|
||||
pub(crate)handle: ID3D12Resource,
|
||||
pub(crate) handle: ID3D12Resource,
|
||||
pub(crate) size: Size<u32>,
|
||||
format: ImageFormat,
|
||||
device: ID3D12Device,
|
||||
max_mipmap: u16,
|
||||
}
|
||||
|
||||
|
||||
impl OwnedImage {
|
||||
pub fn new(
|
||||
device: &ID3D12Device,
|
||||
|
@ -28,7 +39,11 @@ impl OwnedImage {
|
|||
mipmap: bool,
|
||||
) -> error::Result<OwnedImage> {
|
||||
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 {
|
||||
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
Alignment: 0,
|
||||
|
@ -88,10 +103,12 @@ impl OwnedImage {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn create_shader_resource_view(&self, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputTexture> {
|
||||
|
||||
pub(crate) fn create_shader_resource_view(
|
||||
&self,
|
||||
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
filter: FilterMode,
|
||||
wrap_mode: WrapMode,
|
||||
) -> error::Result<InputTexture> {
|
||||
let descriptor = heap.alloc_slot()?;
|
||||
|
||||
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> {
|
||||
|
||||
let descriptor = heap.alloc_slot()?;
|
||||
|
||||
unsafe {
|
||||
|
@ -130,34 +158,33 @@ 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))
|
||||
}
|
||||
|
||||
pub fn scale(&mut self,
|
||||
scaling: Scale2D,
|
||||
format: ImageFormat,
|
||||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
mipmap: bool,
|
||||
) -> error::Result<Size<u32>>
|
||||
{
|
||||
pub fn scale(
|
||||
&mut self,
|
||||
scaling: Scale2D,
|
||||
format: ImageFormat,
|
||||
viewport_size: &Size<u32>,
|
||||
source_size: &Size<u32>,
|
||||
mipmap: bool,
|
||||
) -> error::Result<Size<u32>> {
|
||||
let size = source_size.scale_viewport(scaling, *viewport_size);
|
||||
if self.size != size
|
||||
|| (mipmap && self.max_mipmap == 1)
|
||||
|| (!mipmap && self.max_mipmap != 1)
|
||||
|| format != self.format
|
||||
{
|
||||
let mut new = OwnedImage::new(
|
||||
&self.device,
|
||||
size,
|
||||
format,
|
||||
mipmap
|
||||
)?;
|
||||
let mut new = OwnedImage::new(&self.device, size, format, mipmap)?;
|
||||
|
||||
std::mem::swap(self, &mut new);
|
||||
std::mem::swap(self, &mut new);
|
||||
}
|
||||
Ok(size)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,27 @@
|
|||
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
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 crate::quad_render::DrawQuad;
|
||||
use crate::{error, util};
|
||||
use librashader_reflect::back::cross::CrossHlslContext;
|
||||
use librashader_reflect::back::dxil::DxilObject;
|
||||
use librashader_reflect::back::ShaderCompilerOutput;
|
||||
use librashader_reflect::reflect::semantics::BindingStage;
|
||||
use crate::{error, util};
|
||||
use crate::quad_render::DrawQuad;
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
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(crate) handle: ID3D12PipelineState,
|
||||
|
@ -28,7 +41,7 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
RegisterSpace: 0,
|
||||
OffsetInDescriptorsFromTableStart: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
|
@ -45,11 +58,10 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
RegisterSpace: 0,
|
||||
OffsetInDescriptorsFromTableStart: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
|
||||
// UBO
|
||||
D3D12_ROOT_PARAMETER {
|
||||
ParameterType: D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||
|
@ -57,7 +69,7 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
Descriptor: D3D12_ROOT_DESCRIPTOR {
|
||||
ShaderRegister: 0,
|
||||
RegisterSpace: 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
|
||||
},
|
||||
|
@ -67,10 +79,10 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
Descriptor: D3D12_ROOT_DESCRIPTOR {
|
||||
ShaderRegister: 1,
|
||||
RegisterSpace: 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
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(crate) handle: ID3D12RootSignature
|
||||
pub(crate) handle: ID3D12RootSignature,
|
||||
}
|
||||
|
||||
impl D3D12RootSignature {
|
||||
pub fn new(device: &ID3D12Device)
|
||||
-> error::Result<D3D12RootSignature>
|
||||
{
|
||||
pub fn new(device: &ID3D12Device) -> error::Result<D3D12RootSignature> {
|
||||
let signature = unsafe {
|
||||
let mut rs_blob = None;
|
||||
// todo: D3D12SerializeVersionedRootSignature
|
||||
// todo: hlsl rootsig tbh
|
||||
D3D12SerializeRootSignature(D3D12_SLANG_ROOT_SIGNATURE,
|
||||
D3D_ROOT_SIGNATURE_VERSION_1,
|
||||
&mut rs_blob,
|
||||
None
|
||||
D3D12SerializeRootSignature(
|
||||
D3D12_SLANG_ROOT_SIGNATURE,
|
||||
D3D_ROOT_SIGNATURE_VERSION_1,
|
||||
&mut rs_blob,
|
||||
None,
|
||||
)?;
|
||||
|
||||
// SAFETY: if D3D12SerializeRootSignature succeeds then blob is Some
|
||||
let rs_blob = rs_blob.unwrap();
|
||||
let blob = std::slice::from_raw_parts(rs_blob.GetBufferPointer().cast(),
|
||||
rs_blob.GetBufferSize());
|
||||
let root_signature: ID3D12RootSignature = device.CreateRootSignature(
|
||||
0, blob
|
||||
)?;
|
||||
let blob = std::slice::from_raw_parts(
|
||||
rs_blob.GetBufferPointer().cast(),
|
||||
rs_blob.GetBufferSize(),
|
||||
);
|
||||
let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob)?;
|
||||
root_signature
|
||||
};
|
||||
|
||||
Ok(D3D12RootSignature {
|
||||
handle: signature,
|
||||
})
|
||||
Ok(D3D12RootSignature { handle: signature })
|
||||
}
|
||||
}
|
||||
impl D3D12GraphicsPipeline {
|
||||
|
@ -156,7 +165,7 @@ impl D3D12GraphicsPipeline {
|
|||
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,
|
||||
library: &IDxcUtils,
|
||||
validator: &IDxcValidator,
|
||||
shader_assembly: &ShaderCompilerOutput<DxilObject, ()>,
|
||||
root_signature: &D3D12RootSignature,
|
||||
render_format: DXGI_FORMAT,
|
||||
pub fn new_from_dxil(
|
||||
device: &ID3D12Device,
|
||||
library: &IDxcUtils,
|
||||
validator: &IDxcValidator,
|
||||
shader_assembly: &ShaderCompilerOutput<DxilObject, ()>,
|
||||
root_signature: &D3D12RootSignature,
|
||||
render_format: DXGI_FORMAT,
|
||||
) -> error::Result<D3D12GraphicsPipeline> {
|
||||
if shader_assembly.vertex.requires_runtime_data() {
|
||||
panic!("vertex needs rt data??")
|
||||
|
@ -212,29 +222,48 @@ impl D3D12GraphicsPipeline {
|
|||
if shader_assembly.fragment.requires_runtime_data() {
|
||||
panic!("fragment needs rt data??")
|
||||
}
|
||||
let vertex_dxil =
|
||||
util::dxc_validate_shader(library, validator, &shader_assembly.vertex)?;
|
||||
let vertex_dxil = util::dxc_validate_shader(library, validator, &shader_assembly.vertex)?;
|
||||
let fragment_dxil =
|
||||
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,
|
||||
library: &IDxcUtils,
|
||||
dxc: &IDxcCompiler,
|
||||
shader_assembly: &ShaderCompilerOutput<String, CrossHlslContext>,
|
||||
root_signature: &D3D12RootSignature,
|
||||
render_format: DXGI_FORMAT,
|
||||
pub fn new_from_hlsl(
|
||||
device: &ID3D12Device,
|
||||
library: &IDxcUtils,
|
||||
dxc: &IDxcCompiler,
|
||||
shader_assembly: &ShaderCompilerOutput<String, CrossHlslContext>,
|
||||
root_signature: &D3D12RootSignature,
|
||||
render_format: DXGI_FORMAT,
|
||||
) -> error::Result<D3D12GraphicsPipeline> {
|
||||
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)?;
|
||||
let fragment_dxil =
|
||||
util::dxc_compile_shader(library, dxc,&shader_assembly.fragment, BindingStage::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,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -237,13 +237,13 @@ unsafe extern "system" fn debug_log(
|
|||
}
|
||||
|
||||
pub mod d3d12_hello_triangle {
|
||||
use std::ops::Deref;
|
||||
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::filter_chain::FilterChainD3D12;
|
||||
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;
|
||||
|
||||
|
@ -252,7 +252,7 @@ pub mod d3d12_hello_triangle {
|
|||
device: ID3D12Device,
|
||||
resources: Option<Resources>,
|
||||
pub filter: FilterChainD3D12,
|
||||
framecount: usize
|
||||
framecount: usize,
|
||||
}
|
||||
|
||||
struct Resources {
|
||||
|
@ -278,7 +278,7 @@ pub mod d3d12_hello_triangle {
|
|||
fence: ID3D12Fence,
|
||||
fence_value: u64,
|
||||
fence_event: HANDLE,
|
||||
frambuffer_heap: D3D12DescriptorHeap<CpuStagingHeap>
|
||||
frambuffer_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
}
|
||||
|
||||
impl DXSample for Sample {
|
||||
|
@ -305,7 +305,7 @@ pub mod d3d12_hello_triangle {
|
|||
device,
|
||||
resources: None,
|
||||
filter,
|
||||
framecount: 0
|
||||
framecount: 0,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -394,9 +394,13 @@ pub mod d3d12_hello_triangle {
|
|||
render_target.GetHeapProperties(Some(&mut heapprops), Some(&mut heappflags))?;
|
||||
desc.Flags &= !D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE;
|
||||
let mut fb = None;
|
||||
self.device.CreateCommittedResource(&heapprops, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
None, &mut fb
|
||||
self.device.CreateCommittedResource(
|
||||
&heapprops,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&desc,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
None,
|
||||
&mut fb,
|
||||
)?;
|
||||
|
||||
fb.unwrap()
|
||||
|
@ -487,24 +491,33 @@ pub mod d3d12_hello_triangle {
|
|||
|
||||
fn render(&mut self) {
|
||||
if let Some(resources) = &mut self.resources {
|
||||
let srv = resources.frambuffer_heap.alloc_slot()
|
||||
.unwrap();
|
||||
let srv = resources.frambuffer_heap.alloc_slot().unwrap();
|
||||
|
||||
unsafe {
|
||||
self.device.CreateShaderResourceView(&resources.framebuffer, Some(&D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
|
||||
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||
Texture2D: D3D12_TEX2D_SRV {
|
||||
MipLevels: u32::MAX,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
}), *srv.deref().as_ref())
|
||||
self.device.CreateShaderResourceView(
|
||||
&resources.framebuffer,
|
||||
Some(&D3D12_SHADER_RESOURCE_VIEW_DESC {
|
||||
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
|
||||
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
|
||||
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||
Texture2D: D3D12_TEX2D_SRV {
|
||||
MipLevels: u32::MAX,
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
}),
|
||||
*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.
|
||||
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,
|
||||
frame_count: usize,
|
||||
fn populate_command_list(
|
||||
resources: &mut Resources,
|
||||
filter: &mut FilterChainD3D12,
|
||||
frame_count: usize,
|
||||
framebuffer: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
) -> Result<()> {
|
||||
// Command list allocators can only be reset when the associated
|
||||
|
@ -583,8 +598,10 @@ pub mod d3d12_hello_triangle {
|
|||
}
|
||||
|
||||
unsafe {
|
||||
command_list.CopyResource(&resources.framebuffer,
|
||||
&resources.render_targets[resources.frame_index as usize]);
|
||||
command_list.CopyResource(
|
||||
&resources.framebuffer,
|
||||
&resources.render_targets[resources.frame_index as usize],
|
||||
);
|
||||
command_list.ResourceBarrier(&[transition_barrier(
|
||||
&resources.framebuffer,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
|
@ -597,21 +614,35 @@ pub mod d3d12_hello_triangle {
|
|||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
)]);
|
||||
|
||||
filter.frame(
|
||||
command_list,
|
||||
InputTexture::new_from_raw(framebuffer,
|
||||
Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32),
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
WrapMode::ClampToEdge,
|
||||
FilterMode::Linear,
|
||||
),
|
||||
&Viewport {
|
||||
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();
|
||||
filter
|
||||
.frame(
|
||||
command_list,
|
||||
InputTexture::new_from_raw(
|
||||
framebuffer,
|
||||
Size::new(
|
||||
resources.viewport.Width as u32,
|
||||
resources.viewport.Height as u32,
|
||||
),
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
WrapMode::ClampToEdge,
|
||||
FilterMode::Linear,
|
||||
),
|
||||
&Viewport {
|
||||
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(
|
||||
&resources.render_targets[resources.frame_index as usize],
|
||||
|
@ -620,8 +651,6 @@ pub mod d3d12_hello_triangle {
|
|||
)]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsafe { command_list.Close() }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#![feature(const_trait_impl)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
mod buffer;
|
||||
mod descriptor_heap;
|
||||
mod error;
|
||||
mod filter_chain;
|
||||
mod descriptor_heap;
|
||||
mod hello_triangle;
|
||||
mod samplers;
|
||||
mod luts;
|
||||
mod util;
|
||||
mod mipmap;
|
||||
mod filter_pass;
|
||||
mod quad_render;
|
||||
mod graphics_pipeline;
|
||||
mod buffer;
|
||||
mod framebuffer;
|
||||
mod texture;
|
||||
mod graphics_pipeline;
|
||||
mod hello_triangle;
|
||||
mod luts;
|
||||
mod mipmap;
|
||||
mod quad_render;
|
||||
mod render_target;
|
||||
mod samplers;
|
||||
mod texture;
|
||||
mod util;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -1,15 +1,28 @@
|
|||
use std::ops::Deref;
|
||||
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
|
||||
use crate::error;
|
||||
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 librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||
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 crate::mipmap::{MipmapGenContext};
|
||||
use crate::texture::InputTexture;
|
||||
use std::ops::Deref;
|
||||
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 {
|
||||
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 {
|
||||
|
@ -148,12 +165,21 @@ impl LutTexture {
|
|||
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,
|
||||
&upload, 0, 0, 1, &subresource)?;
|
||||
d3d12_update_subresources(cmd, &resource, &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(
|
||||
|
@ -163,18 +189,24 @@ impl LutTexture {
|
|||
wrap_mode,
|
||||
filter,
|
||||
);
|
||||
Ok((LutTexture {
|
||||
resource,
|
||||
view,
|
||||
miplevels: if mipmap { Some(miplevels) } else { None }
|
||||
}, upload))
|
||||
Ok((
|
||||
LutTexture {
|
||||
resource,
|
||||
view,
|
||||
miplevels: if mipmap { Some(miplevels) } else { None },
|
||||
},
|
||||
upload,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> {
|
||||
if let Some(miplevels) = self.miplevels {
|
||||
gen_mips.generate_mipmaps(&self.resource,
|
||||
miplevels,
|
||||
self.view.size, ImageFormat::R8G8B8A8Unorm.into())?
|
||||
gen_mips.generate_mipmaps(
|
||||
&self.resource,
|
||||
miplevels,
|
||||
self.view.size,
|
||||
ImageFormat::R8G8B8A8Unorm.into(),
|
||||
)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -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::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 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"
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
|
@ -71,23 +79,36 @@ pub struct MipmapGenContext<'a> {
|
|||
gen: &'a D3D12MipmapGen,
|
||||
cmd: &'a ID3D12GraphicsCommandList,
|
||||
heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
residuals: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>
|
||||
residuals: Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>,
|
||||
}
|
||||
|
||||
impl <'a> MipmapGenContext<'a> {
|
||||
fn new(gen: &'a D3D12MipmapGen, cmd: &'a ID3D12GraphicsCommandList, heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>) -> MipmapGenContext<'a> {
|
||||
impl<'a> MipmapGenContext<'a> {
|
||||
fn new(
|
||||
gen: &'a D3D12MipmapGen,
|
||||
cmd: &'a ID3D12GraphicsCommandList,
|
||||
heap: &'a mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
) -> MipmapGenContext<'a> {
|
||||
Self {
|
||||
gen, cmd, heap, residuals: Vec::new()
|
||||
gen,
|
||||
cmd,
|
||||
heap,
|
||||
residuals: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a set of mipmaps for the resource.
|
||||
/// 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)
|
||||
-> error::Result<()>
|
||||
{
|
||||
pub fn generate_mipmaps(
|
||||
&mut self,
|
||||
resource: &ID3D12Resource,
|
||||
miplevels: u16,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
) -> error::Result<()> {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -103,14 +124,15 @@ impl D3D12MipmapGen {
|
|||
pub fn new(device: &ID3D12Device) -> error::Result<D3D12MipmapGen> {
|
||||
unsafe {
|
||||
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 desc = D3D12_COMPUTE_PIPELINE_STATE_DESC {
|
||||
pRootSignature: windows::core::ManuallyDrop::new(&root_signature),
|
||||
CS: D3D12_SHADER_BYTECODE {
|
||||
pShaderBytecode: blob.as_ptr().cast(),
|
||||
BytecodeLength: blob.len()
|
||||
BytecodeLength: blob.len(),
|
||||
},
|
||||
NodeMask: 0,
|
||||
..Default::default()
|
||||
|
@ -129,10 +151,14 @@ impl D3D12MipmapGen {
|
|||
/// Enters a mipmapping compute context.
|
||||
/// This is a relatively expensive operation
|
||||
/// 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)
|
||||
-> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>>
|
||||
where
|
||||
F: FnMut(&mut MipmapGenContext)
|
||||
pub fn mipmapping_context<F>(
|
||||
&self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
mut f: F,
|
||||
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>>
|
||||
where
|
||||
F: FnMut(&mut MipmapGenContext),
|
||||
{
|
||||
let heap: ID3D12DescriptorHeap = (&(*work_heap)).into();
|
||||
unsafe {
|
||||
|
@ -149,15 +175,16 @@ impl D3D12MipmapGen {
|
|||
/// SAFETY:
|
||||
/// - handle must be a CPU handle to an SRV
|
||||
/// - work_heap must have enough descriptors to fit all miplevels.
|
||||
unsafe fn generate_mipmaps(&self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
resource: &ID3D12Resource,
|
||||
unsafe fn generate_mipmaps(
|
||||
&self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
resource: &ID3D12Resource,
|
||||
|
||||
miplevels: u16,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>>
|
||||
{
|
||||
miplevels: u16,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> {
|
||||
// create views for mipmap generation
|
||||
let srv = work_heap.alloc_slot()?;
|
||||
{
|
||||
|
@ -173,8 +200,8 @@ impl D3D12MipmapGen {
|
|||
},
|
||||
};
|
||||
|
||||
self.device.CreateShaderResourceView(resource,
|
||||
Some(&srv_desc), *srv.deref().as_ref());
|
||||
self.device
|
||||
.CreateShaderResourceView(resource, Some(&srv_desc), *srv.deref().as_ref());
|
||||
}
|
||||
|
||||
let mut heap_slots = Vec::with_capacity(miplevels as usize);
|
||||
|
@ -189,12 +216,15 @@ impl D3D12MipmapGen {
|
|||
Texture2D: D3D12_TEX2D_UAV {
|
||||
MipSlice: i as u32,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
self.device.CreateUnorderedAccessView(resource, None,
|
||||
Some(&desc), *descriptor.deref().as_ref()
|
||||
self.device.CreateUnorderedAccessView(
|
||||
resource,
|
||||
None,
|
||||
Some(&desc),
|
||||
*descriptor.deref().as_ref(),
|
||||
);
|
||||
heap_slots.push(descriptor);
|
||||
}
|
||||
|
@ -204,35 +234,41 @@ impl D3D12MipmapGen {
|
|||
for i in 1..miplevels as u32 {
|
||||
let scaled = size.scale_mipmap(i);
|
||||
let mipmap_params = MipConstants {
|
||||
inv_out_texel_size: [
|
||||
1.0 / scaled.width as f32,
|
||||
1.0 / scaled.height as f32
|
||||
],
|
||||
inv_out_texel_size: [1.0 / scaled.width as f32, 1.0 / scaled.height as f32],
|
||||
src_mip_index: (i - 1),
|
||||
};
|
||||
|
||||
let mipmap_params = bytemuck::bytes_of(&mipmap_params);
|
||||
|
||||
|
||||
util::d3d12_resource_transition_subresource(cmd, resource,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
i - 1
|
||||
util::d3d12_resource_transition_subresource(
|
||||
cmd,
|
||||
resource,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
i - 1,
|
||||
);
|
||||
|
||||
util::d3d12_resource_transition_subresource(cmd, resource,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
i
|
||||
util::d3d12_resource_transition_subresource(
|
||||
cmd,
|
||||
resource,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
i,
|
||||
);
|
||||
|
||||
cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref());
|
||||
cmd.SetComputeRoot32BitConstants(2,
|
||||
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
|
||||
mipmap_params.as_ptr().cast(),
|
||||
0);
|
||||
cmd.SetComputeRoot32BitConstants(
|
||||
2,
|
||||
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
|
||||
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.
|
||||
|
||||
|
@ -242,18 +278,18 @@ impl D3D12MipmapGen {
|
|||
|
||||
let barrier = [D3D12_RESOURCE_BARRIER {
|
||||
Type: D3D12_RESOURCE_BARRIER_TYPE_UAV,
|
||||
Anonymous: D3D12_RESOURCE_BARRIER_0 {
|
||||
UAV: uav_barrier
|
||||
},
|
||||
Anonymous: D3D12_RESOURCE_BARRIER_0 { UAV: uav_barrier },
|
||||
..Default::default()
|
||||
}];
|
||||
|
||||
cmd.ResourceBarrier(&barrier);
|
||||
|
||||
util::d3d12_resource_transition_subresource(cmd, resource,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
i
|
||||
util::d3d12_resource_transition_subresource(
|
||||
cmd,
|
||||
resource,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
i,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
use crate::buffer::D3D12Buffer;
|
||||
use crate::error;
|
||||
use bytemuck::{offset_of, Pod, Zeroable};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use windows::core::PCSTR;
|
||||
use windows::w;
|
||||
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::Direct3D::D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
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 librashader_runtime::quad::QuadType;
|
||||
use crate::buffer::{D3D12Buffer};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Default, Zeroable, Pod)]
|
||||
|
@ -47,13 +50,14 @@ pub(crate) struct DrawQuad {
|
|||
}
|
||||
|
||||
impl DrawQuad {
|
||||
pub fn new(device: &ID3D12Device)
|
||||
-> error::Result<DrawQuad> {
|
||||
pub fn new(device: &ID3D12Device) -> error::Result<DrawQuad> {
|
||||
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)?;
|
||||
buffer.map(None)?
|
||||
.slice.copy_from_slice(bytemuck::cast_slice(QUAD_VBO_DATA));
|
||||
buffer
|
||||
.map(None)?
|
||||
.slice
|
||||
.copy_from_slice(bytemuck::cast_slice(QUAD_VBO_DATA));
|
||||
|
||||
let view = D3D12_VERTEX_BUFFER_VIEW {
|
||||
BufferLocation: buffer.gpu_address(),
|
||||
|
@ -62,13 +66,10 @@ impl DrawQuad {
|
|||
};
|
||||
|
||||
let buffer = buffer.into_raw();
|
||||
unsafe {
|
||||
unsafe {
|
||||
buffer.SetName(w!("drawquad"))?;
|
||||
}
|
||||
Ok(DrawQuad {
|
||||
buffer,
|
||||
view
|
||||
})
|
||||
Ok(DrawQuad { buffer, view })
|
||||
}
|
||||
|
||||
pub fn bind_vertices(&self, cmd: &ID3D12GraphicsCommandList, _vbo_type: QuadType) {
|
||||
|
|
|
@ -6,4 +6,3 @@ pub(crate) struct RenderTarget<'a> {
|
|||
pub mvp: &'a [f32; 16],
|
||||
pub output: OutputTexture,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::ops::Deref;
|
||||
use crate::error;
|
||||
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
|
||||
use crate::error;
|
||||
use librashader_common::{FilterMode, WrapMode};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::ops::Deref;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, D3D12_COMPARISON_FUNC_NEVER, D3D12_FLOAT32_MAX, D3D12_SAMPLER_DESC,
|
||||
D3D12_TEXTURE_ADDRESS_MODE,
|
||||
|
|
|
@ -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 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)]
|
||||
pub(crate) enum InputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum OutputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>),
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE),
|
||||
}
|
||||
|
||||
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
|
||||
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
|
||||
match self {
|
||||
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 {
|
||||
match self {
|
||||
OutputDescriptor::Owned(h) => h.deref().as_ref(),
|
||||
OutputDescriptor::Raw(h) => h
|
||||
OutputDescriptor::Raw(h) => h,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,25 +41,21 @@ pub struct OutputTexture {
|
|||
}
|
||||
|
||||
impl OutputTexture {
|
||||
pub fn new(handle: D3D12DescriptorHeapSlot<RenderTargetHeap>,
|
||||
size: Size<u32>,
|
||||
) -> OutputTexture {
|
||||
pub fn new(
|
||||
handle: D3D12DescriptorHeapSlot<RenderTargetHeap>,
|
||||
size: Size<u32>,
|
||||
) -> OutputTexture {
|
||||
let descriptor = OutputDescriptor::Owned(handle);
|
||||
OutputTexture {
|
||||
descriptor,
|
||||
size,
|
||||
}
|
||||
OutputTexture { descriptor, size }
|
||||
}
|
||||
|
||||
// unsafe since the lifetime of the handle has to survive
|
||||
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
size: Size<u32>,
|
||||
pub unsafe fn new_from_raw(
|
||||
handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
size: Size<u32>,
|
||||
) -> OutputTexture {
|
||||
let descriptor = OutputDescriptor::Raw(handle);
|
||||
OutputTexture {
|
||||
descriptor,
|
||||
size,
|
||||
}
|
||||
OutputTexture { descriptor, size }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,31 +65,34 @@ pub struct InputTexture {
|
|||
pub(crate) size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
pub(crate) wrap_mode: WrapMode,
|
||||
pub(crate) filter: FilterMode
|
||||
pub(crate) filter: FilterMode,
|
||||
}
|
||||
|
||||
impl InputTexture {
|
||||
pub fn new(handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||
size: Size<u32>,
|
||||
format: ImageFormat,
|
||||
wrap_mode: WrapMode,
|
||||
filter: FilterMode) -> InputTexture {
|
||||
pub fn new(
|
||||
handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||
size: Size<u32>,
|
||||
format: ImageFormat,
|
||||
wrap_mode: WrapMode,
|
||||
filter: FilterMode,
|
||||
) -> InputTexture {
|
||||
let srv = InputDescriptor::Owned(handle);
|
||||
InputTexture {
|
||||
descriptor: srv,
|
||||
size,
|
||||
format: format.into(),
|
||||
wrap_mode,
|
||||
filter
|
||||
filter,
|
||||
}
|
||||
}
|
||||
|
||||
// unsafe since the lifetime of the handle has to survive
|
||||
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
wrap_mode: WrapMode,
|
||||
filter: FilterMode
|
||||
pub unsafe fn new_from_raw(
|
||||
handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
size: Size<u32>,
|
||||
format: DXGI_FORMAT,
|
||||
wrap_mode: WrapMode,
|
||||
filter: FilterMode,
|
||||
) -> InputTexture {
|
||||
let srv = InputDescriptor::Raw(handle);
|
||||
InputTexture {
|
||||
|
@ -101,7 +100,7 @@ impl InputTexture {
|
|||
size,
|
||||
format,
|
||||
wrap_mode,
|
||||
filter
|
||||
filter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::mem::ManuallyDrop;
|
||||
use std::u64;
|
||||
use crate::error;
|
||||
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::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::Direct3D::Dxc::{DXC_CP, DXC_CP_UTF8, DxcValidatorFlags_Default, DxcValidatorFlags_InPlaceEdit, DxcValidatorFlags_ModuleOnly, DxcValidatorFlags_ValidMask, IDxcBlob, IDxcBlobUtf8, IDxcCompiler, IDxcLibrary, IDxcUtils, IDxcValidator};
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
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 librashader_reflect::reflect::semantics::BindingStage;
|
||||
use crate::error::assume_d3d12_init;
|
||||
|
||||
/// wtf retroarch?
|
||||
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,
|
||||
PCSTR(entry.as_ptr()),
|
||||
PCSTR(version.as_ptr()),
|
||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
|
||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,
|
||||
// if cfg!(feature = "debug-shader") {
|
||||
// D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
|
||||
// } else {
|
||||
|
@ -146,20 +160,22 @@ pub fn fxc_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> error:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn dxc_compile_shader(library: &IDxcUtils, compiler: &IDxcCompiler, source: &String, profile: BindingStage) -> error::Result<IDxcBlob> {
|
||||
pub fn dxc_compile_shader(
|
||||
library: &IDxcUtils,
|
||||
compiler: &IDxcCompiler,
|
||||
source: &String,
|
||||
profile: BindingStage,
|
||||
) -> error::Result<IDxcBlob> {
|
||||
// todo: compile with dxc
|
||||
// let mut source = source.to_vec();
|
||||
|
||||
let include = unsafe {
|
||||
library.CreateDefaultIncludeHandler()?
|
||||
};
|
||||
let include = unsafe { library.CreateDefaultIncludeHandler()? };
|
||||
|
||||
let blob = unsafe {
|
||||
library.CreateBlobFromPinned(
|
||||
source.as_ptr().cast(),
|
||||
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 {
|
||||
let result = compiler.Compile(&blob,
|
||||
let result = compiler.Compile(
|
||||
&blob,
|
||||
PCWSTR::null(),
|
||||
windows::w!("main"),
|
||||
profile,
|
||||
None,
|
||||
&[],
|
||||
&include
|
||||
&include,
|
||||
)?;
|
||||
|
||||
if let Ok(buf) = result.GetErrorBuffer() {
|
||||
unsafe {
|
||||
let buf: IDxcBlobUtf8 = buf.cast().unwrap();
|
||||
let buf = std::slice::from_raw_parts(buf.GetBufferPointer()
|
||||
.cast(), buf.GetBufferSize());
|
||||
let buf =
|
||||
std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize());
|
||||
let str = std::str::from_utf8_unchecked(buf);
|
||||
if str.len() != 0 {
|
||||
eprintln!("{}", str);
|
||||
|
@ -196,26 +213,27 @@ pub fn dxc_compile_shader(library: &IDxcUtils, compiler: &IDxcCompiler, source:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn dxc_validate_shader(library: &IDxcUtils, validator: &IDxcValidator, source: &[u8]) -> error::Result<IDxcBlob> {
|
||||
pub fn dxc_validate_shader(
|
||||
library: &IDxcUtils,
|
||||
validator: &IDxcValidator,
|
||||
source: &[u8],
|
||||
) -> error::Result<IDxcBlob> {
|
||||
// todo: compile with dxc
|
||||
// let mut source = source.to_vec();
|
||||
|
||||
let blob = unsafe {
|
||||
library.CreateBlob(source.as_ptr().cast(),
|
||||
source.len() as u32,
|
||||
DXC_CP(0))?
|
||||
};
|
||||
let blob =
|
||||
unsafe { library.CreateBlob(source.as_ptr().cast(), source.len() as u32, DXC_CP(0))? };
|
||||
|
||||
unsafe {
|
||||
let result = validator
|
||||
.Validate(&blob, DxcValidatorFlags_InPlaceEdit).unwrap();
|
||||
.Validate(&blob, DxcValidatorFlags_InPlaceEdit)
|
||||
.unwrap();
|
||||
|
||||
if let Ok(buf) = result.GetErrorBuffer() {
|
||||
unsafe {
|
||||
let buf: IDxcBlobUtf8 = buf.cast().unwrap();
|
||||
let buf = std::slice::from_raw_parts(buf.GetBufferPointer()
|
||||
.cast(), buf.GetBufferSize());
|
||||
let buf =
|
||||
std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize());
|
||||
let str = std::str::from_utf8_unchecked(buf);
|
||||
if str.len() != 0 {
|
||||
eprintln!("{}", str);
|
||||
|
@ -227,21 +245,28 @@ pub fn dxc_validate_shader(library: &IDxcUtils, validator: &IDxcValidator, sourc
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn d3d12_resource_transition(cmd: &ID3D12GraphicsCommandList,
|
||||
pub fn d3d12_resource_transition(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
resource: &ID3D12Resource,
|
||||
before: 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)]
|
||||
pub fn d3d12_resource_transition_subresource(cmd: &ID3D12GraphicsCommandList,
|
||||
resource: &ID3D12Resource,
|
||||
before: D3D12_RESOURCE_STATES,
|
||||
after: D3D12_RESOURCE_STATES,
|
||||
subresource: u32
|
||||
pub fn d3d12_resource_transition_subresource(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
resource: &ID3D12Resource,
|
||||
before: D3D12_RESOURCE_STATES,
|
||||
after: D3D12_RESOURCE_STATES,
|
||||
subresource: u32,
|
||||
) {
|
||||
let barrier = [D3D12_RESOURCE_BARRIER {
|
||||
Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
||||
|
@ -252,24 +277,22 @@ pub fn d3d12_resource_transition_subresource(cmd: &ID3D12GraphicsCommandList,
|
|||
Subresource: subresource,
|
||||
StateBefore: before,
|
||||
StateAfter: after,
|
||||
})
|
||||
}),
|
||||
},
|
||||
}];
|
||||
|
||||
unsafe {
|
||||
cmd.ResourceBarrier(&barrier)
|
||||
}
|
||||
unsafe { cmd.ResourceBarrier(&barrier) }
|
||||
}
|
||||
|
||||
pub fn d3d12_update_subresources(cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
intermediate_offset: u64,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
source: &[D3D12_SUBRESOURCE_DATA]
|
||||
pub fn d3d12_update_subresources(
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
destination_resource: &ID3D12Resource,
|
||||
intermediate_resource: &ID3D12Resource,
|
||||
intermediate_offset: u64,
|
||||
first_subresouce: u32,
|
||||
num_subresources: u32,
|
||||
source: &[D3D12_SUBRESOURCE_DATA],
|
||||
) -> error::Result<u64> {
|
||||
|
||||
// let allocation_size = std::mem::size_of::<D3D12_PLACED_SUBRESOURCE_FOOTPRINT>()
|
||||
// + std::mem::size_of::<u32>()
|
||||
// + std::mem::size_of::<u64>() * num_subresources;
|
||||
|
@ -280,10 +303,10 @@ pub fn d3d12_update_subresources(cmd: &ID3D12GraphicsCommandList,
|
|||
destination_resource.GetDevice(&mut device)?;
|
||||
assume_d3d12_init!(device, "GetDevice");
|
||||
|
||||
|
||||
let mut layouts = vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); num_subresources as usize];
|
||||
let mut layouts =
|
||||
vec![D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); 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;
|
||||
// texture upload
|
||||
unsafe {
|
||||
|
@ -329,18 +352,15 @@ fn update_subresources(
|
|||
) -> error::Result<u64> {
|
||||
// ToDo: implement validation as in the original function
|
||||
|
||||
|
||||
unsafe {
|
||||
let mut data = std::ptr::null_mut();
|
||||
intermediate_resource.Map(0, None, Some(&mut data))?;
|
||||
|
||||
for i in 0..num_subresources as usize {
|
||||
let dest_data = D3D12_MEMCPY_DEST {
|
||||
pData: data.offset(layouts[i].Offset as isize)
|
||||
as *mut std::ffi::c_void,
|
||||
pData: data.offset(layouts[i].Offset as isize) as *mut std::ffi::c_void,
|
||||
RowPitch: layouts[i].Footprint.RowPitch as usize,
|
||||
SlicePitch: ((layouts[i].Footprint.RowPitch)
|
||||
* num_rows[i]) as usize,
|
||||
SlicePitch: ((layouts[i].Footprint.RowPitch) * num_rows[i]) as usize,
|
||||
};
|
||||
|
||||
memcpy_subresource(
|
||||
|
@ -366,12 +386,11 @@ fn update_subresources(
|
|||
);
|
||||
} else {
|
||||
for i in 0..num_subresources as usize {
|
||||
|
||||
let dest_location = D3D12_TEXTURE_COPY_LOCATION {
|
||||
pResource: windows::core::ManuallyDrop::new(destination_resource),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
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),
|
||||
Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||
Anonymous: D3D12_TEXTURE_COPY_LOCATION_0 {
|
||||
PlacedFootprint: layouts[i]
|
||||
PlacedFootprint: layouts[i],
|
||||
},
|
||||
};
|
||||
|
||||
cmd.CopyTextureRegion(
|
||||
&dest_location,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&source_location,
|
||||
None,
|
||||
);
|
||||
cmd.CopyTextureRegion(&dest_location, 0, 0, 0, &source_location, None);
|
||||
}
|
||||
}
|
||||
Ok(required_size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// this function should not leak to the public API, so
|
||||
|
@ -407,9 +418,8 @@ unsafe fn memcpy_subresource(
|
|||
num_rows: u32,
|
||||
num_slices: u32,
|
||||
) {
|
||||
for z in 0..num_slices as usize {
|
||||
let dest_slice =
|
||||
dest.pData.add(dest.SlicePitch * z);
|
||||
for z in 0..num_slices as usize {
|
||||
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 {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::sync::Arc;
|
||||
use ash::vk;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use crate::error;
|
||||
use crate::vulkan_primitives::VulkanBuffer;
|
||||
use ash::vk;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[rustfmt::skip]
|
||||
static VBO_OFFSCREEN: &[f32; 16] = &[
|
||||
|
@ -24,34 +24,50 @@ static VBO_DEFAULT_FINAL: &[f32; 16] = &[
|
|||
|
||||
pub struct DrawQuad {
|
||||
buffer: VulkanBuffer,
|
||||
device: Arc<ash::Device>
|
||||
device: Arc<ash::Device>,
|
||||
}
|
||||
|
||||
impl DrawQuad {
|
||||
pub fn new(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]>())?;
|
||||
pub fn new(
|
||||
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()?;
|
||||
unsafe {
|
||||
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 {
|
||||
buffer,
|
||||
device: device.clone()
|
||||
device: device.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bind_vbo(&self, cmd: vk::CommandBuffer, vbo: QuadType) {
|
||||
let offset = match vbo {
|
||||
QuadType::Offscreen => 0,
|
||||
QuadType::Final => std::mem::size_of::<[f32; 16]>()
|
||||
QuadType::Final => std::mem::size_of::<[f32; 16]>(),
|
||||
};
|
||||
|
||||
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],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,10 +14,10 @@ use librashader_reflect::reflect::semantics::{
|
|||
};
|
||||
use librashader_reflect::reflect::ShaderReflection;
|
||||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||
use librashader_runtime::quad::QuadType;
|
||||
use librashader_runtime::uniforms::{NoUniformBinder, UniformStorage, UniformStorageAccess};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::sync::Arc;
|
||||
use librashader_runtime::quad::QuadType;
|
||||
|
||||
pub struct FilterPass {
|
||||
pub device: Arc<ash::Device>,
|
||||
|
|
|
@ -38,7 +38,6 @@ mod tests {
|
|||
use crate::hello_triangle::vulkan_base::VulkanBase;
|
||||
use crate::options::FilterChainOptionsVulkan;
|
||||
|
||||
|
||||
#[test]
|
||||
fn triangle_vk() {
|
||||
let entry = unsafe { ash::Entry::load().unwrap() };
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//! Vulkan shader runtime options.
|
||||
|
||||
|
||||
|
||||
/// Options for each Vulkan shader frame.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -3,7 +3,7 @@ pub enum QuadType {
|
|||
/// Offscreen, intermediate passes.
|
||||
Offscreen,
|
||||
/// Final pass to render target.
|
||||
Final
|
||||
Final,
|
||||
}
|
||||
|
||||
/// 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,
|
||||
];
|
||||
|
||||
|
||||
/// Default MVP for use when rendering to the render target.
|
||||
#[rustfmt::skip]
|
||||
pub static DEFAULT_MVP: &[f32; 16] = &[
|
||||
|
|
Loading…
Reference in a new issue