d3d12: bind logic
This commit is contained in:
parent
3506e1a3da
commit
10cd240868
|
@ -420,7 +420,8 @@ impl FilterChainD3D12 {
|
|||
pipeline: graphics_pipeline,
|
||||
config: config.clone(),
|
||||
texture_heap,
|
||||
sampler_heap
|
||||
sampler_heap,
|
||||
source,
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
use librashader_common::Size;
|
||||
use windows::Win32::Graphics::Direct3D11::ID3D11Device;
|
||||
use windows::Win32::Graphics::Direct3D12::ID3D12Device;
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, UniformBinding};
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, UniformBinding};
|
||||
use librashader_reflect::reflect::ShaderReflection;
|
||||
use librashader_runtime::binding::TextureInput;
|
||||
use librashader_runtime::binding::{BindSemantics, TextureInput};
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use crate::buffer::D3D12ConstantBuffer;
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::graphics_pipeline::D3D12GraphicsPipeline;
|
||||
use crate::heap::{D3D12DescriptorHeap, ResourceWorkHeap, SamplerWorkHeap};
|
||||
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap};
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::InputTexture;
|
||||
|
||||
pub(crate) struct FilterPass {
|
||||
|
@ -20,6 +25,8 @@ pub(crate) struct FilterPass {
|
|||
pub(crate) ubo_cbuffer: Option<D3D12ConstantBuffer>,
|
||||
pub(crate) texture_heap: D3D12DescriptorHeap<ResourceWorkHeap>,
|
||||
pub(crate) sampler_heap: D3D12DescriptorHeap<SamplerWorkHeap>,
|
||||
pub source: ShaderSource,
|
||||
|
||||
}
|
||||
|
||||
impl TextureInput for InputTexture {
|
||||
|
@ -27,3 +34,88 @@ impl TextureInput for InputTexture {
|
|||
self.size
|
||||
}
|
||||
}
|
||||
//
|
||||
impl BindSemantics for FilterPass {
|
||||
type InputTexture = InputTexture;
|
||||
type SamplerSet = SamplerSet;
|
||||
type DescriptorSet<'a> =
|
||||
(
|
||||
&'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
&'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
);
|
||||
type DeviceContext = ();
|
||||
type UniformOffset = MemberOffset;
|
||||
|
||||
fn bind_texture<'a>(
|
||||
descriptors: &mut Self::DescriptorSet<'a>,
|
||||
samplers: &Self::SamplerSet,
|
||||
binding: &TextureBinding,
|
||||
texture: &Self::InputTexture,
|
||||
_device: &Self::DeviceContext,
|
||||
) {
|
||||
let (texture_binding,
|
||||
sampler_binding) = descriptors;
|
||||
|
||||
unsafe {
|
||||
texture_binding[binding.binding as usize]
|
||||
.copy_descriptor(*texture.descriptor.as_ref());
|
||||
sampler_binding[binding.binding as usize]
|
||||
.copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).as_ref())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterPass {
|
||||
pub fn get_format(&self) -> ImageFormat {
|
||||
let fb_format = self.source.format;
|
||||
if let Some(format) = self.config.get_format_override() {
|
||||
format
|
||||
} else if fb_format == ImageFormat::Unknown {
|
||||
ImageFormat::R8G8B8A8Unorm
|
||||
} else {
|
||||
fb_format
|
||||
}
|
||||
}
|
||||
|
||||
// framecount should be pre-modded
|
||||
fn build_semantics<'a>(
|
||||
&mut self,
|
||||
pass_index: usize,
|
||||
parent: &FilterCommon,
|
||||
mvp: &[f32; 16],
|
||||
frame_count: u32,
|
||||
frame_direction: i32,
|
||||
fb_size: Size<u32>,
|
||||
viewport_size: Size<u32>,
|
||||
mut descriptors: (
|
||||
&'a mut [D3D12DescriptorHeapSlot<ResourceWorkHeap>; 16],
|
||||
&'a mut [D3D12DescriptorHeapSlot<SamplerWorkHeap>; 16],
|
||||
),
|
||||
original: &InputTexture,
|
||||
source: &InputTexture,
|
||||
) {
|
||||
Self::bind_semantics(
|
||||
&(),
|
||||
&parent.samplers,
|
||||
&mut self.uniform_storage,
|
||||
&mut descriptors,
|
||||
mvp,
|
||||
frame_count,
|
||||
frame_direction,
|
||||
fb_size,
|
||||
viewport_size,
|
||||
original,
|
||||
source,
|
||||
&self.uniform_bindings,
|
||||
&self.reflection.meta.texture_meta,
|
||||
parent.output_textures[0..pass_index]
|
||||
.iter()
|
||||
.map(|o| o.as_ref()),
|
||||
parent.feedback_textures.iter().map(|o| o.as_ref()),
|
||||
parent.history_textures.iter().map(|o| o.as_ref()),
|
||||
parent.luts.iter().map(|(u, i)| (*u, i.as_ref())),
|
||||
&self.source.parameters,
|
||||
&parent.config.parameters,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
use crate::error;
|
||||
use std::cell::RefCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
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_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE};
|
||||
|
||||
|
@ -22,7 +23,6 @@ pub struct ResourceWorkHeap;
|
|||
#[derive(Clone)]
|
||||
pub struct SamplerWorkHeap;
|
||||
|
||||
|
||||
impl const D3D12HeapType for SamplerPaletteHeap {
|
||||
// sampler palettes just get set directly
|
||||
fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC {
|
||||
|
@ -87,6 +87,21 @@ impl<T> D3D12DescriptorHeapSlot<T> {
|
|||
pub fn index(&self) -> usize {
|
||||
self.slot
|
||||
}
|
||||
|
||||
/// unsafe because type must match
|
||||
pub unsafe fn copy_descriptor(&mut self, source: D3D12_CPU_DESCRIPTOR_HANDLE) {
|
||||
unsafe {
|
||||
let heap = self.heap.deref()
|
||||
.borrow();
|
||||
|
||||
heap.device.CopyDescriptorsSimple(
|
||||
1,
|
||||
self.cpu_handle,
|
||||
source,
|
||||
heap.ty
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for D3D12DescriptorHeapSlot<T> {
|
||||
|
@ -258,23 +273,8 @@ impl<T> D3D12DescriptorHeap<T> {
|
|||
todo!("error need to fail");
|
||||
}
|
||||
|
||||
pub fn copy_descriptors<const NUM_DESC: usize>(&mut self,
|
||||
source: &[&D3D12_CPU_DESCRIPTOR_HANDLE; NUM_DESC])
|
||||
-> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> {
|
||||
pub fn alloc_range<const NUM_DESC: usize>(&mut self)-> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> {
|
||||
let dest = array_init::try_array_init(|_| self.alloc_slot())?;
|
||||
let inner = self.0.borrow_mut();
|
||||
|
||||
unsafe {
|
||||
// unfortunately we can't guarantee that the source and dest descriptors are contiguous so...
|
||||
for i in 0..NUM_DESC {
|
||||
inner.device.CopyDescriptorsSimple(
|
||||
1,
|
||||
*dest[i].as_ref(),
|
||||
*source[i],
|
||||
inner.ty
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(dest)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,7 @@ use crate::texture::InputTexture;
|
|||
|
||||
pub struct LutTexture {
|
||||
resource: ID3D12Resource,
|
||||
descriptor: D3D12DescriptorHeapSlot<CpuStagingHeap>,
|
||||
size: Size<u32>,
|
||||
filter: FilterMode,
|
||||
wrap_mode: WrapMode,
|
||||
view: InputTexture,
|
||||
miplevels: Option<u16>,
|
||||
}
|
||||
|
||||
|
@ -160,12 +157,16 @@ impl LutTexture {
|
|||
d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
|
||||
}
|
||||
|
||||
let view = InputTexture::new(
|
||||
descriptor,
|
||||
source.size,
|
||||
ImageFormat::R8G8B8A8Unorm,
|
||||
wrap_mode,
|
||||
filter,
|
||||
);
|
||||
Ok((LutTexture {
|
||||
resource,
|
||||
descriptor,
|
||||
size: source.size,
|
||||
filter,
|
||||
wrap_mode,
|
||||
view,
|
||||
miplevels: if mipmap { Some(miplevels) } else { None }
|
||||
}, upload))
|
||||
}
|
||||
|
@ -174,16 +175,15 @@ impl LutTexture {
|
|||
if let Some(miplevels) = self.miplevels {
|
||||
gen_mips.generate_mipmaps(&self.resource,
|
||||
miplevels,
|
||||
self.size, ImageFormat::R8G8B8A8Unorm.into())?
|
||||
self.view.size, ImageFormat::R8G8B8A8Unorm.into())?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_input(&self)
|
||||
-> InputTexture {
|
||||
InputTexture::new(self.descriptor.clone(),
|
||||
self.size, ImageFormat::R8G8B8A8Unorm,
|
||||
self.wrap_mode, self.filter)
|
||||
impl AsRef<InputTexture> for LutTexture {
|
||||
fn as_ref(&self) -> &InputTexture {
|
||||
&self.view
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
|
|||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot};
|
||||
|
||||
enum InputDescriptor {
|
||||
pub(crate) enum InputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
|
||||
}
|
||||
|
||||
enum OutputDescriptor {
|
||||
pub(crate) enum OutputDescriptor {
|
||||
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
|
||||
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
|
||||
}
|
||||
|
@ -59,11 +59,11 @@ impl OutputTexture {
|
|||
}
|
||||
|
||||
pub struct InputTexture {
|
||||
descriptor: InputDescriptor,
|
||||
pub(crate) descriptor: InputDescriptor,
|
||||
pub(crate) size: Size<u32>,
|
||||
format: ImageFormat,
|
||||
wrap_mode: WrapMode,
|
||||
filter: FilterMode
|
||||
pub(crate) wrap_mode: WrapMode,
|
||||
pub(crate) filter: FilterMode
|
||||
}
|
||||
|
||||
impl InputTexture {
|
||||
|
@ -100,3 +100,9 @@ impl InputTexture {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
impl AsRef<InputTexture> for InputTexture {
|
||||
fn as_ref(&self) -> &InputTexture {
|
||||
self
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue