d3d12: implement mipmaps

This commit is contained in:
chyyran 2023-02-05 18:25:59 -05:00
parent 271788b9c6
commit 0506733dad
4 changed files with 34 additions and 7 deletions

View file

@ -49,6 +49,7 @@ use windows::Win32::Graphics::Direct3D12::{
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN;
use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject}; use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject};
use windows::Win32::System::WindowsProgramming::INFINITE; use windows::Win32::System::WindowsProgramming::INFINITE;
use librashader_runtime::scaling::MipmapSize;
type DxilShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation>>; type DxilShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation>>;
type HlslShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>; type HlslShaderPassMeta = ShaderPassArtifact<impl CompileReflectShader<HLSL, GlslangCompilation>>;
@ -71,6 +72,9 @@ pub struct FilterChainD3D12 {
sampler_heap: ID3D12DescriptorHeap, sampler_heap: ID3D12DescriptorHeap,
residuals: Vec<OutputDescriptor>, residuals: Vec<OutputDescriptor>,
mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
disable_mipmaps: bool,
} }
pub(crate) struct FilterCommon { pub(crate) struct FilterCommon {
@ -184,6 +188,8 @@ impl FilterChainD3D12 {
let (history_framebuffers, history_textures) = let (history_framebuffers, history_textures) =
FilterChainD3D12::init_history(device, &filters)?; FilterChainD3D12::init_history(device, &filters)?;
let mut mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap> =
D3D12DescriptorHeap::new(device, u16::MAX as usize)?;
Ok(FilterChainD3D12 { Ok(FilterChainD3D12 {
common: FilterCommon { common: FilterCommon {
d3d12: device.clone(), d3d12: device.clone(),
@ -212,6 +218,8 @@ impl FilterChainD3D12 {
history_framebuffers, history_framebuffers,
texture_heap, texture_heap,
sampler_heap, sampler_heap,
mipmap_heap,
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
residuals: Vec::new(), residuals: Vec::new(),
}) })
} }
@ -312,8 +320,10 @@ impl FilterChainD3D12 {
let residuals = mipmap_gen.mipmapping_context(&cmd, &mut work_heap, |context| { let residuals = mipmap_gen.mipmapping_context(&cmd, &mut work_heap, |context| {
for lut in luts.values() { 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() { for (index, pass) in pass.iter_mut().enumerate() {
source.filter = pass.config.filter; source.filter = pass.config.filter;
source.wrap_mode = pass.config.wrap_mode; 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]; let target = &self.output_framebuffers[index];
util::d3d12_resource_transition( util::d3d12_resource_transition(
&cmd, &cmd,
@ -641,6 +664,7 @@ impl FilterChainD3D12 {
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
); );
// let target_handle = target.create_shader_resource_view( // let target_handle = target.create_shader_resource_view(
// &mut self.staging_heap, // &mut self.staging_heap,
// pass.config.filter, // pass.config.filter,

View file

@ -20,7 +20,6 @@ use rustc_hash::FxHashMap;
use std::ops::Deref; use std::ops::Deref;
use windows::core::Interface; use windows::core::Interface;
use windows::Win32::Foundation::RECT; use windows::Win32::Foundation::RECT;
use windows::Win32::Graphics::Direct3D11::ID3D11Device;
use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Direct3D12::{
ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4, ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12GraphicsCommandList4,
D3D12_RENDER_PASS_BEGINNING_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD, D3D12_RENDER_PASS_BEGINNING_ACCESS, D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD,

View file

@ -151,14 +151,14 @@ impl D3D12MipmapGen {
/// Enters a mipmapping compute context. /// Enters a mipmapping compute context.
/// This is a relatively expensive operation /// This is a relatively expensive operation
/// and should only be done at most a few times per frame. /// and should only be done at most a few times per frame.
pub fn mipmapping_context<F>( pub fn mipmapping_context<F, E>(
&self, &self,
cmd: &ID3D12GraphicsCommandList, cmd: &ID3D12GraphicsCommandList,
work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>, work_heap: &mut D3D12DescriptorHeap<ResourceWorkHeap>,
mut f: F, mut f: F,
) -> error::Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>> ) -> Result<Vec<D3D12DescriptorHeapSlot<ResourceWorkHeap>>, E>
where where
F: FnMut(&mut MipmapGenContext), F: FnMut(&mut MipmapGenContext) -> Result<(), E>,
{ {
let heap: ID3D12DescriptorHeap = (&(*work_heap)).into(); let heap: ID3D12DescriptorHeap = (&(*work_heap)).into();
unsafe { unsafe {
@ -168,7 +168,7 @@ impl D3D12MipmapGen {
} }
let mut context = MipmapGenContext::new(self, cmd, work_heap); let mut context = MipmapGenContext::new(self, cmd, work_heap);
f(&mut context); f(&mut context)?;
Ok(context.close()) Ok(context.close())
} }

View file

@ -18,6 +18,10 @@ pub struct FilterChainOptionsD3D12 {
pub force_hlsl_pipeline: bool, pub force_hlsl_pipeline: bool,
/// Whether or not to explicitly disable mipmap /// 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, pub force_no_mipmaps: bool,
} }