d3d12: run final pass

This commit is contained in:
chyyran 2023-02-01 18:09:34 -05:00
parent dada615a0a
commit e66c2a628f
10 changed files with 115 additions and 64 deletions

View file

@ -2,6 +2,7 @@ use crate::error;
use std::cell::RefCell; use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_RTV}; use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_RTV};
@ -88,22 +89,24 @@ impl const D3D12HeapType for SamplerWorkHeap {
} }
} }
pub struct D3D12DescriptorHeapSlot<T> { pub type D3D12DescriptorHeapSlot<T> = Rc<D3D12DescriptorHeapSlotInner<T>>;
pub struct D3D12DescriptorHeapSlotInner<T> {
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
heap: Arc<RefCell<D3D12DescriptorHeapInner>>, heap: Rc<RefCell<D3D12DescriptorHeapInner>>,
slot: usize, slot: usize,
_pd: PhantomData<T>, _pd: PhantomData<T>,
} }
impl<T> D3D12DescriptorHeapSlot<T> { impl<T> D3D12DescriptorHeapSlotInner<T> {
/// Get the index of the resource within the heap. /// Get the index of the resource within the heap.
pub fn index(&self) -> usize { pub fn index(&self) -> usize {
self.slot self.slot
} }
/// unsafe because type must match /// unsafe because type must match
pub unsafe fn copy_descriptor(&mut self, source: D3D12_CPU_DESCRIPTOR_HANDLE) { pub unsafe fn copy_descriptor(&self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
unsafe { unsafe {
let heap = self.heap.deref() let heap = self.heap.deref()
.borrow(); .borrow();
@ -118,14 +121,14 @@ impl<T> D3D12DescriptorHeapSlot<T> {
} }
} }
impl<T> AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for D3D12DescriptorHeapSlot<T> { impl<T> AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for D3D12DescriptorHeapSlotInner<T> {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
&self.cpu_handle &self.cpu_handle
} }
} }
impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE> impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE>
for D3D12DescriptorHeapSlot<T> for D3D12DescriptorHeapSlotInner<T>
{ {
fn as_ref(&self) -> &D3D12_GPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_GPU_DESCRIPTOR_HANDLE {
self.gpu_handle.as_ref().unwrap() self.gpu_handle.as_ref().unwrap()
@ -157,7 +160,7 @@ struct D3D12DescriptorHeapInner {
map: Box<[bool]>, map: Box<[bool]>,
} }
pub struct D3D12DescriptorHeap<T>(Arc<RefCell<D3D12DescriptorHeapInner>>, PhantomData<T>); pub struct D3D12DescriptorHeap<T>(Rc<RefCell<D3D12DescriptorHeapInner>>, PhantomData<T>);
impl<T: D3D12HeapType> D3D12DescriptorHeap<T> { impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> { pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> {
@ -182,7 +185,7 @@ impl<T> D3D12DescriptorHeap<T> {
}; };
Ok(D3D12DescriptorHeap( Ok(D3D12DescriptorHeap(
Arc::new(RefCell::new(D3D12DescriptorHeapInner { Rc::new(RefCell::new(D3D12DescriptorHeapInner {
device: device.clone(), device: device.clone(),
heap, heap,
ty: desc.Type, ty: desc.Type,
@ -207,10 +210,10 @@ impl<T> D3D12DescriptorHeap<T> {
/// size must also divide equally into the size of the heap. /// size must also divide equally into the size of the heap.
pub unsafe fn suballocate(self, size: usize) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) { pub unsafe fn suballocate(self, size: usize) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
// has to be called right after creation. // has to be called right after creation.
assert_eq!(Arc::strong_count(&self.0), 1, assert_eq!(Rc::strong_count(&self.0), 1,
"D3D12DescriptorHeap::suballocate can only be callled immediately after creation."); "D3D12DescriptorHeap::suballocate can only be callled immediately after creation.");
let inner = Arc::try_unwrap(self.0) let inner = Rc::try_unwrap(self.0)
.expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.") .expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.")
.into_inner(); .into_inner();
@ -253,7 +256,7 @@ impl<T> D3D12DescriptorHeap<T> {
(heaps.into_iter() (heaps.into_iter()
.map(|inner| D3D12DescriptorHeap( .map(|inner| D3D12DescriptorHeap(
Arc::new(RefCell::new(inner)), Rc::new(RefCell::new(inner)),
PhantomData::default())) PhantomData::default()))
.collect(), inner.heap) .collect(), inner.heap)
} }
@ -274,13 +277,13 @@ impl<T> D3D12DescriptorHeap<T> {
ptr: (handle.ptr as u64 - inner.cpu_start.ptr as u64) + gpu_start.ptr, ptr: (handle.ptr as u64 - inner.cpu_start.ptr as u64) + gpu_start.ptr,
}); });
return Ok(D3D12DescriptorHeapSlot { return Ok(Rc::new(D3D12DescriptorHeapSlotInner {
cpu_handle: handle, cpu_handle: handle,
slot: i, slot: i,
heap: Arc::clone(&self.0), heap: Rc::clone(&self.0),
gpu_handle, gpu_handle,
_pd: Default::default(), _pd: Default::default(),
}); }));
} }
} }
@ -293,7 +296,7 @@ impl<T> D3D12DescriptorHeap<T> {
} }
} }
impl<T> Drop for D3D12DescriptorHeapSlot<T> { impl<T> Drop for D3D12DescriptorHeapSlotInner<T> {
fn drop(&mut self) { fn drop(&mut self) {
let mut inner = self.heap.borrow_mut(); let mut inner = self.heap.borrow_mut();
inner.map[self.slot] = false; inner.map[self.slot] = false;

View file

@ -1,6 +1,6 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use crate::{error, util}; use crate::{error, util};
use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap, SamplerWorkHeap, RenderTargetHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap, SamplerWorkHeap, RenderTargetHeap};
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::luts::LutTexture; use crate::luts::LutTexture;
use librashader_presets::{ShaderPreset, TextureConfig}; use librashader_presets::{ShaderPreset, TextureConfig};
@ -31,7 +31,7 @@ use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
use crate::mipmap::D3D12MipmapGen; use crate::mipmap::D3D12MipmapGen;
use crate::quad_render::DrawQuad; use crate::quad_render::DrawQuad;
use crate::render_target::RenderTarget; use crate::render_target::RenderTarget;
use crate::texture::{InputTexture, OutputTexture}; use crate::texture::{InputTexture, OutputDescriptor, OutputTexture};
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>; type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
@ -49,8 +49,10 @@ pub struct FilterChainD3D12 {
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>, staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>, rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
pub texture_heap: ID3D12DescriptorHeap, texture_heap: ID3D12DescriptorHeap,
pub sampler_heap: ID3D12DescriptorHeap, sampler_heap: ID3D12DescriptorHeap,
residuals: Vec<OutputDescriptor>
} }
pub(crate) struct FilterCommon { pub(crate) struct FilterCommon {
@ -90,7 +92,7 @@ impl FilterChainD3D12 {
let (passes, semantics) = HLSL::compile_preset_passes::<GlslangCompilation, Box<dyn Error>>( let (passes, semantics) = HLSL::compile_preset_passes::<GlslangCompilation, Box<dyn Error>>(
preset.shaders, preset.shaders,
&preset.textures, &preset.textures,
)?; ).unwrap();
let samplers = SamplerSet::new(device)?; let samplers = SamplerSet::new(device)?;
let mipmap_gen = D3D12MipmapGen::new(device).unwrap(); let mipmap_gen = D3D12MipmapGen::new(device).unwrap();
@ -112,7 +114,7 @@ impl FilterChainD3D12 {
let root_signature = D3D12RootSignature::new(device)?; let root_signature = D3D12RootSignature::new(device)?;
let (texture_heap, sampler_heap, filters) let (texture_heap, sampler_heap, filters)
= FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics)?; = FilterChainD3D12::init_passes(device, &root_signature, passes, &semantics).unwrap();
@ -186,7 +188,8 @@ impl FilterChainD3D12 {
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
history_framebuffers, history_framebuffers,
texture_heap, texture_heap,
sampler_heap sampler_heap,
residuals: Vec::new()
}) })
} }
@ -452,6 +455,8 @@ impl FilterChainD3D12 {
options: Option<&()>, options: Option<&()>,
) -> error::Result<()> ) -> error::Result<()>
{ {
drop(self.residuals.drain(..));
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled); let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
let passes = &mut self.passes[0..max]; let passes = &mut self.passes[0..max];
if passes.is_empty() { if passes.is_empty() {
@ -486,8 +491,13 @@ impl FilterChainD3D12 {
let original = input; let original = input;
let mut source = unsafe { original.cloned() }; let mut source = unsafe { original.clone() };
// swap output and feedback **before** recording command buffers
std::mem::swap(
&mut self.output_framebuffers,
&mut self.feedback_framebuffers,
);
// rescale render buffers to ensure all bindings are valid. // rescale render buffers to ensure all bindings are valid.
let mut source_size = source.size(); let mut source_size = source.size();
@ -530,7 +540,6 @@ impl FilterChainD3D12 {
let passes_len = passes.len(); let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1); let (pass, last) = passes.split_at_mut(passes_len - 1);
let mut residuals = Vec::new();
unsafe { unsafe {
let heaps = [self.texture_heap.clone(), self.sampler_heap.clone()]; let heaps = [self.texture_heap.clone(), self.sampler_heap.clone()];
@ -582,11 +591,42 @@ impl FilterChainD3D12 {
// pass.config.filter, // pass.config.filter,
// pass.config.wrap_mode, // pass.config.wrap_mode,
// )?; // )?;
residuals.push(out.output.descriptor); self.residuals.push(out.output.descriptor);
source = self.common.output_textures[index].as_ref().unwrap().cloned() source = self.common.output_textures[index].as_ref().unwrap().clone()
} }
// try to hint the optimizer
assert_eq!(last.len(), 1);
if let Some(pass) = last.iter_mut().next() {
source.filter = pass.config.filter;
source.wrap_mode = pass.config.wrap_mode;
let out = RenderTarget {
x: 0.0,
y: 0.0,
mvp: DEFAULT_MVP,
output: viewport.output.clone(),
};
pass.draw(
cmd,
passes_len - 1,
&self.common,
if pass.config.frame_count_mod > 0 {
frame_count % pass.config.frame_count_mod as usize
} else {
frame_count
} as u32,
1,
viewport,
&original,
&source,
&out,
QuadType::Final
)?;
}
// todo: history
Ok(()) Ok(())
} }

View file

@ -1,3 +1,4 @@
use std::ops::Deref;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use windows::core::Interface; use windows::core::Interface;
use windows::Win32::Foundation::RECT; use windows::Win32::Foundation::RECT;
@ -15,7 +16,7 @@ use crate::buffer::D3D12ConstantBuffer;
use crate::{error, util}; use crate::{error, util};
use crate::filter_chain::FilterCommon; use crate::filter_chain::FilterCommon;
use crate::graphics_pipeline::D3D12GraphicsPipeline; use crate::graphics_pipeline::D3D12GraphicsPipeline;
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
use crate::render_target::RenderTarget; use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::texture::{InputTexture, OutputTexture}; use crate::texture::{InputTexture, OutputTexture};
@ -65,7 +66,7 @@ impl BindSemantics for FilterPass {
texture_binding[binding.binding as usize] texture_binding[binding.binding as usize]
.copy_descriptor(*texture.descriptor.as_ref()); .copy_descriptor(*texture.descriptor.as_ref());
sampler_binding[binding.binding as usize] sampler_binding[binding.binding as usize]
.copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).as_ref()) .copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).deref().as_ref())
} }
} }
} }
@ -187,8 +188,8 @@ impl FilterPass {
} }
unsafe { unsafe {
cmd.SetGraphicsRootDescriptorTable(0, *self.texture_heap[0].as_ref()); cmd.SetGraphicsRootDescriptorTable(0, *self.texture_heap[0].deref().as_ref());
cmd.SetGraphicsRootDescriptorTable(1, *self.sampler_heap[0].as_ref()); cmd.SetGraphicsRootDescriptorTable(1, *self.sampler_heap[0].deref().as_ref());
} }
// todo: check for non-renderpass. // todo: check for non-renderpass.

