rt(d3d12): use InterfaceRef for D3D12InputImage to avoid refcount for input image
This commit is contained in:
parent
b123f63a6e
commit
3c20c83bc9
|
@ -8,6 +8,7 @@ use std::ffi::CStr;
|
||||||
use std::mem::{ManuallyDrop, MaybeUninit};
|
use std::mem::{ManuallyDrop, MaybeUninit};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use windows::core::Interface;
|
||||||
use windows::Win32::Graphics::Direct3D12::{
|
use windows::Win32::Graphics::Direct3D12::{
|
||||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE,
|
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||||
};
|
};
|
||||||
|
@ -93,19 +94,6 @@ config_struct! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<libra_source_image_d3d12_t> for D3D12InputImage {
|
|
||||||
type Error = LibrashaderError;
|
|
||||||
|
|
||||||
fn try_from(value: libra_source_image_d3d12_t) -> Result<Self, Self::Error> {
|
|
||||||
let resource = value.resource.clone();
|
|
||||||
|
|
||||||
Ok(D3D12InputImage {
|
|
||||||
resource: ManuallyDrop::into_inner(resource),
|
|
||||||
descriptor: value.descriptor,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern_fn! {
|
extern_fn! {
|
||||||
/// Create the filter chain given the shader preset.
|
/// Create the filter chain given the shader preset.
|
||||||
///
|
///
|
||||||
|
@ -295,7 +283,10 @@ extern_fn! {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let image = image.try_into()?;
|
let image = D3D12InputImage {
|
||||||
|
resource: image.resource.to_ref(),
|
||||||
|
descriptor: image.descriptor,
|
||||||
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
chain.frame(&command_list, image, &viewport, frame_count, options.as_ref())?;
|
chain.frame(&command_list, image, &viewport, frame_count, options.as_ref())?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub struct Direct3D12 {
|
||||||
_cpu_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
_cpu_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||||
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||||
|
|
||||||
texture: D3D12InputImage,
|
texture: ID3D12Resource,
|
||||||
_heap_slot: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
_heap_slot: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||||
command_pool: ID3D12CommandAllocator,
|
command_pool: ID3D12CommandAllocator,
|
||||||
queue: ID3D12CommandQueue,
|
queue: ID3D12CommandQueue,
|
||||||
|
@ -154,7 +154,10 @@ impl RenderTest for Direct3D12 {
|
||||||
for frame in 0..=frame_count {
|
for frame in 0..=frame_count {
|
||||||
filter_chain.frame(
|
filter_chain.frame(
|
||||||
&cmd,
|
&cmd,
|
||||||
self.texture.clone(),
|
D3D12InputImage {
|
||||||
|
resource: self.texture.to_ref(),
|
||||||
|
descriptor: *self._heap_slot.as_ref(),
|
||||||
|
},
|
||||||
&viewport,
|
&viewport,
|
||||||
frame,
|
frame,
|
||||||
options.as_ref(),
|
options.as_ref(),
|
||||||
|
@ -249,7 +252,7 @@ impl Direct3D12 {
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> anyhow::Result<(
|
) -> anyhow::Result<(
|
||||||
Image<BGRA8>,
|
Image<BGRA8>,
|
||||||
D3D12InputImage,
|
ID3D12Resource,
|
||||||
D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||||
)> {
|
)> {
|
||||||
// 1 time queue infrastructure for lut uploads
|
// 1 time queue infrastructure for lut uploads
|
||||||
|
@ -392,14 +395,7 @@ impl Direct3D12 {
|
||||||
CloseHandle(fence_event)?;
|
CloseHandle(fence_event)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((
|
Ok((image, resource, descriptor))
|
||||||
image,
|
|
||||||
D3D12InputImage {
|
|
||||||
resource,
|
|
||||||
descriptor: descriptor.as_ref().clone(),
|
|
||||||
},
|
|
||||||
descriptor,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -295,7 +295,7 @@ impl OwnedImage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(InputTexture::new::<OutlivesFrame, _>(
|
Ok(InputTexture::new(
|
||||||
&self.resource,
|
&self.resource,
|
||||||
descriptor,
|
descriptor,
|
||||||
self.size,
|
self.size,
|
||||||
|
|
|
@ -201,7 +201,7 @@ impl LutTexture {
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||||
);
|
);
|
||||||
|
|
||||||
let view = InputTexture::new::<OutlivesFrame, _>(
|
let view = InputTexture::new(
|
||||||
&resource,
|
&resource,
|
||||||
descriptor,
|
descriptor,
|
||||||
source.size,
|
source.size,
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap};
|
use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap};
|
||||||
use crate::resource::ResourceHandleStrategy;
|
use crate::resource::{OutlivesFrame, ResourceHandleStrategy};
|
||||||
use d3d12_descriptor_heap::D3D12DescriptorHeapSlot;
|
use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
|
||||||
use librashader_common::{FilterMode, GetSize, Size, WrapMode};
|
use librashader_common::{FilterMode, GetSize, Size, WrapMode};
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
use windows::core::InterfaceRef;
|
||||||
use windows::Win32::Graphics::Direct3D12::{ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE};
|
use windows::Win32::Graphics::Direct3D12::{ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
|
||||||
|
|
||||||
/// An image for use as shader resource view.
|
/// An image for use as shader resource view.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct D3D12InputImage {
|
pub struct D3D12InputImage<'a> {
|
||||||
pub resource: ID3D12Resource,
|
pub resource: InterfaceRef<'a, ID3D12Resource>,
|
||||||
pub descriptor: D3D12_CPU_DESCRIPTOR_HANDLE,
|
pub descriptor: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +96,13 @@ pub struct InputTexture {
|
||||||
pub(crate) format: DXGI_FORMAT,
|
pub(crate) format: DXGI_FORMAT,
|
||||||
pub(crate) wrap_mode: WrapMode,
|
pub(crate) wrap_mode: WrapMode,
|
||||||
pub(crate) filter: FilterMode,
|
pub(crate) filter: FilterMode,
|
||||||
drop_flag: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputTexture {
|
impl InputTexture {
|
||||||
pub fn new<S: ResourceHandleStrategy<T>, T>(
|
// Create a new input texture, with runtime lifetime tracking.
|
||||||
resource: &T,
|
// The source owned framebuffer must outlive this input.
|
||||||
|
pub fn new(
|
||||||
|
resource: &ManuallyDrop<ID3D12Resource>,
|
||||||
handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||||
size: Size<u32>,
|
size: Size<u32>,
|
||||||
format: DXGI_FORMAT,
|
format: DXGI_FORMAT,
|
||||||
|
@ -114,13 +116,12 @@ impl InputTexture {
|
||||||
// as valid for the lifetime of handle.
|
// as valid for the lifetime of handle.
|
||||||
// Also, resource is non-null by construction.
|
// Also, resource is non-null by construction.
|
||||||
// Option<T> and <T> have the same layout.
|
// Option<T> and <T> have the same layout.
|
||||||
resource: unsafe { std::mem::transmute(S::obtain(resource)) },
|
resource: unsafe { std::mem::transmute(OutlivesFrame::obtain(resource)) },
|
||||||
descriptor: srv,
|
descriptor: srv,
|
||||||
size,
|
size,
|
||||||
format,
|
format,
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
filter,
|
filter,
|
||||||
drop_flag: S::NEEDS_CLEANUP,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,42 +133,27 @@ impl InputTexture {
|
||||||
) -> InputTexture {
|
) -> InputTexture {
|
||||||
let desc = unsafe { image.resource.GetDesc() };
|
let desc = unsafe { image.resource.GetDesc() };
|
||||||
InputTexture {
|
InputTexture {
|
||||||
resource: ManuallyDrop::new(image.resource.clone()),
|
resource: unsafe { std::mem::transmute(image.resource) },
|
||||||
descriptor: InputDescriptor::Raw(image.descriptor),
|
descriptor: InputDescriptor::Raw(image.descriptor),
|
||||||
size: Size::new(desc.Width as u32, desc.Height),
|
size: Size::new(desc.Width as u32, desc.Height),
|
||||||
format: desc.Format,
|
format: desc.Format,
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
filter,
|
filter,
|
||||||
drop_flag: true,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for InputTexture {
|
impl Clone for InputTexture {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
// ensure lifetime for raw resources or if there is a drop flag
|
// SAFETY: the parent doesn't have drop flag, so that means
|
||||||
if self.descriptor.is_raw() || self.drop_flag {
|
// we don't need to handle drop.
|
||||||
InputTexture {
|
InputTexture {
|
||||||
resource: ManuallyDrop::clone(&self.resource),
|
resource: unsafe { std::mem::transmute_copy(&self.resource) },
|
||||||
descriptor: self.descriptor.clone(),
|
descriptor: self.descriptor.clone(),
|
||||||
size: self.size,
|
size: self.size,
|
||||||
format: self.format,
|
format: self.format,
|
||||||
wrap_mode: self.wrap_mode,
|
wrap_mode: self.wrap_mode,
|
||||||
filter: self.filter,
|
filter: self.filter,
|
||||||
drop_flag: true,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// SAFETY: the parent doesn't have drop flag, so that means
|
|
||||||
// we don't need to handle drop.
|
|
||||||
InputTexture {
|
|
||||||
resource: unsafe { std::mem::transmute_copy(&self.resource) },
|
|
||||||
descriptor: self.descriptor.clone(),
|
|
||||||
size: self.size,
|
|
||||||
format: self.format,
|
|
||||||
wrap_mode: self.wrap_mode,
|
|
||||||
filter: self.filter,
|
|
||||||
drop_flag: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,11 +171,3 @@ impl GetSize<u32> for D3D12OutputView {
|
||||||
Ok(self.size)
|
Ok(self.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for InputTexture {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.drop_flag {
|
|
||||||
unsafe { ManuallyDrop::drop(&mut self.resource) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -620,7 +620,7 @@ pub mod d3d12_hello_triangle {
|
||||||
.frame(
|
.frame(
|
||||||
command_list,
|
command_list,
|
||||||
D3D12InputImage {
|
D3D12InputImage {
|
||||||
resource: ID3D12Resource::clone(&*resources.framebuffer),
|
resource: resources.framebuffer.to_ref(),
|
||||||
descriptor: framebuffer,
|
descriptor: framebuffer,
|
||||||
},
|
},
|
||||||
&Viewport {
|
&Viewport {
|
||||||
|
|
Loading…
Reference in a new issue