d3d11: implement history
This commit is contained in:
parent
a091cff6ae
commit
7acf208f39
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -418,7 +418,6 @@ dependencies = [
|
|||
"librashader-reflect",
|
||||
"librashader-runtime-d3d11",
|
||||
"librashader-runtime-gl",
|
||||
"librashader-runtime-gl46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -512,23 +511,6 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "librashader-runtime-gl46"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"gl",
|
||||
"glfw",
|
||||
"librashader-common",
|
||||
"librashader-preprocess",
|
||||
"librashader-presets",
|
||||
"librashader-reflect",
|
||||
"librashader-runtime",
|
||||
"rustc-hash",
|
||||
"spirv_cross",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
|
|
@ -8,5 +8,4 @@ members = [
|
|||
"librashader-runtime",
|
||||
"librashader-runtime-d3d11",
|
||||
"librashader-runtime-gl",
|
||||
"librashader-runtime-gl46",
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{FilterMode, ImageFormat, WrapMode};
|
||||
use windows::Win32::Graphics::Direct3D11;
|
||||
use windows::Win32::Graphics::Dxgi::Common as dxgi;
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
|
||||
|
||||
impl From<ImageFormat> for dxgi::DXGI_FORMAT {
|
||||
fn from(format: ImageFormat) -> Self {
|
||||
|
@ -40,6 +41,45 @@ impl From<ImageFormat> for dxgi::DXGI_FORMAT {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<DXGI_FORMAT> for ImageFormat {
|
||||
fn from(format: DXGI_FORMAT) -> Self {
|
||||
match format {
|
||||
dxgi::DXGI_FORMAT_UNKNOWN => ImageFormat::Unknown,
|
||||
dxgi::DXGI_FORMAT_R8_UNORM => ImageFormat::R8Unorm,
|
||||
dxgi::DXGI_FORMAT_R8_UINT => ImageFormat::R8Uint,
|
||||
dxgi::DXGI_FORMAT_R8_SINT => ImageFormat::R8Sint,
|
||||
dxgi::DXGI_FORMAT_R8G8_UNORM => ImageFormat::R8G8Unorm,
|
||||
dxgi::DXGI_FORMAT_R8G8_UINT => ImageFormat::R8G8Uint,
|
||||
dxgi::DXGI_FORMAT_R8G8_SINT => ImageFormat::R8G8Sint,
|
||||
dxgi::DXGI_FORMAT_R8G8B8A8_UNORM => ImageFormat::R8G8B8A8Unorm,
|
||||
dxgi::DXGI_FORMAT_R8G8B8A8_UINT => ImageFormat::R8G8B8A8Uint,
|
||||
dxgi::DXGI_FORMAT_R8G8B8A8_SINT => ImageFormat::R8G8B8A8Sint,
|
||||
dxgi::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB => ImageFormat::R8G8B8A8Srgb,
|
||||
dxgi::DXGI_FORMAT_R10G10B10A2_UNORM => ImageFormat::A2B10G10R10UnormPack32,
|
||||
dxgi::DXGI_FORMAT_R10G10B10A2_UINT => ImageFormat::A2B10G10R10UintPack32,
|
||||
dxgi::DXGI_FORMAT_R16_UINT => ImageFormat::R16Uint,
|
||||
dxgi::DXGI_FORMAT_R16_SINT => ImageFormat::R16Sint,
|
||||
dxgi::DXGI_FORMAT_R16_FLOAT => ImageFormat::R16Sfloat,
|
||||
dxgi::DXGI_FORMAT_R16G16_UINT => ImageFormat::R16G16Uint,
|
||||
dxgi::DXGI_FORMAT_R16G16_SINT => ImageFormat::R16G16Sint,
|
||||
dxgi::DXGI_FORMAT_R16G16_FLOAT => ImageFormat::R16G16Sfloat,
|
||||
dxgi::DXGI_FORMAT_R16G16B16A16_UINT => ImageFormat::R16G16B16A16Uint,
|
||||
dxgi::DXGI_FORMAT_R16G16B16A16_SINT => ImageFormat::R16G16B16A16Sint,
|
||||
dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT => ImageFormat::R16G16B16A16Sfloat,
|
||||
dxgi::DXGI_FORMAT_R32_UINT => ImageFormat::R32Uint,
|
||||
dxgi::DXGI_FORMAT_R32_SINT => ImageFormat::R32Sint,
|
||||
dxgi::DXGI_FORMAT_R32_FLOAT => ImageFormat::R32Sfloat,
|
||||
dxgi::DXGI_FORMAT_R32G32_UINT => ImageFormat::R32G32Uint,
|
||||
dxgi::DXGI_FORMAT_R32G32_SINT => ImageFormat::R32G32Sint,
|
||||
dxgi::DXGI_FORMAT_R32G32_FLOAT => ImageFormat::R32G32Sfloat,
|
||||
dxgi::DXGI_FORMAT_R32G32B32A32_UINT => ImageFormat::R32G32B32A32Uint,
|
||||
dxgi::DXGI_FORMAT_R32G32B32A32_SINT => ImageFormat::R32G32B32A32Sint,
|
||||
dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT => ImageFormat::R32G32B32A32Sfloat,
|
||||
_ => ImageFormat::Unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WrapMode> for Direct3D11::D3D11_TEXTURE_ADDRESS_MODE {
|
||||
fn from(value: WrapMode) -> Self {
|
||||
match value {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::VecDeque;
|
||||
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
||||
use librashader_common::image::Image;
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::cross::GlslangHlslContext;
|
||||
|
@ -16,7 +17,7 @@ use bytemuck::offset_of;
|
|||
use windows::core::PCSTR;
|
||||
use windows::s;
|
||||
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView};
|
||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
||||
|
@ -39,6 +40,9 @@ pub struct FilterChain {
|
|||
pub common: FilterCommon,
|
||||
pub passes: Vec<FilterPass>,
|
||||
pub output_framebuffers: Box<[OwnedFramebuffer]>,
|
||||
pub feedback_framebuffers: Box<[OwnedFramebuffer]>,
|
||||
pub history_framebuffers: VecDeque<OwnedFramebuffer>,
|
||||
pub(crate) draw_quad: DrawQuad,
|
||||
}
|
||||
|
||||
pub struct Direct3D11 {
|
||||
|
@ -51,8 +55,9 @@ pub struct FilterCommon {
|
|||
pub(crate) preset: ShaderPreset,
|
||||
pub(crate) luts: FxHashMap<usize, OwnedTexture>,
|
||||
pub samplers: SamplerSet,
|
||||
pub(crate) draw_quad: DrawQuad,
|
||||
pub output_textures: Box<[Option<Texture>]>
|
||||
pub output_textures: Box<[Option<Texture>]>,
|
||||
pub feedback_textures: Box<[Option<Texture>]>,
|
||||
pub history_textures: Box<[Option<Texture>]>,
|
||||
}
|
||||
|
||||
impl FilterChain {
|
||||
|
@ -187,46 +192,42 @@ 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 mut device_context = None;
|
||||
unsafe {
|
||||
device.GetImmediateContext(&mut device_context);
|
||||
}
|
||||
let device_context = device_context.unwrap();
|
||||
|
||||
// initialize output framebuffers
|
||||
let mut output_framebuffers = Vec::new();
|
||||
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, Size::new(1, 1),
|
||||
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||
let mut output_textures = Vec::new();
|
||||
output_textures.resize_with(filters.len(), || None);
|
||||
//
|
||||
// // initialize feedback framebuffers
|
||||
// let mut feedback_framebuffers = Vec::new();
|
||||
// feedback_framebuffers.resize_with(filters.len(), || Framebuffer::new(1));
|
||||
// let mut feedback_textures = Vec::new();
|
||||
// feedback_textures.resize_with(filters.len(), Texture::default);
|
||||
let mut feedback_framebuffers = Vec::new();
|
||||
feedback_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||
let mut feedback_textures = Vec::new();
|
||||
feedback_textures.resize_with(filters.len(), || None);
|
||||
|
||||
// load luts
|
||||
let luts = FilterChain::load_luts(device, &preset.textures)?;
|
||||
|
||||
// let (history_framebuffers, history_textures) =
|
||||
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||
let (history_framebuffers, history_textures) =
|
||||
FilterChain::init_history(device, &device_context, &filters);
|
||||
|
||||
let mut device_context = None;
|
||||
|
||||
unsafe {
|
||||
device.GetImmediateContext(&mut device_context);
|
||||
}
|
||||
let device_context = device_context.unwrap();
|
||||
let draw_quad = DrawQuad::new(device, &device_context)?;
|
||||
|
||||
// todo: make vbo: d3d11.c 1376
|
||||
Ok(FilterChain {
|
||||
passes: filters,
|
||||
output_framebuffers: output_framebuffers.into_boxed_slice(),
|
||||
// feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
// history_framebuffers,
|
||||
// filter_vao,
|
||||
feedback_framebuffers: feedback_framebuffers.into_boxed_slice(),
|
||||
history_framebuffers,
|
||||
draw_quad,
|
||||
common: FilterCommon {
|
||||
d3d11: Direct3D11 {
|
||||
device: device.clone(),
|
||||
|
@ -238,13 +239,90 @@ impl FilterChain {
|
|||
// semantics,
|
||||
preset,
|
||||
output_textures: output_textures.into_boxed_slice(),
|
||||
// feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
// history_textures,
|
||||
draw_quad,
|
||||
feedback_textures: feedback_textures.into_boxed_slice(),
|
||||
history_textures,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
fn init_history(
|
||||
device: &ID3D11Device,
|
||||
context: &ID3D11DeviceContext,
|
||||
filters: &[FilterPass],
|
||||
) -> (VecDeque<OwnedFramebuffer>, Box<[Option<Texture>]>) {
|
||||
let mut required_images = 0;
|
||||
|
||||
for pass in filters {
|
||||
// If a shader uses history size, but not history, we still need to keep the texture.
|
||||
let texture_count = pass
|
||||
.reflection
|
||||
.meta
|
||||
.texture_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||
.count();
|
||||
let texture_size_count = pass
|
||||
.reflection
|
||||
.meta
|
||||
.texture_size_meta
|
||||
.iter()
|
||||
.filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory)
|
||||
.count();
|
||||
|
||||
required_images = std::cmp::max(required_images, texture_count);
|
||||
required_images = std::cmp::max(required_images, texture_size_count);
|
||||
}
|
||||
|
||||
// not using frame history;
|
||||
if required_images <= 1 {
|
||||
println!("[history] not using frame history");
|
||||
return (VecDeque::new(), Box::new([]));
|
||||
}
|
||||
|
||||
// history0 is aliased with the original
|
||||
|
||||
eprintln!("[history] using frame history with {required_images} images");
|
||||
let mut framebuffers = VecDeque::with_capacity(required_images);
|
||||
framebuffers.resize_with(required_images, || OwnedFramebuffer::new(device, &context, Size::new(1, 1),
|
||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
||||
|
||||
let mut history_textures = Vec::new();
|
||||
history_textures.resize_with(required_images, || None);
|
||||
|
||||
(framebuffers, history_textures.into_boxed_slice())
|
||||
}
|
||||
|
||||
fn push_history(&mut self, input: &DxImageView) -> util::Result<()> {
|
||||
if let Some(mut back) = self.history_framebuffers.pop_back() {
|
||||
let resource = unsafe {
|
||||
let mut resource = None;
|
||||
input.handle.GetResource(&mut resource);
|
||||
|
||||
// todo: make panic-free
|
||||
resource.unwrap()
|
||||
};
|
||||
|
||||
let format = unsafe {
|
||||
let mut desc = Default::default();
|
||||
input.handle.GetDesc(&mut desc);
|
||||
desc.Format
|
||||
};
|
||||
|
||||
if back.size != input.size || (format != DXGI_FORMAT(0) && format != back.format) {
|
||||
eprintln!("[history] resizing");
|
||||
back.init(input.size, ImageFormat::from(format))?;
|
||||
}
|
||||
|
||||
back.copy_from(&resource)?;
|
||||
|
||||
self.history_framebuffers.push_front(back)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn load_luts(
|
||||
device: &ID3D11Device,
|
||||
textures: &[TextureConfig],
|
||||
|
@ -339,10 +417,10 @@ impl FilterChain {
|
|||
let filter = passes[0].config.filter;
|
||||
let wrap_mode = passes[0].config.wrap_mode;
|
||||
|
||||
self.common.draw_quad.bind_vertices();
|
||||
self.draw_quad.bind_vertices();
|
||||
|
||||
let original = Texture {
|
||||
view: input,
|
||||
view: input.clone(),
|
||||
filter,
|
||||
wrap_mode,
|
||||
};
|
||||
|
@ -358,11 +436,21 @@ impl FilterChain {
|
|||
&original,
|
||||
&source,
|
||||
)?;
|
||||
|
||||
self.feedback_framebuffers[index].scale(
|
||||
pass.config.scaling.clone(),
|
||||
pass.get_format(),
|
||||
viewport,
|
||||
&original,
|
||||
&source,
|
||||
)?;
|
||||
}
|
||||
|
||||
let passes_len = passes.len();
|
||||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
||||
|
||||
|
||||
for (index, pass) in passes.iter_mut().enumerate() {
|
||||
for (index, pass) in pass.iter_mut().enumerate() {
|
||||
let target = &self.output_framebuffers[index];
|
||||
let size = target.size;
|
||||
|
||||
|
@ -380,6 +468,33 @@ impl FilterChain {
|
|||
self.common.output_textures[index] = Some(source.clone());
|
||||
}
|
||||
|
||||
assert_eq!(last.len(), 1);
|
||||
for pass in last {
|
||||
source.filter = pass.config.filter;
|
||||
pass.draw(
|
||||
passes_len - 1,
|
||||
&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, None))?;
|
||||
|
||||
// diverge so we don't need to clone output.
|
||||
break;
|
||||
}
|
||||
|
||||
// swap feedback framebuffers with output
|
||||
for (output, feedback) in self
|
||||
.output_framebuffers
|
||||
.iter_mut()
|
||||
.zip(self.feedback_framebuffers.iter_mut())
|
||||
{
|
||||
std::mem::swap(output, feedback);
|
||||
}
|
||||
|
||||
self.push_history(&input)?;
|
||||
Ok(())
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::array;
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::texture::{Texture, OwnedTexture};
|
||||
use librashader_common::{ImageFormat, Size};
|
||||
|
@ -12,6 +13,7 @@ use std::error::Error;
|
|||
use windows::core::ConstBuffer;
|
||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
||||
use windows::Win32::Graphics::Gdi::NULL_PEN;
|
||||
use librashader_runtime::uniforms::UniformStorage;
|
||||
use crate::render_target::RenderTarget;
|
||||
use crate::samplers::SamplerSet;
|
||||
|
@ -39,6 +41,11 @@ pub struct FilterPass {
|
|||
pub source: ShaderSource,
|
||||
pub config: ShaderPassConfig,
|
||||
}
|
||||
|
||||
// https://doc.rust-lang.org/nightly/core/array/fn.from_fn.html is not ~const :(
|
||||
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] =
|
||||
&[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None];
|
||||
|
||||
// slang_process.cpp 229
|
||||
impl FilterPass {
|
||||
pub fn get_format(&self) -> ImageFormat {
|
||||
|
@ -215,33 +222,26 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
// PassFeedback
|
||||
// for (index, feedback) in parent.feedback_textures.iter().enumerate() {
|
||||
// // if let Some(binding) = self
|
||||
// // .reflection
|
||||
// // .meta
|
||||
// // .texture_meta
|
||||
// // .get(&TextureSemantics::PassFeedback.semantics(index))
|
||||
// // {
|
||||
// // if feedback.image.handle == 0 {
|
||||
// // eprintln!("[WARNING] trying to bind PassFeedback: {index} which has texture 0 to slot {} in pass {pass_index}", binding.binding)
|
||||
// // }
|
||||
// // FilterPass::bind_texture(binding, feedback);
|
||||
// // }
|
||||
//
|
||||
// if let Some(offset) = self
|
||||
// .uniform_bindings
|
||||
// .get(&TextureSemantics::PassFeedback.semantics(index).into())
|
||||
// {
|
||||
// let (buffer, offset) = match offset {
|
||||
// MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||
// MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset),
|
||||
// };
|
||||
// FilterPass::build_uniform(
|
||||
// &mut buffer[offset..][..16],
|
||||
// feedback.image.size,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
for (index, feedback) in parent.feedback_textures.iter().enumerate() {
|
||||
let Some(feedback) = feedback else {
|
||||
continue;
|
||||
};
|
||||
if let Some(binding) = self
|
||||
.reflection
|
||||
.meta
|
||||
.texture_meta
|
||||
.get(&TextureSemantics::PassFeedback.semantics(index))
|
||||
{
|
||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, feedback);
|
||||
}
|
||||
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::PassFeedback.semantics(index).into())
|
||||
{
|
||||
self.uniform_storage.bind_vec4(*offset, feedback.view.size, None);
|
||||
}
|
||||
}
|
||||
|
||||
// bind float parameters
|
||||
for (id, offset) in
|
||||
|
@ -381,7 +381,7 @@ impl FilterPass {
|
|||
|
||||
unsafe {
|
||||
// unbind resources.
|
||||
context.PSSetShaderResources(0, Some(&[None; 16]));
|
||||
context.PSSetShaderResources(0, Some(NULL_TEXTURES));
|
||||
context.OMSetRenderTargets(None, None);
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
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::Direct3D11::{D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, 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, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11Resource, 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::texture::{DxImageView, Texture};
|
||||
use crate::util;
|
||||
use crate::util::d3d11_get_closest_format;
|
||||
|
||||
|
@ -13,11 +13,12 @@ pub struct OwnedFramebuffer {
|
|||
pub size: Size<u32>,
|
||||
pub format: DXGI_FORMAT,
|
||||
device: ID3D11Device,
|
||||
context: ID3D11DeviceContext,
|
||||
is_raw: bool
|
||||
}
|
||||
|
||||
impl OwnedFramebuffer {
|
||||
pub fn new(device: &ID3D11Device, size: Size<u32>, format: ImageFormat) -> util::Result<OwnedFramebuffer> {
|
||||
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext, size: Size<u32>, format: ImageFormat) -> util::Result<OwnedFramebuffer> {
|
||||
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);
|
||||
|
@ -30,6 +31,7 @@ impl OwnedFramebuffer {
|
|||
size,
|
||||
format,
|
||||
device: device.clone(),
|
||||
context: context.clone(),
|
||||
is_raw: false,
|
||||
})
|
||||
}
|
||||
|
@ -120,6 +122,22 @@ impl OwnedFramebuffer {
|
|||
viewport: default_viewport(self.size)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn copy_from(&self, image: &ID3D11Resource) -> util::Result<()> {
|
||||
unsafe {
|
||||
|
||||
self.context.CopySubresourceRegion(&self.texture, 0, 0, 0, 0,
|
||||
image, 0, Some(&D3D11_BOX {
|
||||
left: 0,
|
||||
top: 0,
|
||||
front: 0,
|
||||
right: self.size.width,
|
||||
bottom: self.size.height,
|
||||
back: 1,
|
||||
}))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct OutputFramebuffer {
|
||||
|
|
|
@ -261,7 +261,8 @@ pub mod d3d11_hello_triangle {
|
|||
pub backbuffer: ID3D11Texture2D,
|
||||
pub rtv: ID3D11RenderTargetView,
|
||||
pub viewport: D3D11_VIEWPORT,
|
||||
pub shader_output: Option<ID3D11Texture2D>
|
||||
pub shader_output: Option<ID3D11Texture2D>,
|
||||
pub frame_count: usize,
|
||||
}
|
||||
|
||||
impl Sample {
|
||||
|
@ -342,6 +343,7 @@ pub mod d3d11_hello_triangle {
|
|||
MaxDepth: D3D11_MAX_DEPTH,
|
||||
},
|
||||
shader_output: None,
|
||||
frame_count: 0usize
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -467,7 +469,7 @@ pub mod d3d11_hello_triangle {
|
|||
}))?;
|
||||
|
||||
//
|
||||
self.filter.frame(1, &Size {
|
||||
self.filter.frame(resources.frame_count, &Size {
|
||||
width: tex2d_desc.Width,
|
||||
height: tex2d_desc.Height,
|
||||
}, DxImageView { handle: srv, size: Size {
|
||||
|
@ -480,14 +482,15 @@ pub mod d3d11_hello_triangle {
|
|||
width: tex2d_desc.Width,
|
||||
height: tex2d_desc.Height,
|
||||
},
|
||||
viewport: D3D11_VIEWPORT {
|
||||
TopLeftX: 0.0,
|
||||
TopLeftY: 0.0,
|
||||
Width: tex2d_desc.Width as f32,
|
||||
Height: tex2d_desc.Height as f32,
|
||||
MinDepth: 0.0,
|
||||
MaxDepth: 1.0,
|
||||
},
|
||||
viewport: resources.viewport
|
||||
// viewport: D3D11_VIEWPORT {
|
||||
// TopLeftX: 0.0,
|
||||
// TopLeftY: 0.0,
|
||||
// Width: tex2d_desc.Width as f32,
|
||||
// Height: tex2d_desc.Height as f32,
|
||||
// MinDepth: 0.0,
|
||||
// MaxDepth: 1.0,
|
||||
// },
|
||||
}).unwrap();
|
||||
|
||||
// self.context.CopyResource(&resources.backbuffer, &backup);
|
||||
|
@ -496,6 +499,7 @@ pub mod d3d11_hello_triangle {
|
|||
unsafe {
|
||||
resources.swapchain.Present(0, 0).ok()?;
|
||||
}
|
||||
resources.frame_count += 1;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ 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/slang-shaders/crt/crt-royale.slangp").unwrap();
|
||||
let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp").unwrap();
|
||||
|
||||
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
||||
|
||||
hello_triangle::main(sample).unwrap();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bytemuck::offset_of;
|
||||
use windows::core::PCSTR;
|
||||
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_VERTEX_BUFFER, D3D11_BUFFER_DESC, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_SUBRESOURCE_DATA, D3D11_USAGE_IMMUTABLE, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
|
||||
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
|
||||
use windows::Win32::Graphics::Direct3D::{D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED};
|
||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||
use crate::util;
|
||||
|
||||
|
@ -79,8 +79,8 @@ impl DrawQuad {
|
|||
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
|
||||
Some(&self.stride), Some(&self.offset));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn get_spirv_cross_vbo_desc() -> [D3D11_INPUT_ELEMENT_DESC; 2] {
|
||||
[
|
||||
D3D11_INPUT_ELEMENT_DESC {
|
||||
|
|
|
@ -11,7 +11,6 @@ librashader-preprocess = { path = "../librashader-preprocess" }
|
|||
librashader-reflect = { path = "../librashader-reflect" }
|
||||
librashader-runtime-d3d11 = { path = "../librashader-runtime-d3d11" }
|
||||
librashader-runtime-gl = { path = "../librashader-runtime-gl" }
|
||||
librashader-runtime-gl46 = { path = "../librashader-runtime-gl46" }
|
||||
|
||||
|
||||
[features]
|
||||
|
|
Loading…
Reference in a new issue