View file

@ -1,3 +1,4 @@
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::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 windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
@ -5,7 +6,7 @@ use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize}; use librashader_runtime::scaling::{MipmapSize, ViewportSize};
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap}; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap};
use crate::texture::{InputTexture, OutputTexture}; use crate::texture::{InputTexture, OutputTexture};
use crate::util::d3d12_get_closest_format; use crate::util::d3d12_get_closest_format;
@ -106,7 +107,7 @@ impl OwnedImage {
}, },
}; };
self.device.CreateShaderResourceView(&self.handle, Some(&srv_desc), *descriptor.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))
@ -129,7 +130,7 @@ impl OwnedImage {
}, },
}; };
self.device.CreateRenderTargetView(&self.handle, Some(&rtv_desc), *descriptor.as_ref()); self.device.CreateRenderTargetView(&self.handle, Some(&rtv_desc), *descriptor.deref().as_ref());
} }
Ok(OutputTexture::new(descriptor, self.size)) Ok(OutputTexture::new(descriptor, self.size))

View file

@ -237,11 +237,12 @@ unsafe extern "system" fn debug_log(
} }
pub mod d3d12_hello_triangle { pub mod d3d12_hello_triangle {
use std::ops::Deref;
use super::*; use super::*;
use crate::filter_chain::FilterChainD3D12; use crate::filter_chain::FilterChainD3D12;
use std::path::Path; use std::path::Path;
use librashader_common::{FilterMode, Size, Viewport, WrapMode}; use librashader_common::{FilterMode, Size, Viewport, WrapMode};
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap}; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
use crate::texture::{InputTexture, OutputTexture}; use crate::texture::{InputTexture, OutputTexture};
const FRAME_COUNT: u32 = 2; const FRAME_COUNT: u32 = 2;
@ -500,10 +501,10 @@ pub mod d3d12_hello_triangle {
..Default::default() ..Default::default()
} }
}, },
}), *srv.as_ref()) }), *srv.deref().as_ref())
} }
populate_command_list(resources, &mut self.filter, self.framecount, *srv.as_ref()).unwrap(); populate_command_list(resources, &mut self.filter, self.framecount, *srv.deref().as_ref()).unwrap();
// Execute the command list. // Execute the command list.
let command_list = ID3D12CommandList::from(&resources.command_list); let command_list = ID3D12CommandList::from(&resources.command_list);
@ -590,6 +591,12 @@ pub mod d3d12_hello_triangle {
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
)]); )]);
command_list.ResourceBarrier(&[transition_barrier(
&resources.render_targets[resources.frame_index as usize],
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET,
)]);
filter.frame( filter.frame(
command_list, command_list,
InputTexture::new_from_raw(framebuffer, InputTexture::new_from_raw(framebuffer,
@ -602,14 +609,13 @@ pub mod d3d12_hello_triangle {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
mvp: None, mvp: None,
output: OutputTexture::new_from_raw(D3D12_CPU_DESCRIPTOR_HANDLE { output: OutputTexture::new_from_raw(rtv_handle,
ptr: 0 Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32)),
}, Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32)),
}, frame_count, None).unwrap(); }, frame_count, None).unwrap();
command_list.ResourceBarrier(&[transition_barrier( command_list.ResourceBarrier(&[transition_barrier(
&resources.render_targets[resources.frame_index as usize], &resources.render_targets[resources.frame_index as usize],
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT,
)]); )]);
} }

