2023-02-02 10:09:34 +11:00
|
|
|
use std::ops::Deref;
|
2023-01-24 18:02:27 +11:00
|
|
|
use crate::error;
|
2023-02-02 10:09:34 +11:00
|
|
|
use crate::descriptor_heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerPaletteHeap};
|
2023-01-25 15:15:43 +11:00
|
|
|
use librashader_common::{FilterMode, WrapMode};
|
|
|
|
use rustc_hash::FxHashMap;
|
|
|
|
use windows::Win32::Graphics::Direct3D12::{
|
|
|
|
ID3D12Device, D3D12_COMPARISON_FUNC_NEVER, D3D12_FLOAT32_MAX, D3D12_SAMPLER_DESC,
|
|
|
|
D3D12_TEXTURE_ADDRESS_MODE,
|
|
|
|
};
|
2023-01-22 07:34:13 +11:00
|
|
|
|
|
|
|
pub struct SamplerSet {
|
2023-01-25 15:15:43 +11:00
|
|
|
samplers: FxHashMap<(WrapMode, FilterMode), D3D12DescriptorHeapSlot<SamplerPaletteHeap>>,
|
|
|
|
heap: D3D12DescriptorHeap<SamplerPaletteHeap>,
|
2023-01-24 18:02:27 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SamplerSet {
|
2023-01-25 15:15:43 +11:00
|
|
|
pub fn get(
|
|
|
|
&self,
|
|
|
|
wrap: WrapMode,
|
|
|
|
filter: FilterMode,
|
|
|
|
) -> &D3D12DescriptorHeapSlot<SamplerPaletteHeap> {
|
2023-01-24 18:02:27 +11:00
|
|
|
self.samplers.get(&(wrap, filter)).unwrap()
|
|
|
|
}
|
|
|
|
pub fn new(device: &ID3D12Device) -> error::Result<SamplerSet> {
|
|
|
|
let mut samplers = FxHashMap::default();
|
|
|
|
let wrap_modes = &[
|
|
|
|
WrapMode::ClampToBorder,
|
|
|
|
WrapMode::ClampToEdge,
|
|
|
|
WrapMode::Repeat,
|
|
|
|
WrapMode::MirroredRepeat,
|
|
|
|
];
|
|
|
|
|
2023-02-01 09:50:47 +11:00
|
|
|
let mut heap = D3D12DescriptorHeap::new(device, 2 * wrap_modes.len())?;
|
2023-01-24 18:02:27 +11:00
|
|
|
|
|
|
|
for wrap_mode in wrap_modes {
|
|
|
|
unsafe {
|
2023-02-01 09:50:47 +11:00
|
|
|
let linear = heap.alloc_slot()?;
|
2023-01-24 18:02:27 +11:00
|
|
|
device.CreateSampler(
|
|
|
|
&D3D12_SAMPLER_DESC {
|
|
|
|
Filter: FilterMode::Linear.into(),
|
|
|
|
AddressU: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
AddressV: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
AddressW: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
MipLODBias: 0.0,
|
|
|
|
MaxAnisotropy: 1,
|
|
|
|
ComparisonFunc: D3D12_COMPARISON_FUNC_NEVER,
|
|
|
|
BorderColor: [0.0, 0.0, 0.0, 0.0],
|
|
|
|
MinLOD: -D3D12_FLOAT32_MAX,
|
|
|
|
MaxLOD: D3D12_FLOAT32_MAX,
|
|
|
|
},
|
2023-02-02 10:09:34 +11:00
|
|
|
*linear.deref().as_ref(),
|
2023-01-24 18:02:27 +11:00
|
|
|
);
|
|
|
|
|
2023-02-01 09:50:47 +11:00
|
|
|
let nearest = heap.alloc_slot()?;
|
2023-01-24 18:02:27 +11:00
|
|
|
device.CreateSampler(
|
|
|
|
&D3D12_SAMPLER_DESC {
|
|
|
|
Filter: FilterMode::Nearest.into(),
|
|
|
|
AddressU: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
AddressV: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
AddressW: D3D12_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
|
|
|
|
MipLODBias: 0.0,
|
|
|
|
MaxAnisotropy: 1,
|
|
|
|
ComparisonFunc: D3D12_COMPARISON_FUNC_NEVER,
|
|
|
|
BorderColor: [0.0, 0.0, 0.0, 0.0],
|
|
|
|
MinLOD: -D3D12_FLOAT32_MAX,
|
|
|
|
MaxLOD: D3D12_FLOAT32_MAX,
|
|
|
|
},
|
2023-02-02 10:09:34 +11:00
|
|
|
*nearest.deref().as_ref(),
|
2023-01-24 18:02:27 +11:00
|
|
|
);
|
|
|
|
|
|
|
|
samplers.insert((*wrap_mode, FilterMode::Linear), linear);
|
|
|
|
samplers.insert((*wrap_mode, FilterMode::Nearest), nearest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(SamplerSet { samplers, heap })
|
|
|
|
}
|
2023-01-22 07:34:13 +11:00
|
|
|
}
|