rt(d3d12): allow creating output view from a resource ref
This commit is contained in:
parent
3c20c83bc9
commit
40691cc406
|
@ -3,6 +3,7 @@
|
|||
|
||||
use d3d12_descriptor_heap::D3D12DescriptorHeapError;
|
||||
use thiserror::Error;
|
||||
use windows::Win32::Graphics::Direct3D12::D3D12_RESOURCE_DIMENSION;
|
||||
|
||||
/// Cumulative error type for Direct3D12 filter chains.
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -26,6 +27,8 @@ pub enum FilterChainError {
|
|||
HeapError(#[from] D3D12DescriptorHeapError),
|
||||
#[error("allocation error")]
|
||||
AllocationError(#[from] gpu_allocator::AllocationError),
|
||||
#[error("invalid resource dimension {0:?}")]
|
||||
InvalidDimensionError(D3D12_RESOURCE_DIMENSION),
|
||||
#[error("unreachable")]
|
||||
Infallible(#[from] std::convert::Infallible),
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ pub struct FilterChainD3D12 {
|
|||
pub(crate) feedback_framebuffers: Box<[OwnedImage]>,
|
||||
pub(crate) history_framebuffers: VecDeque<OwnedImage>,
|
||||
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
pub(crate) rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
|
||||
work_heap: ID3D12DescriptorHeap,
|
||||
sampler_heap: ID3D12DescriptorHeap,
|
||||
|
|
|
@ -16,20 +16,20 @@ use librashader_runtime::scaling::{MipmapSize, ScaleFramebuffer, ViewportSize};
|
|||
use parking_lot::Mutex;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::sync::Arc;
|
||||
use windows::core::Interface;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_BOX,
|
||||
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_LOAD, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE,
|
||||
D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0,
|
||||
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_DESC,
|
||||
D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,
|
||||
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RTV_DIMENSION_TEXTURE2D,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0,
|
||||
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, D3D12_TEXTURE_COPY_LOCATION,
|
||||
D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEXTURE_COPY_LOCATION,
|
||||
D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
||||
|
@ -309,32 +309,7 @@ impl OwnedImage {
|
|||
&self,
|
||||
heap: &mut D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
) -> error::Result<D3D12OutputView> {
|
||||
let descriptor = heap.allocate_descriptor()?;
|
||||
|
||||
unsafe {
|
||||
let rtv_desc = D3D12_RENDER_TARGET_VIEW_DESC {
|
||||
Format: self.format.into(),
|
||||
ViewDimension: D3D12_RTV_DIMENSION_TEXTURE2D,
|
||||
Anonymous: D3D12_RENDER_TARGET_VIEW_DESC_0 {
|
||||
Texture2D: D3D12_TEX2D_RTV {
|
||||
MipSlice: 0,
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
self.device.CreateRenderTargetView(
|
||||
self.handle.resource(),
|
||||
Some(&rtv_desc),
|
||||
*descriptor.as_ref(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(D3D12OutputView::new(
|
||||
descriptor,
|
||||
self.size,
|
||||
self.format.into(),
|
||||
))
|
||||
D3D12OutputView::new_from_resource_internal(self.resource.to_ref(), &self.device, heap)
|
||||
}
|
||||
|
||||
pub fn scale(
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
use crate::descriptor_heap::{CpuStagingHeap, RenderTargetHeap};
|
||||
use crate::{error, FilterChainD3D12};
|
||||
use crate::resource::{OutlivesFrame, ResourceHandleStrategy};
|
||||
use d3d12_descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot};
|
||||
use librashader_common::{FilterMode, GetSize, Size, WrapMode};
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Deref;
|
||||
use windows::core::InterfaceRef;
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE};
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12Device, ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_RENDER_TARGET_VIEW_DESC,
|
||||
D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||
D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV,
|
||||
};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
|
||||
|
||||
/// A **non-owning** reference to a ID3D12Resource.
|
||||
/// This does not `AddRef` or `Release` the underlying interface.
|
||||
pub type D3D12ResourceRef<'a> = InterfaceRef<'a, ID3D12Resource>;
|
||||
|
||||
/// An image for use as shader resource view.
|
||||
#[derive(Clone)]
|
||||
pub struct D3D12InputImage<'a> {
|
||||
|
@ -87,6 +97,52 @@ impl D3D12OutputView {
|
|||
format,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new output view from a resource ref, linked to the chain.
|
||||
///
|
||||
/// The output view will be automatically disposed on drop.
|
||||
pub fn new_from_resource(
|
||||
image: D3D12ResourceRef,
|
||||
chain: &mut FilterChainD3D12
|
||||
) -> error::Result<D3D12OutputView> {
|
||||
Self::new_from_resource_internal(image, &chain.common.d3d12, &mut chain.rtv_heap)
|
||||
}
|
||||
|
||||
/// Create a new output view from a resource ref
|
||||
pub(crate) fn new_from_resource_internal(
|
||||
image: D3D12ResourceRef,
|
||||
device: &ID3D12Device,
|
||||
heap: &mut D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
) -> error::Result<D3D12OutputView> {
|
||||
let desc = unsafe { image.GetDesc() };
|
||||
if desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D {
|
||||
return Err(crate::error::FilterChainError::InvalidDimensionError(
|
||||
desc.Dimension,
|
||||
));
|
||||
}
|
||||
|
||||
let slot = heap.allocate_descriptor()?;
|
||||
unsafe {
|
||||
let rtv_desc = D3D12_RENDER_TARGET_VIEW_DESC {
|
||||
Format: desc.Format,
|
||||
ViewDimension: D3D12_RTV_DIMENSION_TEXTURE2D,
|
||||
Anonymous: D3D12_RENDER_TARGET_VIEW_DESC_0 {
|
||||
Texture2D: D3D12_TEX2D_RTV {
|
||||
MipSlice: 0,
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
device.CreateRenderTargetView(image.deref(), Some(&rtv_desc), *slot.as_ref());
|
||||
}
|
||||
|
||||
Ok(Self::new(
|
||||
slot,
|
||||
Size::new(desc.Width as u32, desc.Height),
|
||||
desc.Format,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputTexture {
|
||||
|
|
Loading…
Reference in a new issue