View file

@ -3,7 +3,7 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
mod error; mod error;
mod filter_chain; mod filter_chain;
mod heap; mod descriptor_heap;
mod hello_triangle; mod hello_triangle;
mod samplers; mod samplers;
mod luts; mod luts;
@ -25,7 +25,8 @@ mod tests {
#[test] #[test]
fn triangle_d3d12() { fn triangle_d3d12() {
let sample = hello_triangle::d3d12_hello_triangle::Sample::new( let sample = hello_triangle::d3d12_hello_triangle::Sample::new(
"../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", "../test/slang-shaders/crt/crt-royale.slangp",
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
&SampleCommandLine { &SampleCommandLine {
use_warp_device: false, use_warp_device: false,
}, },

View file

@ -1,7 +1,7 @@
use std::ops::Deref;
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, CpuStagingHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, CpuStagingHeap};
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources}; use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::image::Image; use librashader_runtime::image::Image;
@ -91,7 +91,7 @@ impl LutTexture {
}, },
}; };
device.CreateShaderResourceView(&resource, Some(&srv_desc), *descriptor.as_ref()); device.CreateShaderResourceView(&resource, Some(&srv_desc), *descriptor.deref().as_ref());
} }
let mut buffer_desc = D3D12_RESOURCE_DESC { let mut buffer_desc = D3D12_RESOURCE_DESC {

View file

@ -1,10 +1,11 @@
use std::mem::ManuallyDrop; 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::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 windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::Size; use librashader_common::Size;
use crate::{error, util}; use crate::{error, util};
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap};
use crate::util::d3d_compile_shader; use crate::util::d3d_compile_shader;
use bytemuck::{Zeroable, Pod}; use bytemuck::{Zeroable, Pod};
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
@ -173,7 +174,7 @@ impl D3D12MipmapGen {
}; };
self.device.CreateShaderResourceView(resource, self.device.CreateShaderResourceView(resource,
Some(&srv_desc), *srv.as_ref()); Some(&srv_desc), *srv.deref().as_ref());
} }
let mut heap_slots = Vec::with_capacity(miplevels as usize); let mut heap_slots = Vec::with_capacity(miplevels as usize);
@ -193,12 +194,12 @@ impl D3D12MipmapGen {
}; };
self.device.CreateUnorderedAccessView(resource, None, self.device.CreateUnorderedAccessView(resource, None,
Some(&desc), *descriptor.as_ref() Some(&desc), *descriptor.deref().as_ref()
); );
heap_slots.push(descriptor); heap_slots.push(descriptor);
} }
cmd.SetComputeRootDescriptorTable(0, *heap_slots[0].as_ref()); cmd.SetComputeRootDescriptorTable(0, *heap_slots[0].deref().as_ref());
for i in 1..miplevels as u32 { for i in 1..miplevels as u32 {
let scaled = size.scale_mipmap(i); let scaled = size.scale_mipmap(i);
@ -225,7 +226,7 @@ impl D3D12MipmapGen {
i i
); );
cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].as_ref()); cmd.SetComputeRootDescriptorTable(1, *heap_slots[i as usize].deref().as_ref());
cmd.SetComputeRoot32BitConstants(2, cmd.SetComputeRoot32BitConstants(2,
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32, (std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
mipmap_params.as_ptr().cast(), mipmap_params.as_ptr().cast(),

View file

@ -1,5 +1,6 @@
use std::ops::Deref;
use crate::error; use crate::error;
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap}; use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Direct3D12::{
@ -47,7 +48,7 @@ impl SamplerSet {
MinLOD: -D3D12_FLOAT32_MAX, MinLOD: -D3D12_FLOAT32_MAX,
MaxLOD: D3D12_FLOAT32_MAX, MaxLOD: D3D12_FLOAT32_MAX,
}, },
*linear.as_ref(), *linear.deref().as_ref(),
); );
let nearest = heap.alloc_slot()?; let nearest = heap.alloc_slot()?;
@ -64,7 +65,7 @@ impl SamplerSet {
MinLOD: -D3D12_FLOAT32_MAX, MinLOD: -D3D12_FLOAT32_MAX,
MaxLOD: D3D12_FLOAT32_MAX, MaxLOD: D3D12_FLOAT32_MAX,
}, },
*nearest.as_ref(), *nearest.deref().as_ref(),
); );
samplers.insert((*wrap_mode, FilterMode::Linear), linear); samplers.insert((*wrap_mode, FilterMode::Linear), linear);

