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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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::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 }
}
}
}
}

View file

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

View file

@ -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);
@ -207,7 +212,7 @@ impl FilterPass {
Anonymous: Default::default(),
},
}];
cmd.BeginRenderPass(Some(&pass), None, D3D12_RENDER_PASS_FLAG_NONE)
}
@ -220,7 +225,7 @@ impl FilterPass {
MinDepth: 0.0,
MaxDepth: 1.0,
}]);
cmd.RSSetScissorRects(&[RECT {
left: 0,
top: 0,
@ -232,10 +237,8 @@ impl FilterPass {
cmd.DrawInstanced(4, 1, 0, 0)
}
unsafe {
cmd.EndRenderPass()
}
unsafe { cmd.EndRenderPass() }
Ok(())
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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(())
@ -185,4 +217,4 @@ impl AsRef<InputTexture> for LutTexture {
fn as_ref(&self) -> &InputTexture {
&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::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,21 +278,21 @@ 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,
);
}
Ok(heap_slots)
}
}
}

View file

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

View file

@ -6,4 +6,3 @@ pub(crate) struct RenderTarget<'a> {
pub mvp: &'a [f32; 16],
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::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,

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 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,
}
}
}
@ -110,4 +109,4 @@ impl AsRef<InputTexture> for InputTexture {
fn as_ref(&self) -> &InputTexture {
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::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 {

View file

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

View file

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

View file

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

View file

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

View file

@ -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] = &[