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::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};
@ -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,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
heap: Arc<RefCell<D3D12DescriptorHeapInner>>,
heap: Rc<RefCell<D3D12DescriptorHeapInner>>,
slot: usize,
_pd: PhantomData<T>,
}
impl<T> D3D12DescriptorHeapSlot<T> {
impl<T> D3D12DescriptorHeapSlotInner<T> {
/// Get the index of the resource within the heap.
pub fn index(&self) -> usize {
self.slot
}
/// 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 {
let heap = self.heap.deref()
.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 {
&self.cpu_handle
}
}
impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE>
for D3D12DescriptorHeapSlot<T>
for D3D12DescriptorHeapSlotInner<T>
{
fn as_ref(&self) -> &D3D12_GPU_DESCRIPTOR_HANDLE {
self.gpu_handle.as_ref().unwrap()
@ -157,7 +160,7 @@ struct D3D12DescriptorHeapInner {
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> {
pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> {
@ -182,7 +185,7 @@ impl<T> D3D12DescriptorHeap<T> {
};
Ok(D3D12DescriptorHeap(
Arc::new(RefCell::new(D3D12DescriptorHeapInner {
Rc::new(RefCell::new(D3D12DescriptorHeapInner {
device: device.clone(),
heap,
ty: desc.Type,
@ -207,10 +210,10 @@ impl<T> D3D12DescriptorHeap<T> {
/// size must also divide equally into the size of the heap.
pub unsafe fn suballocate(self, size: usize) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
// 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.");
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.")
.into_inner();
@ -253,7 +256,7 @@ impl<T> D3D12DescriptorHeap<T> {
(heaps.into_iter()
.map(|inner| D3D12DescriptorHeap(
Arc::new(RefCell::new(inner)),
Rc::new(RefCell::new(inner)),
PhantomData::default()))
.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,
});
return Ok(D3D12DescriptorHeapSlot {
return Ok(Rc::new(D3D12DescriptorHeapSlotInner {
cpu_handle: handle,
slot: i,
heap: Arc::clone(&self.0),
heap: Rc::clone(&self.0),
gpu_handle,
_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) {
let mut inner = self.heap.borrow_mut();
inner.map[self.slot] = false;

View file

@ -1,6 +1,6 @@
use std::collections::VecDeque;
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::luts::LutTexture;
use librashader_presets::{ShaderPreset, TextureConfig};
@ -31,7 +31,7 @@ use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature};
use crate::mipmap::D3D12MipmapGen;
use crate::quad_render::DrawQuad;
use crate::render_target::RenderTarget;
use crate::texture::{InputTexture, OutputTexture};
use crate::texture::{InputTexture, OutputDescriptor, OutputTexture};
type ShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
@ -49,8 +49,10 @@ pub struct FilterChainD3D12 {
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
pub texture_heap: ID3D12DescriptorHeap,
pub sampler_heap: ID3D12DescriptorHeap,
texture_heap: ID3D12DescriptorHeap,
sampler_heap: ID3D12DescriptorHeap,
residuals: Vec<OutputDescriptor>
}
pub(crate) struct FilterCommon {
@ -90,7 +92,7 @@ impl FilterChainD3D12 {
let (passes, semantics) = HLSL::compile_preset_passes::<GlslangCompilation, Box<dyn Error>>(
preset.shaders,
&preset.textures,
)?;
).unwrap();
let samplers = SamplerSet::new(device)?;
let mipmap_gen = D3D12MipmapGen::new(device).unwrap();
@ -112,7 +114,7 @@ impl FilterChainD3D12 {
let root_signature = D3D12RootSignature::new(device)?;
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(),
history_framebuffers,
texture_heap,
sampler_heap
sampler_heap,
residuals: Vec::new()
})
}
@ -452,6 +455,8 @@ impl FilterChainD3D12 {
options: Option<&()>,
) -> error::Result<()>
{
drop(self.residuals.drain(..));
let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled);
let passes = &mut self.passes[0..max];
if passes.is_empty() {
@ -486,8 +491,13 @@ impl FilterChainD3D12 {
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.
let mut source_size = source.size();
@ -530,7 +540,6 @@ impl FilterChainD3D12 {
let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);
let mut residuals = Vec::new();
unsafe {
let heaps = [self.texture_heap.clone(), self.sampler_heap.clone()];
@ -582,11 +591,42 @@ impl FilterChainD3D12 {
// pass.config.filter,
// pass.config.wrap_mode,
// )?;
residuals.push(out.output.descriptor);
source = self.common.output_textures[index].as_ref().unwrap().cloned()
self.residuals.push(out.output.descriptor);
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(())
}

View file

@ -1,3 +1,4 @@
use std::ops::Deref;
use rustc_hash::FxHashMap;
use windows::core::Interface;
use windows::Win32::Foundation::RECT;
@ -15,7 +16,7 @@ use crate::buffer::D3D12ConstantBuffer;
use crate::{error, util};
use crate::filter_chain::FilterCommon;
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::samplers::SamplerSet;
use crate::texture::{InputTexture, OutputTexture};
@ -65,7 +66,7 @@ impl BindSemantics for FilterPass {
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).as_ref())
.copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).deref().as_ref())
}
}
}
@ -187,8 +188,8 @@ impl FilterPass {
}
unsafe {
cmd.SetGraphicsRootDescriptorTable(0, *self.texture_heap[0].as_ref());
cmd.SetGraphicsRootDescriptorTable(1, *self.sampler_heap[0].as_ref());
cmd.SetGraphicsRootDescriptorTable(0, *self.texture_heap[0].deref().as_ref());
cmd.SetGraphicsRootDescriptorTable(1, *self.sampler_heap[0].deref().as_ref());
}
// 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::Dxgi::Common::{DXGI_SAMPLE_DESC};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
@ -5,7 +6,7 @@ use librashader_presets::Scale2D;
use librashader_runtime::scaling::{MipmapSize, ViewportSize};
use crate::error;
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::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))
@ -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))

View file

@ -237,11 +237,12 @@ 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::heap::{CpuStagingHeap, D3D12DescriptorHeap};
use crate::descriptor_heap::{CpuStagingHeap, D3D12DescriptorHeap};
use crate::texture::{InputTexture, OutputTexture};
const FRAME_COUNT: u32 = 2;
@ -500,10 +501,10 @@ pub mod d3d12_hello_triangle {
..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.
let command_list = ID3D12CommandList::from(&resources.command_list);
@ -590,6 +591,12 @@ pub mod d3d12_hello_triangle {
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(
command_list,
InputTexture::new_from_raw(framebuffer,
@ -602,14 +609,13 @@ pub mod d3d12_hello_triangle {
x: 0.0,
y: 0.0,
mvp: None,
output: OutputTexture::new_from_raw(D3D12_CPU_DESCRIPTOR_HANDLE {
ptr: 0
}, Size::new(resources.viewport.Width as u32, resources.viewport.Height as u32)),
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],
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PRESENT,
)]);
}

View file

@ -3,7 +3,7 @@
#![feature(type_alias_impl_trait)]
mod error;
mod filter_chain;
mod heap;
mod descriptor_heap;
mod hello_triangle;
mod samplers;
mod luts;
@ -25,7 +25,8 @@ mod tests {
#[test]
fn triangle_d3d12() {
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 {
use_warp_device: false,
},

View file

@ -1,7 +1,7 @@
use std::ops::Deref;
use crate::error;
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 librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
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 {

View file

@ -1,10 +1,11 @@
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::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap};
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap};
use crate::util::d3d_compile_shader;
use bytemuck::{Zeroable, Pod};
use librashader_runtime::scaling::MipmapSize;
@ -173,7 +174,7 @@ impl D3D12MipmapGen {
};
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);
@ -193,12 +194,12 @@ impl D3D12MipmapGen {
};
self.device.CreateUnorderedAccessView(resource, None,
Some(&desc), *descriptor.as_ref()
Some(&desc), *descriptor.deref().as_ref()
);
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 {
let scaled = size.scale_mipmap(i);
@ -225,7 +226,7 @@ impl D3D12MipmapGen {
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,
(std::mem::size_of::<MipConstants>() / std::mem::size_of::<u32>()) as u32,
mipmap_params.as_ptr().cast(),

View file

@ -1,5 +1,6 @@
use std::ops::Deref;
use crate::error;
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
use windows::Win32::Graphics::Direct3D12::{
@ -47,7 +48,7 @@ impl SamplerSet {
MinLOD: -D3D12_FLOAT32_MAX,
MaxLOD: D3D12_FLOAT32_MAX,
},
*linear.as_ref(),
*linear.deref().as_ref(),
);
let nearest = heap.alloc_slot()?;
@ -64,7 +65,7 @@ impl SamplerSet {
MinLOD: -D3D12_FLOAT32_MAX,
MaxLOD: D3D12_FLOAT32_MAX,
},
*nearest.as_ref(),
*nearest.deref().as_ref(),
);
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::Dxgi::Common::DXGI_FORMAT;
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 {
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
}
#[derive(Clone)]
pub(crate) enum OutputDescriptor {
Owned(D3D12DescriptorHeapSlot<RenderTargetHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
@ -16,7 +19,7 @@ pub(crate) enum OutputDescriptor {
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self {
InputDescriptor::Owned(h) => h.as_ref(),
InputDescriptor::Owned(h) => h.deref().as_ref(),
InputDescriptor::Raw(h) => h
}
}
@ -25,12 +28,13 @@ impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self {
OutputDescriptor::Owned(h) => h.as_ref(),
OutputDescriptor::Owned(h) => h.deref().as_ref(),
OutputDescriptor::Raw(h) => h
}
}
}
#[derive(Clone)]
pub struct OutputTexture {
pub(crate) descriptor: OutputDescriptor,
pub(crate) size: Size<u32>,
@ -59,6 +63,7 @@ impl OutputTexture {
}
}
#[derive(Clone)]
pub struct InputTexture {
pub(crate) descriptor: InputDescriptor,
pub(crate) size: Size<u32>,
@ -99,14 +104,6 @@ impl InputTexture {
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 {