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::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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue