diff --git a/librashader-common/src/image.rs b/librashader-common/src/image.rs index 33ee081..a3252cd 100644 --- a/librashader-common/src/image.rs +++ b/librashader-common/src/image.rs @@ -2,7 +2,8 @@ use std::path::Path; pub struct Image { pub bytes: Vec, - pub size: Size + pub size: Size, + pub pitch: usize, } impl Image { @@ -11,9 +12,13 @@ impl Image { let height = image.height(); let width = image.width(); + let pitch = image.sample_layout().height_stride.max( + image.sample_layout().width_stride + ); Ok(Image { - bytes: image.to_vec(), + bytes: image.into_raw(), + pitch, size: Size { height, width, diff --git a/librashader-runtime-dx11/src/filter_chain.rs b/librashader-runtime-dx11/src/filter_chain.rs index 804d12b..f4e1fbf 100644 --- a/librashader-runtime-dx11/src/filter_chain.rs +++ b/librashader-runtime-dx11/src/filter_chain.rs @@ -1,19 +1,22 @@ -use std::error::Error; -use std::path::Path; -use rustc_hash::FxHashMap; -use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_SHADER_RESOURCE, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, ID3D11Device, ID3D11DeviceContext}; -use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC}; +use crate::texture::OwnedTexture; use librashader_common::image::Image; use librashader_common::Size; use librashader_preprocess::ShaderSource; use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig}; -use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation}; use librashader_reflect::back::cross::GlslangHlslContext; use librashader_reflect::back::targets::HLSL; +use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation}; use librashader_reflect::front::shaderc::GlslangCompilation; +use librashader_reflect::reflect::semantics::{ + ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics, +}; use librashader_reflect::reflect::ReflectShader; -use librashader_reflect::reflect::semantics::{ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics}; -use crate::util::Texture; +use rustc_hash::FxHashMap; +use std::error::Error; +use std::path::Path; +use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_SHADER_RESOURCE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, ID3D11Device, ID3D11DeviceContext}; +use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC}; +use crate::util; type ShaderPassMeta<'a> = ( &'a ShaderPassConfig, @@ -23,19 +26,20 @@ type ShaderPassMeta<'a> = ( >, ); +pub struct FilterChain { + pub luts: FxHashMap, +} -struct FilterChain { - +pub struct Direct3D11 { + pub(crate) device_context: ID3D11DeviceContext, + pub(crate) device: ID3D11Device, } pub struct FilterCommon { - pub(crate) device_context: ID3D11DeviceContext, + pub(crate) d3d11: Direct3D11, pub(crate) preset: ShaderPreset, } -// todo: d3d11.c 2097 -type Result = std::result::Result>; - impl FilterChain { fn load_pass_semantics( uniform_semantics: &mut FxHashMap, @@ -87,7 +91,7 @@ impl FilterChain { } /// Load a filter chain from a pre-parsed `ShaderPreset`. - pub fn load_from_preset(preset: ShaderPreset) -> Result { + pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result { let (passes, semantics) = FilterChain::load_preset(&preset)?; // initialize passes @@ -112,13 +116,13 @@ impl FilterChain { // feedback_textures.resize_with(filters.len(), Texture::default); // load luts - let luts = FilterChain::load_luts(&preset.textures)?; + let luts = FilterChain::load_luts(device, &preset.textures)?; // let (history_framebuffers, history_textures) = // FilterChain::init_history(&filters, default_filter, default_wrap); - Ok(FilterChain { + luts // passes: filters, // output_framebuffers: output_framebuffers.into_boxed_slice(), // feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), @@ -137,41 +141,42 @@ impl FilterChain { }) } - fn load_luts(device: &ID3D11Device, textures: &[TextureConfig]) -> Result> { + fn load_luts( + device: &ID3D11Device, + textures: &[TextureConfig], + ) -> util::Result> { let mut luts = FxHashMap::default(); for (index, texture) in textures.iter().enumerate() { let image = Image::load(&texture.path)?; let desc = D3D11_TEXTURE2D_DESC { - Width: image.width, - Height: image.height, + Width: image.size.width, + Height: image.size.height, Format: DXGI_FORMAT_R8G8B8A8_UNORM, + Usage: D3D11_USAGE_DEFAULT, MiscFlags: if texture.mipmap { D3D11_RESOURCE_MISC_GENERATE_MIPS } else { - 0 + D3D11_RESOURCE_MISC_FLAG(0) }, ..Default::default() }; - let mut texture = Texture::new(device, image.size, desc); + let mut texture = OwnedTexture::new(device, &image, desc)?; // todo: update texture d3d11_common: 150 luts.insert(index, texture); - } Ok(luts) } /// Load the shader preset at the given path into a filter chain. - pub fn load_from_path(path: impl AsRef) -> Result { + pub fn load_from_path(device: &ID3D11Device, path: impl AsRef) -> util::Result { // load passes from preset let preset = ShaderPreset::try_parse(path)?; - Self::load_from_preset(preset) + Self::load_from_preset(device, preset) } - fn load_preset( - preset: &ShaderPreset, - ) -> Result<(Vec, ReflectSemantics)> { + fn load_preset(preset: &ShaderPreset) -> util::Result<(Vec, ReflectSemantics)> { let mut uniform_semantics: FxHashMap = Default::default(); let mut texture_semantics: FxHashMap> = Default::default(); @@ -198,7 +203,7 @@ impl FilterChain { Ok::<_, Box>((shader, source, reflect)) }) .into_iter() - .collect::)>>>()?; + .collect::)>>>()?; for details in &passes { FilterChain::load_pass_semantics( @@ -234,4 +239,4 @@ impl FilterChain { Ok((passes, semantics)) } -} \ No newline at end of file +} diff --git a/librashader-runtime-dx11/src/filter_pass.rs b/librashader-runtime-dx11/src/filter_pass.rs index bba4500..fbaab7d 100644 --- a/librashader-runtime-dx11/src/filter_pass.rs +++ b/librashader-runtime-dx11/src/filter_pass.rs @@ -1,20 +1,26 @@ -use std::error::Error; -use rustc_hash::FxHashMap; -use windows::Win32::Graphics::Direct3D11::{D3D11_MAP_WRITE_DISCARD, ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader}; -use windows::Win32::Graphics::Direct3D::ID3DBlob; +use crate::filter_chain::FilterCommon; +use crate::texture::{ExternalTexture, OwnedTexture}; use librashader_common::Size; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::back::cross::GlslangHlslContext; use librashader_reflect::back::ShaderCompilerOutput; -use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniformSemantic, VariableSemantics}; +use librashader_reflect::reflect::semantics::{ + BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniformSemantic, + VariableSemantics, +}; use librashader_reflect::reflect::ShaderReflection; -use crate::filter_chain::FilterCommon; -use crate::util::Texture; +use rustc_hash::FxHashMap; +use std::error::Error; +use windows::Win32::Graphics::Direct3D::ID3DBlob; +use windows::Win32::Graphics::Direct3D11::{ + ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, + ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, +}; pub struct DxShader { pub blob: ID3DBlob, - pub compiled: T + pub compiled: T, } pub struct ConstantBuffer { @@ -22,7 +28,7 @@ pub struct ConstantBuffer { pub size: u32, pub stage_mask: BindingStage, pub buffer: ID3D11Buffer, - pub storage: Box<[u8]> + pub storage: Box<[u8]>, } // slang_process.cpp 141 @@ -34,7 +40,6 @@ pub struct FilterPass { pub uniform_bindings: FxHashMap, - pub uniform_buffer: ConstantBuffer, pub push_buffer: ConstantBuffer, pub source: ShaderSource, @@ -48,10 +53,8 @@ impl FilterPass { } #[inline(always)] - fn build_uniform( - buffer: &mut [u8], - value: T, - ) where + fn build_uniform(buffer: &mut [u8], value: T) + where T: Copy, T: bytemuck::Pod, { @@ -65,14 +68,15 @@ impl FilterPass { buffer.copy_from_slice(vec4); } - fn bind_texture(texture_binding: &mut [Option; 16], - sampler_binding: &mut [Option; 16], - binding: &TextureBinding, - texture: &Texture - ) - { + fn bind_texture( + texture_binding: &mut [Option; 16], + sampler_binding: &mut [Option; 16], + binding: &TextureBinding, + texture: &ExternalTexture, + ) { texture_binding[binding.binding as usize] = Some(texture.srv.clone()); - sampler_binding[binding.binding as usize] = Some(texture.sampler.clone()); + // todo: make samplers for all wrapmode/filtermode combos. + // sampler_binding[binding.binding as usize] = Some(texture.sampler.clone()); } // framecount should be pre-modded @@ -85,17 +89,14 @@ impl FilterPass { frame_direction: i32, fb_size: Size, // viewport: &Viewport, - original: &Texture, - source: &Texture, + original: &ExternalTexture, + source: &ExternalTexture, ) { - let mut textures: [Option; 16] = std::array::from_fn(|_| None); let mut samplers: [Option; 16] = std::array::from_fn(|_| None); // Bind MVP - if let Some(offset) = - self.uniform_bindings.get(&VariableSemantics::MVP.into()) - { + if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::MVP.into()) { let mvp_size = mvp.len() * std::mem::size_of::(); let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), @@ -105,10 +106,7 @@ impl FilterPass { } // bind OutputSize - if let Some(offset) = self - .uniform_bindings - .get(&VariableSemantics::Output.into()) - { + if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::Output.into()) { let (buffer, offset) = match offset { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), @@ -153,10 +151,7 @@ impl FilterPass { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), }; - FilterPass::build_uniform( - &mut buffer[offset..][..4], - frame_direction, - ) + FilterPass::build_uniform(&mut buffer[offset..][..4], frame_direction) } // bind Original sampler @@ -178,10 +173,7 @@ impl FilterPass { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), }; - FilterPass::build_vec4( - &mut buffer[offset..][..16], - original.size, - ); + FilterPass::build_vec4(&mut buffer[offset..][..16], original.size); } // bind Source sampler @@ -204,10 +196,7 @@ impl FilterPass { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), }; - FilterPass::build_vec4( - &mut buffer[offset..][..16], - source.size, - ); + FilterPass::build_vec4(&mut buffer[offset..][..16], source.size); } if let Some(binding) = self @@ -227,10 +216,7 @@ impl FilterPass { MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), }; - FilterPass::build_vec4( - &mut buffer[offset..][..16], - original.size, - ); + FilterPass::build_vec4(&mut buffer[offset..][..16], original.size); } // for (index, output) in parent.history_textures.iter().enumerate() { @@ -317,12 +303,12 @@ impl FilterPass { // bind float parameters for (id, offset) in - self.uniform_bindings - .iter() - .filter_map(|(binding, value)| match binding { - UniformBinding::Parameter(id) => Some((id, value)), - _ => None, - }) + self.uniform_bindings + .iter() + .filter_map(|(binding, value)| match binding { + UniformBinding::Parameter(id) => Some((id, value)), + _ => None, + }) { let id = id.as_str(); let (buffer, offset) = match offset { @@ -385,10 +371,7 @@ impl FilterPass { parent: &FilterCommon, frame_count: u32, frame_direction: i32, - ) -> std::result::Result<(), Box> - { - - + ) -> std::result::Result<(), Box> { Ok(()) } -} \ No newline at end of file +} diff --git a/librashader-runtime-dx11/src/hello_triangle.rs b/librashader-runtime-dx11/src/hello_triangle.rs index 1af01c8..ee9aea6 100644 --- a/librashader-runtime-dx11/src/hello_triangle.rs +++ b/librashader-runtime-dx11/src/hello_triangle.rs @@ -63,19 +63,20 @@ PixelOutput main(PixelInput pixelInput) return output; }\0"; - -use std::mem::transmute; use gfx_maths::Mat4; +use std::mem::transmute; -trait DXSample { +pub trait DXSample { fn new() -> Result - where - Self: Sized; + where + Self: Sized; fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()>; fn update(&mut self) {} - fn render(&mut self) -> Result<()> { Ok(()) } + fn render(&mut self) -> Result<()> { + Ok(()) + } fn on_key_up(&mut self, _key: u8) {} fn on_key_down(&mut self, _key: u8) {} @@ -88,9 +89,9 @@ trait DXSample { } } -fn run_sample() -> Result<()> - where - S: DXSample, +fn run_sample(mut sample: S) -> Result<()> +where + S: DXSample, { let instance = unsafe { GetModuleHandleA(None)? }; @@ -104,8 +105,6 @@ fn run_sample() -> Result<()> ..Default::default() }; - let mut sample = S::new()?; - let size = sample.window_size(); let atom = unsafe { RegisterClassExA(&wc) }; @@ -121,8 +120,6 @@ fn run_sample() -> Result<()> let mut title = sample.title(); - - title.push('\0'); let hwnd = unsafe { @@ -216,7 +213,6 @@ extern "system" fn wndproc( } } - #[repr(C)] struct Vertex { position: [f32; 3], @@ -228,37 +224,37 @@ struct Vertex { struct TriangleUniforms { projection_matrix: Mat4, model_matrix: Mat4, - view_matrix: Mat4 + view_matrix: Mat4, } -mod d3d11_hello_triangle { +pub mod d3d11_hello_triangle { + use super::*; + use gfx_maths::{Quaternion, Vec3}; use std::slice; use std::time::Instant; - use gfx_maths::{Quaternion, Vec3}; - use super::*; const FRAME_COUNT: u32 = 2; pub struct Sample { - dxgi_factory: IDXGIFactory4, - device: ID3D11Device, - context: ID3D11DeviceContext, - resources: Option + pub dxgi_factory: IDXGIFactory4, + pub device: ID3D11Device, + pub context: ID3D11DeviceContext, + pub resources: Option, } pub struct Resources { - swapchain: IDXGISwapChain, - depth_buffer: ID3D11Texture2D, - depth_stencil_view: ID3D11DepthStencilView, - triangle_vertices: ID3D11Buffer, - triangle_indices: ID3D11Buffer, - triangle_uniforms: ID3D11Buffer, - vs: ID3D11VertexShader, - ps: ID3D11PixelShader, - input_layout: ID3D11InputLayout, - frame_start: Instant, - frame_end: Instant, - elapsed: f32, + pub swapchain: IDXGISwapChain, + pub depth_buffer: ID3D11Texture2D, + pub depth_stencil_view: ID3D11DepthStencilView, + pub triangle_vertices: ID3D11Buffer, + pub triangle_indices: ID3D11Buffer, + pub triangle_uniforms: ID3D11Buffer, + pub vs: ID3D11VertexShader, + pub ps: ID3D11PixelShader, + pub input_layout: ID3D11InputLayout, + pub frame_start: Instant, + pub frame_end: Instant, + pub elapsed: f32, triangle_uniform_values: TriangleUniforms, pub backbuffer: ID3D11Texture2D, pub rtv: ID3D11RenderTargetView, @@ -272,7 +268,7 @@ mod d3d11_hello_triangle { dxgi_factory, device, context, - resources: None + resources: None, }) } @@ -288,21 +284,24 @@ mod d3d11_hello_triangle { let vs_compiled = unsafe { // SAFETY: slice as valid for as long as vs_blob is alive. - slice::from_raw_parts(vs_blob.GetBufferPointer().cast::(), vs_blob.GetBufferSize()) + slice::from_raw_parts( + vs_blob.GetBufferPointer().cast::(), + vs_blob.GetBufferSize(), + ) }; - let vs = unsafe { - self.device.CreateVertexShader(vs_compiled, None) - }?; + let vs = unsafe { self.device.CreateVertexShader(vs_compiled, None) }?; let ps = unsafe { - let ps = slice::from_raw_parts(ps_blob.GetBufferPointer().cast::(), ps_blob.GetBufferSize()); + let ps = slice::from_raw_parts( + ps_blob.GetBufferPointer().cast::(), + ps_blob.GetBufferSize(), + ); self.device.CreatePixelShader(ps, None) }?; - - let (input_layout, stencil_state, raster_state) - = create_pipeline_state(&self.device, vs_compiled)?; + let (input_layout, stencil_state, raster_state) = + create_pipeline_state(&self.device, vs_compiled)?; unsafe { self.context.OMSetDepthStencilState(&stencil_state, 1); @@ -332,7 +331,7 @@ mod d3d11_hello_triangle { Height: HEIGHT as f32, MinDepth: D3D11_MIN_DEPTH, MaxDepth: D3D11_MAX_DEPTH, - } + }, }); Ok(()) @@ -348,7 +347,7 @@ mod d3d11_hello_triangle { let time = time.as_secs() as f32 * 1000.0; // framelimit set to 60fps - if time < (1000.0f32 / 144.0f32) { + if time < (1000.0f32 / 60.0f32) { return Ok(()); } @@ -361,21 +360,42 @@ mod d3d11_hello_triangle { let buffer_number = 0; unsafe { - let mapped_resource = self.context.Map(&resources.triangle_uniforms, 0, D3D11_MAP_WRITE_DISCARD, 0)?; - std::ptr::copy_nonoverlapping(&resources.triangle_uniform_values, mapped_resource.pData.cast(), 1); + let mapped_resource = self.context.Map( + &resources.triangle_uniforms, + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + )?; + std::ptr::copy_nonoverlapping( + &resources.triangle_uniform_values, + mapped_resource.pData.cast(), + 1, + ); self.context.Unmap(&resources.triangle_uniforms, 0); } unsafe { - self.context.VSSetConstantBuffers(buffer_number, Some(&[Some(resources.triangle_uniforms.clone())])); - self.context.OMSetRenderTargets(Some(&[Some(resources.rtv.clone())]), &resources.depth_stencil_view); + self.context.VSSetConstantBuffers( + buffer_number, + Some(&[Some(resources.triangle_uniforms.clone())]), + ); + self.context.OMSetRenderTargets( + Some(&[Some(resources.rtv.clone())]), + &resources.depth_stencil_view, + ); self.context.RSSetViewports(Some(&[resources.viewport])) } unsafe { let color = [0.3, 0.4, 0.6, 1.0]; - self.context.ClearRenderTargetView(&resources.rtv, color.as_ptr()); - self.context.ClearDepthStencilView(&resources.depth_stencil_view, D3D11_CLEAR_DEPTH.0 as u32, 1.0, 0); + self.context + .ClearRenderTargetView(&resources.rtv, color.as_ptr()); + self.context.ClearDepthStencilView( + &resources.depth_stencil_view, + D3D11_CLEAR_DEPTH.0 as u32, + 1.0, + 0, + ); self.context.IASetInputLayout(&resources.input_layout); } @@ -383,18 +403,25 @@ mod d3d11_hello_triangle { self.context.VSSetShader(&resources.vs, None); self.context.PSSetShader(&resources.ps, None); - let stride =std::mem::size_of::() as u32; + let stride = std::mem::size_of::() as u32; let offset = 0; - self.context.IASetVertexBuffers(0, 1, Some(&Some(resources.triangle_vertices.clone())), Some(&stride), Some(&offset)); - self.context.IASetIndexBuffer(&resources.triangle_indices, DXGI_FORMAT_R32_UINT, 0); - self.context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + self.context.IASetVertexBuffers( + 0, + 1, + Some(&Some(resources.triangle_vertices.clone())), + Some(&stride), + Some(&offset), + ); + self.context + .IASetIndexBuffer(&resources.triangle_indices, DXGI_FORMAT_R32_UINT, 0); + self.context + .IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); } unsafe { self.context.DrawIndexed(3, 0, 0); } - unsafe { resources.swapchain.Present(0, 0).ok()?; } @@ -402,7 +429,10 @@ mod d3d11_hello_triangle { } } - fn create_rtv(device: &ID3D11Device, swapchain: &IDXGISwapChain) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)>{ + fn create_rtv( + device: &ID3D11Device, + swapchain: &IDXGISwapChain, + ) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)> { unsafe { let backbuffer: ID3D11Texture2D = swapchain.GetBuffer(0)?; let rtv = device.CreateRenderTargetView(&backbuffer, None)?; @@ -410,28 +440,38 @@ mod d3d11_hello_triangle { Ok((rtv, backbuffer)) } } - fn create_pipeline_state(device: &ID3D11Device, vs_blob: &[u8]) -> Result<(ID3D11InputLayout, ID3D11DepthStencilState, ID3D11RasterizerState)> { + fn create_pipeline_state( + device: &ID3D11Device, + vs_blob: &[u8], + ) -> Result<( + ID3D11InputLayout, + ID3D11DepthStencilState, + ID3D11RasterizerState, + )> { unsafe { - let input_layout = device.CreateInputLayout(&[ - D3D11_INPUT_ELEMENT_DESC { - SemanticName: s!("POSITION"), - SemanticIndex: 0, - Format: DXGI_FORMAT_R32G32B32_FLOAT, - InputSlot: 0, - AlignedByteOffset: 0, - InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA, - InstanceDataStepRate: 0 - }, - D3D11_INPUT_ELEMENT_DESC { - SemanticName: s!("COLOR"), - SemanticIndex: 0, - Format: DXGI_FORMAT_R32G32B32_FLOAT, - InputSlot: 0, - AlignedByteOffset: D3D11_APPEND_ALIGNED_ELEMENT, - InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA, - InstanceDataStepRate: 0 - }, - ], vs_blob)?; + let input_layout = device.CreateInputLayout( + &[ + D3D11_INPUT_ELEMENT_DESC { + SemanticName: s!("POSITION"), + SemanticIndex: 0, + Format: DXGI_FORMAT_R32G32B32_FLOAT, + InputSlot: 0, + AlignedByteOffset: 0, + InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA, + InstanceDataStepRate: 0, + }, + D3D11_INPUT_ELEMENT_DESC { + SemanticName: s!("COLOR"), + SemanticIndex: 0, + Format: DXGI_FORMAT_R32G32B32_FLOAT, + InputSlot: 0, + AlignedByteOffset: D3D11_APPEND_ALIGNED_ELEMENT, + InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA, + InstanceDataStepRate: 0, + }, + ], + vs_blob, + )?; let stencil_state = device.CreateDepthStencilState(&D3D11_DEPTH_STENCIL_DESC { DepthEnable: BOOL::from(true), @@ -451,7 +491,7 @@ mod d3d11_hello_triangle { StencilDepthFailOp: D3D11_STENCIL_OP_DECR, StencilPassOp: D3D11_STENCIL_OP_KEEP, StencilFunc: D3D11_COMPARISON_ALWAYS, - } + }, })?; let rasterizer_state = device.CreateRasterizerState(&D3D11_RASTERIZER_DESC { @@ -464,41 +504,47 @@ mod d3d11_hello_triangle { FrontCounterClockwise: BOOL::from(false), MultisampleEnable: BOOL::from(false), ScissorEnable: BOOL::from(false), - SlopeScaledDepthBias: 0.0f32 + SlopeScaledDepthBias: 0.0f32, })?; Ok((input_layout, stencil_state, rasterizer_state)) } } - fn create_depth_buffer(device: &ID3D11Device) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)>{ + fn create_depth_buffer( + device: &ID3D11Device, + ) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)> { unsafe { - let buffer = device.CreateTexture2D(&D3D11_TEXTURE2D_DESC { - Width: WIDTH as u32, - Height: HEIGHT as u32, - MipLevels: 1, - ArraySize: 1, - Format: DXGI_FORMAT_D24_UNORM_S8_UINT, - SampleDesc: DXGI_SAMPLE_DESC { - Count: 1, - Quality: 0 - }, - Usage: D3D11_USAGE_DEFAULT, - BindFlags: D3D11_BIND_DEPTH_STENCIL, - CPUAccessFlags: Default::default(), - MiscFlags: Default::default(), - }, None)?; - - let view = device.CreateDepthStencilView(&buffer,Some(&D3D11_DEPTH_STENCIL_VIEW_DESC { - Format: DXGI_FORMAT_D24_UNORM_S8_UINT, - ViewDimension: D3D11_DSV_DIMENSION_TEXTURE2D, - Anonymous: D3D11_DEPTH_STENCIL_VIEW_DESC_0 { - Texture2D: D3D11_TEX2D_DSV { - MipSlice: 0, + let buffer = device.CreateTexture2D( + &D3D11_TEXTURE2D_DESC { + Width: WIDTH as u32, + Height: HEIGHT as u32, + MipLevels: 1, + ArraySize: 1, + Format: DXGI_FORMAT_D24_UNORM_S8_UINT, + SampleDesc: DXGI_SAMPLE_DESC { + Count: 1, + Quality: 0, }, + Usage: D3D11_USAGE_DEFAULT, + BindFlags: D3D11_BIND_DEPTH_STENCIL, + CPUAccessFlags: Default::default(), + MiscFlags: Default::default(), }, - ..Default::default() - }))?; + None, + )?; + + let view = device.CreateDepthStencilView( + &buffer, + Some(&D3D11_DEPTH_STENCIL_VIEW_DESC { + Format: DXGI_FORMAT_D24_UNORM_S8_UINT, + ViewDimension: D3D11_DSV_DIMENSION_TEXTURE2D, + Anonymous: D3D11_DEPTH_STENCIL_VIEW_DESC_0 { + Texture2D: D3D11_TEX2D_DSV { MipSlice: 0 }, + }, + ..Default::default() + }), + )?; Ok((buffer, view)) } @@ -506,22 +552,21 @@ mod d3d11_hello_triangle { fn create_triangle_uniforms(device: &ID3D11Device) -> Result { unsafe { - device.CreateBuffer(&D3D11_BUFFER_DESC { - ByteWidth: (std::mem::size_of::()) as u32, - Usage: D3D11_USAGE_DYNAMIC, - BindFlags: D3D11_BIND_CONSTANT_BUFFER, - CPUAccessFlags: D3D11_CPU_ACCESS_WRITE, - MiscFlags: Default::default(), - StructureByteStride: 0, - }, None) + device.CreateBuffer( + &D3D11_BUFFER_DESC { + ByteWidth: (std::mem::size_of::()) as u32, + Usage: D3D11_USAGE_DYNAMIC, + BindFlags: D3D11_BIND_CONSTANT_BUFFER, + CPUAccessFlags: D3D11_CPU_ACCESS_WRITE, + MiscFlags: Default::default(), + StructureByteStride: 0, + }, + None, + ) } } - - - fn create_triangle_buffers( - device: &ID3D11Device, - ) -> Result<(ID3D11Buffer, ID3D11Buffer)> { + fn create_triangle_buffers(device: &ID3D11Device) -> Result<(ID3D11Buffer, ID3D11Buffer)> { let vertices = [ Vertex { position: [0.5f32, -0.5, 0.0], @@ -539,35 +584,40 @@ mod d3d11_hello_triangle { let indices = [0, 1, 2]; unsafe { - let vertex_buffer = device.CreateBuffer(&D3D11_BUFFER_DESC { - ByteWidth: (std::mem::size_of::() * vertices.len()) as u32, - Usage: D3D11_USAGE_DEFAULT, - BindFlags: D3D11_BIND_VERTEX_BUFFER, - CPUAccessFlags: Default::default(), - MiscFlags: Default::default(), - StructureByteStride: 0, - }, Some(&D3D11_SUBRESOURCE_DATA { - pSysMem: vertices.as_ptr().cast(), - SysMemPitch: 0, - SysMemSlicePitch: 0, - }))?; + let vertex_buffer = device.CreateBuffer( + &D3D11_BUFFER_DESC { + ByteWidth: (std::mem::size_of::() * vertices.len()) as u32, + Usage: D3D11_USAGE_DEFAULT, + BindFlags: D3D11_BIND_VERTEX_BUFFER, + CPUAccessFlags: Default::default(), + MiscFlags: Default::default(), + StructureByteStride: 0, + }, + Some(&D3D11_SUBRESOURCE_DATA { + pSysMem: vertices.as_ptr().cast(), + SysMemPitch: 0, + SysMemSlicePitch: 0, + }), + )?; - let index_buffer = device.CreateBuffer(&D3D11_BUFFER_DESC { - ByteWidth: (std::mem::size_of::() * indices.len()) as u32, - Usage: D3D11_USAGE_DEFAULT, - BindFlags: D3D11_BIND_INDEX_BUFFER, - CPUAccessFlags: Default::default(), - MiscFlags: Default::default(), - StructureByteStride: 0, - }, Some(&D3D11_SUBRESOURCE_DATA { - pSysMem: indices.as_ptr().cast(), - SysMemPitch: 0, - SysMemSlicePitch: 0, - }))?; + let index_buffer = device.CreateBuffer( + &D3D11_BUFFER_DESC { + ByteWidth: (std::mem::size_of::() * indices.len()) as u32, + Usage: D3D11_USAGE_DEFAULT, + BindFlags: D3D11_BIND_INDEX_BUFFER, + CPUAccessFlags: Default::default(), + MiscFlags: Default::default(), + StructureByteStride: 0, + }, + Some(&D3D11_SUBRESOURCE_DATA { + pSysMem: indices.as_ptr().cast(), + SysMemPitch: 0, + SysMemSlicePitch: 0, + }), + )?; Ok((vertex_buffer, index_buffer)) } - } fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> { let dxgi_factory_flags = if cfg!(debug_assertions) { @@ -583,19 +633,27 @@ mod d3d11_hello_triangle { let mut out_context = None; let mut _out_feature_level = D3D_FEATURE_LEVEL_11_0; - unsafe { D3D11CreateDevice(None, D3D_DRIVER_TYPE_HARDWARE, - HINSTANCE::default(), - Default::default(), - Some(&feature_levels), - D3D11_SDK_VERSION, - Some(&mut out_device), - Some(&mut _out_feature_level), - Some(&mut out_context)) + unsafe { + D3D11CreateDevice( + None, + D3D_DRIVER_TYPE_HARDWARE, + HINSTANCE::default(), + D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG, + Some(&feature_levels), + D3D11_SDK_VERSION, + Some(&mut out_device), + Some(&mut _out_feature_level), + Some(&mut out_context), + ) }?; Ok((dxgi_factory, out_device.unwrap(), out_context.unwrap())) } - fn create_swapchain(fac: &IDXGIFactory4, device: &ID3D11Device, hwnd: HWND) -> Result{ + fn create_swapchain( + fac: &IDXGIFactory4, + device: &ID3D11Device, + hwnd: HWND, + ) -> Result { let swapchain_desc = DXGI_SWAP_CHAIN_DESC { BufferDesc: DXGI_MODE_DESC { Width: WIDTH as u32, @@ -620,7 +678,6 @@ mod d3d11_hello_triangle { Flags: 0, }; - let mut swap_chain = None; unsafe { fac.CreateSwapChain(&*device, &swapchain_desc, &mut swap_chain) @@ -630,21 +687,30 @@ mod d3d11_hello_triangle { Ok(swap_chain.expect("[dx11] swapchain creation failed.")) } - fn compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result{ + fn compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result { unsafe { let mut blob = None; - D3DCompile(source.as_ptr().cast(), source.len(), - None, None, None, - PCSTR(entry.as_ptr()), - PCSTR(version.as_ptr()), D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, &mut blob, None)?; + D3DCompile( + source.as_ptr().cast(), + source.len(), + None, + None, + None, + PCSTR(entry.as_ptr()), + PCSTR(version.as_ptr()), + D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, + 0, + &mut blob, + None, + )?; Ok(blob.unwrap()) } } } -pub fn main() -> Result<()> { - run_sample::()?; +pub fn main(sample: S) -> Result<()> { + run_sample(sample)?; Ok(()) -} \ No newline at end of file +} diff --git a/librashader-runtime-dx11/src/lib.rs b/librashader-runtime-dx11/src/lib.rs index e5ab23c..6d79da6 100644 --- a/librashader-runtime-dx11/src/lib.rs +++ b/librashader-runtime-dx11/src/lib.rs @@ -1,31 +1,40 @@ #![feature(type_alias_impl_trait)] +#![feature(let_chains)] mod filter_chain; - use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::back::targets::HLSL; use librashader_reflect::back::{CompileShader, FromCompilation}; +use librashader_reflect::front::shaderc::GlslangCompilation; use rustc_hash::FxHashMap; use std::error::Error; use std::path::Path; -use librashader_reflect::front::shaderc::GlslangCompilation; -use librashader_reflect::reflect::semantics::{ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics}; +use librashader_reflect::reflect::semantics::{ + ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics, +}; use librashader_reflect::reflect::ReflectShader; +mod filter_pass; #[cfg(test)] mod hello_triangle; -mod filter_pass; +mod texture; mod util; #[cfg(test)] mod tests { + use crate::hello_triangle::DXSample; use super::*; #[test] fn triangle_dx11() { - hello_triangle::main().unwrap(); + let sample = hello_triangle::d3d11_hello_triangle::Sample::new().unwrap(); + let device = sample.device.clone(); + let chain = filter_chain::FilterChain::load_from_path(&device, "../test/slang-shaders/crt/crt-royale.slangp").unwrap(); + std::mem::forget(chain); + hello_triangle::main(sample).unwrap(); + } } diff --git a/librashader-runtime-dx11/src/texture.rs b/librashader-runtime-dx11/src/texture.rs new file mode 100644 index 0000000..0f080ea --- /dev/null +++ b/librashader-runtime-dx11/src/texture.rs @@ -0,0 +1,146 @@ +use librashader_common::Size; +use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_FLAG, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_SRV, D3D11_BIND_FLAG, D3D11_RESOURCE_MISC_FLAG, D3D11_USAGE_STAGING, ID3D11DeviceContext, D3D11_SUBRESOURCE_DATA, D3D11_MAP_WRITE, D3D11_BOX}; +use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D; +use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; +use librashader_common::image::Image; +use crate::util::d3d11_get_closest_format; +use crate::util::Result; + +#[derive(Debug, Clone)] +pub struct ExternalTexture { + pub srv: ID3D11ShaderResourceView, + pub size: Size, // pub image: GlImage, +} + +#[derive(Debug, Clone)] +pub struct OwnedTexture { + pub handle: ID3D11Texture2D, + // pub staging: ID3D11Texture2D, + pub srv: ID3D11ShaderResourceView, + pub desc: D3D11_TEXTURE2D_DESC, + pub size: Size, // pub image: GlImage, + // pub filter: FilterMode, + // pub mip_filter: FilterMode, + // pub wrap_mode: WrapMode, +} + +impl OwnedTexture { + pub fn new(device: &ID3D11Device, source: &Image, desc: D3D11_TEXTURE2D_DESC) -> Result { + let mut desc = D3D11_TEXTURE2D_DESC { + Width: source.size.width, + Height: source.size.height, + // todo: set this to 0 + MipLevels: if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 { + 0 + } else { + 1 + }, + ArraySize: 1, + SampleDesc: DXGI_SAMPLE_DESC { + Count: 1, + Quality: 0, + }, + CPUAccessFlags: if desc.Usage == D3D11_USAGE_DYNAMIC { + D3D11_CPU_ACCESS_WRITE + } else { + D3D11_CPU_ACCESS_FLAG(0) + }, + ..desc + }; + desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + + // determine number of mipmaps required + if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 { + let mut width = desc.Width >> 5; + let mut height = desc.Height >> 5; + desc.BindFlags |= D3D11_BIND_RENDER_TARGET; + + while width != 0 && height != 0 { + width >>= 1; + height >>= 1; + desc.MipLevels += 1; + } + } + + // determine if format is supported. + // bruh why does D3D11_FORMAT_SUPPORT not implement bitor??? + let mut format_support = + D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0; + if (desc.BindFlags & D3D11_BIND_RENDER_TARGET).0 != 0 { + format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0; + } + + eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len()); + eprintln!("{:#?}", desc); + + // let data = Some(&D3D11_SUBRESOURCE_DATA { + // pSysMem: source.bytes.as_ptr().cast(), + // SysMemPitch: source.pitch as u32, + // SysMemSlicePitch: 0 + // }); + unsafe { + let handle = device.CreateTexture2D(&desc, None).unwrap(); + + let srv = device.CreateShaderResourceView(&handle, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { + Format: desc.Format, + ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D, + Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 { + Texture2D: D3D11_TEX2D_SRV { + MostDetailedMip: 0, + MipLevels: u32::MAX + } + }, + }))?; + + + let mut context = None; + device.GetImmediateContext(&mut context); + + // todo: make this fallible + let context = context.unwrap(); + + // need a staging texture to defer mipmap generation + let staging = device.CreateTexture2D(&D3D11_TEXTURE2D_DESC { + MipLevels: 1, + BindFlags: D3D11_BIND_FLAG(0), + MiscFlags: D3D11_RESOURCE_MISC_FLAG(0), + Usage: D3D11_USAGE_STAGING, + CPUAccessFlags: D3D11_CPU_ACCESS_WRITE, + ..desc + }, Some(&D3D11_SUBRESOURCE_DATA { + pSysMem: source.bytes.as_ptr().cast(), + SysMemPitch: source.pitch as u32, + SysMemSlicePitch: 0 + }))?; + + // todo: do format conversion (leverage image crate..? is this necessary tbh)... + + context.CopySubresourceRegion(&handle, 0, 0, 0, 0, + &staging, 0, Some(&D3D11_BOX { + left: 0, + top: 0, + front: 0, + right: source.size.width, + bottom: source.size.height, + back: 1, + })); + + if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 { + context.GenerateMips(&srv) + } + + // let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?; + // staging.Upd + + + + Ok(OwnedTexture { + handle, + // staging, + srv, + desc, + size: source.size, + }) + } + } +} diff --git a/librashader-runtime-dx11/src/util.rs b/librashader-runtime-dx11/src/util.rs index bc5cb0c..9846994 100644 --- a/librashader-runtime-dx11/src/util.rs +++ b/librashader-runtime-dx11/src/util.rs @@ -1,64 +1,105 @@ -use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, ID3D11Device, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11Texture2D}; -use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; use librashader_common::{FilterMode, Size, WrapMode}; -#[derive(Debug, Clone)] -pub struct Texture { - pub handle: ID3D11Texture2D, - pub staging: ID3D11Texture2D, - pub srv: ID3D11ShaderResourceView, - pub sampler: ID3D11SamplerState, - pub desc: D3D11_TEXTURE2D_DESC, - pub size: Size - // pub image: GlImage, - // pub filter: FilterMode, - // pub mip_filter: FilterMode, - // pub wrap_mode: WrapMode, +use windows::Win32::Graphics::Direct3D11::*; +use windows::Win32::Graphics::Dxgi::Common::*; +use std::error::Error; + +/// wtf retroarch? +const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000); + +const fn d3d11_format_fallback_list(format: DXGI_FORMAT) -> Option<&'static [DXGI_FORMAT]> { + match format { + DXGI_FORMAT_R32G32B32A32_FLOAT => Some(&[ + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R32G32B32_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_R16G16B16A16_FLOAT => Some(&[ + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_R8G8B8A8_UNORM => Some(&[ + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB => Some(&[ + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_B8G8R8A8_UNORM => Some(&[ + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_B8G8R8X8_UNORM => Some(&[ + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_B5G6R5_UNORM => Some(&[ + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_EX_A4R4G4B4_UNORM | DXGI_FORMAT_B4G4R4A4_UNORM => Some(&[ + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_A8_UNORM => Some(&[ + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + DXGI_FORMAT_R8_UNORM => Some(&[ + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + ]), + _ => None, + } } -impl Texture { - pub fn new(device: &ID3D11Device, size: Size, desc: D3D11_TEXTURE2D_DESC) -> Texture { - let mut desc = D3D11_TEXTURE2D_DESC { - Width: size.width, - Height: size.height, - MipLevels: 1, - ArraySize: 1, - SampleDesc: DXGI_SAMPLE_DESC { - Count: 1, - Quality: 0 - }, - CPUAccessFlags: if desc.Usage == D3D11_USAGE_DYNAMIC { - D3D11_CPU_ACCESS_WRITE - } else { - 0 - }, - ..desc - }; - desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; +pub fn d3d11_get_closest_format( + device: &ID3D11Device, + format: DXGI_FORMAT, + format_support_mask: i32, +) -> DXGI_FORMAT { + let default_list = [format, DXGI_FORMAT_UNKNOWN]; + let format_support_list = d3d11_format_fallback_list(format) + .unwrap_or(&default_list); + let format_support_mask = format_support_mask as u32; - // determine number of mipmaps required - if desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS { - let mut width = desc.Width >> 5; - let mut height = desc.Height >> 5; - desc.BindFlags |= D3D11_BIND_RENDER_TARGET; - - while width != 0 && height != 0 { - width >>= 1; - height >>= 1; - desc.MipLevels += 1; + for supported in format_support_list { + unsafe { + if let Ok(supported_format) = device.CheckFormatSupport(*supported) + && (supported_format & format_support_mask) == format_support_mask { + return *supported; } } - - // determine if format is supported. - let mut format_support = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; - if desc.BindFlags |= D3D11_BIND_RENDER_TARGET { - format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET; - } - - // todo: actually check format support - - // d3d11_common: 83 - todo!(); - } -} \ No newline at end of file + return DXGI_FORMAT_UNKNOWN; +} + +// todo: d3d11.c 2097 +pub type Result = std::result::Result>; diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 9b0744a..4e9065a 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -147,7 +147,8 @@ impl Framebuffer { } } - pub(crate) fn copy_from(&mut self, image: &GlImage) -> Result<()>{ + pub(crate) fn copy_from(&mut self, image: &GlImage) -> Result<()> { + // todo: may want to use a shader and draw a quad to be faster. if image.size != self.size || image.format != self.format { self.init(image.size, image.format)?; } diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index b9e8837..d4a7054 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -27,7 +27,7 @@ mod tests { fn triangle_gl() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); let mut filter = - FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp") + FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp") .unwrap(); hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter); }