View file

@ -1,13 +1,16 @@
use std::ops::Deref;
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE}; use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap}; use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeapSlot, RenderTargetHeap};
#[derive(Clone)]
pub(crate) enum InputDescriptor { pub(crate) enum InputDescriptor {
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>), Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE) Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
} }
#[derive(Clone)]
pub(crate) enum OutputDescriptor { pub(crate) enum OutputDescriptor {
Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>), Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE) Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
@ -16,7 +19,7 @@ pub(crate) enum OutputDescriptor {
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor { impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self { match self {
InputDescriptor::Owned(h) => h.as_ref(), InputDescriptor::Owned(h) => h.deref().as_ref(),
InputDescriptor::Raw(h) => h InputDescriptor::Raw(h) => h
} }
} }
@ -25,12 +28,13 @@ impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor { impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE { fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self { match self {
OutputDescriptor::Owned(h) => h.as_ref(), OutputDescriptor::Owned(h) => h.deref().as_ref(),
OutputDescriptor::Raw(h) => h OutputDescriptor::Raw(h) => h
} }
} }
} }
#[derive(Clone)]
pub struct OutputTexture { pub struct OutputTexture {
pub(crate) descriptor: OutputDescriptor, pub(crate) descriptor: OutputDescriptor,
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
@ -59,6 +63,7 @@ impl OutputTexture {
} }
} }
#[derive(Clone)]
pub struct InputTexture { pub struct InputTexture {
pub(crate) descriptor: InputDescriptor, pub(crate) descriptor: InputDescriptor,
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
@ -99,14 +104,6 @@ impl InputTexture {
filter filter
} }
} }
// parent descriptor has to stay alive.
pub fn cloned(&self) -> InputTexture {
unsafe {
Self::new_from_raw(*self.descriptor.as_ref(),
self.size, self.format, self.wrap_mode, self.filter)
}
}
} }
impl AsRef<InputTexture> for InputTexture { impl AsRef<InputTexture> for InputTexture {