dx12: fix mipmapping
This commit is contained in:
parent
1fe4b47981
commit
99954f011f
|
@ -7,13 +7,7 @@ use std::ops::Deref;
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::error::FilterChainError;
|
||||
use windows::Win32::Graphics::Direct3D12::{
|
||||
ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC,
|
||||
D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE,
|
||||
};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, ID3D12Resource};
|
||||
|
||||
#[const_trait]
|
||||
pub trait D3D12HeapType {
|
||||
|
@ -169,6 +163,12 @@ impl<T: D3D12HeapType> D3D12DescriptorHeap<T> {
|
|||
}
|
||||
|
||||
impl<T> D3D12DescriptorHeap<T> {
|
||||
/// Gets a cloned handle to the inner heap
|
||||
pub fn handle(&self) -> ID3D12DescriptorHeap {
|
||||
let inner = self.0.borrow();
|
||||
inner.heap.clone()
|
||||
}
|
||||
|
||||
pub unsafe fn new_with_desc(
|
||||
device: &ID3D12Device,
|
||||
desc: D3D12_DESCRIPTOR_HEAP_DESC,
|
||||
|
@ -210,7 +210,8 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
pub unsafe fn suballocate(
|
||||
self,
|
||||
size: usize,
|
||||
) -> (Vec<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
|
||||
reserved: usize,
|
||||
) -> (Vec<D3D12DescriptorHeap<T>>, Option<D3D12DescriptorHeap<T>>, ID3D12DescriptorHeap) {
|
||||
// has to be called right after creation.
|
||||
assert_eq!(
|
||||
Rc::strong_count(&self.0),
|
||||
|
@ -222,9 +223,11 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
.expect("[d3d12] undefined behaviour to suballocate a descriptor heap with live descriptors.")
|
||||
.into_inner();
|
||||
|
||||
let num_descriptors = inner.num_descriptors - reserved;
|
||||
|
||||
// number of suballocated heaps
|
||||
let num_heaps = inner.num_descriptors / size;
|
||||
let remainder = inner.num_descriptors % size;
|
||||
let num_heaps = num_descriptors / size;
|
||||
let remainder = num_descriptors % size;
|
||||
|
||||
assert_eq!(
|
||||
remainder, 0,
|
||||
|
@ -259,6 +262,28 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
start += size;
|
||||
}
|
||||
|
||||
let mut reserved_heap = None;
|
||||
if reserved != 0 {
|
||||
assert_eq!(reserved, inner.num_descriptors - start, "The input heap could not fit the number of requested reserved descriptors.");
|
||||
let new_cpu_start = root_cpu_ptr + (start * inner.handle_size);
|
||||
let new_gpu_start = root_gpu_ptr.map(|r| D3D12_GPU_DESCRIPTOR_HANDLE {
|
||||
ptr: r + (start as u64 * inner.handle_size as u64),
|
||||
});
|
||||
|
||||
reserved_heap = Some(D3D12DescriptorHeapInner {
|
||||
device: inner.device.clone(),
|
||||
heap: inner.heap.clone(),
|
||||
ty: inner.ty,
|
||||
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE { ptr: new_cpu_start },
|
||||
gpu_start: new_gpu_start,
|
||||
handle_size: inner.handle_size,
|
||||
start: 0,
|
||||
num_descriptors: reserved,
|
||||
map: bitvec![0; reserved].into_boxed_bitslice(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
(
|
||||
heaps
|
||||
.into_iter()
|
||||
|
@ -266,6 +291,9 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
D3D12DescriptorHeap(Rc::new(RefCell::new(inner)), PhantomData::default())
|
||||
})
|
||||
.collect(),
|
||||
reserved_heap.map(|inner| {
|
||||
D3D12DescriptorHeap(Rc::new(RefCell::new(inner)), PhantomData::default())
|
||||
}),
|
||||
inner.heap,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -47,6 +47,10 @@ use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleO
|
|||
use windows::Win32::System::WindowsProgramming::INFINITE;
|
||||
|
||||
use rayon::prelude::*;
|
||||
use librashader_runtime::scaling::MipmapSize;
|
||||
|
||||
const MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS: usize = 1024;
|
||||
|
||||
type DxilShaderPassMeta =
|
||||
ShaderPassArtifact<impl CompileReflectShader<DXIL, GlslangCompilation> + Send>;
|
||||
type HlslShaderPassMeta =
|
||||
|
@ -66,7 +70,7 @@ pub struct FilterChainD3D12 {
|
|||
staging_heap: D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
rtv_heap: D3D12DescriptorHeap<RenderTargetHeap>,
|
||||
|
||||
texture_heap: ID3D12DescriptorHeap,
|
||||
work_heap: ID3D12DescriptorHeap,
|
||||
sampler_heap: ID3D12DescriptorHeap,
|
||||
|
||||
residuals: Vec<OutputDescriptor>,
|
||||
|
@ -123,7 +127,7 @@ impl FilterChainD3D12 {
|
|||
)?;
|
||||
|
||||
let samplers = SamplerSet::new(device)?;
|
||||
let mipmap_gen = D3D12MipmapGen::new(device)?;
|
||||
let mipmap_gen = D3D12MipmapGen::new(device, false)?;
|
||||
|
||||
let draw_quad = DrawQuad::new(device)?;
|
||||
let mut staging_heap = D3D12DescriptorHeap::new(
|
||||
|
@ -136,11 +140,11 @@ impl FilterChainD3D12 {
|
|||
)?;
|
||||
|
||||
let luts =
|
||||
FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen)?;
|
||||
FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures)?;
|
||||
|
||||
let root_signature = D3D12RootSignature::new(device)?;
|
||||
|
||||
let (texture_heap, sampler_heap, filters) = FilterChainD3D12::init_passes(
|
||||
let (texture_heap, sampler_heap, filters, mipmap_heap) = FilterChainD3D12::init_passes(
|
||||
device,
|
||||
&root_signature,
|
||||
passes,
|
||||
|
@ -181,8 +185,6 @@ impl FilterChainD3D12 {
|
|||
let (history_framebuffers, history_textures) =
|
||||
FilterChainD3D12::init_history(device, &filters)?;
|
||||
|
||||
let mipmap_heap: D3D12DescriptorHeap<ResourceWorkHeap> =
|
||||
D3D12DescriptorHeap::new(device, u16::MAX as usize)?;
|
||||
Ok(FilterChainD3D12 {
|
||||
common: FilterCommon {
|
||||
d3d12: device.clone(),
|
||||
|
@ -209,7 +211,7 @@ impl FilterChainD3D12 {
|
|||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
texture_heap,
|
||||
work_heap: texture_heap,
|
||||
sampler_heap,
|
||||
mipmap_heap,
|
||||
disable_mipmaps: options.map_or(false, |o| o.force_no_mipmaps),
|
||||
|
@ -252,8 +254,9 @@ impl FilterChainD3D12 {
|
|||
device: &ID3D12Device,
|
||||
heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
|
||||
textures: &[TextureConfig],
|
||||
mipmap_gen: &D3D12MipmapGen,
|
||||
) -> error::Result<FxHashMap<usize, LutTexture>> {
|
||||
// use separate mipgen to load luts.
|
||||
let mipmap_gen = D3D12MipmapGen::new(device, true)?;
|
||||
let mut work_heap: D3D12DescriptorHeap<ResourceWorkHeap> =
|
||||
D3D12DescriptorHeap::new(device, u16::MAX as usize)?;
|
||||
unsafe {
|
||||
|
@ -339,20 +342,20 @@ impl FilterChainD3D12 {
|
|||
hlsl_passes: Vec<HlslShaderPassMeta>,
|
||||
semantics: &ShaderSemantics,
|
||||
force_hlsl: bool,
|
||||
) -> error::Result<(ID3D12DescriptorHeap, ID3D12DescriptorHeap, Vec<FilterPass>)> {
|
||||
) -> error::Result<(ID3D12DescriptorHeap, ID3D12DescriptorHeap, Vec<FilterPass>, D3D12DescriptorHeap<ResourceWorkHeap>)> {
|
||||
let shader_count = passes.len();
|
||||
let work_heap = D3D12DescriptorHeap::<ResourceWorkHeap>::new(
|
||||
device,
|
||||
(MAX_BINDINGS_COUNT as usize) * shader_count,
|
||||
(MAX_BINDINGS_COUNT as usize) * shader_count + MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS,
|
||||
)?;
|
||||
let (work_heaps, texture_heap_handle) =
|
||||
unsafe { work_heap.suballocate(MAX_BINDINGS_COUNT as usize) };
|
||||
let (work_heaps, mipmap_heap, texture_heap_handle) =
|
||||
unsafe { work_heap.suballocate(MAX_BINDINGS_COUNT as usize, MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS) };
|
||||
|
||||
let sampler_work_heap =
|
||||
D3D12DescriptorHeap::new(device, (MAX_BINDINGS_COUNT as usize) * shader_count)?;
|
||||
|
||||
let (sampler_work_heaps, sampler_heap_handle) =
|
||||
unsafe { sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize) };
|
||||
let (sampler_work_heaps, _, sampler_heap_handle) =
|
||||
unsafe { sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize, 0) };
|
||||
|
||||
let filters: Vec<error::Result<_>> = passes.into_par_iter()
|
||||
.zip(hlsl_passes)
|
||||
|
@ -468,7 +471,8 @@ impl FilterChainD3D12 {
|
|||
let filters: error::Result<Vec<_>> = filters.into_iter().collect();
|
||||
let filters = filters?;
|
||||
|
||||
Ok((texture_heap_handle, sampler_heap_handle, filters))
|
||||
// Panic SAFETY: mipmap_heap is always 1024 descriptors.
|
||||
Ok((texture_heap_handle, sampler_heap_handle, filters, mipmap_heap.unwrap()))
|
||||
}
|
||||
|
||||
fn push_history(
|
||||
|
@ -595,32 +599,32 @@ impl FilterChainD3D12 {
|
|||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
||||
|
||||
unsafe {
|
||||
let heaps = [self.texture_heap.clone(), self.sampler_heap.clone()];
|
||||
let heaps = [self.work_heap.clone(), self.sampler_heap.clone()];
|
||||
cmd.SetDescriptorHeaps(&heaps);
|
||||
cmd.SetGraphicsRootSignature(&self.common.root_signature.handle);
|
||||
self.common.mipmap_gen.pin_root_signature(cmd);
|
||||
}
|
||||
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,
|
||||
// )?;
|
||||
// Ok::<(), FilterChainError>(())
|
||||
// },
|
||||
// )?;
|
||||
// }
|
||||
// }
|
||||
if pass.config.mipmap_input && !self.disable_mipmaps {
|
||||
unsafe {
|
||||
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,
|
||||
)?;
|
||||
Ok::<(), FilterChainError>(())
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
let target = &self.output_framebuffers[index];
|
||||
util::d3d12_resource_transition(
|
||||
|
@ -666,11 +670,6 @@ impl FilterChainD3D12 {
|
|||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
);
|
||||
|
||||
// let target_handle = target.create_shader_resource_view(
|
||||
// &mut self.staging_heap,
|
||||
// pass.config.filter,
|
||||
// pass.config.wrap_mode,
|
||||
// )?;
|
||||
self.residuals.push(out.output.descriptor);
|
||||
source = self.common.output_textures[index].as_ref().unwrap().clone()
|
||||
}
|
||||
|
|
|
@ -8,25 +8,26 @@ use librashader_reflect::back::ShaderCompilerOutput;
|
|||
use librashader_reflect::reflect::semantics::BindingStage;
|
||||
use windows::Win32::Foundation::BOOL;
|
||||
use windows::Win32::Graphics::Direct3D::Dxc::{IDxcBlob, IDxcCompiler, IDxcUtils, IDxcValidator};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12PipelineState, ID3D12RootSignature, D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA, D3D12_COLOR_WRITE_ENABLE_ALL, D3D12_CULL_MODE_NONE, D3D12_DESCRIPTOR_RANGE, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_FILL_MODE_SOLID, D3D12_GRAPHICS_PIPELINE_STATE_DESC, D3D12_INPUT_LAYOUT_DESC, D3D12_LOGIC_OP_NOOP, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, D3D12_RASTERIZER_DESC, D3D12_RENDER_TARGET_BLEND_DESC, D3D12_ROOT_DESCRIPTOR, D3D12_ROOT_DESCRIPTOR_TABLE, D3D12_ROOT_PARAMETER, D3D12_ROOT_PARAMETER_0, D3D12_ROOT_PARAMETER_TYPE_CBV, D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, D3D12_ROOT_SIGNATURE_DESC, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT, D3D12_SHADER_BYTECODE, D3D12_SHADER_VISIBILITY_ALL, D3D12_SHADER_VISIBILITY_PIXEL, D3D_ROOT_SIGNATURE_VERSION_1, D3D12SerializeVersionedRootSignature, D3D12_VERSIONED_ROOT_SIGNATURE_DESC, D3D_ROOT_SIGNATURE_VERSION_1_0, D3D12_VERSIONED_ROOT_SIGNATURE_DESC_0};
|
||||
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12PipelineState, ID3D12RootSignature, D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA, D3D12_COLOR_WRITE_ENABLE_ALL, D3D12_CULL_MODE_NONE, D3D12_DESCRIPTOR_RANGE, D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_FILL_MODE_SOLID, D3D12_GRAPHICS_PIPELINE_STATE_DESC, D3D12_INPUT_LAYOUT_DESC, D3D12_LOGIC_OP_NOOP, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, D3D12_RASTERIZER_DESC, D3D12_RENDER_TARGET_BLEND_DESC, D3D12_ROOT_DESCRIPTOR, D3D12_ROOT_DESCRIPTOR_TABLE, D3D12_ROOT_PARAMETER, D3D12_ROOT_PARAMETER_0, D3D12_ROOT_PARAMETER_TYPE_CBV, D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, D3D12_ROOT_SIGNATURE_DESC, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT, D3D12_SHADER_BYTECODE, D3D12_SHADER_VISIBILITY_ALL, D3D12_SHADER_VISIBILITY_PIXEL, D3D_ROOT_SIGNATURE_VERSION_1, D3D12SerializeVersionedRootSignature, D3D12_VERSIONED_ROOT_SIGNATURE_DESC, D3D_ROOT_SIGNATURE_VERSION_1_0, D3D12_VERSIONED_ROOT_SIGNATURE_DESC_0, D3D_ROOT_SIGNATURE_VERSION_1_1, D3D12_ROOT_SIGNATURE_DESC1, D3D12_ROOT_PARAMETER1, D3D12_ROOT_PARAMETER1_0, D3D12_ROOT_DESCRIPTOR1, D3D12_ROOT_DESCRIPTOR_TABLE1, D3D12_DESCRIPTOR_RANGE1, D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE, D3D12_DESCRIPTOR_RANGE_FLAG_NONE, D3D12_ROOT_DESCRIPTOR_FLAG_NONE, D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE, D3D12_DESCRIPTOR_RANGE_FLAGS};
|
||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC};
|
||||
|
||||
pub struct D3D12GraphicsPipeline {
|
||||
pub(crate) handle: ID3D12PipelineState,
|
||||
}
|
||||
|
||||
const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
||||
const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER1; 4] = &[
|
||||
// srvs
|
||||
D3D12_ROOT_PARAMETER {
|
||||
D3D12_ROOT_PARAMETER1 {
|
||||
ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
|
||||
Anonymous: D3D12_ROOT_PARAMETER_0 {
|
||||
DescriptorTable: D3D12_ROOT_DESCRIPTOR_TABLE {
|
||||
Anonymous: D3D12_ROOT_PARAMETER1_0 {
|
||||
DescriptorTable: D3D12_ROOT_DESCRIPTOR_TABLE1 {
|
||||
NumDescriptorRanges: 1,
|
||||
pDescriptorRanges: &D3D12_DESCRIPTOR_RANGE {
|
||||
pDescriptorRanges: &D3D12_DESCRIPTOR_RANGE1 {
|
||||
RangeType: D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
|
||||
NumDescriptors: 16,
|
||||
BaseShaderRegister: 0,
|
||||
RegisterSpace: 0,
|
||||
Flags: D3D12_DESCRIPTOR_RANGE_FLAGS(D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE.0 | D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE.0),
|
||||
OffsetInDescriptorsFromTableStart: 0,
|
||||
},
|
||||
},
|
||||
|
@ -34,16 +35,17 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
// samplers
|
||||
D3D12_ROOT_PARAMETER {
|
||||
D3D12_ROOT_PARAMETER1 {
|
||||
ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
|
||||
Anonymous: D3D12_ROOT_PARAMETER_0 {
|
||||
DescriptorTable: D3D12_ROOT_DESCRIPTOR_TABLE {
|
||||
Anonymous: D3D12_ROOT_PARAMETER1_0 {
|
||||
DescriptorTable: D3D12_ROOT_DESCRIPTOR_TABLE1 {
|
||||
NumDescriptorRanges: 1,
|
||||
pDescriptorRanges: &D3D12_DESCRIPTOR_RANGE {
|
||||
pDescriptorRanges: &D3D12_DESCRIPTOR_RANGE1 {
|
||||
RangeType: D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
|
||||
NumDescriptors: 16,
|
||||
BaseShaderRegister: 0,
|
||||
RegisterSpace: 0,
|
||||
Flags: D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE,
|
||||
OffsetInDescriptorsFromTableStart: 0,
|
||||
},
|
||||
},
|
||||
|
@ -51,22 +53,25 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
ShaderVisibility: D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
// UBO
|
||||
D3D12_ROOT_PARAMETER {
|
||||
D3D12_ROOT_PARAMETER1 {
|
||||
ParameterType: D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||
Anonymous: D3D12_ROOT_PARAMETER_0 {
|
||||
Descriptor: D3D12_ROOT_DESCRIPTOR {
|
||||
Anonymous: D3D12_ROOT_PARAMETER1_0 {
|
||||
Descriptor: D3D12_ROOT_DESCRIPTOR1 {
|
||||
ShaderRegister: 0,
|
||||
RegisterSpace: 0,
|
||||
Flags: D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
|
||||
},
|
||||
D3D12_ROOT_PARAMETER {
|
||||
// push
|
||||
D3D12_ROOT_PARAMETER1 {
|
||||
ParameterType: D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||
Anonymous: D3D12_ROOT_PARAMETER_0 {
|
||||
Descriptor: D3D12_ROOT_DESCRIPTOR {
|
||||
Anonymous: D3D12_ROOT_PARAMETER1_0 {
|
||||
Descriptor: D3D12_ROOT_DESCRIPTOR1 {
|
||||
ShaderRegister: 1,
|
||||
RegisterSpace: 0,
|
||||
Flags: D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
},
|
||||
ShaderVisibility: D3D12_SHADER_VISIBILITY_ALL,
|
||||
|
@ -74,9 +79,9 @@ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
|
|||
];
|
||||
|
||||
const D3D12_SLANG_VERSIONED_ROOT_SIGNATURE: &D3D12_VERSIONED_ROOT_SIGNATURE_DESC = &D3D12_VERSIONED_ROOT_SIGNATURE_DESC {
|
||||
Version: D3D_ROOT_SIGNATURE_VERSION_1_0,
|
||||
Version: D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||
Anonymous: D3D12_VERSIONED_ROOT_SIGNATURE_DESC_0 {
|
||||
Desc_1_0: D3D12_ROOT_SIGNATURE_DESC {
|
||||
Desc_1_1: D3D12_ROOT_SIGNATURE_DESC1 {
|
||||
NumParameters: D3D12_SLANG_ROOT_PARAMETERS.len() as u32,
|
||||
pParameters: D3D12_SLANG_ROOT_PARAMETERS.as_ptr(),
|
||||
NumStaticSamplers: 0,
|
||||
|
|
|
@ -30,8 +30,8 @@ static GENERATE_MIPS_SRC: &[u8] = b"
|
|||
\" DENY_GEOMETRY_SHADER_ROOT_ACCESS |\" \\
|
||||
\" DENY_HULL_SHADER_ROOT_ACCESS |\" \\
|
||||
\" DENY_PIXEL_SHADER_ROOT_ACCESS ),\" \\
|
||||
\"DescriptorTable ( SRV(t0, flags=DATA_VOLATILE) ),\" \\
|
||||
\"DescriptorTable ( UAV(u0, flags=DATA_VOLATILE) ),\" \\
|
||||
\"DescriptorTable ( SRV(t0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),\" \\
|
||||
\"DescriptorTable ( UAV(u0, flags=DATA_VOLATILE|DESCRIPTORS_VOLATILE) ),\" \\
|
||||
\"RootConstants(num32BitConstants=3, b0),\" \\
|
||||
\"StaticSampler(s0,\"\\
|
||||
\" filter = FILTER_MIN_MAG_LINEAR_MIP_POINT,\"\\
|
||||
|
@ -66,6 +66,8 @@ pub struct D3D12MipmapGen {
|
|||
device: ID3D12Device,
|
||||
root_signature: ID3D12RootSignature,
|
||||
pipeline: ID3D12PipelineState,
|
||||
own_heaps: bool,
|
||||
root_index_offset: usize,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Zeroable, Pod)]
|
||||
|
@ -121,7 +123,7 @@ impl<'a> MipmapGenContext<'a> {
|
|||
}
|
||||
|
||||
impl D3D12MipmapGen {
|
||||
pub fn new(device: &ID3D12Device) -> error::Result<D3D12MipmapGen> {
|
||||
pub fn new(device: &ID3D12Device, own_heaps: bool) -> error::Result<D3D12MipmapGen> {
|
||||
unsafe {
|
||||
let blob = fxc_compile_shader(GENERATE_MIPS_SRC, b"main\0", b"cs_5_1\0")?;
|
||||
let blob =
|
||||
|
@ -144,13 +146,29 @@ impl D3D12MipmapGen {
|
|||
device: device.clone(),
|
||||
root_signature,
|
||||
pipeline,
|
||||
own_heaps,
|
||||
root_index_offset: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// If own_heap is false, this sets the compute root signature.
|
||||
/// Otherwise, this does nothing and the root signature is set upon entering a
|
||||
/// Mipmapping Context
|
||||
pub fn pin_root_signature(&self, cmd: &ID3D12GraphicsCommandList) {
|
||||
if !self.own_heaps {
|
||||
unsafe {
|
||||
cmd.SetComputeRootSignature(&self.root_signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Enters a mipmapping compute context.
|
||||
/// This is a relatively expensive operation
|
||||
/// This is a relatively expensive operation if set_heap is true,
|
||||
/// and should only be done at most a few times per frame.
|
||||
///
|
||||
/// If own_heap is false, then you must ensure that the compute root signature
|
||||
/// is already bound before entering the context.
|
||||
pub fn mipmapping_context<F, E>(
|
||||
&self,
|
||||
cmd: &ID3D12GraphicsCommandList,
|
||||
|
@ -162,9 +180,12 @@ impl D3D12MipmapGen {
|
|||
{
|
||||
let heap: ID3D12DescriptorHeap = (&(*work_heap)).into();
|
||||
unsafe {
|
||||
cmd.SetComputeRootSignature(&self.root_signature);
|
||||
cmd.SetPipelineState(&self.pipeline);
|
||||
cmd.SetDescriptorHeaps(&[heap]);
|
||||
|
||||
if self.own_heaps {
|
||||
cmd.SetComputeRootSignature(&self.root_signature);
|
||||
cmd.SetDescriptorHeaps(&[heap]);
|
||||
}
|
||||
}
|
||||
|
||||
let mut context = MipmapGenContext::new(self, cmd, work_heap);
|
||||
|
@ -291,6 +312,14 @@ impl D3D12MipmapGen {
|
|||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
i,
|
||||
);
|
||||
|
||||
util::d3d12_resource_transition_subresource(
|
||||
cmd,
|
||||
resource,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||
i - 1,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(heap_slots)
|
||||
|
|
Loading…
Reference in a new issue