d3d12: texture infrastructure

This commit is contained in:
chyyran 2023-01-31 17:50:47 -05:00 committed by Ronny Chan
parent 17203692f0
commit c28e5195c2
17 changed files with 282 additions and 118 deletions

View file

@ -98,10 +98,6 @@ impl OwnedFramebuffer {
} }
pub fn init(&mut self, size: Size<u32>, format: ImageFormat) -> error::Result<()> { pub fn init(&mut self, size: Size<u32>, format: ImageFormat) -> error::Result<()> {
if self.is_raw {
return Ok(());
}
let format = d3d11_get_closest_format( let format = d3d11_get_closest_format(
&self.device, &self.device,
DXGI_FORMAT::from(format), DXGI_FORMAT::from(format),

View file

@ -38,8 +38,8 @@ mod tests {
// "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", // "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
// "../test/null.slangp", // "../test/null.slangp",
const FILTER_PATH: &'static str = "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp"; const FILTER_PATH: &str = "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp";
const IMAGE_PATH: &'static str = "../test/finalfightlong.png"; const IMAGE_PATH: &str = "../test/finalfightlong.png";
#[test] #[test]
fn triangle_d3d11_args() { fn triangle_d3d11_args() {
let mut args = env::args(); let mut args = env::args();

View file

@ -1,5 +1,5 @@
use std::ops::Range; use std::ops::Range;
use windows::Win32::Graphics::Direct3D12::{D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, ID3D12Device, ID3D12Resource}; use windows::Win32::Graphics::Direct3D12::{D3D12_CONSTANT_BUFFER_VIEW_DESC, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RANGE, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, ID3D12Device, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;

View file

@ -1,6 +1,6 @@
use std::borrow::Borrow;
use crate::{error, util}; use crate::{error};
use crate::heap::{D3D12DescriptorHeap, LutTextureHeap, ResourceWorkHeap}; use crate::heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap};
use crate::samplers::SamplerSet; use crate::samplers::SamplerSet;
use crate::luts::LutTexture; use crate::luts::LutTexture;
use librashader_presets::{ShaderPreset, TextureConfig}; use librashader_presets::{ShaderPreset, TextureConfig};
@ -15,7 +15,7 @@ use windows::core::Interface;
use windows::w; use windows::w;
use windows::Win32::Foundation::CloseHandle; use windows::Win32::Foundation::CloseHandle;
use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Direct3D12::{
ID3D12CommandAllocator, ID3D12CommandList, ID3D12CommandQueue, ID3D12Device, ID3D12Fence, ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence,
ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC, ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC,
D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE, D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE,
}; };
@ -57,7 +57,7 @@ pub(crate) struct FilterCommon {
// pub history_textures: Box<[Option<InputTexture>]>, // pub history_textures: Box<[Option<InputTexture>]>,
pub config: FilterMutable, pub config: FilterMutable,
// pub disable_mipmaps: bool, // pub disable_mipmaps: bool,
lut_heap: D3D12DescriptorHeap<LutTextureHeap>, lut_heap: D3D12DescriptorHeap<CpuStagingHeap>,
pub luts: FxHashMap<usize, LutTexture>, pub luts: FxHashMap<usize, LutTexture>,
pub mipmap_gen: D3D12MipmapGen, pub mipmap_gen: D3D12MipmapGen,
pub root_signature: D3D12RootSignature, pub root_signature: D3D12RootSignature,
@ -77,12 +77,11 @@ impl FilterChainD3D12 {
Self::load_from_preset(device, preset, options) Self::load_from_preset(device, preset, options)
} }
/// 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, device: &ID3D12Device,
preset: ShaderPreset, preset: ShaderPreset,
options: Option<&()>, _options: Option<&()>,
) -> error::Result<FilterChainD3D12> { ) -> error::Result<FilterChainD3D12> {
let (passes, semantics) = HLSL::compile_preset_passes::<GlslangCompilation, Box<dyn Error>>( let (passes, semantics) = HLSL::compile_preset_passes::<GlslangCompilation, Box<dyn Error>>(
preset.shaders, preset.shaders,
@ -128,7 +127,7 @@ impl FilterChainD3D12 {
fn load_luts( fn load_luts(
device: &ID3D12Device, device: &ID3D12Device,
heap: &mut D3D12DescriptorHeap<LutTextureHeap>, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
textures: &[TextureConfig], textures: &[TextureConfig],
mipmap_gen: &D3D12MipmapGen mipmap_gen: &D3D12MipmapGen
) -> error::Result<FxHashMap<usize, LutTexture>> { ) -> error::Result<FxHashMap<usize, LutTexture>> {

View file

@ -1,20 +1,24 @@
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, ID3D12Device, ID3D12Resource}; use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT1_RENDER_TARGET, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_MEMORY_POOL_UNKNOWN, D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV, ID3D12Device, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC}; use windows::Win32::Graphics::Dxgi::Common::{DXGI_SAMPLE_DESC};
use librashader_common::{ImageFormat, Size}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeap};
use crate::texture::InputTexture;
use crate::util::d3d12_get_closest_format; use crate::util::d3d12_get_closest_format;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct OwnedImage { pub(crate) struct OwnedImage {
render: ID3D12Resource, handle: ID3D12Resource,
pub(crate) size: Size<u32>, pub(crate) size: Size<u32>,
format: DXGI_FORMAT, format: ImageFormat,
device: ID3D12Device, device: ID3D12Device,
max_mipmap: u16, max_mipmap: u16,
} }
impl OwnedImage {
pub fn new( pub fn new(
device: &ID3D12Device, device: &ID3D12Device,
size: Size<u32>, size: Size<u32>,
@ -22,7 +26,7 @@ pub fn new(
mipmap: bool, mipmap: bool,
) -> error::Result<OwnedImage> { ) -> error::Result<OwnedImage> {
unsafe { unsafe {
let miplevels = source.size.calculate_miplevels() as u16; let miplevels = size.calculate_miplevels() as u16;
let mut desc = D3D12_RESOURCE_DESC { let mut desc = D3D12_RESOURCE_DESC {
Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D, Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
Alignment: 0, Alignment: 0,
@ -75,11 +79,60 @@ pub fn new(
assume_d3d12_init!(resource, "CreateCommittedResource"); assume_d3d12_init!(resource, "CreateCommittedResource");
Ok(OwnedImage { Ok(OwnedImage {
render: resource, handle: resource,
size, size,
format: desc.Format, format,
device: device.clone(), device: device.clone(),
max_mipmap: miplevels, max_mipmap: miplevels,
}) })
} }
} }
pub(crate) fn create_shader_resource_view(&self, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputTexture> {
let descriptor = heap.alloc_slot()?;
unsafe {
let srv_desc = D3D12_SHADER_RESOURCE_VIEW_DESC {
Format: self.format.into(),
ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING,
Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D12_TEX2D_SRV {
MipLevels: self.max_mipmap as u32,
..Default::default()
},
},
};
self.device.CreateShaderResourceView(&self.handle, Some(&srv_desc), *descriptor.as_ref());
}
Ok(InputTexture::new(descriptor, self.size, self.format, wrap_mode, filter))
}
pub(crate) fn create_render_target_view(&self, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
filter: FilterMode, wrap_mode: WrapMode) -> error::Result<InputTexture> {
let descriptor = heap.alloc_slot()?;
unsafe {
let rtv_desc = D3D12_RENDER_TARGET_VIEW_DESC {
Format: self.format.into(),
ViewDimension: D3D12_RTV_DIMENSION_TEXTURE2D,
Anonymous: D3D12_RENDER_TARGET_VIEW_DESC_0 {
Texture2D: D3D12_TEX2D_RTV {
MipSlice: 0,
..Default::default()
},
},
};
self.device.CreateRenderTargetView(&self.handle, Some(&rtv_desc), *descriptor.as_ref());
}
Ok(InputTexture::new(descriptor, self.size, self.format, wrap_mode, filter))
}
}

View file

@ -1,6 +1,6 @@
use windows::core::Vtable;
use windows::Win32::Foundation::BOOL; use windows::Win32::Foundation::BOOL;
use windows::Win32::Graphics::Direct3D12::{D3D12_BLEND_DESC, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP, D3D12_BLEND_OP_ADD, D3D12_BLEND_SRC_ALPHA, D3D12_COLOR_WRITE_ENABLE_ALL, D3D12_CULL_MODE_NONE, D3D12_DESCRIPTOR_RANGE, D3D12_DESCRIPTOR_RANGE_TYPE, 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, D3D12SerializeRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, D3D_ROOT_SIGNATURE_VERSION_1_0, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature}; use windows::Win32::Graphics::Direct3D12::{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, D3D12SerializeRootSignature, D3D_ROOT_SIGNATURE_VERSION_1, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature};
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC}; use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC};
use librashader_reflect::back::cross::CrossHlslContext; use librashader_reflect::back::cross::CrossHlslContext;
use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::back::ShaderCompilerOutput;
@ -11,7 +11,7 @@ pub struct D3D12GraphicsPipeline {
pipeline_state: ID3D12PipelineState, pipeline_state: ID3D12PipelineState,
} }
const D3D12_SLANG_ROOT_PARAMETERS: &'static [D3D12_ROOT_PARAMETER; 4] = &[ const D3D12_SLANG_ROOT_PARAMETERS: &[D3D12_ROOT_PARAMETER; 4] = &[
// srvs // srvs
D3D12_ROOT_PARAMETER { D3D12_ROOT_PARAMETER {
ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
@ -70,7 +70,7 @@ const D3D12_SLANG_ROOT_PARAMETERS: &'static [D3D12_ROOT_PARAMETER; 4] = &[
} }
]; ];
const D3D12_SLANG_ROOT_SIGNATURE: &'static D3D12_ROOT_SIGNATURE_DESC = &D3D12_ROOT_SIGNATURE_DESC { const D3D12_SLANG_ROOT_SIGNATURE: &D3D12_ROOT_SIGNATURE_DESC = &D3D12_ROOT_SIGNATURE_DESC {
NumParameters: D3D12_SLANG_ROOT_PARAMETERS.len() as u32, NumParameters: D3D12_SLANG_ROOT_PARAMETERS.len() as u32,
pParameters: D3D12_SLANG_ROOT_PARAMETERS.as_ptr(), pParameters: D3D12_SLANG_ROOT_PARAMETERS.as_ptr(),
NumStaticSamplers: 0, NumStaticSamplers: 0,

View file

@ -15,9 +15,13 @@ pub trait D3D12HeapType {
} }
pub trait D3D12ShaderVisibleHeapType: D3D12HeapType {} pub trait D3D12ShaderVisibleHeapType: D3D12HeapType {}
#[derive(Clone)]
pub struct SamplerPaletteHeap; pub struct SamplerPaletteHeap;
pub struct LutTextureHeap;
#[derive(Clone)]
pub struct CpuStagingHeap;
#[derive(Clone)]
pub struct ResourceWorkHeap; pub struct ResourceWorkHeap;
impl D3D12ShaderVisibleHeapType for SamplerPaletteHeap {} impl D3D12ShaderVisibleHeapType for SamplerPaletteHeap {}
@ -34,7 +38,7 @@ impl const D3D12HeapType for SamplerPaletteHeap {
} }
} }
impl const D3D12HeapType for LutTextureHeap { impl const D3D12HeapType for CpuStagingHeap {
// Lut texture heaps are CPU only and get bound to the descriptor heap of the shader. // Lut texture heaps are CPU only and get bound to the descriptor heap of the shader.
fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC { fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC {
D3D12_DESCRIPTOR_HEAP_DESC { D3D12_DESCRIPTOR_HEAP_DESC {
@ -59,6 +63,7 @@ impl const D3D12HeapType for ResourceWorkHeap {
} }
} }
#[derive(Clone)]
pub struct D3D12DescriptorHeapSlot<T> { pub struct D3D12DescriptorHeapSlot<T> {
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
@ -184,7 +189,7 @@ impl<T> D3D12DescriptorHeap<T> {
source: &[&D3D12_CPU_DESCRIPTOR_HANDLE; NUM_DESC]) source: &[&D3D12_CPU_DESCRIPTOR_HANDLE; NUM_DESC])
-> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> { -> error::Result<[D3D12DescriptorHeapSlot<T>; NUM_DESC]> {
let dest = array_init::try_array_init(|_| self.alloc_slot())?; let dest = array_init::try_array_init(|_| self.alloc_slot())?;
let mut inner = self.0.borrow_mut(); let inner = self.0.borrow_mut();
unsafe { unsafe {
// unfortunately we can't guarantee that the source and dest descriptors are contiguous so... // unfortunately we can't guarantee that the source and dest descriptors are contiguous so...

View file

@ -226,9 +226,9 @@ fn get_hardware_adapter(factory: &IDXGIFactory4) -> Result<IDXGIAdapter1> {
unsafe extern "system" fn debug_log( unsafe extern "system" fn debug_log(
category: D3D12_MESSAGE_CATEGORY, category: D3D12_MESSAGE_CATEGORY,
severity: D3D12_MESSAGE_SEVERITY, severity: D3D12_MESSAGE_SEVERITY,
id: D3D12_MESSAGE_ID, _id: D3D12_MESSAGE_ID,
pdescription: ::windows::core::PCSTR, pdescription: ::windows::core::PCSTR,
pcontext: *mut ::core::ffi::c_void, _pcontext: *mut ::core::ffi::c_void,
) { ) {
unsafe { unsafe {
let desc = CStr::from_ptr(pdescription.as_ptr().cast()); let desc = CStr::from_ptr(pdescription.as_ptr().cast());
@ -622,7 +622,7 @@ pub mod d3d12_hello_triangle {
device: &ID3D12Device, device: &ID3D12Device,
root_signature: &ID3D12RootSignature, root_signature: &ID3D12RootSignature,
) -> Result<ID3D12PipelineState> { ) -> Result<ID3D12PipelineState> {
let compile_flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; let _compile_flags = D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
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")?;
@ -709,7 +709,7 @@ pub mod d3d12_hello_triangle {
fn create_vertex_buffer( fn create_vertex_buffer(
device: &ID3D12Device, device: &ID3D12Device,
aspect_ratio: f32, _aspect_ratio: f32,
) -> Result<(ID3D12Resource, D3D12_VERTEX_BUFFER_VIEW)> { ) -> Result<(ID3D12Resource, D3D12_VERTEX_BUFFER_VIEW)> {
let vertices = [ let vertices = [
Vertex { Vertex {

View file

@ -14,6 +14,7 @@ mod quad_render;
mod graphics_pipeline; mod graphics_pipeline;
mod buffer; mod buffer;
mod framebuffer; mod framebuffer;
mod texture;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -1,18 +1,19 @@
use std::mem::ManuallyDrop;
use crate::error; use crate::error;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, LutTextureHeap, ResourceWorkHeap}; use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, CpuStagingHeap};
use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources}; use crate::util::{d3d12_get_closest_format, d3d12_resource_transition, d3d12_update_subresources};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::image::Image; use librashader_runtime::image::Image;
use windows::Win32::Graphics::Direct3D12::{ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_RANGE, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE}; use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_FORMAT_SUPPORT1_MIP, D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE};
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use librashader_runtime::scaling::MipmapSize; use librashader_runtime::scaling::MipmapSize;
use crate::mipmap::{D3D12MipmapGen, MipmapGenContext}; use crate::mipmap::{MipmapGenContext};
use crate::texture::InputTexture;
pub struct LutTexture { pub struct LutTexture {
resource: ID3D12Resource, resource: ID3D12Resource,
descriptor: D3D12DescriptorHeapSlot<LutTextureHeap>, descriptor: D3D12DescriptorHeapSlot<CpuStagingHeap>,
size: Size<u32>, size: Size<u32>,
filter: FilterMode, filter: FilterMode,
wrap_mode: WrapMode, wrap_mode: WrapMode,
@ -22,7 +23,7 @@ pub struct LutTexture {
impl LutTexture { impl LutTexture {
pub fn new( pub fn new(
device: &ID3D12Device, device: &ID3D12Device,
heap: &mut D3D12DescriptorHeap<LutTextureHeap>, heap: &mut D3D12DescriptorHeap<CpuStagingHeap>,
cmd: &ID3D12GraphicsCommandList, cmd: &ID3D12GraphicsCommandList,
source: &Image, source: &Image,
filter: FilterMode, filter: FilterMode,
@ -172,10 +173,17 @@ impl LutTexture {
pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> { pub fn generate_mipmaps(&self, gen_mips: &mut MipmapGenContext) -> error::Result<()> {
if let Some(miplevels) = self.miplevels { if let Some(miplevels) = self.miplevels {
gen_mips.generate_mipmaps(&self.resource, gen_mips.generate_mipmaps(&self.resource,
miplevels as u16, miplevels,
self.size, ImageFormat::R8G8B8A8Unorm.into())? self.size, ImageFormat::R8G8B8A8Unorm.into())?
} }
Ok(()) Ok(())
} }
pub fn as_input(&self)
-> InputTexture {
InputTexture::new(self.descriptor.clone(),
self.size, ImageFormat::R8G8B8A8Unorm,
self.wrap_mode, self.filter)
}
} }

View file

@ -1,6 +1,6 @@
use std::borrow::Borrow;
use std::mem::ManuallyDrop; use std::mem::ManuallyDrop;
use windows::Win32::Graphics::Direct3D12::{D3D12_COMPUTE_PIPELINE_STATE_DESC, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_DESCRIPTOR_RANGE, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_TYPE_UAV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_UAV_BARRIER, D3D12_ROOT_CONSTANTS, D3D12_ROOT_DESCRIPTOR_TABLE, D3D12_ROOT_PARAMETER, D3D12_ROOT_PARAMETER_0, D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS, D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, D3D12_ROOT_SIGNATURE_DESC, D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS, D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS, D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS, D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS, D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS, D3D12_SHADER_BYTECODE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SHADER_VISIBILITY_ALL, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_STATIC_SAMPLER_DESC, D3D12_TEX2D_SRV, D3D12_TEX2D_UAV, D3D12_TEXTURE_ADDRESS_MODE_CLAMP, D3D12_UAV_DIMENSION_TEXTURE2D, D3D12_UNORDERED_ACCESS_VIEW_DESC, D3D12_UNORDERED_ACCESS_VIEW_DESC_0, ID3D12CommandList, ID3D12DescriptorHeap, ID3D12Device, ID3D12GraphicsCommandList, ID3D12PipelineState, ID3D12Resource, ID3D12RootSignature}; use windows::Win32::Graphics::Direct3D12::{D3D12_COMPUTE_PIPELINE_STATE_DESC, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_BARRIER_TYPE_UAV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_UAV_BARRIER, D3D12_SHADER_BYTECODE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEX2D_UAV, D3D12_UAV_DIMENSION_TEXTURE2D, D3D12_UNORDERED_ACCESS_VIEW_DESC, D3D12_UNORDERED_ACCESS_VIEW_DESC_0, ID3D12DescriptorHeap, ID3D12Device, ID3D12GraphicsCommandList, ID3D12PipelineState, ID3D12Resource, ID3D12RootSignature};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
use librashader_common::Size; use librashader_common::Size;
use crate::{error, util}; use crate::{error, util};
@ -140,7 +140,7 @@ impl D3D12MipmapGen {
cmd.SetDescriptorHeaps(&[heap]); cmd.SetDescriptorHeaps(&[heap]);
} }
let mut context = MipmapGenContext::new(&self, cmd, work_heap); let mut context = MipmapGenContext::new(self, cmd, work_heap);
f(&mut context); f(&mut context);
Ok(context.close()) Ok(context.close())
} }

View file

@ -2,10 +2,10 @@ use crate::error;
use bytemuck::{offset_of, Pod, Zeroable}; use bytemuck::{offset_of, Pod, Zeroable};
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::w; use windows::w;
use windows::Win32::Graphics::Direct3D::{D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP}; use windows::Win32::Graphics::Direct3D::{D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP};
use windows::Win32::Graphics::Direct3D12::{D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW, ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource}; use windows::Win32::Graphics::Direct3D12::{D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, D3D12_INPUT_ELEMENT_DESC, D3D12_VERTEX_BUFFER_VIEW, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource};
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer}; use crate::buffer::{D3D12Buffer};
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone, Default, Zeroable, Pod)] #[derive(Debug, Copy, Clone, Default, Zeroable, Pod)]

View file

@ -29,11 +29,11 @@ impl SamplerSet {
WrapMode::MirroredRepeat, WrapMode::MirroredRepeat,
]; ];
let mut heap = D3D12DescriptorHeap::new(&device, 2 * wrap_modes.len())?; let mut heap = D3D12DescriptorHeap::new(device, 2 * wrap_modes.len())?;
for wrap_mode in wrap_modes { for wrap_mode in wrap_modes {
unsafe { unsafe {
let mut linear = heap.alloc_slot()?; let linear = heap.alloc_slot()?;
device.CreateSampler( device.CreateSampler(
&D3D12_SAMPLER_DESC { &D3D12_SAMPLER_DESC {
Filter: FilterMode::Linear.into(), Filter: FilterMode::Linear.into(),
@ -50,7 +50,7 @@ impl SamplerSet {
*linear.as_ref(), *linear.as_ref(),
); );
let mut nearest = heap.alloc_slot()?; let nearest = heap.alloc_slot()?;
device.CreateSampler( device.CreateSampler(
&D3D12_SAMPLER_DESC { &D3D12_SAMPLER_DESC {
Filter: FilterMode::Nearest.into(), Filter: FilterMode::Nearest.into(),

View file

@ -0,0 +1,102 @@
use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE};
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot};
enum InputDescriptor {
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
}
enum OutputDescriptor {
Owned(D3D12DescriptorHeapSlot<CpuStagingHeap>),
Raw(D3D12_CPU_DESCRIPTOR_HANDLE)
}
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for InputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self {
InputDescriptor::Owned(h) => h.as_ref(),
InputDescriptor::Raw(h) => h
}
}
}
impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE> for OutputDescriptor {
fn as_ref(&self) -> &D3D12_CPU_DESCRIPTOR_HANDLE {
match self {
OutputDescriptor::Owned(h) => h.as_ref(),
OutputDescriptor::Raw(h) => h
}
}
}
pub struct OutputTexture {
descriptor: OutputDescriptor,
size: Size<u32>,
}
impl OutputTexture {
pub fn new(handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
size: Size<u32>,
) -> OutputTexture {
let descriptor = OutputDescriptor::Owned(handle);
OutputTexture {
descriptor,
size,
}
}
// unsafe since the lifetime of the handle has to survive
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE,
size: Size<u32>,
) -> OutputTexture {
let descriptor = OutputDescriptor::Raw(handle);
OutputTexture {
descriptor,
size,
}
}
}
pub struct InputTexture {
descriptor: InputDescriptor,
size: Size<u32>,
format: ImageFormat,
wrap_mode: WrapMode,
filter: FilterMode
}
impl InputTexture {
pub fn new(handle: D3D12DescriptorHeapSlot<CpuStagingHeap>,
size: Size<u32>,
format: ImageFormat,
wrap_mode: WrapMode,
filter: FilterMode) -> InputTexture {
let srv = InputDescriptor::Owned(handle);
InputTexture {
descriptor: srv,
size,
format,
wrap_mode,
filter
}
}
// unsafe since the lifetime of the handle has to survive
pub unsafe fn new_from_raw(handle: D3D12_CPU_DESCRIPTOR_HANDLE,
size: Size<u32>,
format: ImageFormat,
wrap_mode: WrapMode,
filter: FilterMode
) -> InputTexture {
let srv = InputDescriptor::Raw(handle);
InputTexture {
descriptor: srv,
size,
format,
wrap_mode,
filter
}
}
}

View file

@ -2,9 +2,9 @@ use std::mem::ManuallyDrop;
use std::u64; use std::u64;
use crate::error; use crate::error;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_OPTIMIZATION_LEVEL3, D3DCOMPILE_SKIP_OPTIMIZATION}; use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_SKIP_OPTIMIZATION};
use windows::Win32::Graphics::Direct3D::ID3DBlob; use windows::Win32::Graphics::Direct3D::ID3DBlob;
use windows::Win32::Graphics::Direct3D12::{ID3D12Device, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FEATURE_FORMAT_SUPPORT, ID3D12CommandList, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_RESOURCE_DESC, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_DESC1, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_TRANSITION_BARRIER, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_STATES, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_MEMCPY_DEST, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT}; use windows::Win32::Graphics::Direct3D12::{ID3D12Device, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FEATURE_FORMAT_SUPPORT, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_RESOURCE_BARRIER, D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE, D3D12_RESOURCE_BARRIER_0, D3D12_RESOURCE_TRANSITION_BARRIER, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, D3D12_RESOURCE_STATES, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_MEMCPY_DEST, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_TEXTURE_COPY_LOCATION, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, D3D12_TEXTURE_COPY_LOCATION_0, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT};
use windows::Win32::Graphics::Dxgi::Common::*; use windows::Win32::Graphics::Dxgi::Common::*;
use crate::error::assume_d3d12_init; use crate::error::assume_d3d12_init;
@ -326,13 +326,13 @@ unsafe fn memcpy_subresource(
) { ) {
for z in 0..num_slices as usize { for z in 0..num_slices as usize {
let dest_slice = let dest_slice =
dest.pData.offset((dest.SlicePitch * z) as isize); dest.pData.add(dest.SlicePitch * z);
let src_slice = src.pData.offset((src.SlicePitch * z as isize) as isize); let src_slice = src.pData.offset(src.SlicePitch * z as isize);
for y in 0..num_rows as usize { for y in 0..num_rows as usize {
std::ptr::copy_nonoverlapping( std::ptr::copy_nonoverlapping(
src_slice.offset((src.RowPitch * y as isize) as isize), src_slice.offset(src.RowPitch * y as isize),
dest_slice.offset((dest.RowPitch * y) as isize), dest_slice.add(dest.RowPitch * y),
row_sizes_in_bytes as usize, row_sizes_in_bytes as usize,
); );
} }

View file

@ -37,7 +37,7 @@ mod tests {
use crate::filter_chain::FilterChainVulkan; use crate::filter_chain::FilterChainVulkan;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::options::FilterChainOptionsVulkan; use crate::options::FilterChainOptionsVulkan;
use ash::vk;
#[test] #[test]
fn triangle_vk() { fn triangle_vk() {

View file

@ -1,6 +1,6 @@
//! Vulkan shader runtime options. //! Vulkan shader runtime options.
use ash::vk;
/// Options for each Vulkan shader frame. /// Options for each Vulkan shader frame.
#[repr(C)] #[repr(C)]