dx11: begin to work on dx11 implementation
This commit is contained in:
parent
5d476d5229
commit
dadfb6ba33
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -426,6 +426,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"gl",
|
||||
"image",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -468,6 +469,7 @@ dependencies = [
|
|||
name = "librashader-runtime-dx11"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"gfx-maths",
|
||||
"librashader-common",
|
||||
"librashader-preprocess",
|
||||
|
|
27
README.md
27
README.md
|
@ -22,23 +22,30 @@ of DirectX and OpenGL, as well as Metal, are not supported (but pull-requests ar
|
|||
| DirectX 9 | ❌ | |
|
||||
| Metal | ❌ | |
|
||||
|
||||
## Usage
|
||||
|
||||
🚧 *`librashader_ld` is WIP* 🚧
|
||||
|
||||
librashader provides both a Rust API under the `librashader` crate, and a C API. Both APIs are first-class, fully supported.
|
||||
|
||||
The librashader C API is best used by linking statically with `librashader_ld`, which implements a loader that dynamically
|
||||
loads the librashader (`librashader.so` or `rashader.dll`) implementation in the search path.
|
||||
|
||||
## License
|
||||
The core parts of librashader such as the preprocessor, the preset parser,
|
||||
the reflection library, and the runtimes, are all licensed under the Mozilla Public License version 2.0.
|
||||
|
||||
The librashader C API, i.e. its headers and definitions, *not its implementation in `librashader_capi`*,
|
||||
are unique to librashader and are more permissively licensed, and may allow you to use librashader in your permissively
|
||||
are more permissively licensed, and may allow you to use librashader in your permissively
|
||||
licensed or proprietary project.
|
||||
|
||||
While the code for `librashader_capi` (`librashader.so` and `rashader.dll`) is still under MPL-2.0,
|
||||
you may use librashader in proprietary works by linking against the MIT licensed `librashader_ld`,
|
||||
which implements the librashader C API, and thunks its calls to any `librashader.so` or `rashader.dll`
|
||||
library found in the load path, *provided that `librashader.so` or `rashader.dll` are distributed under the restrictions
|
||||
of MPLv2*.
|
||||
To facilitate easier use of librashader in projects incompatible with MPL-2.0, `librashader_ld`
|
||||
implements a loader which thunks its calls to any `librashader.so` or `rashader.dll`
|
||||
library found in the load path. A non-MPL-2.0 compatible project may link against
|
||||
`librashader_ld` to use the librashader runtime, *provided that `librashader.so` or `rashader.dll`
|
||||
are distributed under the restrictions of MPLv2*.
|
||||
|
||||
Note that if your project is not compatible with MPLv2, you **can not distribute `librashader.so` or `rashader.dll`**
|
||||
alongside your project, **only `librashader-ld.so` or `rashader-ld.dll`**, which will do nothing without a librashader
|
||||
implementation in the load path. The end user must obtain the implementation of librashader themselves.
|
||||
Note that this means that if your project is not compatible with MPL-2.0, you **can not distribute `librashader.so` or `rashader.dll`**
|
||||
alongside your project. The end user must obtain the implementation of librashader themselves.
|
||||
|
||||
You may, at your discretion, choose to distribute `librashader` under the terms of MPL-2.0 instead of GPLv3.
|
||||
At your discretion, you may instead choose to distribute `librashader` under the terms of GPLv3 rather than MPL-2.0
|
|
@ -8,7 +8,13 @@ edition = "2021"
|
|||
[features]
|
||||
default = []
|
||||
opengl = ["gl"]
|
||||
directx = ["windows"]
|
||||
|
||||
[dependencies]
|
||||
gl = { version = "0.14.0", optional = true }
|
||||
image = "0.24.5"
|
||||
num-traits = "0.2.15"
|
||||
#
|
||||
#[dependencies.windows]
|
||||
#optional = true
|
||||
#version = "0.43.0"
|
||||
|
|
39
librashader-common/src/dx.rs
Normal file
39
librashader-common/src/dx.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
use crate::{FilterMode, ShaderFormat, WrapMode};
|
||||
//
|
||||
// impl From<ShaderFormat> for gl::types::GLenum {
|
||||
// fn from(format: ShaderFormat) -> 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,
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -2,8 +2,7 @@ use std::path::Path;
|
|||
|
||||
pub struct Image {
|
||||
pub bytes: Vec<u8>,
|
||||
pub height: u32,
|
||||
pub width: u32,
|
||||
pub size: Size<u32>
|
||||
}
|
||||
|
||||
impl Image {
|
||||
|
@ -15,10 +14,13 @@ impl Image {
|
|||
|
||||
Ok(Image {
|
||||
bytes: image.to_vec(),
|
||||
size: Size {
|
||||
height,
|
||||
width,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub use image::ImageError as ImageError;
|
||||
use crate::Size;
|
|
@ -1,9 +1,15 @@
|
|||
#[cfg(feature = "opengl")]
|
||||
pub mod gl;
|
||||
#[cfg(feature = "dxgi")]
|
||||
pub mod dx;
|
||||
|
||||
pub mod image;
|
||||
pub mod runtime;
|
||||
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::str::FromStr;
|
||||
use num_traits::AsPrimitive;
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -139,3 +145,16 @@ impl<T> Size<T> {
|
|||
Size { width, height }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Size<T>> for [f32; 4]
|
||||
where T: Copy + AsPrimitive<f32>
|
||||
{
|
||||
fn from(value: Size<T>) -> Self {
|
||||
[
|
||||
value.width.as_(),
|
||||
value.height.as_(),
|
||||
1.0 / value.width.as_(),
|
||||
1.0 / value.height.as_(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
0
librashader-common/src/runtime.rs
Normal file
0
librashader-common/src/runtime.rs
Normal file
|
@ -29,10 +29,15 @@ impl FromCompilation<GlslangCompilation> for GLSL {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct GlslangHlslContext {
|
||||
pub compiler: CompiledAst<spirv_cross::hlsl::Target>,
|
||||
}
|
||||
|
||||
|
||||
impl FromCompilation<GlslangCompilation> for HLSL {
|
||||
type Target = HLSL;
|
||||
type Options = Option<()>;
|
||||
type Context = ();
|
||||
type Context = GlslangHlslContext;
|
||||
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context> + ReflectShader;
|
||||
|
||||
fn from_compilation(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
|
||||
use crate::front::shaderc::GlslangCompilation;
|
||||
use crate::reflect::semantics::{BindingStage, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, MemberOffset, PushReflection, ReflectSemantics, ShaderReflection, TextureImage, TextureSemanticMap, TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection, ValidateTypeSemantics, VariableMeta, VariableSemanticMap, VariableSemantics};
|
||||
use crate::reflect::semantics::{BindingStage, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, MemberOffset, PushReflection, ReflectSemantics, ShaderReflection, TextureBinding, TextureSemanticMap, TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection, ValidateTypeSemantics, VariableMeta, VariableSemanticMap, VariableSemantics};
|
||||
use crate::reflect::{
|
||||
ReflectMeta, ReflectShader,
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ use spirv_cross::hlsl::ShaderModel;
|
|||
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
|
||||
use spirv_cross::{ErrorCode, glsl, hlsl};
|
||||
|
||||
use crate::back::cross::GlslangGlslContext;
|
||||
use crate::back::cross::{GlslangGlslContext, GlslangHlslContext};
|
||||
use crate::back::targets::{GLSL, HLSL};
|
||||
use crate::back::{CompileShader, ShaderCompilerOutput};
|
||||
|
||||
|
@ -492,7 +492,7 @@ where
|
|||
|
||||
meta.texture_meta.insert(
|
||||
semantic,
|
||||
TextureImage {
|
||||
TextureBinding {
|
||||
binding: texture.binding,
|
||||
},
|
||||
);
|
||||
|
@ -819,12 +819,12 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
|||
|
||||
impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
|
||||
type Options = Option<()>;
|
||||
type Context = ();
|
||||
type Context = GlslangHlslContext;
|
||||
|
||||
fn compile(
|
||||
mut self,
|
||||
_options: Self::Options,
|
||||
) -> Result<ShaderCompilerOutput<String>, ShaderCompileError> {
|
||||
) -> Result<ShaderCompilerOutput<String, GlslangHlslContext>, ShaderCompileError> {
|
||||
let mut options = hlsl::CompilerOptions::default();
|
||||
options.shader_model = ShaderModel::V5_0;
|
||||
|
||||
|
@ -834,7 +834,12 @@ impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
|
|||
Ok(ShaderCompilerOutput {
|
||||
vertex: self.vertex.compile()?,
|
||||
fragment: self.fragment.compile()?,
|
||||
context: (),
|
||||
context: GlslangHlslContext {
|
||||
compiler: CompiledAst {
|
||||
vertex: self.vertex,
|
||||
fragment: self.fragment
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::ShaderReflectError;
|
||||
use crate::reflect::semantics::{
|
||||
SemanticMap, TextureImage, TextureSemantics, TextureSizeMeta, VariableMeta, VariableSemantics,
|
||||
SemanticMap, TextureBinding, TextureSemantics, TextureSizeMeta, VariableMeta, VariableSemantics,
|
||||
};
|
||||
use rustc_hash::FxHashMap;
|
||||
use semantics::ReflectSemantics;
|
||||
|
@ -26,7 +26,7 @@ pub trait ReflectShader {
|
|||
pub struct ReflectMeta {
|
||||
pub parameter_meta: FxHashMap<String, VariableMeta>,
|
||||
pub variable_meta: FxHashMap<VariableSemantics, VariableMeta>,
|
||||
pub texture_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureImage>,
|
||||
pub texture_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureBinding>,
|
||||
pub texture_size_meta: FxHashMap<SemanticMap<TextureSemantics>, TextureSizeMeta>,
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ pub struct TextureSizeMeta {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TextureImage {
|
||||
pub struct TextureBinding {
|
||||
pub binding: u32,
|
||||
}
|
||||
|
||||
|
@ -324,3 +324,23 @@ pub struct ReflectSemantics {
|
|||
pub uniform_semantics: FxHashMap<String, UniformSemantic>,
|
||||
pub non_uniform_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||
pub enum UniformBinding {
|
||||
Parameter(String),
|
||||
SemanticVariable(VariableSemantics),
|
||||
TextureSize(SemanticMap<TextureSemantics>),
|
||||
}
|
||||
|
||||
impl From<VariableSemantics> for UniformBinding {
|
||||
fn from(value: VariableSemantics) -> Self {
|
||||
UniformBinding::SemanticVariable(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SemanticMap<TextureSemantics>> for UniformBinding {
|
||||
fn from(value: SemanticMap<TextureSemantics>) -> Self {
|
||||
UniformBinding::TextureSize(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ edition = "2021"
|
|||
"librashader-reflect" = { path = "../librashader-reflect" }
|
||||
rustc-hash = "1.1.0"
|
||||
gfx-maths = "0.2.8"
|
||||
bytemuck = "1.12.3"
|
||||
|
||||
[dependencies.windows]
|
||||
version = "0.43.0"
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
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 librashader_common::image::Image;
|
||||
use librashader_common::Size;
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use librashader_presets::{ShaderPassConfig, ShaderPreset};
|
||||
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::front::shaderc::GlslangCompilation;
|
||||
use librashader_reflect::reflect::ReflectShader;
|
||||
use librashader_reflect::reflect::semantics::{ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics};
|
||||
use crate::util::Texture;
|
||||
|
||||
type ShaderPassMeta<'a> = (
|
||||
&'a ShaderPassConfig,
|
||||
ShaderSource,
|
||||
CompilerBackend<
|
||||
impl CompileShader<HLSL, Options = Option<()>, Context = ()> + ReflectShader,
|
||||
impl CompileShader<HLSL, Options = Option<()>, Context = GlslangHlslContext> + ReflectShader,
|
||||
>,
|
||||
);
|
||||
|
||||
|
@ -22,6 +28,12 @@ struct FilterChain {
|
|||
|
||||
}
|
||||
|
||||
pub struct FilterCommon {
|
||||
pub(crate) device_context: ID3D11DeviceContext,
|
||||
pub(crate) preset: ShaderPreset,
|
||||
}
|
||||
|
||||
// todo: d3d11.c 2097
|
||||
type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
||||
|
||||
impl FilterChain {
|
||||
|
@ -100,7 +112,7 @@ impl FilterChain {
|
|||
// feedback_textures.resize_with(filters.len(), Texture::default);
|
||||
|
||||
// load luts
|
||||
// let luts = FilterChain::load_luts(&preset.textures)?;
|
||||
let luts = FilterChain::load_luts(&preset.textures)?;
|
||||
|
||||
// let (history_framebuffers, history_textures) =
|
||||
// FilterChain::init_history(&filters, default_filter, default_wrap);
|
||||
|
@ -125,6 +137,31 @@ impl FilterChain {
|
|||
})
|
||||
}
|
||||
|
||||
fn load_luts(device: &ID3D11Device, textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>> {
|
||||
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,
|
||||
Format: DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
MiscFlags: if texture.mipmap {
|
||||
D3D11_RESOURCE_MISC_GENERATE_MIPS
|
||||
} else {
|
||||
0
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut texture = Texture::new(device, image.size, 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<Path>) -> Result<FilterChain> {
|
||||
// load passes from preset
|
||||
|
|
394
librashader-runtime-dx11/src/filter_pass.rs
Normal file
394
librashader-runtime-dx11/src/filter_pass.rs
Normal file
|
@ -0,0 +1,394 @@
|
|||
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 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::ShaderReflection;
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::util::Texture;
|
||||
|
||||
pub struct DxShader<T> {
|
||||
pub blob: ID3DBlob,
|
||||
pub compiled: T
|
||||
}
|
||||
|
||||
pub struct ConstantBuffer {
|
||||
pub binding: u32,
|
||||
pub size: u32,
|
||||
pub stage_mask: BindingStage,
|
||||
pub buffer: ID3D11Buffer,
|
||||
pub storage: Box<[u8]>
|
||||
}
|
||||
|
||||
// slang_process.cpp 141
|
||||
pub struct FilterPass {
|
||||
pub reflection: ShaderReflection,
|
||||
pub compiled: ShaderCompilerOutput<String, GlslangHlslContext>,
|
||||
pub vertex_shader: DxShader<ID3D11VertexShader>,
|
||||
pub pixel_shader: DxShader<ID3D11PixelShader>,
|
||||
|
||||
pub uniform_bindings: FxHashMap<UniformBinding, MemberOffset>,
|
||||
|
||||
|
||||
pub uniform_buffer: ConstantBuffer,
|
||||
pub push_buffer: ConstantBuffer,
|
||||
pub source: ShaderSource,
|
||||
pub config: ShaderPassConfig,
|
||||
}
|
||||
// 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<T>(
|
||||
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);
|
||||
}
|
||||
|
||||
fn bind_texture(texture_binding: &mut [Option<ID3D11ShaderResourceView>; 16],
|
||||
sampler_binding: &mut [Option<ID3D11SamplerState>; 16],
|
||||
binding: &TextureBinding,
|
||||
texture: &Texture
|
||||
)
|
||||
{
|
||||
texture_binding[binding.binding as usize] = Some(texture.srv.clone());
|
||||
sampler_binding[binding.binding as usize] = Some(texture.sampler.clone());
|
||||
}
|
||||
|
||||
// framecount should be pre-modded
|
||||
fn build_semantics(
|
||||
&mut self,
|
||||
pass_index: usize,
|
||||
parent: &FilterCommon,
|
||||
mvp: &[f32],
|
||||
frame_count: u32,
|
||||
frame_direction: i32,
|
||||
fb_size: Size<u32>,
|
||||
// viewport: &Viewport,
|
||||
original: &Texture,
|
||||
source: &Texture,
|
||||
) {
|
||||
|
||||
let mut textures: [Option<ID3D11ShaderResourceView>; 16] = std::array::from_fn(|_| None);
|
||||
let mut samplers: [Option<ID3D11SamplerState>; 16] = std::array::from_fn(|_| None);
|
||||
|
||||
// Bind MVP
|
||||
if let Some(offset) =
|
||||
self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
||||
{
|
||||
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
||||
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_mvp(&mut buffer[offset..][..mvp_size], mvp)
|
||||
}
|
||||
|
||||
// bind OutputSize
|
||||
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),
|
||||
};
|
||||
|
||||
FilterPass::build_vec4(&mut buffer[offset..][..16], fb_size)
|
||||
}
|
||||
|
||||
// bind FinalViewportSize
|
||||
// if let Some(offset) = self
|
||||
// .uniform_bindings
|
||||
// .get(&VariableSemantics::FinalViewport.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_vec4(
|
||||
// &mut buffer[offset..][..16],
|
||||
// viewport.output.size,
|
||||
// )
|
||||
// }
|
||||
|
||||
// bind FrameCount
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::FrameCount.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..][..4], frame_count)
|
||||
}
|
||||
|
||||
// bind FrameDirection
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::FrameDirection.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..][..4],
|
||||
frame_direction,
|
||||
)
|
||||
}
|
||||
|
||||
// bind Original sampler
|
||||
if let Some(binding) = self
|
||||
.reflection
|
||||
.meta
|
||||
.texture_meta
|
||||
.get(&TextureSemantics::Original.semantics(0))
|
||||
{
|
||||
FilterPass::bind_texture(&mut textures, &mut samplers, binding, original);
|
||||
}
|
||||
//
|
||||
// bind OriginalSize
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::Original.semantics(0).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_vec4(
|
||||
&mut buffer[offset..][..16],
|
||||
original.size,
|
||||
);
|
||||
}
|
||||
|
||||
// bind Source sampler
|
||||
if let Some(binding) = self
|
||||
.reflection
|
||||
.meta
|
||||
.texture_meta
|
||||
.get(&TextureSemantics::Source.semantics(0))
|
||||
{
|
||||
// eprintln!("setting source binding to {}", binding.binding);
|
||||
FilterPass::bind_texture(&mut textures, &mut samplers, binding, source);
|
||||
}
|
||||
|
||||
// bind SourceSize
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::Source.semantics(0).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_vec4(
|
||||
&mut buffer[offset..][..16],
|
||||
source.size,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(binding) = self
|
||||
.reflection
|
||||
.meta
|
||||
.texture_meta
|
||||
.get(&TextureSemantics::OriginalHistory.semantics(0))
|
||||
{
|
||||
FilterPass::bind_texture(&mut textures, &mut samplers, binding, original);
|
||||
}
|
||||
|
||||
if let Some(offset) = self
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::OriginalHistory.semantics(0).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_vec4(
|
||||
&mut buffer[offset..][..16],
|
||||
original.size,
|
||||
);
|
||||
}
|
||||
|
||||
// for (index, output) in parent.history_textures.iter().enumerate() {
|
||||
// // if let Some(binding) = self
|
||||
// // .reflection
|
||||
// // .meta
|
||||
// // .texture_meta
|
||||
// // .get(&TextureSemantics::OriginalHistory.semantics(index + 1))
|
||||
// // {
|
||||
// // FilterPass::bind_texture(binding, output);
|
||||
// // }
|
||||
//
|
||||
// if let Some((location, offset)) = self.uniform_bindings.get(
|
||||
// &TextureSemantics::OriginalHistory
|
||||
// .semantics(index + 1)
|
||||
// .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_vec4(
|
||||
// location.location(),
|
||||
// &mut buffer[offset..][..16],
|
||||
// output.image.size,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// 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,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// 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,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// bind float parameters
|
||||
for (id, offset) in
|
||||
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 {
|
||||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset),
|
||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset),
|
||||
};
|
||||
|
||||
// todo: cache parameters.
|
||||
// presets override params
|
||||
let default = self
|
||||
.source
|
||||
.parameters
|
||||
.iter()
|
||||
.find(|&p| p.id == id)
|
||||
.map(|f| f.initial)
|
||||
.unwrap_or(0f32);
|
||||
|
||||
let value = parent
|
||||
.preset
|
||||
.parameters
|
||||
.iter()
|
||||
.find(|&p| p.name == id)
|
||||
.map(|p| p.value)
|
||||
.unwrap_or(default);
|
||||
|
||||
FilterPass::build_uniform(&mut buffer[offset..][..4], value)
|
||||
}
|
||||
|
||||
// bind luts
|
||||
// for (index, lut) in &parent.luts {
|
||||
// if let Some(binding) = self
|
||||
// .reflection
|
||||
// .meta
|
||||
// .texture_meta
|
||||
// .get(&TextureSemantics::User.semantics(*index))
|
||||
// {
|
||||
// FilterPass::bind_texture(binding, lut);
|
||||
// }
|
||||
//
|
||||
// if let Some((location, offset)) = self
|
||||
// .uniform_bindings
|
||||
// .get(&TextureSemantics::User.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_vec4(
|
||||
// location.location(),
|
||||
// &mut buffer[offset..][..16],
|
||||
// lut.image.size,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
pass_index: usize,
|
||||
parent: &FilterCommon,
|
||||
frame_count: u32,
|
||||
frame_direction: i32,
|
||||
) -> std::result::Result<(), Box<dyn Error>>
|
||||
{
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -392,6 +392,10 @@ mod d3d11_hello_triangle {
|
|||
|
||||
unsafe {
|
||||
self.context.DrawIndexed(3, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
unsafe {
|
||||
resources.swapchain.Present(0, 0).ok()?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -17,6 +17,8 @@ use librashader_reflect::reflect::ReflectShader;
|
|||
|
||||
#[cfg(test)]
|
||||
mod hello_triangle;
|
||||
mod filter_pass;
|
||||
mod util;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
64
librashader-runtime-dx11/src/util.rs
Normal file
64
librashader-runtime-dx11/src/util.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
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<u32>
|
||||
// pub image: GlImage,
|
||||
// pub filter: FilterMode,
|
||||
// pub mip_filter: FilterMode,
|
||||
// pub wrap_mode: WrapMode,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
pub fn new(device: &ID3D11Device, size: Size<u32>, 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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!();
|
||||
|
||||
}
|
||||
}
|
|
@ -46,22 +46,3 @@ pub enum MemberLocation {
|
|||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TextureUnit<T>(T);
|
||||
|
||||
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||
pub enum UniformBinding {
|
||||
Parameter(String),
|
||||
SemanticVariable(VariableSemantics),
|
||||
TextureSize(SemanticMap<TextureSemantics>),
|
||||
}
|
||||
|
||||
impl From<VariableSemantics> for UniformBinding {
|
||||
fn from(value: VariableSemantics) -> Self {
|
||||
UniformBinding::SemanticVariable(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SemanticMap<TextureSemantics>> for UniformBinding {
|
||||
fn from(value: SemanticMap<TextureSemantics>) -> Self {
|
||||
UniformBinding::TextureSize(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::binding::{UniformBinding, UniformLocation, VariableLocation};
|
||||
use crate::binding::{UniformLocation, VariableLocation};
|
||||
use crate::filter_pass::FilterPass;
|
||||
use crate::framebuffer::{Framebuffer, GlImage, Viewport};
|
||||
use crate::quad_render::DrawQuad;
|
||||
|
@ -14,7 +14,7 @@ use librashader_preprocess::ShaderSource;
|
|||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||
use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion};
|
||||
use librashader_reflect::back::targets::GLSL;
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformMeta, UniformSemantic, VariableSemantics};
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta, UniformSemantic, VariableSemantics};
|
||||
use librashader_reflect::reflect::ReflectShader;
|
||||
use rustc_hash::FxHashMap;
|
||||
use spirv_cross::spirv::Decoration;
|
||||
|
@ -472,9 +472,9 @@ impl FilterChain {
|
|||
.into_boxed_slice();
|
||||
|
||||
// todo: reflect indexed parameters
|
||||
let mut variable_bindings = FxHashMap::default();
|
||||
let mut uniform_bindings = FxHashMap::default();
|
||||
for param in reflection.meta.parameter_meta.values() {
|
||||
variable_bindings.insert(
|
||||
uniform_bindings.insert(
|
||||
UniformBinding::Parameter(param.id.clone()),
|
||||
(
|
||||
FilterChain::reflect_uniform_location(program, param),
|
||||
|
@ -484,7 +484,7 @@ impl FilterChain {
|
|||
}
|
||||
|
||||
for (semantics, param) in &reflection.meta.variable_meta {
|
||||
variable_bindings.insert(
|
||||
uniform_bindings.insert(
|
||||
UniformBinding::SemanticVariable(*semantics),
|
||||
(
|
||||
FilterChain::reflect_uniform_location(program, param),
|
||||
|
@ -494,7 +494,7 @@ impl FilterChain {
|
|||
}
|
||||
|
||||
for (semantics, param) in &reflection.meta.texture_size_meta {
|
||||
variable_bindings.insert(
|
||||
uniform_bindings.insert(
|
||||
UniformBinding::TextureSize(*semantics),
|
||||
(
|
||||
FilterChain::reflect_uniform_location(program, param),
|
||||
|
@ -520,7 +520,7 @@ impl FilterChain {
|
|||
ubo_ring,
|
||||
uniform_buffer,
|
||||
push_buffer,
|
||||
variable_bindings,
|
||||
uniform_bindings,
|
||||
source,
|
||||
config: config.clone(),
|
||||
});
|
||||
|
|
|
@ -6,12 +6,10 @@ use librashader_reflect::reflect::ShaderReflection;
|
|||
use librashader_common::{ShaderFormat, Size};
|
||||
use librashader_preprocess::ShaderSource;
|
||||
use librashader_presets::ShaderPassConfig;
|
||||
use librashader_reflect::reflect::semantics::{
|
||||
MemberOffset, TextureImage, TextureSemantics, VariableSemantics,
|
||||
};
|
||||
use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::binding::{UniformBinding, UniformLocation, VariableLocation};
|
||||
use crate::binding::{UniformLocation, VariableLocation};
|
||||
use crate::filter_chain::FilterCommon;
|
||||
use crate::framebuffer::Viewport;
|
||||
use crate::render_target::RenderTarget;
|
||||
|
@ -25,7 +23,7 @@ pub struct FilterPass {
|
|||
pub ubo_ring: Option<InlineRingBuffer<GLuint, 16>>,
|
||||
pub uniform_buffer: Box<[u8]>,
|
||||
pub push_buffer: Box<[u8]>,
|
||||
pub variable_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
||||
pub uniform_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
||||
pub source: ShaderSource,
|
||||
pub config: ShaderPassConfig,
|
||||
}
|
||||
|
@ -36,13 +34,8 @@ impl FilterPass {
|
|||
buffer.copy_from_slice(mvp);
|
||||
}
|
||||
|
||||
fn build_vec4(location: UniformLocation<GLint>, buffer: &mut [u8], size: Size<u32>) {
|
||||
let vec4 = [
|
||||
size.width as f32,
|
||||
size.height as f32,
|
||||
1.0 / size.width as f32,
|
||||
1.0 / size.height as f32,
|
||||
];
|
||||
fn build_vec4(location: UniformLocation<GLint>, buffer: &mut [u8], size: impl Into<[f32; 4]>) {
|
||||
let vec4 = size.into();
|
||||
if location.fragment >= 0 || location.vertex >= 0 {
|
||||
unsafe {
|
||||
if location.vertex >= 0 {
|
||||
|
@ -95,7 +88,7 @@ impl FilterPass {
|
|||
Self::build_uniform(location, buffer, value, gl::Uniform1f)
|
||||
}
|
||||
|
||||
fn bind_texture(binding: &TextureImage, texture: &Texture) {
|
||||
fn bind_texture(binding: &TextureBinding, texture: &Texture) {
|
||||
unsafe {
|
||||
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
||||
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
||||
|
@ -269,7 +262,7 @@ impl FilterPass {
|
|||
) {
|
||||
// Bind MVP
|
||||
if let Some((_location, offset)) =
|
||||
self.variable_bindings.get(&VariableSemantics::MVP.into())
|
||||
self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
||||
{
|
||||
let mvp_size = mvp.len() * std::mem::size_of::<f32>();
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -281,7 +274,7 @@ impl FilterPass {
|
|||
|
||||
// bind OutputSize
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::Output.into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -294,7 +287,7 @@ impl FilterPass {
|
|||
|
||||
// bind FinalViewportSize
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::FinalViewport.into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -310,7 +303,7 @@ impl FilterPass {
|
|||
|
||||
// bind FrameCount
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::FrameCount.into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -322,7 +315,7 @@ impl FilterPass {
|
|||
|
||||
// bind FrameDirection
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&VariableSemantics::FrameDirection.into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -348,7 +341,7 @@ impl FilterPass {
|
|||
|
||||
// bind OriginalSize
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::Original.semantics(0).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -375,7 +368,7 @@ impl FilterPass {
|
|||
|
||||
// bind SourceSize
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::Source.semantics(0).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -398,7 +391,7 @@ impl FilterPass {
|
|||
FilterPass::bind_texture(binding, original);
|
||||
}
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::OriginalHistory.semantics(0).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -422,7 +415,7 @@ impl FilterPass {
|
|||
FilterPass::bind_texture(binding, output);
|
||||
}
|
||||
|
||||
if let Some((location, offset)) = self.variable_bindings.get(
|
||||
if let Some((location, offset)) = self.uniform_bindings.get(
|
||||
&TextureSemantics::OriginalHistory
|
||||
.semantics(index + 1)
|
||||
.into(),
|
||||
|
@ -451,7 +444,7 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::PassOutput.semantics(index).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -481,7 +474,7 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::PassFeedback.semantics(index).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
@ -498,7 +491,7 @@ impl FilterPass {
|
|||
|
||||
// bind float parameters
|
||||
for (id, (location, offset)) in
|
||||
self.variable_bindings
|
||||
self.uniform_bindings
|
||||
.iter()
|
||||
.filter_map(|(binding, value)| match binding {
|
||||
UniformBinding::Parameter(id) => Some((id, value)),
|
||||
|
@ -544,7 +537,7 @@ impl FilterPass {
|
|||
}
|
||||
|
||||
if let Some((location, offset)) = self
|
||||
.variable_bindings
|
||||
.uniform_bindings
|
||||
.get(&TextureSemantics::User.semantics(*index).into())
|
||||
{
|
||||
let (buffer, offset) = match offset {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
name = "librashader"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
|
Loading…
Reference in a new issue