diff --git a/librashader-common/src/d3d11.rs b/librashader-common/src/d3d11.rs index f29741c..2c8418a 100644 --- a/librashader-common/src/d3d11.rs +++ b/librashader-common/src/d3d11.rs @@ -1,41 +1,41 @@ -use crate::{FilterMode, ShaderFormat, WrapMode}; +use crate::{FilterMode, ImageFormat, WrapMode}; use windows::Win32::Graphics::Direct3D11; use windows::Win32::Graphics::Dxgi::Common as dxgi; -impl From for dxgi::DXGI_FORMAT { - fn from(format: ShaderFormat) -> Self { +impl From for dxgi::DXGI_FORMAT { + fn from(format: ImageFormat) -> Self { match format { - ShaderFormat::Unknown => dxgi::DXGI_FORMAT_UNKNOWN, - ShaderFormat::R8Unorm => dxgi::DXGI_FORMAT_R8_UNORM, - ShaderFormat::R8Uint => dxgi::DXGI_FORMAT_R8_UINT, - ShaderFormat::R8Sint => dxgi::DXGI_FORMAT_R8_SINT, - ShaderFormat::R8G8Unorm => dxgi::DXGI_FORMAT_R8G8_UNORM, - ShaderFormat::R8G8Uint => dxgi::DXGI_FORMAT_R8G8_UINT, - ShaderFormat::R8G8Sint => dxgi::DXGI_FORMAT_R8G8_SINT, - ShaderFormat::R8G8B8A8Unorm => dxgi::DXGI_FORMAT_R8G8B8A8_UNORM, - ShaderFormat::R8G8B8A8Uint => dxgi::DXGI_FORMAT_R8G8B8A8_UINT, - ShaderFormat::R8G8B8A8Sint => dxgi::DXGI_FORMAT_R8G8B8A8_SINT, - ShaderFormat::R8G8B8A8Srgb => dxgi::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - ShaderFormat::A2B10G10R10UnormPack32 => dxgi::DXGI_FORMAT_R10G10B10A2_UNORM, - ShaderFormat::A2B10G10R10UintPack32 => dxgi::DXGI_FORMAT_R10G10B10A2_UINT, - ShaderFormat::R16Uint => dxgi::DXGI_FORMAT_R16_UINT, - ShaderFormat::R16Sint => dxgi::DXGI_FORMAT_R16_SINT, - ShaderFormat::R16Sfloat => dxgi::DXGI_FORMAT_R16_FLOAT, - ShaderFormat::R16G16Uint => dxgi::DXGI_FORMAT_R16G16_UINT, - ShaderFormat::R16G16Sint => dxgi::DXGI_FORMAT_R16G16_SINT, - ShaderFormat::R16G16Sfloat => dxgi::DXGI_FORMAT_R16G16_FLOAT, - ShaderFormat::R16G16B16A16Uint => dxgi::DXGI_FORMAT_R16G16B16A16_UINT, - ShaderFormat::R16G16B16A16Sint => dxgi::DXGI_FORMAT_R16G16B16A16_SINT, - ShaderFormat::R16G16B16A16Sfloat => dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT, - ShaderFormat::R32Uint => dxgi::DXGI_FORMAT_R32_UINT, - ShaderFormat::R32Sint =>dxgi::DXGI_FORMAT_R32_SINT, - ShaderFormat::R32Sfloat => dxgi::DXGI_FORMAT_R32_FLOAT, - ShaderFormat::R32G32Uint => dxgi::DXGI_FORMAT_R32G32_UINT, - ShaderFormat::R32G32Sint => dxgi::DXGI_FORMAT_R32G32_SINT, - ShaderFormat::R32G32Sfloat => dxgi::DXGI_FORMAT_R32G32_FLOAT, - ShaderFormat::R32G32B32A32Uint => dxgi::DXGI_FORMAT_R32G32B32A32_UINT, - ShaderFormat::R32G32B32A32Sint => dxgi::DXGI_FORMAT_R32G32B32A32_SINT, - ShaderFormat::R32G32B32A32Sfloat => dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT, + ImageFormat::Unknown => dxgi::DXGI_FORMAT_UNKNOWN, + ImageFormat::R8Unorm => dxgi::DXGI_FORMAT_R8_UNORM, + ImageFormat::R8Uint => dxgi::DXGI_FORMAT_R8_UINT, + ImageFormat::R8Sint => dxgi::DXGI_FORMAT_R8_SINT, + ImageFormat::R8G8Unorm => dxgi::DXGI_FORMAT_R8G8_UNORM, + ImageFormat::R8G8Uint => dxgi::DXGI_FORMAT_R8G8_UINT, + ImageFormat::R8G8Sint => dxgi::DXGI_FORMAT_R8G8_SINT, + ImageFormat::R8G8B8A8Unorm => dxgi::DXGI_FORMAT_R8G8B8A8_UNORM, + ImageFormat::R8G8B8A8Uint => dxgi::DXGI_FORMAT_R8G8B8A8_UINT, + ImageFormat::R8G8B8A8Sint => dxgi::DXGI_FORMAT_R8G8B8A8_SINT, + ImageFormat::R8G8B8A8Srgb => dxgi::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + ImageFormat::A2B10G10R10UnormPack32 => dxgi::DXGI_FORMAT_R10G10B10A2_UNORM, + ImageFormat::A2B10G10R10UintPack32 => dxgi::DXGI_FORMAT_R10G10B10A2_UINT, + ImageFormat::R16Uint => dxgi::DXGI_FORMAT_R16_UINT, + ImageFormat::R16Sint => dxgi::DXGI_FORMAT_R16_SINT, + ImageFormat::R16Sfloat => dxgi::DXGI_FORMAT_R16_FLOAT, + ImageFormat::R16G16Uint => dxgi::DXGI_FORMAT_R16G16_UINT, + ImageFormat::R16G16Sint => dxgi::DXGI_FORMAT_R16G16_SINT, + ImageFormat::R16G16Sfloat => dxgi::DXGI_FORMAT_R16G16_FLOAT, + ImageFormat::R16G16B16A16Uint => dxgi::DXGI_FORMAT_R16G16B16A16_UINT, + ImageFormat::R16G16B16A16Sint => dxgi::DXGI_FORMAT_R16G16B16A16_SINT, + ImageFormat::R16G16B16A16Sfloat => dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT, + ImageFormat::R32Uint => dxgi::DXGI_FORMAT_R32_UINT, + ImageFormat::R32Sint =>dxgi::DXGI_FORMAT_R32_SINT, + ImageFormat::R32Sfloat => dxgi::DXGI_FORMAT_R32_FLOAT, + ImageFormat::R32G32Uint => dxgi::DXGI_FORMAT_R32G32_UINT, + ImageFormat::R32G32Sint => dxgi::DXGI_FORMAT_R32G32_SINT, + ImageFormat::R32G32Sfloat => dxgi::DXGI_FORMAT_R32G32_FLOAT, + ImageFormat::R32G32B32A32Uint => dxgi::DXGI_FORMAT_R32G32B32A32_UINT, + ImageFormat::R32G32B32A32Sint => dxgi::DXGI_FORMAT_R32G32B32A32_SINT, + ImageFormat::R32G32B32A32Sfloat => dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT, } } } diff --git a/librashader-common/src/gl.rs b/librashader-common/src/gl.rs index b0039fb..366c703 100644 --- a/librashader-common/src/gl.rs +++ b/librashader-common/src/gl.rs @@ -1,39 +1,39 @@ -use crate::{FilterMode, ShaderFormat, WrapMode}; +use crate::{FilterMode, ImageFormat, WrapMode}; -impl From for gl::types::GLenum { - fn from(format: ShaderFormat) -> Self { +impl From for gl::types::GLenum { + fn from(format: ImageFormat) -> Self { match format { - ShaderFormat::Unknown => 0 as gl::types::GLenum, - ShaderFormat::R8Unorm => gl::R8, - ShaderFormat::R8Uint => gl::R8UI, - ShaderFormat::R8Sint => gl::R8I, - ShaderFormat::R8G8Unorm => gl::RG8, - ShaderFormat::R8G8Uint => gl::RG8UI, - ShaderFormat::R8G8Sint => gl::RG8I, - ShaderFormat::R8G8B8A8Unorm => gl::RGBA8, - ShaderFormat::R8G8B8A8Uint => gl::RGBA8UI, - ShaderFormat::R8G8B8A8Sint => gl::RGBA8I, - ShaderFormat::R8G8B8A8Srgb => gl::SRGB8_ALPHA8, - ShaderFormat::A2B10G10R10UnormPack32 => gl::RGB10_A2, - ShaderFormat::A2B10G10R10UintPack32 => gl::RGB10_A2UI, - ShaderFormat::R16Uint => gl::R16UI, - ShaderFormat::R16Sint => gl::R16I, - ShaderFormat::R16Sfloat => gl::R16F, - ShaderFormat::R16G16Uint => gl::RG16UI, - ShaderFormat::R16G16Sint => gl::RG16I, - ShaderFormat::R16G16Sfloat => gl::RG16F, - ShaderFormat::R16G16B16A16Uint => gl::RGBA16UI, - ShaderFormat::R16G16B16A16Sint => gl::RGBA16I, - ShaderFormat::R16G16B16A16Sfloat => gl::RGBA16F, - ShaderFormat::R32Uint => gl::R32UI, - ShaderFormat::R32Sint => gl::R32I, - ShaderFormat::R32Sfloat => gl::R32F, - ShaderFormat::R32G32Uint => gl::RG32UI, - ShaderFormat::R32G32Sint => gl::RG32I, - ShaderFormat::R32G32Sfloat => gl::RG32F, - ShaderFormat::R32G32B32A32Uint => gl::RGBA32UI, - ShaderFormat::R32G32B32A32Sint => gl::RGBA32I, - ShaderFormat::R32G32B32A32Sfloat => gl::RGBA32F, + ImageFormat::Unknown => 0 as gl::types::GLenum, + ImageFormat::R8Unorm => gl::R8, + ImageFormat::R8Uint => gl::R8UI, + ImageFormat::R8Sint => gl::R8I, + ImageFormat::R8G8Unorm => gl::RG8, + ImageFormat::R8G8Uint => gl::RG8UI, + ImageFormat::R8G8Sint => gl::RG8I, + ImageFormat::R8G8B8A8Unorm => gl::RGBA8, + ImageFormat::R8G8B8A8Uint => gl::RGBA8UI, + ImageFormat::R8G8B8A8Sint => gl::RGBA8I, + ImageFormat::R8G8B8A8Srgb => gl::SRGB8_ALPHA8, + ImageFormat::A2B10G10R10UnormPack32 => gl::RGB10_A2, + ImageFormat::A2B10G10R10UintPack32 => gl::RGB10_A2UI, + ImageFormat::R16Uint => gl::R16UI, + ImageFormat::R16Sint => gl::R16I, + ImageFormat::R16Sfloat => gl::R16F, + ImageFormat::R16G16Uint => gl::RG16UI, + ImageFormat::R16G16Sint => gl::RG16I, + ImageFormat::R16G16Sfloat => gl::RG16F, + ImageFormat::R16G16B16A16Uint => gl::RGBA16UI, + ImageFormat::R16G16B16A16Sint => gl::RGBA16I, + ImageFormat::R16G16B16A16Sfloat => gl::RGBA16F, + ImageFormat::R32Uint => gl::R32UI, + ImageFormat::R32Sint => gl::R32I, + ImageFormat::R32Sfloat => gl::R32F, + ImageFormat::R32G32Uint => gl::RG32UI, + ImageFormat::R32G32Sint => gl::RG32I, + ImageFormat::R32G32Sfloat => gl::RG32F, + ImageFormat::R32G32B32A32Uint => gl::RGBA32UI, + ImageFormat::R32G32B32A32Sint => gl::RGBA32I, + ImageFormat::R32G32B32A32Sfloat => gl::RGBA32F, } } } diff --git a/librashader-common/src/lib.rs b/librashader-common/src/lib.rs index 959443f..a85614e 100644 --- a/librashader-common/src/lib.rs +++ b/librashader-common/src/lib.rs @@ -13,7 +13,7 @@ use num_traits::AsPrimitive; #[repr(u32)] #[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub enum ShaderFormat { +pub enum ImageFormat { #[default] Unknown = 0, @@ -88,7 +88,7 @@ pub enum WrapMode { MirroredRepeat, } -impl FromStr for ShaderFormat { +impl FromStr for ImageFormat { type Err = Infallible; fn from_str(s: &str) -> Result { diff --git a/librashader-preprocess/src/lib.rs b/librashader-preprocess/src/lib.rs index 61dceae..a58f725 100644 --- a/librashader-preprocess/src/lib.rs +++ b/librashader-preprocess/src/lib.rs @@ -5,7 +5,7 @@ mod stage; use crate::include::read_source; pub use error::*; -use librashader_common::ShaderFormat; +use librashader_common::ImageFormat; use std::path::Path; #[derive(Debug, Clone, PartialEq)] @@ -14,7 +14,7 @@ pub struct ShaderSource { pub fragment: String, pub name: Option, pub parameters: Vec, - pub format: ShaderFormat, + pub format: ImageFormat, } #[derive(Debug, Clone, PartialEq)] diff --git a/librashader-preprocess/src/pragma.rs b/librashader-preprocess/src/pragma.rs index e6d7da5..6a5cd0e 100644 --- a/librashader-preprocess/src/pragma.rs +++ b/librashader-preprocess/src/pragma.rs @@ -1,5 +1,5 @@ use crate::{PreprocessError, ShaderParameter}; -use librashader_common::ShaderFormat; +use librashader_common::ImageFormat; use nom::bytes::complete::{is_not, tag, take_while}; use nom::character::complete::multispace1; @@ -10,7 +10,7 @@ use std::str::FromStr; #[derive(Debug)] pub(crate) struct ShaderMeta { - pub(crate) format: ShaderFormat, + pub(crate) format: ImageFormat, pub(crate) parameters: Vec, pub(crate) name: Option, } @@ -73,7 +73,7 @@ fn parse_parameter_string(input: &str) -> Result) -> Result { let source = source.as_ref(); let mut parameters: Vec = Vec::new(); - let mut format = ShaderFormat::default(); + let mut format = ImageFormat::default(); let mut name = None; for line in source.lines() { if line.starts_with("#pragma parameter ") { @@ -88,14 +88,14 @@ pub(crate) fn parse_pragma_meta(source: impl AsRef) -> Result = ( pub struct FilterChain { pub common: FilterCommon, pub passes: Vec, + pub output_framebuffers: Box<[OwnedFramebuffer]>, } pub struct Direct3D11 { @@ -185,15 +186,16 @@ impl FilterChain { // initialize passes let filters = FilterChain::init_passes(device, passes, &semantics).unwrap(); - // let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default(); - // let default_wrap = filters - // .first() - // .map(|f| f.config.wrap_mode) - // .unwrap_or_default(); + let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default(); + let default_wrap = filters + .first() + .map(|f| f.config.wrap_mode) + .unwrap_or_default(); - // // initialize output framebuffers - // let mut output_framebuffers = Vec::new(); - // output_framebuffers.resize_with(filters.len(), || Framebuffer::new(1)); + // initialize output framebuffers + let mut output_framebuffers = Vec::new(); + output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, Size::new(1, 1), + ImageFormat::R8G8B8A8Unorm).unwrap()); // let mut output_textures = Vec::new(); // output_textures.resize_with(filters.len(), Texture::default); // @@ -220,7 +222,7 @@ impl FilterChain { // todo: make vbo: d3d11.c 1376 Ok(FilterChain { passes: filters, - // output_framebuffers: output_framebuffers.into_boxed_slice(), + output_framebuffers: output_framebuffers.into_boxed_slice(), // feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), // history_framebuffers, // filter_vao, @@ -346,13 +348,34 @@ impl FilterChain { let mut source = original.clone(); + // rescale render buffers to ensure all bindings are valid. + for (index, pass) in passes.iter_mut().enumerate() { + self.output_framebuffers[index].scale( + pass.config.scaling.clone(), + pass.get_format(), + viewport, + &original, + &source, + )?; + } + + for (index, pass) in passes.iter_mut().enumerate() { + let target = &self.output_framebuffers[index]; + let size = target.size; + pass.draw(index, &self.common, if pass.config.frame_count_mod > 0 { count % pass.config.frame_count_mod as usize } else { count - } as u32, 1, viewport, &original, &source, RenderTarget::new(output.clone(), None))?; + } as u32, 1, viewport, &original, &source, RenderTarget::new(target.as_output_framebuffer().unwrap(), None))?; + + source = Texture { + view: DxImageView { handle: target.create_shader_resource_view().unwrap(), size }, + filter, + wrap_mode, + }; } Ok(()) diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index 3b8dbf3..b11c787 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -1,6 +1,6 @@ use crate::filter_chain::FilterCommon; use crate::texture::{Texture, OwnedTexture}; -use librashader_common::Size; +use librashader_common::{ImageFormat, Size}; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::back::cross::GlslangHlslContext; @@ -41,25 +41,14 @@ pub struct FilterPass { } // slang_process.cpp 229 impl FilterPass { - fn build_mvp(buffer: &mut [u8], mvp: &[f32]) { - let mvp = bytemuck::cast_slice(mvp); - buffer.copy_from_slice(mvp); - } - - #[inline(always)] - fn build_uniform(buffer: &mut [u8], value: T) - where - T: Copy, - T: bytemuck::Pod, - { - let buffer = bytemuck::cast_slice_mut(buffer); - buffer[0] = value; - } - - fn build_vec4(buffer: &mut [u8], size: impl Into<[f32; 4]>) { - let vec4 = size.into(); - let vec4 = bytemuck::cast_slice(&vec4); - buffer.copy_from_slice(vec4); + pub fn get_format(&self) -> ImageFormat { + let mut fb_format = ImageFormat::R8G8B8A8Unorm; + if self.config.srgb_framebuffer { + fb_format = ImageFormat::R8G8B8A8Srgb; + } else if self.config.float_framebuffer { + fb_format = ImageFormat::R16G16B16A16Sfloat; + } + fb_format } fn bind_texture( @@ -204,30 +193,24 @@ impl FilterPass { // } // PassOutput - // for (index, output) in parent.output_textures.iter().enumerate() { - // if let Some(binding) = self - // .reflection - // .meta - // .texture_meta - // .get(&TextureSemantics::PassOutput.semantics(index)) - // { - // FilterPass::bind_texture(binding, output); - // } - // - // if let Some(offset) = self - // .uniform_bindings - // .get(&TextureSemantics::PassOutput.semantics(index).into()) - // { - // let (buffer, offset) = match offset { - // MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - // MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - // }; - // FilterPass::build_uniform( - // &mut buffer[offset..][..16], - // output.image.size, - // ); - // } - // } + for (index, output) in parent.output_textures.iter().enumerate() { + if let Some(binding) = self + .reflection + .meta + .texture_meta + .get(&TextureSemantics::PassOutput.semantics(index)) + { + FilterPass::bind_texture(binding, output); + } + + if let Some(offset) = self + .uniform_bindings + .get(&TextureSemantics::PassOutput.semantics(index).into()) + { + self.uniform_storage.bind_vec4(*offset, output.image.size, None); + + } + } // PassFeedback // for (index, feedback) in parent.feedback_textures.iter().enumerate() { diff --git a/librashader-runtime-d3d11/src/framebuffer.rs b/librashader-runtime-d3d11/src/framebuffer.rs index 4e5e22b..a7528f4 100644 --- a/librashader-runtime-d3d11/src/framebuffer.rs +++ b/librashader-runtime-d3d11/src/framebuffer.rs @@ -1,16 +1,192 @@ -use windows::Win32::Graphics::Direct3D11::{D3D11_VIEWPORT, ID3D11RenderTargetView, ID3D11ShaderResourceView, ID3D11Texture2D}; -use librashader_common::Size; +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_RENDER_TARGET_VIEW_DESC, D3D11_RENDER_TARGET_VIEW_DESC_0, D3D11_RTV_DIMENSION_TEXTURE2D, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_RTV, D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, D3D11_VIEWPORT, ID3D11Device, ID3D11RenderTargetView, ID3D11ShaderResourceView, ID3D11Texture2D}; +use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D; +use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC}; +use librashader_common::{ImageFormat, Size}; +use librashader_presets::{Scale2D, ScaleType, Scaling}; +use crate::texture::Texture; +use crate::util; +use crate::util::d3d11_get_closest_format; + #[derive(Debug, Clone)] pub struct OwnedFramebuffer { - pub srv: ID3D11ShaderResourceView, - pub rtv: ID3D11RenderTargetView, pub texture: ID3D11Texture2D, + pub size: Size, + pub format: DXGI_FORMAT, + device: ID3D11Device, + is_raw: bool } -#[derive(Debug, Clone)] +impl OwnedFramebuffer { + pub fn new(device: &ID3D11Device, size: Size, format: ImageFormat) -> util::Result { + unsafe { + let format = d3d11_get_closest_format(device, DXGI_FORMAT::from(format), + D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0); + eprintln!("{format:?}"); + let desc = default_desc(size, format); + let texture = device.CreateTexture2D(&desc, None)?; + Ok(OwnedFramebuffer { + texture, + size, + format, + device: device.clone(), + is_raw: false, + }) + } + } + + pub(crate) fn scale( + &mut self, + scaling: Scale2D, + format: ImageFormat, + viewport_size: &Size, + _original: &Texture, + source: &Texture, + ) -> util::Result> { + if self.is_raw { + return Ok(self.size); + } + + let width; + let height; + + match scaling.x { + Scaling { + scale_type: ScaleType::Input, + factor, + } => width = source.view.size.width * factor, + Scaling { + scale_type: ScaleType::Absolute, + factor, + } => width = factor.into(), + Scaling { + scale_type: ScaleType::Viewport, + factor, + } => width = viewport_size.width * factor, + }; + + match scaling.y { + Scaling { + scale_type: ScaleType::Input, + factor, + } => height = source.view.size.height * factor, + Scaling { + scale_type: ScaleType::Absolute, + factor, + } => height = factor.into(), + Scaling { + scale_type: ScaleType::Viewport, + factor, + } => height = viewport_size.height * factor, + }; + + let size = Size { + width: width.round() as u32, + height: height.round() as u32, + }; + + if self.size != size { + self.size = size; + + self.init( + size, + if format == ImageFormat::Unknown { + ImageFormat::R8G8B8A8Unorm + } else { + format + }, + )?; + } + Ok(size) + } + + pub fn init(&mut self, size: Size, format: ImageFormat) -> util::Result<()> { + if self.is_raw { + return Ok(()); + } + + let format = d3d11_get_closest_format(&self.device, DXGI_FORMAT::from(format), + D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0); + let desc = default_desc(size, format); + unsafe { + let mut texture = self.device.CreateTexture2D(&desc, None)?; + std::mem::swap(&mut self.texture, &mut texture); + drop(texture) + } + self.format = format; + + Ok(()) + } + + pub fn create_shader_resource_view(&self) -> util::Result { + unsafe { + Ok(self.device.CreateShaderResourceView(&self.texture, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { + Format: self.format, + ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D, + Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 { + Texture2D: D3D11_TEX2D_SRV { + MostDetailedMip: 0, + MipLevels: u32::MAX, + } + }, + }))?) + } + } + + pub fn create_render_target_view(&self) -> util::Result { + unsafe { + Ok(self.device.CreateRenderTargetView(&self.texture, Some(&D3D11_RENDER_TARGET_VIEW_DESC { + Format: self.format, + ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D, + Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 { + Texture2D: D3D11_TEX2D_RTV { + MipSlice: 0, + } + }, + }))?) + } + } + + pub fn as_output_framebuffer(&self) -> util::Result { + Ok(OutputFramebuffer { + rtv: self.create_render_target_view()?, + size: self.size, + viewport: default_viewport(self.size) + }) + } +} +#[derive(Debug, Clone)] pub struct OutputFramebuffer { pub rtv: ID3D11RenderTargetView, pub size: Size, pub viewport: D3D11_VIEWPORT +} + +fn default_desc(size: Size, format: DXGI_FORMAT) -> D3D11_TEXTURE2D_DESC { + D3D11_TEXTURE2D_DESC { + Width: size.width, + Height: size.height, + MipLevels: 1, + ArraySize: 1, + Format: format, + SampleDesc: DXGI_SAMPLE_DESC { + Count: 1, + Quality: 0, + }, + Usage: D3D11_USAGE_DEFAULT, + BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, + CPUAccessFlags: D3D11_CPU_ACCESS_WRITE, + MiscFlags: Default::default(), + } +} +pub const fn default_viewport(size: Size) -> D3D11_VIEWPORT { + D3D11_VIEWPORT { + TopLeftX: 0.0, + TopLeftY: 0.0, + Width: size.width as f32, + Height: size.height as f32, + MinDepth: 0.0, + MaxDepth: 1.0, + } } \ No newline at end of file diff --git a/librashader-runtime-d3d11/src/hello_triangle.rs b/librashader-runtime-d3d11/src/hello_triangle.rs index fed1bfd..11ee51c 100644 --- a/librashader-runtime-d3d11/src/hello_triangle.rs +++ b/librashader-runtime-d3d11/src/hello_triangle.rs @@ -694,7 +694,7 @@ pub mod d3d11_hello_triangle { let dxgi_factory_flags = if cfg!(debug_assertions) { DXGI_CREATE_FACTORY_DEBUG } else { - 0 + DXGI_CREATE_FACTORY_DEBUG }; let dxgi_factory: IDXGIFactory4 = unsafe { CreateDXGIFactory2(dxgi_factory_flags) }?; @@ -709,7 +709,7 @@ pub mod d3d11_hello_triangle { None, D3D_DRIVER_TYPE_HARDWARE, HINSTANCE::default(), - D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG, + D3D11_CREATE_DEVICE_DEBUG, Some(&feature_levels), D3D11_SDK_VERSION, Some(&mut out_device), diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index 198d96d..f3da2ab 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -34,7 +34,7 @@ mod tests { #[test] fn triangle_d3d11() { - let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); + let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap(); // let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap(); hello_triangle::main(sample).unwrap(); diff --git a/librashader-runtime-gl/src/filter_pass.rs b/librashader-runtime-gl/src/filter_pass.rs index e632923..f07046e 100644 --- a/librashader-runtime-gl/src/filter_pass.rs +++ b/librashader-runtime-gl/src/filter_pass.rs @@ -4,7 +4,7 @@ use librashader_reflect::back::cross::GlslangGlslContext; use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::reflect::ShaderReflection; -use librashader_common::{ShaderFormat, Size}; +use librashader_common::{ImageFormat, Size}; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics}; @@ -135,12 +135,12 @@ impl FilterPass { impl FilterPass { - pub fn get_format(&self) -> ShaderFormat { - let mut fb_format = ShaderFormat::R8G8B8A8Unorm; + pub fn get_format(&self) -> ImageFormat { + let mut fb_format = ImageFormat::R8G8B8A8Unorm; if self.config.srgb_framebuffer { - fb_format = ShaderFormat::R8G8B8A8Srgb; + fb_format = ImageFormat::R8G8B8A8Srgb; } else if self.config.float_framebuffer { - fb_format = ShaderFormat::R16G16B16A16Sfloat; + fb_format = ImageFormat::R16G16B16A16Sfloat; } fb_format } diff --git a/librashader-runtime-gl/src/framebuffer.rs b/librashader-runtime-gl/src/framebuffer.rs index 8cfa69d..d52286e 100644 --- a/librashader-runtime-gl/src/framebuffer.rs +++ b/librashader-runtime-gl/src/framebuffer.rs @@ -1,7 +1,7 @@ use crate::util; use crate::texture::Texture; use gl::types::{GLenum, GLint, GLsizei, GLuint}; -use librashader_common::{FilterMode, ShaderFormat, Size, WrapMode}; +use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_presets::{Scale2D, ScaleType, Scaling}; use crate::error::FilterChainError; use crate::error::Result; @@ -75,7 +75,7 @@ impl Framebuffer { pub(crate) fn scale( &mut self, scaling: Scale2D, - format: ShaderFormat, + format: ImageFormat, viewport: &Viewport, _original: &Texture, source: &Texture, @@ -127,8 +127,8 @@ impl Framebuffer { self.init( size, - if format == ShaderFormat::Unknown { - ShaderFormat::R8G8B8A8Unorm + if format == ImageFormat::Unknown { + ImageFormat::R8G8B8A8Unorm } else { format }, @@ -302,7 +302,7 @@ impl Framebuffer { gl::TexStorage2D( gl::TEXTURE_2D, self.levels as GLsizei, - ShaderFormat::R8G8B8A8Unorm.into(), + ImageFormat::R8G8B8A8Unorm.into(), size.width as GLsizei, size.height as GLsizei, ); diff --git a/librashader-runtime-gl46/src/filter_pass.rs b/librashader-runtime-gl46/src/filter_pass.rs index 7c3445d..6d67d44 100644 --- a/librashader-runtime-gl46/src/filter_pass.rs +++ b/librashader-runtime-gl46/src/filter_pass.rs @@ -3,7 +3,7 @@ use librashader_reflect::back::cross::GlslangGlslContext; use librashader_reflect::back::ShaderCompilerOutput; use librashader_reflect::reflect::ShaderReflection; -use librashader_common::{ShaderFormat, Size}; +use librashader_common::{ImageFormat, Size}; use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics}; @@ -124,12 +124,12 @@ impl FilterPass { } impl FilterPass { - pub fn get_format(&self) -> ShaderFormat { - let mut fb_format = ShaderFormat::R8G8B8A8Unorm; + pub fn get_format(&self) -> ImageFormat { + let mut fb_format = ImageFormat::R8G8B8A8Unorm; if self.config.srgb_framebuffer { - fb_format = ShaderFormat::R8G8B8A8Srgb; + fb_format = ImageFormat::R8G8B8A8Srgb; } else if self.config.float_framebuffer { - fb_format = ShaderFormat::R16G16B16A16Sfloat; + fb_format = ImageFormat::R16G16B16A16Sfloat; } fb_format } diff --git a/librashader-runtime-gl46/src/framebuffer.rs b/librashader-runtime-gl46/src/framebuffer.rs index bdfdaba..3cf1c87 100644 --- a/librashader-runtime-gl46/src/framebuffer.rs +++ b/librashader-runtime-gl46/src/framebuffer.rs @@ -1,7 +1,7 @@ use crate::util; use crate::texture::Texture; use gl::types::{GLenum, GLint, GLsizei, GLuint}; -use librashader_common::{FilterMode, ShaderFormat, Size, WrapMode}; +use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_presets::{Scale2D, ScaleType, Scaling}; use crate::error::FilterChainError; use crate::error::Result; @@ -73,7 +73,7 @@ impl Framebuffer { pub(crate) fn scale( &mut self, scaling: Scale2D, - format: ShaderFormat, + format: ImageFormat, viewport: &Viewport, _original: &Texture, source: &Texture, @@ -125,8 +125,8 @@ impl Framebuffer { self.init( size, - if format == ShaderFormat::Unknown { - ShaderFormat::R8G8B8A8Unorm + if format == ImageFormat::Unknown { + ImageFormat::R8G8B8A8Unorm } else { format }, @@ -241,7 +241,7 @@ impl Framebuffer { gl::TextureStorage2D( self.image, self.levels as GLsizei, - ShaderFormat::R8G8B8A8Unorm.into(), + ImageFormat::R8G8B8A8Unorm.into(), size.width as GLsizei, size.height as GLsizei, ); diff --git a/librashader/src/lib.rs b/librashader/src/lib.rs index 9ca9d61..5059c70 100644 --- a/librashader/src/lib.rs +++ b/librashader/src/lib.rs @@ -73,7 +73,7 @@ pub mod targets { pub use librashader_common::{ FilterMode, - ShaderFormat, + ImageFormat, Size, WrapMode };