d3d12: implement sampler palette
This commit is contained in:
parent
4dc34fceb2
commit
2f82c5f430
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -746,6 +746,7 @@ name = "librashader-runtime-d3d12"
|
|||
version = "0.1.0-beta.8"
|
||||
dependencies = [
|
||||
"array-init",
|
||||
"bit-set",
|
||||
"bytemuck",
|
||||
"gfx-maths",
|
||||
"librashader-common",
|
||||
|
|
|
@ -15,6 +15,7 @@ description = "RetroArch shaders for all."
|
|||
default = []
|
||||
opengl = ["gl"]
|
||||
d3d11 = ["windows", "dxgi"]
|
||||
d3d12 = ["windows", "dxgi"]
|
||||
dxgi = ["windows"]
|
||||
vulkan = ["ash"]
|
||||
|
||||
|
@ -32,4 +33,5 @@ features = [
|
|||
"Win32_Graphics_Dxgi_Common",
|
||||
"Win32_Graphics_Direct3D",
|
||||
"Win32_Graphics_Direct3D11",
|
||||
"Win32_Graphics_Direct3D12",
|
||||
]
|
||||
|
|
22
librashader-common/src/d3d12.rs
Normal file
22
librashader-common/src/d3d12.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use crate::{FilterMode, WrapMode};
|
||||
use windows::Win32::Graphics::Direct3D12;
|
||||
|
||||
impl From<WrapMode> for Direct3D12::D3D12_TEXTURE_ADDRESS_MODE {
|
||||
fn from(value: WrapMode) -> Self {
|
||||
match value {
|
||||
WrapMode::ClampToBorder => Direct3D12::D3D12_TEXTURE_ADDRESS_MODE_BORDER,
|
||||
WrapMode::ClampToEdge => Direct3D12::D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
|
||||
WrapMode::Repeat => Direct3D12::D3D12_TEXTURE_ADDRESS_MODE_WRAP,
|
||||
WrapMode::MirroredRepeat => Direct3D12::D3D12_TEXTURE_ADDRESS_MODE_MIRROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FilterMode> for Direct3D12::D3D12_FILTER {
|
||||
fn from(value: FilterMode) -> Self {
|
||||
match value {
|
||||
FilterMode::Linear => Direct3D12::D3D12_FILTER_MIN_MAG_MIP_LINEAR,
|
||||
_ => Direct3D12::D3D12_FILTER_MIN_MAG_MIP_POINT,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,10 @@ pub mod dxgi;
|
|||
#[cfg(all(target_os = "windows", feature = "d3d11"))]
|
||||
pub mod d3d11;
|
||||
|
||||
/// Direct3D 12 common conversions.
|
||||
#[cfg(all(target_os = "windows", feature = "d3d12"))]
|
||||
pub mod d3d12;
|
||||
|
||||
mod viewport;
|
||||
pub use viewport::Viewport;
|
||||
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_GPU_DESCRIPTOR_HANDLE, ID3D12DescriptorHeap, ID3D12Device};
|
||||
use crate::error;
|
||||
|
||||
pub struct D3D12DescriptorHeapSlot {
|
||||
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
heap: Arc<D3D12DescriptorHeap>
|
||||
}
|
||||
|
||||
pub struct D3D12DescriptorHeap {
|
||||
heap: ID3D12DescriptorHeap,
|
||||
desc: D3D12_DESCRIPTOR_HEAP_DESC,
|
||||
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
gpu_handle: D3D12_GPU_DESCRIPTOR_HANDLE,
|
||||
alignment: u32,
|
||||
map: Box<[bool]>,
|
||||
start: usize
|
||||
}
|
||||
|
||||
impl D3D12DescriptorHeap {
|
||||
pub fn new(device: &ID3D12Device, desc: D3D12_DESCRIPTOR_HEAP_DESC) -> error::Result<Arc<D3D12DescriptorHeap>> {
|
||||
unsafe {
|
||||
let heap: ID3D12DescriptorHeap = device.CreateDescriptorHeap(&desc)?;
|
||||
let cpu_handle = heap.GetCPUDescriptorHandleForHeapStart();
|
||||
let gpu_handle = heap.GetGPUDescriptorHandleForHeapStart();
|
||||
let alignment = device.GetDescriptorHandleIncrementSize(desc.Type);
|
||||
let mut map = Vec::new();
|
||||
map.resize(desc.NumDescriptors as usize, false);
|
||||
|
||||
Ok(Arc::new(D3D12DescriptorHeap {
|
||||
heap,
|
||||
desc,
|
||||
cpu_handle,
|
||||
gpu_handle,
|
||||
alignment,
|
||||
map: Box::new([]),
|
||||
start: 0,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate_slot(self: &Arc<D3D12DescriptorHeap>) -> error::Result<D3D12DescriptorHeapSlot> {
|
||||
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
|
||||
|
||||
for i in self.start..self.desc.NumDescriptors as usize {
|
||||
if !self.map[i] {
|
||||
self.map[i] = true;
|
||||
handle.ptr = self.cpu_handle.ptr + (i * self.alignment) as u64;
|
||||
self.start = i + 1;
|
||||
return Ok(D3D12DescriptorHeapSlot {
|
||||
cpu_handle: handle,
|
||||
heap: Arc::clone(self),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
todo!("error need to fail");
|
||||
}
|
||||
|
||||
pub fn free_slot(&mut self) -> error::Result<D3D12_CPU_DESCRIPTOR_HANDLE> {
|
||||
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
|
||||
|
||||
for i in self.start..self.desc.NumDescriptors as usize {
|
||||
if !self.map[i] {
|
||||
self.map[i] = true;
|
||||
handle.ptr = self.cpu_handle.ptr + (i * self.alignment) as u64;
|
||||
self.start = i + 1;
|
||||
return Ok(handle);
|
||||
}
|
||||
}
|
||||
|
||||
todo!("error need to fail");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Drop
|
|
@ -2,11 +2,13 @@ use std::error::Error;
|
|||
use std::path::Path;
|
||||
use rustc_hash::FxHashMap;
|
||||
use windows::Win32::Graphics::Direct3D12::ID3D12Device;
|
||||
use librashader_presets::ShaderPreset;
|
||||
use librashader_presets::{ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::targets::HLSL;
|
||||
use librashader_reflect::front::GlslangCompilation;
|
||||
use librashader_reflect::reflect::presets::CompilePresetTarget;
|
||||
use crate::error;
|
||||
use crate::samplers::SamplerSet;
|
||||
use crate::texture::LutTexture;
|
||||
|
||||
pub struct FilterChainD3D12 {
|
||||
pub(crate) common: FilterCommon,
|
||||
|
@ -20,7 +22,7 @@ pub struct FilterChainD3D12 {
|
|||
pub(crate) struct FilterCommon {
|
||||
pub(crate) d3d12: ID3D12Device,
|
||||
// pub(crate) luts: FxHashMap<usize, LutTexture>,
|
||||
// pub samplers: SamplerSet,
|
||||
pub samplers: SamplerSet,
|
||||
// pub output_textures: Box<[Option<InputTexture>]>,
|
||||
// pub feedback_textures: Box<[Option<InputTexture>]>,
|
||||
// pub history_textures: Box<[Option<InputTexture>]>,
|
||||
|
@ -31,16 +33,25 @@ pub(crate) struct FilterCommon {
|
|||
impl FilterChainD3D12 {
|
||||
/// Load the shader preset at the given path into a filter chain.
|
||||
pub fn load_from_path(
|
||||
device: &ID3D12Device,
|
||||
path: impl AsRef<Path>,
|
||||
options: Option<&()>,
|
||||
) -> error::Result<FilterChainD3D12> {
|
||||
// load passes from preset
|
||||
let preset = ShaderPreset::try_parse(path)?;
|
||||
Self::load_from_preset(preset, options)
|
||||
Self::load_from_preset(device, preset, options)
|
||||
}
|
||||
|
||||
fn load_luts(
|
||||
device: &ID3D12Device,
|
||||
textures: &[TextureConfig],
|
||||
) -> error::Result<FxHashMap<usize, LutTexture>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||
pub fn load_from_preset(
|
||||
device: &ID3D12Device,
|
||||
preset: ShaderPreset,
|
||||
options: Option<&()>,
|
||||
) -> error::Result<FilterChainD3D12> {
|
||||
|
@ -49,7 +60,12 @@ impl FilterChainD3D12 {
|
|||
Box<dyn Error>,
|
||||
>(preset.shaders, &preset.textures)?;
|
||||
|
||||
|
||||
todo!()
|
||||
let samplers = SamplerSet::new(&device)?;
|
||||
Ok(FilterChainD3D12 {
|
||||
common: FilterCommon {
|
||||
d3d12: device.clone(),
|
||||
samplers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
130
librashader-runtime-d3d12/src/heap.rs
Normal file
130
librashader-runtime-d3d12/src/heap.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
use std::cell::RefCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, ID3D12DescriptorHeap, ID3D12Device};
|
||||
use crate::error;
|
||||
|
||||
#[const_trait]
|
||||
pub trait D3D12HeapType {
|
||||
fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC;
|
||||
}
|
||||
pub struct SamplerHeap;
|
||||
|
||||
impl const D3D12HeapType for SamplerHeap
|
||||
{
|
||||
fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC {
|
||||
D3D12_DESCRIPTOR_HEAP_DESC {
|
||||
Type: D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
|
||||
NumDescriptors: size as u32,
|
||||
Flags: D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE,
|
||||
NodeMask: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct D3D12DescriptorHeapSlot<T> {
|
||||
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
gpu_handle: D3D12_GPU_DESCRIPTOR_HANDLE,
|
||||
heap: Arc<RefCell<D3D12DescriptorHeapInner>>,
|
||||
slot: usize,
|
||||
_pd: PhantomData<T>
|
||||
}
|
||||
|
||||
impl<T> D3D12DescriptorHeapSlot<T> {
|
||||
/// Get the index of the resource within the heap.
|
||||
pub fn index(&self) -> usize {
|
||||
self.slot
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for D3D12DescriptorHeapSlot<T> {
|
||||
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
|
||||
&self.cpu_handle
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE> for D3D12DescriptorHeapSlot<T> {
|
||||
fn as_ref(&self) -> &D3D12_GPU_DESCRIPTOR_HANDLE {
|
||||
&self.gpu_handle
|
||||
}
|
||||
}
|
||||
|
||||
struct D3D12DescriptorHeapInner {
|
||||
heap: ID3D12DescriptorHeap,
|
||||
desc: D3D12_DESCRIPTOR_HEAP_DESC,
|
||||
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE,
|
||||
gpu_start: D3D12_GPU_DESCRIPTOR_HANDLE,
|
||||
handle_size: usize,
|
||||
start: usize,
|
||||
// Bit flag representation of available handles in the heap.
|
||||
//
|
||||
// 0 - Occupied
|
||||
// 1 - free
|
||||
map: Box<[bool]>,
|
||||
}
|
||||
|
||||
pub struct D3D12DescriptorHeap<T>(Arc<RefCell<D3D12DescriptorHeapInner>>, PhantomData<T>);
|
||||
|
||||
impl<T:D3D12HeapType> D3D12DescriptorHeap<T> {
|
||||
pub fn new(device: &ID3D12Device, size: usize) -> error::Result<D3D12DescriptorHeap<T>> {
|
||||
let desc = T::get_desc(size);
|
||||
unsafe {
|
||||
D3D12DescriptorHeap::new_with_desc(device, desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> D3D12DescriptorHeap<T> {
|
||||
pub unsafe fn new_with_desc(device: &ID3D12Device, desc: D3D12_DESCRIPTOR_HEAP_DESC) -> error::Result<D3D12DescriptorHeap<T>> {
|
||||
unsafe {
|
||||
let heap: ID3D12DescriptorHeap = device.CreateDescriptorHeap(&desc)?;
|
||||
let cpu_start = heap.GetCPUDescriptorHandleForHeapStart();
|
||||
let gpu_start = heap.GetGPUDescriptorHandleForHeapStart();
|
||||
Ok(D3D12DescriptorHeap(Arc::new(RefCell::new(D3D12DescriptorHeapInner {
|
||||
heap,
|
||||
desc,
|
||||
cpu_start,
|
||||
gpu_start,
|
||||
handle_size: device.GetDescriptorHandleIncrementSize(desc.Type) as usize,
|
||||
start: 0,
|
||||
map: vec![false; desc.NumDescriptors as usize].into_boxed_slice(),
|
||||
})), PhantomData::default()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_slot(&mut self) -> error::Result<D3D12DescriptorHeapSlot<T>> {
|
||||
let mut handle = D3D12_CPU_DESCRIPTOR_HANDLE { ptr: 0 };
|
||||
|
||||
let mut inner = self.0.borrow_mut();
|
||||
for i in inner.start..inner.desc.NumDescriptors as usize {
|
||||
if !inner.map[i] {
|
||||
inner.map[i] = true;
|
||||
handle.ptr = inner.cpu_start.ptr + (i * inner.handle_size);
|
||||
inner.start = i + 1;
|
||||
|
||||
let gpu_handle = D3D12_GPU_DESCRIPTOR_HANDLE {
|
||||
ptr: (handle.ptr as u64 - inner.cpu_start.ptr as u64 + inner.gpu_start.ptr),
|
||||
};
|
||||
return Ok(D3D12DescriptorHeapSlot {
|
||||
cpu_handle: handle,
|
||||
slot: i,
|
||||
heap: Arc::clone(&self.0),
|
||||
gpu_handle,
|
||||
_pd: Default::default(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
todo!("error need to fail");
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for D3D12DescriptorHeapSlot<T> {
|
||||
fn drop(&mut self) {
|
||||
let mut inner = self.heap.borrow_mut();
|
||||
inner.map[self.slot] = false;
|
||||
if inner.start > self.slot {
|
||||
inner.start = self.slot
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
use std::ffi::CStr;
|
||||
use windows::{
|
||||
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
||||
Win32::Graphics::Direct3D12::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
||||
|
@ -27,9 +28,10 @@ float4 PSMain(PSInput input) : SV_TARGET
|
|||
}\0";
|
||||
|
||||
use std::mem::transmute;
|
||||
use std::path::Path;
|
||||
|
||||
pub trait DXSample {
|
||||
fn new(command_line: &SampleCommandLine) -> Result<Self>
|
||||
fn new(filter: impl AsRef<Path>, command_line: &SampleCommandLine) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
|
@ -221,7 +223,17 @@ fn get_hardware_adapter(factory: &IDXGIFactory4) -> Result<IDXGIAdapter1> {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
unsafe extern "system" fn debug_log(category: D3D12_MESSAGE_CATEGORY, severity: D3D12_MESSAGE_SEVERITY, id: D3D12_MESSAGE_ID, pdescription: ::windows::core::PCSTR, pcontext: *mut ::core::ffi::c_void) {
|
||||
unsafe {
|
||||
let desc = CStr::from_ptr(pdescription.as_ptr().cast());
|
||||
eprintln!("[{severity:?}-{category:?}] {desc:?}")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub mod d3d12_hello_triangle {
|
||||
use std::path::Path;
|
||||
use crate::filter_chain::FilterChainD3D12;
|
||||
use super::*;
|
||||
|
||||
const FRAME_COUNT: u32 = 2;
|
||||
|
@ -230,6 +242,7 @@ pub mod d3d12_hello_triangle {
|
|||
dxgi_factory: IDXGIFactory4,
|
||||
device: ID3D12Device,
|
||||
resources: Option<Resources>,
|
||||
pub filter: FilterChainD3D12,
|
||||
}
|
||||
|
||||
struct Resources {
|
||||
|
@ -258,13 +271,20 @@ pub mod d3d12_hello_triangle {
|
|||
}
|
||||
|
||||
impl DXSample for Sample {
|
||||
fn new(command_line: &SampleCommandLine) -> Result<Self> {
|
||||
fn new(filter: impl AsRef<Path>, command_line: &SampleCommandLine) -> Result<Self> {
|
||||
let (dxgi_factory, device) = create_device(command_line)?;
|
||||
//
|
||||
// let queue = device.cast::<ID3D12InfoQueue1>()?;
|
||||
// unsafe {
|
||||
// queue.RegisterMessageCallback(Some(debug_log), D3D12_MESSAGE_CALLBACK_FLAG_NONE, std::ptr::null_mut(), &mut 0).expect("could not register message callback");
|
||||
// }
|
||||
let filter = FilterChainD3D12::load_from_path(&device, filter, None).unwrap();
|
||||
|
||||
Ok(Sample {
|
||||
dxgi_factory,
|
||||
device,
|
||||
resources: None,
|
||||
filter,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -516,20 +536,16 @@ pub mod d3d12_hello_triangle {
|
|||
}
|
||||
|
||||
fn create_device(command_line: &SampleCommandLine) -> Result<(IDXGIFactory4, ID3D12Device)> {
|
||||
if cfg!(debug_assertions) {
|
||||
unsafe {
|
||||
let mut debug: Option<ID3D12Debug> = None;
|
||||
if let Some(debug) = D3D12GetDebugInterface(&mut debug).ok().and(debug) {
|
||||
debug.EnableDebugLayer();
|
||||
}
|
||||
}
|
||||
}
|
||||
// unsafe {
|
||||
// let mut debug: Option<ID3D12Debug> = None;
|
||||
// if let Some(debug) = D3D12GetDebugInterface(&mut debug).ok().and(debug) {
|
||||
// eprintln!("enabling debug");
|
||||
// debug.EnableDebugLayer();
|
||||
// }
|
||||
// }
|
||||
|
||||
let dxgi_factory_flags = if cfg!(debug_assertions) {
|
||||
DXGI_CREATE_FACTORY_DEBUG
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let dxgi_factory_flags = DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
||||
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?;
|
||||
|
||||
|
@ -540,7 +556,7 @@ pub mod d3d12_hello_triangle {
|
|||
}?;
|
||||
|
||||
let mut device: Option<ID3D12Device> = None;
|
||||
unsafe { D3D12CreateDevice(&adapter, D3D_FEATURE_LEVEL_11_0, &mut device) }?;
|
||||
unsafe { D3D12CreateDevice(&adapter, D3D_FEATURE_LEVEL_12_2, &mut device) }?;
|
||||
Ok((dxgi_factory, device.unwrap()))
|
||||
}
|
||||
|
||||
|
@ -593,11 +609,7 @@ pub mod d3d12_hello_triangle {
|
|||
device: &ID3D12Device,
|
||||
root_signature: &ID3D12RootSignature,
|
||||
) -> Result<ID3D12PipelineState> {
|
||||
let compile_flags = if cfg!(debug_assertions) {
|
||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let compile_flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||
|
||||
let vertex_shader = compile_shader(SHADER, b"VSMain\0", b"vs_5_0\0")?;
|
||||
let pixel_shader = compile_shader(SHADER, b"PSMain\0", b"ps_5_0\0")?;
|
||||
|
|
|
@ -1,7 +1,71 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
use windows::Win32::Graphics::Direct3D12::D3D12_GPU_DESCRIPTOR_HANDLE;
|
||||
use windows::Win32::Graphics::Direct3D12::{D3D12_COMPARISON_FUNC_NEVER, D3D12_FLOAT32_MAX, D3D12_SAMPLER_DESC, D3D12_TEXTURE_ADDRESS_MODE, ID3D12Device};
|
||||
use librashader_common::{FilterMode, WrapMode};
|
||||
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerHeap};
|
||||
use crate::error;
|
||||
|
||||
pub struct SamplerSet {
|
||||
samplers: FxHashMap<(WrapMode, FilterMode), D3D12_GPU_DESCRIPTOR_HANDLE>,
|
||||
samplers: FxHashMap<(WrapMode, FilterMode), D3D12DescriptorHeapSlot<SamplerHeap>>,
|
||||
heap: D3D12DescriptorHeap<SamplerHeap>
|
||||
}
|
||||
|
||||
impl SamplerSet {
|
||||
pub fn get(&self, wrap: WrapMode, filter: FilterMode) -> &D3D12DescriptorHeapSlot<SamplerHeap> {
|
||||
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,
|
||||
];
|
||||
|
||||
let mut heap = D3D12DescriptorHeap::new(&device, (2 * wrap_modes.len()))?;
|
||||
|
||||
for wrap_mode in wrap_modes {
|
||||
unsafe {
|
||||
let mut linear = heap.alloc_slot()?;
|
||||
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,
|
||||
},
|
||||
*linear.as_ref(),
|
||||
);
|
||||
|
||||
let mut nearest = heap.alloc_slot()?;
|
||||
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,
|
||||
},
|
||||
*nearest.as_ref()
|
||||
);
|
||||
|
||||
samplers.insert((*wrap_mode, FilterMode::Linear), linear);
|
||||
samplers.insert((*wrap_mode, FilterMode::Nearest), nearest);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(SamplerSet { samplers, heap })
|
||||
}
|
||||
}
|
||||
|
|
20
librashader-runtime-d3d12/src/texture.rs
Normal file
20
librashader-runtime-d3d12/src/texture.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use windows::Win32::Graphics::Direct3D12::{D3D12_RESOURCE_DESC, ID3D12Device, ID3D12Resource};
|
||||
use librashader_common::{FilterMode, WrapMode};
|
||||
use librashader_runtime::image::Image;
|
||||
|
||||
pub struct LutTexture {
|
||||
handle: ID3D12Resource,
|
||||
|
||||
}
|
||||
|
||||
impl LutTexture {
|
||||
pub fn new(
|
||||
device: &ID3D12Device,
|
||||
source: &Image,
|
||||
desc: D3D12_RESOURCE_DESC,
|
||||
filter: FilterMode,
|
||||
wrap_mode: WrapMode,
|
||||
) {
|
||||
// todo: d3d12:800
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue