d3d12: implement mipmaps
This commit is contained in:
parent
271788b9c6
commit
0506733dad
|
@ -49,6 +49,7 @@ use windows::Win32::Graphics::Direct3D12::{
|
|||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN;
|
||||
use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject};
|
||||
use windows::Win32::System::WindowsProgramming::INFINITE;
|
||||
use librashader_runtime::scaling::MipmapSize;
|
||||
|
||||
type DxilShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation>>;
|
||||
type HlslShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
|
||||
|
@ -71,6 +72,9 @@ pub struct FilterChainD3D12 {
|
|||
sampler_heap: ID3D12DescriptorHeap,
|
||||
|
||||
residuals: Vec<OutputDescriptor>,
|
||||
mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
|
||||
disable_mipmaps: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct FilterCommon {
|
||||
|
@ -184,6 +188,8 @@ impl FilterChainD3D12 {
|
|||
let (history_framebuffers, history_textures) =
|
||||
FilterChainD3D12::init_history(device, &filters)?;
|
||||
|
||||
let mut mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap> =
|
||||
D3D12DescriptorHeap::new(device, u16::MAX as usize)?;
|
||||
Ok(FilterChainD3D12 {
|
||||
common: FilterCommon {
|
||||
d3d12: device.clone(),
|
||||
|
@ -212,6 +218,8 @@ impl FilterChainD3D12 {
|
|||
history_framebuffers,
|
||||
texture_heap,
|
||||
sampler_heap,
|
||||
mipmap_heap,
|
||||
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
|
||||
residuals: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
@ -312,8 +320,10 @@ impl FilterChainD3D12 {
|
|||
|
||||
let residuals = mipmap_gen.mipmapping_context(&cmd, &mut work_heap, |context| {
|
||||
for lut in luts.values() {
|
||||
lut.generate_mipmaps(context).unwrap()
|
||||
lut.generate_mipmaps(context)?;
|
||||
}
|
||||
|
||||
Ok::<(), Box<dyn Error>>(())
|
||||
})?;
|
||||
|
||||
//
|
||||
|
@ -598,6 +608,19 @@ impl FilterChainD3D12 {
|
|||
for (index, pass) in pass.iter_mut().enumerate() {
|
||||
source.filter = pass.config.filter;
|
||||
source.wrap_mode = pass.config.wrap_mode;
|
||||
|
||||
if pass.config.mipmap_input && !self.disable_mipmaps {
|
||||
unsafe {
|
||||
// this is so bad.
|
||||
self.common.mipmap_gen.mipmapping_context(cmd, &mut self.mipmap_heap, |ctx| {
|
||||
ctx.generate_mipmaps(&source.resource,
|
||||
source.size().calculate_miplevels() as u16, source.size,
|
||||
source.format.into())?;
|
||||
Ok::<(), Box<dyn Error>>(())
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
let target = &self.output_framebuffers[index];
|
||||
util::d3d12_resource_transition(
|
||||
&cmd,
|
||||
|
@ -641,6 +664,7 @@ impl FilterChainD3D12 {
|
|||
D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
);
|
||||
|
||||
// let target_handle = target.create_shader_resource_view(
|
||||
// &mut self.staging_heap,
|
||||
// pass.config.filter,
|
||||
|
|
|
@ -20,7 +20,6 @@ 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,
|
||||
|
|
|
@ -151,14 +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>(
|
||||
pub fn mipmapping_context<F, E>(
|
||||
&self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
mut f: F,
|
||||
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>>
|
||||
) -> Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>, E>
|
||||
where
|
||||
F: FnMut(&mut MipmapGenContext),
|
||||
F: FnMut(&mut MipmapGenContext) -> Result<(), E>,
|
||||
{
|
||||
let heap: ID3D12DescriptorHeap = (&(*work_heap)).into();
|
||||
unsafe {
|
||||
|
@ -168,7 +168,7 @@ impl D3D12MipmapGen {
|
|||
}
|
||||
|
||||
let mut context = MipmapGenContext::new(self, cmd, work_heap);
|
||||
f(&mut context);
|
||||
f(&mut context)?;
|
||||
Ok(context.close())
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ pub struct FilterChainOptionsD3D12 {
|
|||
pub force_hlsl_pipeline: bool,
|
||||
|
||||
/// Whether or not to explicitly disable mipmap
|
||||
/// generation regardless of shader preset settings.
|
||||
/// generation for intermediate passes regardless
|
||||
/// of shader preset settings.
|
||||
///
|
||||
/// Mipmap generation Direct3D may be prohibitively expensive
|
||||
/// on some hardware environments.
|
||||
pub force_no_mipmaps: bool,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue