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"
|
version = "0.1.0-beta.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-init",
|
"array-init",
|
||||||
|
"bit-set",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"gfx-maths",
|
"gfx-maths",
|
||||||
"librashader-common",
|
"librashader-common",
|
||||||
|
|
|
@ -15,6 +15,7 @@ description = "RetroArch shaders for all."
|
||||||
default = []
|
default = []
|
||||||
opengl = ["gl"]
|
opengl = ["gl"]
|
||||||
d3d11 = ["windows", "dxgi"]
|
d3d11 = ["windows", "dxgi"]
|
||||||
|
d3d12 = ["windows", "dxgi"]
|
||||||
dxgi = ["windows"]
|
dxgi = ["windows"]
|
||||||
vulkan = ["ash"]
|
vulkan = ["ash"]
|
||||||
|
|
||||||
|
@ -32,4 +33,5 @@ features = [
|
||||||
"Win32_Graphics_Dxgi_Common",
|
"Win32_Graphics_Dxgi_Common",
|
||||||
"Win32_Graphics_Direct3D",
|
"Win32_Graphics_Direct3D",
|
||||||
"Win32_Graphics_Direct3D11",
|
"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"))]
|
#[cfg(all(target_os = "windows", feature = "d3d11"))]
|
||||||
pub mod d3d11;
|
pub mod d3d11;
|
||||||
|
|
||||||
|
/// Direct3D 12 common conversions.
|
||||||
|
#[cfg(all(target_os = "windows", feature = "d3d12"))]
|
||||||
|
pub mod d3d12;
|
||||||
|
|
||||||
mod viewport;
|
mod viewport;
|
||||||
pub use viewport::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 std::path::Path;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use windows::Win32::Graphics::Direct3D12::ID3D12Device;
|
use windows::Win32::Graphics::Direct3D12::ID3D12Device;
|
||||||
use librashader_presets::ShaderPreset;
|
use librashader_presets::{ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::front::GlslangCompilation;
|
use librashader_reflect::front::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::presets::CompilePresetTarget;
|
use librashader_reflect::reflect::presets::CompilePresetTarget;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
|
use crate::samplers::SamplerSet;
|
||||||
|
use crate::texture::LutTexture;
|
||||||
|
|
||||||
pub struct FilterChainD3D12 {
|
pub struct FilterChainD3D12 {
|
||||||
pub(crate) common: FilterCommon,
|
pub(crate) common: FilterCommon,
|
||||||
|
@ -20,7 +22,7 @@ pub struct FilterChainD3D12 {
|
||||||
pub(crate) struct FilterCommon {
|
pub(crate) struct FilterCommon {
|
||||||
pub(crate) d3d12: ID3D12Device,
|
pub(crate) d3d12: ID3D12Device,
|
||||||
// pub(crate) luts: FxHashMap<usize, LutTexture>,
|
// pub(crate) luts: FxHashMap<usize, LutTexture>,
|
||||||
// pub samplers: SamplerSet,
|
pub samplers: SamplerSet,
|
||||||
// pub output_textures: Box<[Option<InputTexture>]>,
|
// pub output_textures: Box<[Option<InputTexture>]>,
|
||||||
// pub feedback_textures: Box<[Option<InputTexture>]>,
|
// pub feedback_textures: Box<[Option<InputTexture>]>,
|
||||||
// pub history_textures: Box<[Option<InputTexture>]>,
|
// pub history_textures: Box<[Option<InputTexture>]>,
|
||||||
|
@ -31,16 +33,25 @@ pub(crate) struct FilterCommon {
|
||||||
impl FilterChainD3D12 {
|
impl FilterChainD3D12 {
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(
|
pub fn load_from_path(
|
||||||
|
device: &ID3D12Device,
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
options: Option<&()>,
|
options: Option<&()>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
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`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(
|
pub fn load_from_preset(
|
||||||
|
device: &ID3D12Device,
|
||||||
preset: ShaderPreset,
|
preset: ShaderPreset,
|
||||||
options: Option<&()>,
|
options: Option<&()>,
|
||||||
) -> error::Result<FilterChainD3D12> {
|
) -> error::Result<FilterChainD3D12> {
|
||||||
|
@ -49,7 +60,12 @@ impl FilterChainD3D12 {
|
||||||
Box<dyn Error>,
|
Box<dyn Error>,
|
||||||
>(preset.shaders, &preset.textures)?;
|
>(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
|
let samplers = SamplerSet::new(&device)?;
|
||||||
todo!()
|
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::{
|
use windows::{
|
||||||
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
||||||
Win32::Graphics::Direct3D12::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
Win32::Graphics::Direct3D12::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
||||||
|
@ -27,9 +28,10 @@ float4 PSMain(PSInput input) : SV_TARGET
|
||||||
}\0";
|
}\0";
|
||||||
|
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
pub trait DXSample {
|
pub trait DXSample {
|
||||||
fn new(command_line: &SampleCommandLine) -> Result<Self>
|
fn new(filter: impl AsRef<Path>, command_line: &SampleCommandLine) -> Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
|
@ -221,7 +223,17 @@ fn get_hardware_adapter(factory: &IDXGIFactory4) -> Result<IDXGIAdapter1> {
|
||||||
unreachable!()
|
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 {
|
pub mod d3d12_hello_triangle {
|
||||||
|
use std::path::Path;
|
||||||
|
use crate::filter_chain::FilterChainD3D12;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const FRAME_COUNT: u32 = 2;
|
const FRAME_COUNT: u32 = 2;
|
||||||
|
@ -230,6 +242,7 @@ pub mod d3d12_hello_triangle {
|
||||||
dxgi_factory: IDXGIFactory4,
|
dxgi_factory: IDXGIFactory4,
|
||||||
device: ID3D12Device,
|
device: ID3D12Device,
|
||||||
resources: Option<Resources>,
|
resources: Option<Resources>,
|
||||||
|
pub filter: FilterChainD3D12,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Resources {
|
struct Resources {
|
||||||
|
@ -258,13 +271,20 @@ pub mod d3d12_hello_triangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DXSample for Sample {
|
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 (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 {
|
Ok(Sample {
|
||||||
dxgi_factory,
|
dxgi_factory,
|
||||||
device,
|
device,
|
||||||
resources: None,
|
resources: None,
|
||||||
|
filter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,20 +536,16 @@ pub mod d3d12_hello_triangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_device(command_line: &SampleCommandLine) -> Result<(IDXGIFactory4, ID3D12Device)> {
|
fn create_device(command_line: &SampleCommandLine) -> Result<(IDXGIFactory4, ID3D12Device)> {
|
||||||
if cfg!(debug_assertions) {
|
// unsafe {
|
||||||
unsafe {
|
// let mut debug: Option<ID3D12Debug> = None;
|
||||||
let mut debug: Option<ID3D12Debug> = None;
|
// if let Some(debug) = D3D12GetDebugInterface(&mut debug).ok().and(debug) {
|
||||||
if let Some(debug) = D3D12GetDebugInterface(&mut debug).ok().and(debug) {
|
// eprintln!("enabling debug");
|
||||||
debug.EnableDebugLayer();
|
// debug.EnableDebugLayer();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
let dxgi_factory_flags = if cfg!(debug_assertions) {
|
|
||||||
DXGI_CREATE_FACTORY_DEBUG
|
let dxgi_factory_flags = DXGI_CREATE_FACTORY_DEBUG;
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?;
|
let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?;
|
||||||
|
|
||||||
|
@ -540,7 +556,7 @@ pub mod d3d12_hello_triangle {
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let mut device: Option<ID3D12Device> = None;
|
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()))
|
Ok((dxgi_factory, device.unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,11 +609,7 @@ pub mod d3d12_hello_triangle {
|
||||||
device: &ID3D12Device,
|
device: &ID3D12Device,
|
||||||
root_signature: &ID3D12RootSignature,
|
root_signature: &ID3D12RootSignature,
|
||||||
) -> Result<ID3D12PipelineState> {
|
) -> Result<ID3D12PipelineState> {
|
||||||
let compile_flags = if cfg!(debug_assertions) {
|
let compile_flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
|
||||||
D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
let vertex_shader = compile_shader(SHADER, b"VSMain\0", b"vs_5_0\0")?;
|
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")?;
|
let pixel_shader = compile_shader(SHADER, b"PSMain\0", b"ps_5_0\0")?;
|
||||||
|
|
|
@ -1,7 +1,71 @@
|
||||||
use rustc_hash::FxHashMap;
|
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 librashader_common::{FilterMode, WrapMode};
|
||||||
|
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, SamplerHeap};
|
||||||
|
use crate::error;
|
||||||
|
|
||||||
pub struct SamplerSet {
|
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