fmt: run cargo fmt and clippy
This commit is contained in:
parent
f5c56895fb
commit
5088e1c55b
|
@ -75,7 +75,7 @@ impl From<DXGI_FORMAT> for ImageFormat {
|
||||||
dxgi::DXGI_FORMAT_R32G32B32A32_UINT => ImageFormat::R32G32B32A32Uint,
|
dxgi::DXGI_FORMAT_R32G32B32A32_UINT => ImageFormat::R32G32B32A32Uint,
|
||||||
dxgi::DXGI_FORMAT_R32G32B32A32_SINT => ImageFormat::R32G32B32A32Sint,
|
dxgi::DXGI_FORMAT_R32G32B32A32_SINT => ImageFormat::R32G32B32A32Sint,
|
||||||
dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT => ImageFormat::R32G32B32A32Sfloat,
|
dxgi::DXGI_FORMAT_R32G32B32A32_FLOAT => ImageFormat::R32G32B32A32Sfloat,
|
||||||
_ => ImageFormat::Unknown
|
_ => ImageFormat::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl From<FilterMode> for Direct3D11::D3D11_FILTER {
|
||||||
fn from(value: FilterMode) -> Self {
|
fn from(value: FilterMode) -> Self {
|
||||||
match value {
|
match value {
|
||||||
FilterMode::Linear => Direct3D11::D3D11_FILTER_MIN_MAG_MIP_LINEAR,
|
FilterMode::Linear => Direct3D11::D3D11_FILTER_MIN_MAG_MIP_LINEAR,
|
||||||
_ => Direct3D11::D3D11_FILTER_MIN_MAG_MIP_POINT
|
_ => Direct3D11::D3D11_FILTER_MIN_MAG_MIP_POINT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,20 +12,18 @@ impl Image {
|
||||||
|
|
||||||
let height = image.height();
|
let height = image.height();
|
||||||
let width = image.width();
|
let width = image.width();
|
||||||
let pitch = image.sample_layout().height_stride.max(
|
let pitch = image
|
||||||
image.sample_layout().width_stride
|
.sample_layout()
|
||||||
);
|
.height_stride
|
||||||
|
.max(image.sample_layout().width_stride);
|
||||||
|
|
||||||
Ok(Image {
|
Ok(Image {
|
||||||
bytes: image.into_raw(),
|
bytes: image.into_raw(),
|
||||||
pitch,
|
pitch,
|
||||||
size: Size {
|
size: Size { height, width },
|
||||||
height,
|
|
||||||
width,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use image::ImageError as ImageError;
|
|
||||||
use crate::Size;
|
use crate::Size;
|
||||||
|
pub use image::ImageError;
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
#[cfg(feature = "opengl")]
|
|
||||||
pub mod gl;
|
|
||||||
#[cfg(feature = "d3d11")]
|
#[cfg(feature = "d3d11")]
|
||||||
pub mod d3d11;
|
pub mod d3d11;
|
||||||
|
#[cfg(feature = "opengl")]
|
||||||
|
pub mod gl;
|
||||||
|
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod runtime;
|
pub mod runtime;
|
||||||
|
|
||||||
|
use num_traits::AsPrimitive;
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use num_traits::AsPrimitive;
|
|
||||||
|
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
|
@ -146,7 +145,8 @@ impl<T> Size<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<Size<T>> for [f32; 4]
|
impl<T> From<Size<T>> for [f32; 4]
|
||||||
where T: Copy + AsPrimitive<f32>
|
where
|
||||||
|
T: Copy + AsPrimitive<f32>,
|
||||||
{
|
{
|
||||||
fn from(value: Size<T>) -> Self {
|
fn from(value: Size<T>) -> Self {
|
||||||
[
|
[
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::back::targets::{GLSL, HLSL};
|
use crate::back::targets::{GLSL, HLSL};
|
||||||
use crate::back::{CompilerBackend, CompileShader, FromCompilation};
|
use crate::back::{CompileShader, CompilerBackend, FromCompilation};
|
||||||
use crate::error::ShaderReflectError;
|
use crate::error::ShaderReflectError;
|
||||||
use crate::front::shaderc::GlslangCompilation;
|
use crate::front::shaderc::GlslangCompilation;
|
||||||
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect};
|
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect};
|
||||||
|
@ -15,14 +15,12 @@ impl FromCompilation<GlslangCompilation> for GLSL {
|
||||||
type Target = GLSL;
|
type Target = GLSL;
|
||||||
type Options = GlVersion;
|
type Options = GlVersion;
|
||||||
type Context = GlslangGlslContext;
|
type Context = GlslangGlslContext;
|
||||||
type Output = impl CompileShader<Self::Target, Options = GlVersion, Context = GlslangGlslContext> + ReflectShader;
|
type Output = impl CompileShader<Self::Target, Options = GlVersion, Context = GlslangGlslContext>
|
||||||
|
+ ReflectShader;
|
||||||
|
|
||||||
fn from_compilation(
|
fn from_compilation(
|
||||||
compile: GlslangCompilation,
|
compile: GlslangCompilation,
|
||||||
) -> Result<
|
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
|
||||||
CompilerBackend<Self::Output>,
|
|
||||||
ShaderReflectError,
|
|
||||||
> {
|
|
||||||
Ok(CompilerBackend {
|
Ok(CompilerBackend {
|
||||||
backend: GlslReflect::try_from(compile)?,
|
backend: GlslReflect::try_from(compile)?,
|
||||||
})
|
})
|
||||||
|
@ -33,19 +31,16 @@ pub struct GlslangHlslContext {
|
||||||
pub compiler: CompiledProgram<spirv_cross::hlsl::Target>,
|
pub compiler: CompiledProgram<spirv_cross::hlsl::Target>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl FromCompilation<GlslangCompilation> for HLSL {
|
impl FromCompilation<GlslangCompilation> for HLSL {
|
||||||
type Target = HLSL;
|
type Target = HLSL;
|
||||||
type Options = Option<()>;
|
type Options = Option<()>;
|
||||||
type Context = GlslangHlslContext;
|
type Context = GlslangHlslContext;
|
||||||
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context> + ReflectShader;
|
type Output = impl CompileShader<Self::Target, Options = Self::Options, Context = Self::Context>
|
||||||
|
+ ReflectShader;
|
||||||
|
|
||||||
fn from_compilation(
|
fn from_compilation(
|
||||||
compile: GlslangCompilation,
|
compile: GlslangCompilation,
|
||||||
) -> Result<
|
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
|
||||||
CompilerBackend<Self::Output>,
|
|
||||||
ShaderReflectError,
|
|
||||||
> {
|
|
||||||
Ok(CompilerBackend {
|
Ok(CompilerBackend {
|
||||||
backend: HlslReflect::try_from(compile)?,
|
backend: HlslReflect::try_from(compile)?,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
pub mod cross;
|
pub mod cross;
|
||||||
pub mod targets;
|
pub mod targets;
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
use crate::back::targets::OutputTarget;
|
use crate::back::targets::OutputTarget;
|
||||||
use crate::error::{ShaderCompileError, ShaderReflectError};
|
use crate::error::{ShaderCompileError, ShaderReflectError};
|
||||||
use crate::reflect::{ReflectShader, ShaderReflection};
|
|
||||||
use crate::reflect::semantics::ReflectSemantics;
|
use crate::reflect::semantics::ReflectSemantics;
|
||||||
|
use crate::reflect::{ReflectShader, ShaderReflection};
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ShaderCompilerOutput<T, Context = ()> {
|
pub struct ShaderCompilerOutput<T, Context = ()> {
|
||||||
|
@ -45,14 +45,10 @@ pub trait FromCompilation<T> {
|
||||||
type Options;
|
type Options;
|
||||||
type Context;
|
type Context;
|
||||||
|
|
||||||
type Output: CompileShader<Self::Target, Context = Self::Context, Options=Self::Options> + ReflectShader;
|
type Output: CompileShader<Self::Target, Context = Self::Context, Options = Self::Options>
|
||||||
|
+ ReflectShader;
|
||||||
|
|
||||||
fn from_compilation(
|
fn from_compilation(compile: T) -> Result<CompilerBackend<Self::Output>, ShaderReflectError>;
|
||||||
compile: T,
|
|
||||||
) -> Result<
|
|
||||||
CompilerBackend<Self::Output>,
|
|
||||||
ShaderReflectError,
|
|
||||||
>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CompilerBackend<T> {
|
pub struct CompilerBackend<T> {
|
||||||
|
|
|
@ -18,8 +18,8 @@ impl OutputTarget for SPIRV {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
use crate::back::FromCompilation;
|
|
||||||
use crate::back::targets::GLSL;
|
use crate::back::targets::GLSL;
|
||||||
|
use crate::back::FromCompilation;
|
||||||
use crate::front::shaderc::GlslangCompilation;
|
use crate::front::shaderc::GlslangCompilation;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn test_compile(value: GlslangCompilation) {
|
pub fn test_compile(value: GlslangCompilation) {
|
||||||
|
|
|
@ -19,6 +19,8 @@ pub fn compile_spirv(source: &ShaderSource) -> Result<NagaCompilation, ShaderCom
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::front::naga::compile_spirv;
|
use crate::front::naga::compile_spirv;
|
||||||
|
use crate::front::shaderc::GlslangCompilation;
|
||||||
|
use librashader_preprocess::ShaderSource;
|
||||||
use naga::back::glsl::{PipelineOptions, Version};
|
use naga::back::glsl::{PipelineOptions, Version};
|
||||||
use naga::back::spv::{Capability, WriterFlags};
|
use naga::back::spv::{Capability, WriterFlags};
|
||||||
use naga::front::glsl::{Options, Parser};
|
use naga::front::glsl::{Options, Parser};
|
||||||
|
@ -26,8 +28,6 @@ mod test {
|
||||||
use naga::valid::{Capabilities, ValidationFlags};
|
use naga::valid::{Capabilities, ValidationFlags};
|
||||||
use naga::{FastHashSet, ShaderStage};
|
use naga::{FastHashSet, ShaderStage};
|
||||||
use rspirv::binary::Disassemble;
|
use rspirv::binary::Disassemble;
|
||||||
use librashader_preprocess::ShaderSource;
|
|
||||||
use crate::front::shaderc::GlslangCompilation;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn compile_naga_test() {
|
pub fn compile_naga_test() {
|
||||||
|
|
|
@ -8,7 +8,6 @@ pub struct GlslangCompilation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlslangCompilation {
|
impl GlslangCompilation {
|
||||||
|
|
||||||
/// Tries to compile SPIR-V from the provided shader source.
|
/// Tries to compile SPIR-V from the provided shader source.
|
||||||
pub fn compile(source: &ShaderSource) -> Result<Self, ShaderCompileError> {
|
pub fn compile(source: &ShaderSource) -> Result<Self, ShaderCompileError> {
|
||||||
compile_spirv(source)
|
compile_spirv(source)
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
use std::ops::Deref;
|
|
||||||
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
|
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
|
||||||
use crate::front::shaderc::GlslangCompilation;
|
use crate::front::shaderc::GlslangCompilation;
|
||||||
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::semantics::{
|
||||||
|
BindingStage, MemberOffset, PushReflection, ReflectSemantics, ShaderReflection, TextureBinding,
|
||||||
|
TextureSemanticMap, TextureSemantics, TextureSizeMeta, TypeInfo, UboReflection,
|
||||||
|
ValidateTypeSemantics, VariableMeta, VariableSemanticMap, VariableSemantics,
|
||||||
|
MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE,
|
||||||
|
};
|
||||||
use crate::reflect::{align_uniform_size, ReflectMeta, ReflectShader};
|
use crate::reflect::{align_uniform_size, ReflectMeta, ReflectShader};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use spirv_cross::hlsl::ShaderModel;
|
use spirv_cross::hlsl::ShaderModel;
|
||||||
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
|
use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type};
|
||||||
use spirv_cross::{ErrorCode, glsl, hlsl};
|
use spirv_cross::{glsl, hlsl, ErrorCode};
|
||||||
|
|
||||||
use crate::back::cross::{GlslangGlslContext, GlslangHlslContext};
|
use crate::back::cross::{GlslangGlslContext, GlslangHlslContext};
|
||||||
use crate::back::targets::{GLSL, HLSL};
|
use crate::back::targets::{GLSL, HLSL};
|
||||||
use crate::back::{CompileShader, ShaderCompilerOutput};
|
use crate::back::{CompileShader, ShaderCompilerOutput};
|
||||||
|
|
||||||
|
|
||||||
pub struct CrossReflect<T>
|
pub struct CrossReflect<T>
|
||||||
where
|
where
|
||||||
T: spirv_cross::spirv::Target,
|
T: spirv_cross::spirv::Target,
|
||||||
|
@ -847,8 +851,8 @@ impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
|
||||||
context: GlslangHlslContext {
|
context: GlslangHlslContext {
|
||||||
compiler: CompiledProgram {
|
compiler: CompiledProgram {
|
||||||
vertex: CompiledAst(self.vertex),
|
vertex: CompiledAst(self.vertex),
|
||||||
fragment: CompiledAst(self.fragment)
|
fragment: CompiledAst(self.fragment),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -861,11 +865,13 @@ mod test {
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::back::CompileShader;
|
use crate::back::CompileShader;
|
||||||
use crate::reflect::semantics::{ReflectSemantics, SemanticMap, UniformSemantic, VariableSemantics};
|
use crate::front::shaderc::GlslangCompilation;
|
||||||
|
use crate::reflect::semantics::{
|
||||||
|
ReflectSemantics, SemanticMap, UniformSemantic, VariableSemantics,
|
||||||
|
};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use spirv_cross::glsl;
|
use spirv_cross::glsl;
|
||||||
use spirv_cross::glsl::{CompilerOptions, Version};
|
use spirv_cross::glsl::{CompilerOptions, Version};
|
||||||
use crate::front::shaderc::GlslangCompilation;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_into() {
|
pub fn test_into() {
|
||||||
|
|
|
@ -328,7 +328,6 @@ pub struct ReflectSemantics {
|
||||||
pub texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
|
pub texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||||
pub enum UniformBinding {
|
pub enum UniformBinding {
|
||||||
Parameter(String),
|
Parameter(String),
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
use std::collections::VecDeque;
|
|
||||||
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
use crate::texture::{DxImageView, OwnedTexture, Texture};
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::cross::GlslangHlslContext;
|
use librashader_reflect::back::cross::GlslangHlslContext;
|
||||||
use librashader_reflect::back::targets::HLSL;
|
use librashader_reflect::back::targets::HLSL;
|
||||||
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
|
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
use librashader_reflect::reflect::semantics::{ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformSemantic, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{
|
||||||
|
ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformSemantic,
|
||||||
|
VariableSemantics,
|
||||||
|
};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
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, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC};
|
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
|
||||||
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
use crate::filter_pass::{ConstantBufferBinding, FilterPass};
|
||||||
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
use crate::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
|
||||||
use crate::quad_render::DrawQuad;
|
use crate::quad_render::DrawQuad;
|
||||||
|
@ -26,6 +24,13 @@ use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::d3d11_compile_bound_shader;
|
use crate::util::d3d11_compile_bound_shader;
|
||||||
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC,
|
||||||
|
D3D11_CPU_ACCESS_WRITE, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
||||||
|
D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC,
|
||||||
|
};
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM};
|
||||||
|
|
||||||
// todo: get rid of preset
|
// todo: get rid of preset
|
||||||
type ShaderPassMeta<'a> = (
|
type ShaderPassMeta<'a> = (
|
||||||
|
@ -64,14 +69,17 @@ impl FilterChain {
|
||||||
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
|
||||||
eprintln!("{size}");
|
eprintln!("{size}");
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
let buffer = device.CreateBuffer(
|
||||||
|
&D3D11_BUFFER_DESC {
|
||||||
ByteWidth: size,
|
ByteWidth: size,
|
||||||
Usage: D3D11_USAGE_DYNAMIC,
|
Usage: D3D11_USAGE_DYNAMIC,
|
||||||
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
|
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
|
||||||
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
||||||
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
|
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
|
||||||
StructureByteStride: 0,
|
StructureByteStride: 0,
|
||||||
}, None)?;
|
},
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
@ -81,8 +89,7 @@ impl FilterChain {
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
passes: Vec<ShaderPassMeta>,
|
passes: Vec<ShaderPassMeta>,
|
||||||
semantics: &ReflectSemantics,
|
semantics: &ReflectSemantics,
|
||||||
) -> util::Result<Vec<FilterPass>>
|
) -> util::Result<Vec<FilterPass>> {
|
||||||
{
|
|
||||||
// let mut filters = Vec::new();
|
// let mut filters = Vec::new();
|
||||||
let mut filters = Vec::new();
|
let mut filters = Vec::new();
|
||||||
|
|
||||||
|
@ -90,25 +97,26 @@ impl FilterChain {
|
||||||
let reflection = reflect.reflect(index, semantics)?;
|
let reflection = reflect.reflect(index, semantics)?;
|
||||||
let hlsl = reflect.compile(None)?;
|
let hlsl = reflect.compile(None)?;
|
||||||
|
|
||||||
let vertex_dxil = util::d3d_compile_shader(
|
let vertex_dxil =
|
||||||
hlsl.vertex.as_bytes(),
|
util::d3d_compile_shader(hlsl.vertex.as_bytes(), b"main\0", b"vs_5_0\0")?;
|
||||||
b"main\0",
|
let vs = d3d11_compile_bound_shader(
|
||||||
b"vs_5_0\0"
|
device,
|
||||||
|
&vertex_dxil,
|
||||||
|
None,
|
||||||
|
ID3D11Device::CreateVertexShader,
|
||||||
)?;
|
)?;
|
||||||
let vs = d3d11_compile_bound_shader(device, &vertex_dxil, None,
|
|
||||||
ID3D11Device::CreateVertexShader)?;
|
|
||||||
|
|
||||||
let ia_desc = DrawQuad::get_spirv_cross_vbo_desc();
|
let ia_desc = DrawQuad::get_spirv_cross_vbo_desc();
|
||||||
let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxil)?;
|
let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxil)?;
|
||||||
|
|
||||||
let fragment_dxil = util::d3d_compile_shader(
|
let fragment_dxil =
|
||||||
hlsl.fragment.as_bytes(),
|
util::d3d_compile_shader(hlsl.fragment.as_bytes(), b"main\0", b"ps_5_0\0")?;
|
||||||
b"main\0",
|
let ps = d3d11_compile_bound_shader(
|
||||||
b"ps_5_0\0"
|
device,
|
||||||
|
&fragment_dxil,
|
||||||
|
None,
|
||||||
|
ID3D11Device::CreatePixelShader,
|
||||||
)?;
|
)?;
|
||||||
let ps = d3d11_compile_bound_shader(device, &fragment_dxil, None,
|
|
||||||
ID3D11Device::CreatePixelShader)?;
|
|
||||||
|
|
||||||
|
|
||||||
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 {
|
||||||
let buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
|
let buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
|
||||||
|
@ -134,7 +142,8 @@ impl FilterChain {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let uniform_storage = UniformStorage::new(reflection
|
let uniform_storage = UniformStorage::new(
|
||||||
|
reflection
|
||||||
.ubo
|
.ubo
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ubo| ubo.size as usize)
|
.map(|ubo| ubo.size as usize)
|
||||||
|
@ -143,28 +152,20 @@ impl FilterChain {
|
||||||
.push_constant
|
.push_constant
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|push| push.size as usize)
|
.map(|push| push.size as usize)
|
||||||
.unwrap_or(0));
|
.unwrap_or(0),
|
||||||
|
);
|
||||||
|
|
||||||
let mut uniform_bindings = FxHashMap::default();
|
let mut uniform_bindings = FxHashMap::default();
|
||||||
for param in reflection.meta.parameter_meta.values() {
|
for param in reflection.meta.parameter_meta.values() {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset);
|
||||||
UniformBinding::Parameter(param.id.clone()),
|
|
||||||
param.offset,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (semantics, param) in &reflection.meta.variable_meta {
|
for (semantics, param) in &reflection.meta.variable_meta {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset);
|
||||||
UniformBinding::SemanticVariable(*semantics),
|
|
||||||
param.offset
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (semantics, param) in &reflection.meta.texture_size_meta {
|
for (semantics, param) in &reflection.meta.texture_size_meta {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset);
|
||||||
UniformBinding::TextureSize(*semantics),
|
|
||||||
param.offset
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filters.push(FilterPass {
|
filters.push(FilterPass {
|
||||||
|
@ -184,7 +185,10 @@ impl FilterChain {
|
||||||
Ok(filters)
|
Ok(filters)
|
||||||
}
|
}
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result<FilterChain> {
|
pub fn load_from_preset(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
preset: ShaderPreset,
|
||||||
|
) -> util::Result<FilterChain> {
|
||||||
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
let (passes, semantics) = FilterChain::load_preset(&preset)?;
|
||||||
|
|
||||||
let samplers = SamplerSet::new(device)?;
|
let samplers = SamplerSet::new(device)?;
|
||||||
|
@ -200,15 +204,29 @@ impl FilterChain {
|
||||||
|
|
||||||
// initialize output framebuffers
|
// initialize output framebuffers
|
||||||
let mut output_framebuffers = Vec::new();
|
let mut output_framebuffers = Vec::new();
|
||||||
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
output_framebuffers.resize_with(filters.len(), || {
|
||||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
OwnedFramebuffer::new(
|
||||||
|
device,
|
||||||
|
&device_context,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
let mut output_textures = Vec::new();
|
let mut output_textures = Vec::new();
|
||||||
output_textures.resize_with(filters.len(), || None);
|
output_textures.resize_with(filters.len(), || None);
|
||||||
//
|
//
|
||||||
// // initialize feedback framebuffers
|
// // initialize feedback framebuffers
|
||||||
let mut feedback_framebuffers = Vec::new();
|
let mut feedback_framebuffers = Vec::new();
|
||||||
feedback_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
|
feedback_framebuffers.resize_with(filters.len(), || {
|
||||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
OwnedFramebuffer::new(
|
||||||
|
device,
|
||||||
|
&device_context,
|
||||||
|
Size::new(1, 1),
|
||||||
|
ImageFormat::R8G8B8A8Unorm,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
let mut feedback_textures = Vec::new();
|
let mut feedback_textures = Vec::new();
|
||||||
feedback_textures.resize_with(filters.len(), || None);
|
feedback_textures.resize_with(filters.len(), || None);
|
||||||
|
|
||||||
|
@ -218,7 +236,6 @@ impl FilterChain {
|
||||||
let (history_framebuffers, history_textures) =
|
let (history_framebuffers, history_textures) =
|
||||||
FilterChain::init_history(device, &device_context, &filters);
|
FilterChain::init_history(device, &device_context, &filters);
|
||||||
|
|
||||||
|
|
||||||
let draw_quad = DrawQuad::new(device, &device_context)?;
|
let draw_quad = DrawQuad::new(device, &device_context)?;
|
||||||
|
|
||||||
// todo: make vbo: d3d11.c 1376
|
// todo: make vbo: d3d11.c 1376
|
||||||
|
@ -231,7 +248,7 @@ impl FilterChain {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
d3d11: Direct3D11 {
|
d3d11: Direct3D11 {
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
device_context
|
device_context,
|
||||||
},
|
},
|
||||||
luts,
|
luts,
|
||||||
samplers,
|
samplers,
|
||||||
|
@ -245,7 +262,6 @@ impl FilterChain {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn init_history(
|
fn init_history(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
context: &ID3D11DeviceContext,
|
context: &ID3D11DeviceContext,
|
||||||
|
@ -284,8 +300,10 @@ impl FilterChain {
|
||||||
|
|
||||||
eprintln!("[history] using frame history with {required_images} images");
|
eprintln!("[history] using frame history with {required_images} images");
|
||||||
let mut framebuffers = VecDeque::with_capacity(required_images);
|
let mut framebuffers = VecDeque::with_capacity(required_images);
|
||||||
framebuffers.resize_with(required_images, || OwnedFramebuffer::new(device, &context, Size::new(1, 1),
|
framebuffers.resize_with(required_images, || {
|
||||||
ImageFormat::R8G8B8A8Unorm).unwrap());
|
OwnedFramebuffer::new(device, context, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
let mut history_textures = Vec::new();
|
let mut history_textures = Vec::new();
|
||||||
history_textures.resize_with(required_images, || None);
|
history_textures.resize_with(required_images, || None);
|
||||||
|
@ -322,7 +340,6 @@ impl FilterChain {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn load_luts(
|
fn load_luts(
|
||||||
device: &ID3D11Device,
|
device: &ID3D11Device,
|
||||||
textures: &[TextureConfig],
|
textures: &[TextureConfig],
|
||||||
|
@ -344,15 +361,18 @@ impl FilterChain {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut texture = OwnedTexture::new(device, &image, desc,
|
let texture =
|
||||||
texture.filter_mode, texture.wrap_mode)?;
|
OwnedTexture::new(device, &image, desc, texture.filter_mode, texture.wrap_mode)?;
|
||||||
luts.insert(index, texture);
|
luts.insert(index, texture);
|
||||||
}
|
}
|
||||||
Ok(luts)
|
Ok(luts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(device: &ID3D11Device, path: impl AsRef<Path>) -> util::Result<FilterChain> {
|
pub fn load_from_path(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
) -> util::Result<FilterChain> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(device, preset)
|
Self::load_from_preset(device, preset)
|
||||||
|
@ -385,7 +405,8 @@ impl FilterChain {
|
||||||
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
Ok::<_, Box<dyn Error>>((shader, source, reflect))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<util::Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
|
.collect::<util::Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
|
||||||
|
)?;
|
||||||
|
|
||||||
for details in &passes {
|
for details in &passes {
|
||||||
librashader_runtime::semantics::insert_pass_semantics(
|
librashader_runtime::semantics::insert_pass_semantics(
|
||||||
|
@ -394,9 +415,11 @@ impl FilterChain {
|
||||||
details.0,
|
details.0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
librashader_runtime::semantics::insert_lut_semantics(&preset.textures,
|
librashader_runtime::semantics::insert_lut_semantics(
|
||||||
|
&preset.textures,
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics);
|
&mut texture_semantics,
|
||||||
|
);
|
||||||
|
|
||||||
let semantics = ReflectSemantics {
|
let semantics = ReflectSemantics {
|
||||||
uniform_semantics,
|
uniform_semantics,
|
||||||
|
@ -406,8 +429,13 @@ impl FilterChain {
|
||||||
Ok((passes, semantics))
|
Ok((passes, semantics))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame(&mut self, count: usize, viewport: &Size<u32>, input: DxImageView, output: OutputFramebuffer) -> util::Result<()> {
|
pub fn frame(
|
||||||
|
&mut self,
|
||||||
|
count: usize,
|
||||||
|
viewport: &Size<u32>,
|
||||||
|
input: DxImageView,
|
||||||
|
output: OutputFramebuffer,
|
||||||
|
) -> util::Result<()> {
|
||||||
let passes = &mut self.passes;
|
let passes = &mut self.passes;
|
||||||
|
|
||||||
if passes.is_empty() {
|
if passes.is_empty() {
|
||||||
|
@ -449,19 +477,30 @@ impl FilterChain {
|
||||||
let passes_len = passes.len();
|
let passes_len = passes.len();
|
||||||
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
let (pass, last) = passes.split_at_mut(passes_len - 1);
|
||||||
|
|
||||||
|
|
||||||
for (index, pass) in pass.iter_mut().enumerate() {
|
for (index, pass) in pass.iter_mut().enumerate() {
|
||||||
let target = &self.output_framebuffers[index];
|
let target = &self.output_framebuffers[index];
|
||||||
let size = target.size;
|
let size = target.size;
|
||||||
|
|
||||||
pass.draw(index, &self.common, if pass.config.frame_count_mod > 0 {
|
pass.draw(
|
||||||
|
index,
|
||||||
|
&self.common,
|
||||||
|
if pass.config.frame_count_mod > 0 {
|
||||||
count % pass.config.frame_count_mod as usize
|
count % pass.config.frame_count_mod as usize
|
||||||
} else {
|
} else {
|
||||||
count
|
count
|
||||||
} as u32, 1, viewport, &original, &source, RenderTarget::new(target.as_output_framebuffer().unwrap(), None))?;
|
} as u32,
|
||||||
|
1,
|
||||||
|
viewport,
|
||||||
|
&original,
|
||||||
|
&source,
|
||||||
|
RenderTarget::new(target.as_output_framebuffer().unwrap(), None),
|
||||||
|
)?;
|
||||||
|
|
||||||
source = Texture {
|
source = Texture {
|
||||||
view: DxImageView { handle: target.create_shader_resource_view().unwrap(), size },
|
view: DxImageView {
|
||||||
|
handle: target.create_shader_resource_view().unwrap(),
|
||||||
|
size,
|
||||||
|
},
|
||||||
filter,
|
filter,
|
||||||
wrap_mode,
|
wrap_mode,
|
||||||
};
|
};
|
||||||
|
@ -479,7 +518,12 @@ impl FilterChain {
|
||||||
} else {
|
} else {
|
||||||
count
|
count
|
||||||
} as u32,
|
} as u32,
|
||||||
1, viewport, &original, &source, RenderTarget::new(output, None))?;
|
1,
|
||||||
|
viewport,
|
||||||
|
&original,
|
||||||
|
&source,
|
||||||
|
RenderTarget::new(output, None),
|
||||||
|
)?;
|
||||||
|
|
||||||
// diverge so we don't need to clone output.
|
// diverge so we don't need to clone output.
|
||||||
break;
|
break;
|
||||||
|
@ -496,6 +540,5 @@ impl FilterChain {
|
||||||
|
|
||||||
self.push_history(&input)?;
|
self.push_history(&input)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
use std::array;
|
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::texture::{Texture, OwnedTexture};
|
use crate::texture::Texture;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::ShaderPassConfig;
|
use librashader_presets::ShaderPassConfig;
|
||||||
use librashader_reflect::back::cross::GlslangHlslContext;
|
use librashader_reflect::back::cross::GlslangHlslContext;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
use librashader_reflect::reflect::semantics::{BindingStage, MAX_BINDINGS_COUNT, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, UniformSemantic, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{
|
||||||
|
BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics,
|
||||||
|
};
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use windows::core::ConstBuffer;
|
|
||||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
|
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
|
||||||
use windows::Win32::Graphics::Gdi::NULL_PEN;
|
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD,
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
};
|
||||||
|
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
|
use librashader_runtime::uniforms::UniformStorage;
|
||||||
|
|
||||||
pub struct ConstantBufferBinding {
|
pub struct ConstantBufferBinding {
|
||||||
pub binding: u32,
|
pub binding: u32,
|
||||||
|
@ -43,8 +46,9 @@ pub struct FilterPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://doc.rust-lang.org/nightly/core/array/fn.from_fn.html is not ~const :(
|
// https://doc.rust-lang.org/nightly/core/array/fn.from_fn.html is not ~const :(
|
||||||
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] =
|
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] = &[
|
||||||
&[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None];
|
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
|
||||||
|
];
|
||||||
|
|
||||||
// slang_process.cpp 229
|
// slang_process.cpp 229
|
||||||
impl FilterPass {
|
impl FilterPass {
|
||||||
|
@ -66,13 +70,14 @@ impl FilterPass {
|
||||||
texture: &Texture,
|
texture: &Texture,
|
||||||
) {
|
) {
|
||||||
texture_binding[binding.binding as usize] = Some(texture.view.handle.clone());
|
texture_binding[binding.binding as usize] = Some(texture.view.handle.clone());
|
||||||
sampler_binding[binding.binding as usize] = Some(samplers.get(texture.wrap_mode, texture.filter).clone());
|
sampler_binding[binding.binding as usize] =
|
||||||
|
Some(samplers.get(texture.wrap_mode, texture.filter).clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// framecount should be pre-modded
|
// framecount should be pre-modded
|
||||||
fn build_semantics(
|
fn build_semantics(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
_pass_index: usize,
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
mvp: &[f32; 16],
|
mvp: &[f32; 16],
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
|
@ -81,7 +86,10 @@ impl FilterPass {
|
||||||
viewport_size: Size<u32>,
|
viewport_size: Size<u32>,
|
||||||
original: &Texture,
|
original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
) -> ([Option<ID3D11ShaderResourceView>; 16], [Option<ID3D11SamplerState>; 16]){
|
) -> (
|
||||||
|
[Option<ID3D11ShaderResourceView>; 16],
|
||||||
|
[Option<ID3D11SamplerState>; 16],
|
||||||
|
) {
|
||||||
let mut textures: [Option<ID3D11ShaderResourceView>; 16] = std::array::from_fn(|_| None);
|
let mut textures: [Option<ID3D11ShaderResourceView>; 16] = std::array::from_fn(|_| None);
|
||||||
let mut samplers: [Option<ID3D11SamplerState>; 16] = std::array::from_fn(|_| None);
|
let mut samplers: [Option<ID3D11SamplerState>; 16] = std::array::from_fn(|_| None);
|
||||||
|
|
||||||
|
@ -116,7 +124,8 @@ impl FilterPass {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&VariableSemantics::FrameDirection.into())
|
.get(&VariableSemantics::FrameDirection.into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_scalar(*offset, frame_direction, None);
|
self.uniform_storage
|
||||||
|
.bind_scalar(*offset, frame_direction, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind Original sampler
|
// bind Original sampler
|
||||||
|
@ -126,7 +135,13 @@ impl FilterPass {
|
||||||
.texture_meta
|
.texture_meta
|
||||||
.get(&TextureSemantics::Original.semantics(0))
|
.get(&TextureSemantics::Original.semantics(0))
|
||||||
{
|
{
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, original);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
original,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// bind OriginalSize
|
// bind OriginalSize
|
||||||
|
@ -134,7 +149,8 @@ impl FilterPass {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::Original.semantics(0).into())
|
.get(&TextureSemantics::Original.semantics(0).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, original.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, original.view.size, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind Source sampler
|
// bind Source sampler
|
||||||
|
@ -145,7 +161,13 @@ impl FilterPass {
|
||||||
.get(&TextureSemantics::Source.semantics(0))
|
.get(&TextureSemantics::Source.semantics(0))
|
||||||
{
|
{
|
||||||
// eprintln!("setting source binding to {}", binding.binding);
|
// eprintln!("setting source binding to {}", binding.binding);
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, source);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
source,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind SourceSize
|
// bind SourceSize
|
||||||
|
@ -153,7 +175,8 @@ impl FilterPass {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::Source.semantics(0).into())
|
.get(&TextureSemantics::Source.semantics(0).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, source.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, source.view.size, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(binding) = self
|
if let Some(binding) = self
|
||||||
|
@ -162,14 +185,21 @@ impl FilterPass {
|
||||||
.texture_meta
|
.texture_meta
|
||||||
.get(&TextureSemantics::OriginalHistory.semantics(0))
|
.get(&TextureSemantics::OriginalHistory.semantics(0))
|
||||||
{
|
{
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, original);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
original,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(offset) = self
|
if let Some(offset) = self
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::OriginalHistory.semantics(0).into())
|
.get(&TextureSemantics::OriginalHistory.semantics(0).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, original.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, original.view.size, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (index, output) in parent.history_textures.iter().enumerate() {
|
// for (index, output) in parent.history_textures.iter().enumerate() {
|
||||||
|
@ -210,14 +240,21 @@ impl FilterPass {
|
||||||
.texture_meta
|
.texture_meta
|
||||||
.get(&TextureSemantics::PassOutput.semantics(index))
|
.get(&TextureSemantics::PassOutput.semantics(index))
|
||||||
{
|
{
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, output);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
output,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(offset) = self
|
if let Some(offset) = self
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::PassOutput.semantics(index).into())
|
.get(&TextureSemantics::PassOutput.semantics(index).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, output.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, output.view.size, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,14 +269,21 @@ impl FilterPass {
|
||||||
.texture_meta
|
.texture_meta
|
||||||
.get(&TextureSemantics::PassFeedback.semantics(index))
|
.get(&TextureSemantics::PassFeedback.semantics(index))
|
||||||
{
|
{
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, feedback);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
feedback,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(offset) = self
|
if let Some(offset) = self
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::PassFeedback.semantics(index).into())
|
.get(&TextureSemantics::PassFeedback.semantics(index).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, feedback.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, feedback.view.size, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,14 +327,21 @@ impl FilterPass {
|
||||||
.texture_meta
|
.texture_meta
|
||||||
.get(&TextureSemantics::User.semantics(*index))
|
.get(&TextureSemantics::User.semantics(*index))
|
||||||
{
|
{
|
||||||
FilterPass::bind_texture(&parent.samplers, &mut textures, &mut samplers, binding, &lut.image);
|
FilterPass::bind_texture(
|
||||||
|
&parent.samplers,
|
||||||
|
&mut textures,
|
||||||
|
&mut samplers,
|
||||||
|
binding,
|
||||||
|
&lut.image,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(offset) = self
|
if let Some(offset) = self
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::User.semantics(*index).into())
|
.get(&TextureSemantics::User.semantics(*index).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, lut.image.view.size, None);
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, lut.image.view.size, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +359,7 @@ impl FilterPass {
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
output: RenderTarget,
|
output: RenderTarget,
|
||||||
) -> std::result::Result<(), Box<dyn Error>> {
|
) -> std::result::Result<(), Box<dyn Error>> {
|
||||||
let device = &parent.d3d11.device;
|
let _device = &parent.d3d11.device;
|
||||||
let context = &parent.d3d11.device_context;
|
let context = &parent.d3d11.device_context;
|
||||||
unsafe {
|
unsafe {
|
||||||
context.IASetInputLayout(&self.vertex_layout);
|
context.IASetInputLayout(&self.vertex_layout);
|
||||||
|
@ -316,16 +367,27 @@ impl FilterPass {
|
||||||
context.PSSetShader(&self.pixel_shader, None);
|
context.PSSetShader(&self.pixel_shader, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (textures, samplers) = self.build_semantics(pass_index, parent, output.mvp, frame_count, frame_direction,
|
let (textures, samplers) = self.build_semantics(
|
||||||
output.output.size, *viewport, original, source);
|
pass_index,
|
||||||
|
parent,
|
||||||
|
output.mvp,
|
||||||
|
frame_count,
|
||||||
|
frame_direction,
|
||||||
|
output.output.size,
|
||||||
|
*viewport,
|
||||||
|
original,
|
||||||
|
source,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(ubo) = &self.uniform_buffer {
|
if let Some(ubo) = &self.uniform_buffer {
|
||||||
// upload uniforms
|
// upload uniforms
|
||||||
unsafe {
|
unsafe {
|
||||||
let map = context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?;
|
let map = context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?;
|
||||||
std::ptr::copy_nonoverlapping(self.uniform_storage.ubo.as_ptr(), map.pData.cast(), ubo.size as usize);
|
std::ptr::copy_nonoverlapping(
|
||||||
|
self.uniform_storage.ubo.as_ptr(),
|
||||||
|
map.pData.cast(),
|
||||||
|
ubo.size as usize,
|
||||||
|
);
|
||||||
context.Unmap(&ubo.buffer, 0);
|
context.Unmap(&ubo.buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +407,11 @@ impl FilterPass {
|
||||||
// upload push constants
|
// upload push constants
|
||||||
unsafe {
|
unsafe {
|
||||||
let map = context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?;
|
let map = context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?;
|
||||||
std::ptr::copy_nonoverlapping(self.uniform_storage.push.as_ptr(), map.pData.cast(), push.size as usize);
|
std::ptr::copy_nonoverlapping(
|
||||||
|
self.uniform_storage.push.as_ptr(),
|
||||||
|
map.pData.cast(),
|
||||||
|
push.size as usize,
|
||||||
|
);
|
||||||
context.Unmap(&push.buffer, 0);
|
context.Unmap(&push.buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +437,7 @@ impl FilterPass {
|
||||||
context.PSSetSamplers(0, Some(&samplers));
|
context.PSSetSamplers(0, Some(&samplers));
|
||||||
|
|
||||||
context.OMSetRenderTargets(Some(&[Some(output.output.rtv.clone())]), None);
|
context.OMSetRenderTargets(Some(&[Some(output.output.rtv.clone())]), None);
|
||||||
context.RSSetViewports(Some(&[output.output.viewport.clone()]))
|
context.RSSetViewports(Some(&[output.output.viewport]))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
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 crate::texture::Texture;
|
||||||
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::{DxImageView, Texture};
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::d3d11_get_closest_format;
|
use crate::util::d3d11_get_closest_format;
|
||||||
|
use librashader_common::{ImageFormat, Size};
|
||||||
|
use librashader_presets::Scale2D;
|
||||||
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11Resource,
|
||||||
|
ID3D11ShaderResourceView, ID3D11Texture2D, 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_VIEWPORT,
|
||||||
|
};
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_SAMPLE_DESC};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct OwnedFramebuffer {
|
pub struct OwnedFramebuffer {
|
||||||
|
@ -14,14 +23,24 @@ pub struct OwnedFramebuffer {
|
||||||
pub format: DXGI_FORMAT,
|
pub format: DXGI_FORMAT,
|
||||||
device: ID3D11Device,
|
device: ID3D11Device,
|
||||||
context: ID3D11DeviceContext,
|
context: ID3D11DeviceContext,
|
||||||
is_raw: bool
|
is_raw: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedFramebuffer {
|
impl OwnedFramebuffer {
|
||||||
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext, size: Size<u32>, format: ImageFormat) -> util::Result<OwnedFramebuffer> {
|
pub fn new(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
context: &ID3D11DeviceContext,
|
||||||
|
size: Size<u32>,
|
||||||
|
format: ImageFormat,
|
||||||
|
) -> util::Result<OwnedFramebuffer> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let format = d3d11_get_closest_format(device, DXGI_FORMAT::from(format),
|
let format = d3d11_get_closest_format(
|
||||||
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
|
device,
|
||||||
|
DXGI_FORMAT::from(format),
|
||||||
|
D3D11_FORMAT_SUPPORT_TEXTURE2D.0
|
||||||
|
| D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0
|
||||||
|
| D3D11_FORMAT_SUPPORT_RENDER_TARGET.0,
|
||||||
|
);
|
||||||
eprintln!("{format:?}");
|
eprintln!("{format:?}");
|
||||||
let desc = default_desc(size, format);
|
let desc = default_desc(size, format);
|
||||||
let texture = device.CreateTexture2D(&desc, None)?;
|
let texture = device.CreateTexture2D(&desc, None)?;
|
||||||
|
@ -71,9 +90,13 @@ impl OwnedFramebuffer {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let format = d3d11_get_closest_format(&self.device, DXGI_FORMAT::from(format),
|
let format = d3d11_get_closest_format(
|
||||||
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 |
|
&self.device,
|
||||||
D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
|
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);
|
let desc = default_desc(size, format);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -88,30 +111,34 @@ impl OwnedFramebuffer {
|
||||||
|
|
||||||
pub fn create_shader_resource_view(&self) -> util::Result<ID3D11ShaderResourceView> {
|
pub fn create_shader_resource_view(&self) -> util::Result<ID3D11ShaderResourceView> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(self.device.CreateShaderResourceView(&self.texture, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
Ok(self.device.CreateShaderResourceView(
|
||||||
|
&self.texture,
|
||||||
|
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
||||||
Format: self.format,
|
Format: self.format,
|
||||||
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
||||||
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||||
Texture2D: D3D11_TEX2D_SRV {
|
Texture2D: D3D11_TEX2D_SRV {
|
||||||
MostDetailedMip: 0,
|
MostDetailedMip: 0,
|
||||||
MipLevels: u32::MAX,
|
MipLevels: u32::MAX,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}))?)
|
},
|
||||||
|
}),
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_render_target_view(&self) -> util::Result<ID3D11RenderTargetView> {
|
pub fn create_render_target_view(&self) -> util::Result<ID3D11RenderTargetView> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(self.device.CreateRenderTargetView(&self.texture, Some(&D3D11_RENDER_TARGET_VIEW_DESC {
|
Ok(self.device.CreateRenderTargetView(
|
||||||
|
&self.texture,
|
||||||
|
Some(&D3D11_RENDER_TARGET_VIEW_DESC {
|
||||||
Format: self.format,
|
Format: self.format,
|
||||||
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
||||||
Texture2D: D3D11_TEX2D_RTV {
|
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
|
||||||
MipSlice: 0,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}))?)
|
}),
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,22 +146,29 @@ impl OwnedFramebuffer {
|
||||||
Ok(OutputFramebuffer {
|
Ok(OutputFramebuffer {
|
||||||
rtv: self.create_render_target_view()?,
|
rtv: self.create_render_target_view()?,
|
||||||
size: self.size,
|
size: self.size,
|
||||||
viewport: default_viewport(self.size)
|
viewport: default_viewport(self.size),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_from(&self, image: &ID3D11Resource) -> util::Result<()> {
|
pub fn copy_from(&self, image: &ID3D11Resource) -> util::Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
self.context.CopySubresourceRegion(
|
||||||
self.context.CopySubresourceRegion(&self.texture, 0, 0, 0, 0,
|
&self.texture,
|
||||||
image, 0, Some(&D3D11_BOX {
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
image,
|
||||||
|
0,
|
||||||
|
Some(&D3D11_BOX {
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
front: 0,
|
front: 0,
|
||||||
right: self.size.width,
|
right: self.size.width,
|
||||||
bottom: self.size.height,
|
bottom: self.size.height,
|
||||||
back: 1,
|
back: 1,
|
||||||
}))
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -143,7 +177,7 @@ impl OwnedFramebuffer {
|
||||||
pub struct OutputFramebuffer {
|
pub struct OutputFramebuffer {
|
||||||
pub rtv: ID3D11RenderTargetView,
|
pub rtv: ID3D11RenderTargetView,
|
||||||
pub size: Size<u32>,
|
pub size: Size<u32>,
|
||||||
pub viewport: D3D11_VIEWPORT
|
pub viewport: D3D11_VIEWPORT,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_desc(size: Size<u32>, format: DXGI_FORMAT) -> D3D11_TEXTURE2D_DESC {
|
fn default_desc(size: Size<u32>, format: DXGI_FORMAT) -> D3D11_TEXTURE2D_DESC {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::sync::mpsc::Receiver;
|
|
||||||
|
|
||||||
const WIDTH: i32 = 900;
|
const WIDTH: i32 = 900;
|
||||||
const HEIGHT: i32 = 700;
|
const HEIGHT: i32 = 700;
|
||||||
const TITLE: &str = "librashader DirectX 11";
|
const TITLE: &str = "librashader DirectX 11";
|
||||||
|
@ -7,11 +5,10 @@ const TITLE: &str = "librashader DirectX 11";
|
||||||
use windows::{
|
use windows::{
|
||||||
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
|
||||||
Win32::Graphics::Direct3D11::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
Win32::Graphics::Direct3D11::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
|
||||||
Win32::System::LibraryLoader::*, Win32::System::Threading::*,
|
Win32::System::LibraryLoader::*, Win32::UI::WindowsAndMessaging::*,
|
||||||
Win32::System::WindowsProgramming::*, Win32::UI::WindowsAndMessaging::*,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static VERTEX_SHADER: &'static [u8] = b"
|
static VERTEX_SHADER: &[u8] = b"
|
||||||
cbuffer cb : register(b0)
|
cbuffer cb : register(b0)
|
||||||
{
|
{
|
||||||
row_major float4x4 projectionMatrix : packoffset(c0);
|
row_major float4x4 projectionMatrix : packoffset(c0);
|
||||||
|
@ -44,7 +41,7 @@ VertexOutput main(VertexInput vertexInput)
|
||||||
return output;
|
return output;
|
||||||
}\0";
|
}\0";
|
||||||
|
|
||||||
static PIXEL_SHADER: &'static [u8] = b"
|
static PIXEL_SHADER: &[u8] = b"
|
||||||
struct PixelInput
|
struct PixelInput
|
||||||
{
|
{
|
||||||
float3 color : COLOR;
|
float3 color : COLOR;
|
||||||
|
@ -224,15 +221,15 @@ struct TriangleUniforms {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod d3d11_hello_triangle {
|
pub mod d3d11_hello_triangle {
|
||||||
use std::path::Path;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use gfx_maths::{Quaternion, Vec3};
|
use std::path::Path;
|
||||||
use std::slice;
|
|
||||||
use std::time::Instant;
|
|
||||||
use librashader_common::Size;
|
|
||||||
use crate::filter_chain::FilterChain;
|
use crate::filter_chain::FilterChain;
|
||||||
use crate::framebuffer::OutputFramebuffer;
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
use crate::texture::DxImageView;
|
use crate::texture::DxImageView;
|
||||||
|
use librashader_common::Size;
|
||||||
|
use std::slice;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
const FRAME_COUNT: u32 = 2;
|
const FRAME_COUNT: u32 = 2;
|
||||||
|
|
||||||
|
@ -279,8 +276,6 @@ pub mod d3d11_hello_triangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl DXSample for Sample {
|
impl DXSample for Sample {
|
||||||
|
|
||||||
|
|
||||||
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
|
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
|
||||||
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
|
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
|
||||||
let (rtv, backbuffer) = create_rtv(&self.device, &swapchain)?;
|
let (rtv, backbuffer) = create_rtv(&self.device, &swapchain)?;
|
||||||
|
@ -317,7 +312,6 @@ pub mod d3d11_hello_triangle {
|
||||||
self.context.RSSetState(&raster_state);
|
self.context.RSSetState(&raster_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self.resources = Some(Resources {
|
self.resources = Some(Resources {
|
||||||
swapchain,
|
swapchain,
|
||||||
rtv,
|
rtv,
|
||||||
|
@ -343,7 +337,7 @@ pub mod d3d11_hello_triangle {
|
||||||
MaxDepth: D3D11_MAX_DEPTH,
|
MaxDepth: D3D11_MAX_DEPTH,
|
||||||
},
|
},
|
||||||
shader_output: None,
|
shader_output: None,
|
||||||
frame_count: 0usize
|
frame_count: 0usize,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -364,7 +358,7 @@ pub mod d3d11_hello_triangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
resources.elapsed += 0.0000001 * time;
|
resources.elapsed += 0.0000001 * time;
|
||||||
resources.elapsed %= 6.283185307179586f32;
|
resources.elapsed %= 6.283_185_5_f32;
|
||||||
|
|
||||||
// resources.triangle_uniform_values.model_matrix = Mat4::rotate(Quaternion::axis_angle(Vec3::new(0.0, 0.0, 1.0), resources.elapsed));
|
// resources.triangle_uniform_values.model_matrix = Mat4::rotate(Quaternion::axis_angle(Vec3::new(0.0, 0.0, 1.0), resources.elapsed));
|
||||||
resources.triangle_uniform_values.model_matrix = Mat4::identity();
|
resources.triangle_uniform_values.model_matrix = Mat4::identity();
|
||||||
|
@ -437,53 +431,67 @@ pub mod d3d11_hello_triangle {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut tex2d_desc = Default::default();
|
let mut tex2d_desc = Default::default();
|
||||||
resources.backbuffer.GetDesc(&mut tex2d_desc);
|
resources.backbuffer.GetDesc(&mut tex2d_desc);
|
||||||
let backup = self.device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
|
let backup = self.device.CreateTexture2D(
|
||||||
|
&D3D11_TEXTURE2D_DESC {
|
||||||
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
|
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
|
||||||
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
|
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
|
||||||
..tex2d_desc
|
..tex2d_desc
|
||||||
}, None)?;
|
},
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
self.context.CopyResource(&backup, &resources.backbuffer);
|
self.context.CopyResource(&backup, &resources.backbuffer);
|
||||||
|
|
||||||
let srv = self.device.CreateShaderResourceView(&backup, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
let srv = self.device.CreateShaderResourceView(
|
||||||
|
&backup,
|
||||||
|
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
||||||
Format: tex2d_desc.Format,
|
Format: tex2d_desc.Format,
|
||||||
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
||||||
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||||
Texture2D: D3D11_TEX2D_SRV {
|
Texture2D: D3D11_TEX2D_SRV {
|
||||||
MostDetailedMip: 0,
|
MostDetailedMip: 0,
|
||||||
MipLevels: u32::MAX,
|
MipLevels: u32::MAX,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}))?;
|
},
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
let shader_out = self.device.CreateTexture2D(&tex2d_desc, None)?;
|
let shader_out = self.device.CreateTexture2D(&tex2d_desc, None)?;
|
||||||
|
|
||||||
let rtv = self.device.CreateRenderTargetView(&shader_out, Some(&D3D11_RENDER_TARGET_VIEW_DESC {
|
let _rtv = self.device.CreateRenderTargetView(
|
||||||
|
&shader_out,
|
||||||
|
Some(&D3D11_RENDER_TARGET_VIEW_DESC {
|
||||||
Format: tex2d_desc.Format,
|
Format: tex2d_desc.Format,
|
||||||
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||||
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
|
||||||
Texture2D: D3D11_TEX2D_RTV {
|
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
|
||||||
MipSlice: 0,
|
},
|
||||||
}
|
}),
|
||||||
}
|
)?;
|
||||||
}))?;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
self.filter.frame(resources.frame_count, &Size {
|
self.filter
|
||||||
|
.frame(
|
||||||
|
resources.frame_count,
|
||||||
|
&Size {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
}, DxImageView { handle: srv, size: Size {
|
},
|
||||||
|
DxImageView {
|
||||||
|
handle: srv,
|
||||||
|
size: Size {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
} }, OutputFramebuffer {
|
},
|
||||||
|
},
|
||||||
|
OutputFramebuffer {
|
||||||
rtv: resources.rtv.clone(),
|
rtv: resources.rtv.clone(),
|
||||||
// rtv,
|
// rtv,
|
||||||
size: Size {
|
size: Size {
|
||||||
width: tex2d_desc.Width,
|
width: tex2d_desc.Width,
|
||||||
height: tex2d_desc.Height,
|
height: tex2d_desc.Height,
|
||||||
},
|
},
|
||||||
viewport: resources.viewport
|
viewport: resources.viewport, // viewport: D3D11_VIEWPORT {
|
||||||
// viewport: D3D11_VIEWPORT {
|
|
||||||
// TopLeftX: 0.0,
|
// TopLeftX: 0.0,
|
||||||
// TopLeftY: 0.0,
|
// TopLeftY: 0.0,
|
||||||
// Width: tex2d_desc.Width as f32,
|
// Width: tex2d_desc.Width as f32,
|
||||||
|
@ -491,7 +499,9 @@ pub mod d3d11_hello_triangle {
|
||||||
// MinDepth: 0.0,
|
// MinDepth: 0.0,
|
||||||
// MaxDepth: 1.0,
|
// MaxDepth: 1.0,
|
||||||
// },
|
// },
|
||||||
}).unwrap();
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// self.context.CopyResource(&resources.backbuffer, &backup);
|
// self.context.CopyResource(&resources.backbuffer, &backup);
|
||||||
}
|
}
|
||||||
|
@ -755,7 +765,7 @@ pub mod d3d11_hello_triangle {
|
||||||
|
|
||||||
let mut swap_chain = None;
|
let mut swap_chain = None;
|
||||||
unsafe {
|
unsafe {
|
||||||
fac.CreateSwapChain(&*device, &swapchain_desc, &mut swap_chain)
|
fac.CreateSwapChain(device, &swapchain_desc, &mut swap_chain)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,43 +3,31 @@
|
||||||
|
|
||||||
mod filter_chain;
|
mod filter_chain;
|
||||||
|
|
||||||
use librashader_preprocess::ShaderSource;
|
|
||||||
use librashader_presets::ShaderPassConfig;
|
|
||||||
use librashader_reflect::back::targets::HLSL;
|
|
||||||
use librashader_reflect::back::{CompileShader, FromCompilation};
|
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use std::error::Error;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use librashader_reflect::reflect::semantics::{
|
|
||||||
ReflectSemantics, SemanticMap, TextureSemantics, UniformSemantic, VariableSemantics,
|
|
||||||
};
|
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
|
||||||
|
|
||||||
mod filter_pass;
|
mod filter_pass;
|
||||||
|
mod framebuffer;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod hello_triangle;
|
mod hello_triangle;
|
||||||
|
mod quad_render;
|
||||||
|
mod render_target;
|
||||||
|
mod samplers;
|
||||||
mod texture;
|
mod texture;
|
||||||
mod util;
|
mod util;
|
||||||
mod samplers;
|
|
||||||
mod render_target;
|
|
||||||
mod framebuffer;
|
|
||||||
mod quad_render;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::hello_triangle::DXSample;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn triangle_d3d11() {
|
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/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();
|
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap();
|
||||||
|
|
||||||
hello_triangle::main(sample).unwrap();
|
hello_triangle::main(sample).unwrap();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,40 @@
|
||||||
|
use crate::util;
|
||||||
use bytemuck::offset_of;
|
use bytemuck::offset_of;
|
||||||
use windows::core::PCSTR;
|
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::Direct3D11::{
|
||||||
|
ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_VERTEX_BUFFER, D3D11_BUFFER_DESC,
|
||||||
|
D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_SUBRESOURCE_DATA,
|
||||||
|
D3D11_USAGE_IMMUTABLE,
|
||||||
|
};
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R32G32_FLOAT;
|
||||||
use crate::util;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
struct D3D11Vertex {
|
struct D3D11Vertex {
|
||||||
position: [f32; 2],
|
position: [f32; 2],
|
||||||
texcoord: [f32; 2],
|
texcoord: [f32; 2],
|
||||||
color: [f32; 4]
|
color: [f32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
const CLEAR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
|
const CLEAR: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
|
||||||
|
|
||||||
static QUAD_VBO_DATA: &'static [D3D11Vertex; 4] = &[
|
static QUAD_VBO_DATA: &[D3D11Vertex; 4] = &[
|
||||||
D3D11Vertex {
|
D3D11Vertex {
|
||||||
position: [0.0, 0.0],
|
position: [0.0, 0.0],
|
||||||
texcoord: [0.0, 1.0],
|
texcoord: [0.0, 1.0],
|
||||||
color: CLEAR,
|
color: CLEAR,
|
||||||
},
|
},
|
||||||
|
|
||||||
D3D11Vertex {
|
D3D11Vertex {
|
||||||
position: [0.0, 1.0],
|
position: [0.0, 1.0],
|
||||||
texcoord: [0.0, 0.0],
|
texcoord: [0.0, 0.0],
|
||||||
color: CLEAR,
|
color: CLEAR,
|
||||||
},
|
},
|
||||||
|
|
||||||
D3D11Vertex {
|
D3D11Vertex {
|
||||||
position: [1.0, 0.0],
|
position: [1.0, 0.0],
|
||||||
texcoord: [1.0, 1.0],
|
texcoord: [1.0, 1.0],
|
||||||
color: CLEAR,
|
color: CLEAR,
|
||||||
},
|
},
|
||||||
|
|
||||||
D3D11Vertex {
|
D3D11Vertex {
|
||||||
position: [1.0, 1.0],
|
position: [1.0, 1.0],
|
||||||
texcoord: [1.0, 0.0],
|
texcoord: [1.0, 0.0],
|
||||||
|
@ -51,33 +52,42 @@ pub(crate) struct DrawQuad {
|
||||||
impl DrawQuad {
|
impl DrawQuad {
|
||||||
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
|
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
|
let buffer = device.CreateBuffer(
|
||||||
|
&D3D11_BUFFER_DESC {
|
||||||
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
|
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
|
||||||
Usage: D3D11_USAGE_IMMUTABLE,
|
Usage: D3D11_USAGE_IMMUTABLE,
|
||||||
BindFlags: D3D11_BIND_VERTEX_BUFFER,
|
BindFlags: D3D11_BIND_VERTEX_BUFFER,
|
||||||
CPUAccessFlags: Default::default(),
|
CPUAccessFlags: Default::default(),
|
||||||
MiscFlags: Default::default(),
|
MiscFlags: Default::default(),
|
||||||
StructureByteStride: 0,
|
StructureByteStride: 0,
|
||||||
}, Some(&D3D11_SUBRESOURCE_DATA {
|
},
|
||||||
|
Some(&D3D11_SUBRESOURCE_DATA {
|
||||||
pSysMem: QUAD_VBO_DATA.as_ptr().cast(),
|
pSysMem: QUAD_VBO_DATA.as_ptr().cast(),
|
||||||
SysMemPitch: 0,
|
SysMemPitch: 0,
|
||||||
SysMemSlicePitch: 0,
|
SysMemSlicePitch: 0,
|
||||||
}))?;
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(DrawQuad {
|
Ok(DrawQuad {
|
||||||
buffer,
|
buffer,
|
||||||
context: context.clone(),
|
context: context.clone(),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
stride: std::mem::size_of::<D3D11Vertex>() as u32
|
stride: std::mem::size_of::<D3D11Vertex>() as u32,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_vertices(&self) {
|
pub fn bind_vertices(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
self.context
|
||||||
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
|
.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
Some(&self.stride), Some(&self.offset));
|
self.context.IASetVertexBuffers(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
Some(&Some(self.buffer.clone())),
|
||||||
|
Some(&self.stride),
|
||||||
|
Some(&self.offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +110,7 @@ impl DrawQuad {
|
||||||
AlignedByteOffset: offset_of!(D3D11Vertex, texcoord) as u32,
|
AlignedByteOffset: offset_of!(D3D11Vertex, texcoord) as u32,
|
||||||
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
|
||||||
InstanceDataStepRate: 0,
|
InstanceDataStepRate: 0,
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
use windows::Win32::Graphics::Direct3D11::ID3D11RenderTargetView;
|
use crate::framebuffer::OutputFramebuffer;
|
||||||
use librashader_common::Size;
|
|
||||||
use crate::framebuffer::{OutputFramebuffer};
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static DEFAULT_MVP: &[f32; 16] = &[
|
static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
|
@ -13,7 +11,7 @@ static DEFAULT_MVP: &[f32; 16] = &[
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RenderTarget<'a> {
|
pub struct RenderTarget<'a> {
|
||||||
pub mvp: &'a [f32; 16],
|
pub mvp: &'a [f32; 16],
|
||||||
pub output: OutputFramebuffer
|
pub output: OutputFramebuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RenderTarget<'a> {
|
impl<'a> RenderTarget<'a> {
|
||||||
|
@ -31,4 +29,3 @@ impl<'a> RenderTarget<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,26 @@
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use windows::Win32::Graphics::Direct3D11::{D3D11_COMPARISON_NEVER, D3D11_FLOAT32_MAX, D3D11_SAMPLER_DESC, D3D11_TEXTURE_ADDRESS_MODE, ID3D11Device, ID3D11SamplerState};
|
|
||||||
use librashader_common::{FilterMode, WrapMode};
|
|
||||||
use crate::util::Result;
|
use crate::util::Result;
|
||||||
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
ID3D11Device, ID3D11SamplerState, D3D11_COMPARISON_NEVER, D3D11_FLOAT32_MAX,
|
||||||
|
D3D11_SAMPLER_DESC, D3D11_TEXTURE_ADDRESS_MODE,
|
||||||
|
};
|
||||||
pub struct SamplerSet {
|
pub struct SamplerSet {
|
||||||
samplers: FxHashMap<(WrapMode, FilterMode), ID3D11SamplerState>
|
samplers: FxHashMap<(WrapMode, FilterMode), ID3D11SamplerState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SamplerSet {
|
impl SamplerSet {
|
||||||
pub fn get(&self, wrap: WrapMode, filter: FilterMode) -> &ID3D11SamplerState {
|
pub fn get(&self, wrap: WrapMode, filter: FilterMode) -> &ID3D11SamplerState {
|
||||||
self.samplers.get(&(wrap, filter))
|
self.samplers.get(&(wrap, filter)).unwrap()
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
pub fn new(device: &ID3D11Device) -> Result<SamplerSet> {
|
pub fn new(device: &ID3D11Device) -> Result<SamplerSet> {
|
||||||
let mut samplers = FxHashMap::default();
|
let mut samplers = FxHashMap::default();
|
||||||
let wrap_modes =
|
let wrap_modes = &[
|
||||||
&[WrapMode::ClampToBorder, WrapMode::ClampToEdge, WrapMode::Repeat, WrapMode::MirroredRepeat];
|
WrapMode::ClampToBorder,
|
||||||
|
WrapMode::ClampToEdge,
|
||||||
|
WrapMode::Repeat,
|
||||||
|
WrapMode::MirroredRepeat,
|
||||||
|
];
|
||||||
for wrap_mode in wrap_modes {
|
for wrap_mode in wrap_modes {
|
||||||
unsafe {
|
unsafe {
|
||||||
let linear = device.CreateSamplerState(&D3D11_SAMPLER_DESC {
|
let linear = device.CreateSamplerState(&D3D11_SAMPLER_DESC {
|
||||||
|
@ -48,9 +54,6 @@ impl SamplerSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SamplerSet {
|
Ok(SamplerSet { samplers })
|
||||||
samplers
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
|
||||||
use windows::Win32::Graphics::Direct3D11::{ID3D11Device, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_CPU_ACCESS_FLAG, D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE, D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_TEX2D_SRV, D3D11_BIND_FLAG, D3D11_RESOURCE_MISC_FLAG, D3D11_USAGE_STAGING, ID3D11DeviceContext, D3D11_SUBRESOURCE_DATA, D3D11_MAP_WRITE, D3D11_BOX};
|
|
||||||
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
|
||||||
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use crate::util::d3d11_get_closest_format;
|
use librashader_common::{FilterMode, Size, WrapMode};
|
||||||
|
use windows::Win32::Graphics::Direct3D::D3D_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::{
|
||||||
|
ID3D11Device, ID3D11ShaderResourceView, ID3D11Texture2D, D3D11_BIND_FLAG,
|
||||||
|
D3D11_BIND_RENDER_TARGET, D3D11_BIND_SHADER_RESOURCE, D3D11_BOX, D3D11_CPU_ACCESS_FLAG,
|
||||||
|
D3D11_CPU_ACCESS_WRITE, D3D11_FORMAT_SUPPORT_RENDER_TARGET, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE,
|
||||||
|
D3D11_FORMAT_SUPPORT_TEXTURE2D, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS,
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC, D3D11_SHADER_RESOURCE_VIEW_DESC_0, D3D11_SUBRESOURCE_DATA,
|
||||||
|
D3D11_TEX2D_SRV, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DYNAMIC, D3D11_USAGE_STAGING,
|
||||||
|
};
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
|
||||||
|
|
||||||
use crate::util::Result;
|
use crate::util::Result;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -29,7 +36,13 @@ pub struct OwnedTexture {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedTexture {
|
impl OwnedTexture {
|
||||||
pub fn new(device: &ID3D11Device, source: &Image, desc: D3D11_TEXTURE2D_DESC, filter: FilterMode, wrap_mode: WrapMode) -> Result<OwnedTexture> {
|
pub fn new(
|
||||||
|
device: &ID3D11Device,
|
||||||
|
source: &Image,
|
||||||
|
desc: D3D11_TEXTURE2D_DESC,
|
||||||
|
filter: FilterMode,
|
||||||
|
wrap_mode: WrapMode,
|
||||||
|
) -> Result<OwnedTexture> {
|
||||||
let mut desc = D3D11_TEXTURE2D_DESC {
|
let mut desc = D3D11_TEXTURE2D_DESC {
|
||||||
Width: source.size.width,
|
Width: source.size.width,
|
||||||
Height: source.size.height,
|
Height: source.size.height,
|
||||||
|
@ -80,17 +93,19 @@ impl OwnedTexture {
|
||||||
unsafe {
|
unsafe {
|
||||||
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
let handle = device.CreateTexture2D(&desc, None).unwrap();
|
||||||
|
|
||||||
let srv = device.CreateShaderResourceView(&handle, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
let srv = device.CreateShaderResourceView(
|
||||||
|
&handle,
|
||||||
|
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
|
||||||
Format: desc.Format,
|
Format: desc.Format,
|
||||||
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
|
||||||
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
|
||||||
Texture2D: D3D11_TEX2D_SRV {
|
Texture2D: D3D11_TEX2D_SRV {
|
||||||
MostDetailedMip: 0,
|
MostDetailedMip: 0,
|
||||||
MipLevels: u32::MAX
|
MipLevels: u32::MAX,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}))?;
|
},
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut context = None;
|
let mut context = None;
|
||||||
device.GetImmediateContext(&mut context);
|
device.GetImmediateContext(&mut context);
|
||||||
|
@ -99,31 +114,42 @@ impl OwnedTexture {
|
||||||
let context = context.unwrap();
|
let context = context.unwrap();
|
||||||
|
|
||||||
// need a staging texture to defer mipmap generation
|
// need a staging texture to defer mipmap generation
|
||||||
let staging = device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
|
let staging = device.CreateTexture2D(
|
||||||
|
&D3D11_TEXTURE2D_DESC {
|
||||||
MipLevels: 1,
|
MipLevels: 1,
|
||||||
BindFlags: D3D11_BIND_FLAG(0),
|
BindFlags: D3D11_BIND_FLAG(0),
|
||||||
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
|
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
|
||||||
Usage: D3D11_USAGE_STAGING,
|
Usage: D3D11_USAGE_STAGING,
|
||||||
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
|
||||||
..desc
|
..desc
|
||||||
}, Some(&D3D11_SUBRESOURCE_DATA {
|
},
|
||||||
|
Some(&D3D11_SUBRESOURCE_DATA {
|
||||||
pSysMem: source.bytes.as_ptr().cast(),
|
pSysMem: source.bytes.as_ptr().cast(),
|
||||||
SysMemPitch: source.pitch as u32,
|
SysMemPitch: source.pitch as u32,
|
||||||
SysMemSlicePitch: 0
|
SysMemSlicePitch: 0,
|
||||||
}))?;
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
// todo: do format conversion (leverage image crate..?
|
// todo: do format conversion (leverage image crate..?
|
||||||
// is this necessary with CopySubresourceRegion)...
|
// is this necessary with CopySubresourceRegion)...
|
||||||
|
|
||||||
context.CopySubresourceRegion(&handle, 0, 0, 0, 0,
|
context.CopySubresourceRegion(
|
||||||
&staging, 0, Some(&D3D11_BOX {
|
&handle,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&staging,
|
||||||
|
0,
|
||||||
|
Some(&D3D11_BOX {
|
||||||
left: 0,
|
left: 0,
|
||||||
top: 0,
|
top: 0,
|
||||||
front: 0,
|
front: 0,
|
||||||
right: source.size.width,
|
right: source.size.width,
|
||||||
bottom: source.size.height,
|
bottom: source.size.height,
|
||||||
back: 1,
|
back: 1,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
|
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
|
||||||
context.GenerateMips(&srv)
|
context.GenerateMips(&srv)
|
||||||
|
@ -132,8 +158,6 @@ impl OwnedTexture {
|
||||||
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
|
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
|
||||||
// staging.Upd
|
// staging.Upd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ok(OwnedTexture {
|
Ok(OwnedTexture {
|
||||||
handle,
|
handle,
|
||||||
// staging,
|
// staging,
|
||||||
|
@ -144,8 +168,8 @@ impl OwnedTexture {
|
||||||
size: source.size,
|
size: source.size,
|
||||||
},
|
},
|
||||||
filter,
|
filter,
|
||||||
wrap_mode
|
wrap_mode,
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
|
||||||
|
|
||||||
use windows::Win32::Graphics::Direct3D11::*;
|
|
||||||
use windows::Win32::Graphics::Dxgi::Common::*;
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use windows::core::PCSTR;
|
use windows::core::PCSTR;
|
||||||
use windows::Win32::Graphics::Direct3D::Fxc::{D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_SKIP_OPTIMIZATION};
|
use windows::Win32::Graphics::Direct3D::Fxc::{
|
||||||
|
D3DCompile, D3DCOMPILE_DEBUG, D3DCOMPILE_SKIP_OPTIMIZATION,
|
||||||
|
};
|
||||||
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
use windows::Win32::Graphics::Direct3D::ID3DBlob;
|
||||||
|
use windows::Win32::Graphics::Direct3D11::*;
|
||||||
|
use windows::Win32::Graphics::Dxgi::Common::*;
|
||||||
|
|
||||||
/// wtf retroarch?
|
/// wtf retroarch?
|
||||||
const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000);
|
const DXGI_FORMAT_EX_A4R4G4B4_UNORM: DXGI_FORMAT = DXGI_FORMAT(1000);
|
||||||
|
@ -90,8 +90,7 @@ pub fn d3d11_get_closest_format(
|
||||||
format_support_mask: i32,
|
format_support_mask: i32,
|
||||||
) -> DXGI_FORMAT {
|
) -> DXGI_FORMAT {
|
||||||
let default_list = [format, DXGI_FORMAT_UNKNOWN];
|
let default_list = [format, DXGI_FORMAT_UNKNOWN];
|
||||||
let format_support_list = d3d11_format_fallback_list(format)
|
let format_support_list = d3d11_format_fallback_list(format).unwrap_or(&default_list);
|
||||||
.unwrap_or(&default_list);
|
|
||||||
let format_support_mask = format_support_mask as u32;
|
let format_support_mask = format_support_mask as u32;
|
||||||
|
|
||||||
for supported in format_support_list {
|
for supported in format_support_list {
|
||||||
|
@ -102,7 +101,7 @@ pub fn d3d11_get_closest_format(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DXGI_FORMAT_UNKNOWN;
|
DXGI_FORMAT_UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result<ID3DBlob> {
|
pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result<ID3DBlob> {
|
||||||
|
@ -130,39 +129,42 @@ pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ShaderFactory<'a, L, T>
|
pub type ShaderFactory<'a, L, T> =
|
||||||
= unsafe fn (&'a ID3D11Device, &[u8], linkage: L) -> windows::core::Result<T>;
|
unsafe fn(&'a ID3D11Device, &[u8], linkage: L) -> windows::core::Result<T>;
|
||||||
|
|
||||||
pub fn d3d11_compile_bound_shader<'a, T, L>(device: &'a ID3D11Device, blob: &ID3DBlob, linkage: L, factory: ShaderFactory<'a, L, T>)
|
pub fn d3d11_compile_bound_shader<'a, T, L>(
|
||||||
-> Result<T>
|
device: &'a ID3D11Device,
|
||||||
where L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,{
|
blob: &ID3DBlob,
|
||||||
|
linkage: L,
|
||||||
|
factory: ShaderFactory<'a, L, T>,
|
||||||
|
) -> Result<T>
|
||||||
|
where
|
||||||
|
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
// SAFETY: slice as valid for as long as vs_blob is alive.
|
// SAFETY: slice as valid for as long as vs_blob is alive.
|
||||||
let dxil = slice::from_raw_parts(
|
let dxil =
|
||||||
blob.GetBufferPointer().cast::<u8>(),
|
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize());
|
||||||
blob.GetBufferSize(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let compiled = factory(device, dxil, linkage)?;
|
let compiled = factory(device, dxil, linkage)?;
|
||||||
Ok(compiled)
|
Ok(compiled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn d3d11_create_input_layout(
|
||||||
pub fn d3d11_create_input_layout(device: &ID3D11Device, desc: &[D3D11_INPUT_ELEMENT_DESC], blob: &ID3DBlob) -> Result<ID3D11InputLayout> {
|
device: &ID3D11Device,
|
||||||
|
desc: &[D3D11_INPUT_ELEMENT_DESC],
|
||||||
|
blob: &ID3DBlob,
|
||||||
|
) -> Result<ID3D11InputLayout> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// SAFETY: slice as valid for as long as vs_blob is alive.
|
// SAFETY: slice as valid for as long as vs_blob is alive.
|
||||||
let dxil = slice::from_raw_parts(
|
let dxil =
|
||||||
blob.GetBufferPointer().cast::<u8>(),
|
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize());
|
||||||
blob.GetBufferSize(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let compiled =
|
let compiled = device.CreateInputLayout(desc, dxil)?;
|
||||||
device.CreateInputLayout(desc, dxil)?;
|
|
||||||
Ok(compiled)
|
Ok(compiled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: d3d11.c 2097
|
// todo: d3d11.c 2097
|
||||||
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use gl::types::GLint;
|
use gl::types::GLint;
|
||||||
use librashader_reflect::reflect::semantics::BindingStage;
|
use librashader_reflect::reflect::semantics::BindingStage;
|
||||||
use librashader_runtime::uniforms::{BindUniform, UniformStorage, UniformScalar};
|
use librashader_runtime::uniforms::{BindUniform, UniformScalar, UniformStorage};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum VariableLocation {
|
pub enum VariableLocation {
|
||||||
|
@ -37,7 +37,6 @@ impl UniformLocation<GLint> {
|
||||||
|
|
||||||
pub(crate) type BufferStorage = UniformStorage<GlUniformBinder, UniformLocation<GLint>>;
|
pub(crate) type BufferStorage = UniformStorage<GlUniformBinder, UniformLocation<GLint>>;
|
||||||
|
|
||||||
|
|
||||||
pub trait GlUniformScalar: UniformScalar {
|
pub trait GlUniformScalar: UniformScalar {
|
||||||
const FACTORY: unsafe fn(GLint, Self) -> ();
|
const FACTORY: unsafe fn(GLint, Self) -> ();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +55,8 @@ impl GlUniformScalar for u32 {
|
||||||
|
|
||||||
pub(crate) struct GlUniformBinder;
|
pub(crate) struct GlUniformBinder;
|
||||||
impl<T> BindUniform<UniformLocation<GLint>, T> for GlUniformBinder
|
impl<T> BindUniform<UniformLocation<GLint>, T> for GlUniformBinder
|
||||||
where T: GlUniformScalar
|
where
|
||||||
|
T: GlUniformScalar,
|
||||||
{
|
{
|
||||||
fn bind_uniform(value: T, location: UniformLocation<GLint>) -> Option<()> {
|
fn bind_uniform(value: T, location: UniformLocation<GLint>) -> Option<()> {
|
||||||
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
|
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub enum FilterChainError {
|
||||||
#[error("shader reflect error")]
|
#[error("shader reflect error")]
|
||||||
ShaderReflectError(#[from] ShaderReflectError),
|
ShaderReflectError(#[from] ShaderReflectError),
|
||||||
#[error("lut loading error")]
|
#[error("lut loading error")]
|
||||||
LutLoadError(#[from] ImageError)
|
LutLoadError(#[from] ImageError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, FilterChainError>;
|
pub type Result<T> = std::result::Result<T, FilterChainError>;
|
|
@ -1,31 +1,34 @@
|
||||||
use crate::binding::{UniformLocation, VariableLocation};
|
use crate::binding::{UniformLocation, VariableLocation};
|
||||||
|
use crate::error::{FilterChainError, Result};
|
||||||
use crate::filter_pass::FilterPass;
|
use crate::filter_pass::FilterPass;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use crate::util::{gl_get_version, gl_u16_to_version, InlineRingBuffer};
|
use crate::util::{gl_get_version, gl_u16_to_version};
|
||||||
use crate::error::{FilterChainError, Result};
|
|
||||||
|
|
||||||
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
use gl::types::{GLint, GLuint};
|
||||||
use librashader_common::image::Image;
|
|
||||||
use librashader_common::{FilterMode, Size, WrapMode};
|
use crate::binding::BufferStorage;
|
||||||
|
use crate::gl::{DrawQuad, Framebuffer, GLInterface, LoadLut, UboRing};
|
||||||
|
use crate::options::{FilterChainOptions, FrameOptions};
|
||||||
|
use crate::samplers::SamplerSet;
|
||||||
|
use crate::texture::Texture;
|
||||||
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
|
||||||
use librashader_reflect::back::cross::{GlslangGlslContext, GlVersion};
|
use librashader_reflect::back::cross::{GlVersion, GlslangGlslContext};
|
||||||
use librashader_reflect::back::targets::GLSL;
|
use librashader_reflect::back::targets::GLSL;
|
||||||
use librashader_reflect::reflect::semantics::{MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta, UniformSemantic, VariableSemantics};
|
use librashader_reflect::back::{CompileShader, CompilerBackend, FromCompilation};
|
||||||
|
use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
|
use librashader_reflect::reflect::semantics::{
|
||||||
|
MemberOffset, ReflectSemantics, SemanticMap, TextureSemantics, UniformBinding, UniformMeta,
|
||||||
|
UniformSemantic, VariableSemantics,
|
||||||
|
};
|
||||||
use librashader_reflect::reflect::ReflectShader;
|
use librashader_reflect::reflect::ReflectShader;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use spirv_cross::spirv::Decoration;
|
use spirv_cross::spirv::Decoration;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use librashader_reflect::back::{CompilerBackend, CompileShader, FromCompilation};
|
|
||||||
use librashader_reflect::front::shaderc::GlslangCompilation;
|
|
||||||
use crate::options::{FilterChainOptions, FrameOptions};
|
|
||||||
use crate::samplers::SamplerSet;
|
|
||||||
use crate::texture::Texture;
|
|
||||||
use crate::binding::BufferStorage;
|
|
||||||
use crate::gl::{DrawQuad, Framebuffer, GLInterface, LoadLut, UboRing};
|
|
||||||
|
|
||||||
pub struct FilterChain<T: GLInterface> {
|
pub struct FilterChain<T: GLInterface> {
|
||||||
passes: Box<[FilterPass<T>]>,
|
passes: Box<[FilterPass<T>]>,
|
||||||
|
@ -48,7 +51,7 @@ pub struct FilterCommon {
|
||||||
|
|
||||||
pub struct FilterMutable {
|
pub struct FilterMutable {
|
||||||
pub(crate) passes_enabled: usize,
|
pub(crate) passes_enabled: usize,
|
||||||
pub(crate) parameters: FxHashMap<String, f32>
|
pub(crate) parameters: FxHashMap<String, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChain<T> {
|
impl<T: GLInterface> FilterChain<T> {
|
||||||
|
@ -90,11 +93,15 @@ type ShaderPassMeta = (
|
||||||
|
|
||||||
impl<T: GLInterface> FilterChain<T> {
|
impl<T: GLInterface> FilterChain<T> {
|
||||||
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
/// Load a filter chain from a pre-parsed `ShaderPreset`.
|
||||||
pub fn load_from_preset(preset: ShaderPreset, options: Option<&FilterChainOptions>) -> Result<Self> {
|
pub fn load_from_preset(
|
||||||
|
preset: ShaderPreset,
|
||||||
|
options: Option<&FilterChainOptions>,
|
||||||
|
) -> Result<Self> {
|
||||||
let (passes, semantics) = Self::load_preset(preset.shaders, &preset.textures)?;
|
let (passes, semantics) = Self::load_preset(preset.shaders, &preset.textures)?;
|
||||||
|
|
||||||
let version = options.map(|o| gl_u16_to_version(o.gl_version))
|
let version = options
|
||||||
.unwrap_or_else(|| gl_get_version());
|
.map(|o| gl_u16_to_version(o.gl_version))
|
||||||
|
.unwrap_or_else(gl_get_version);
|
||||||
|
|
||||||
// initialize passes
|
// initialize passes
|
||||||
let filters = Self::init_passes(version, passes, &semantics)?;
|
let filters = Self::init_passes(version, passes, &semantics)?;
|
||||||
|
@ -137,8 +144,11 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
common: FilterCommon {
|
common: FilterCommon {
|
||||||
config: FilterMutable {
|
config: FilterMutable {
|
||||||
passes_enabled: preset.shader_count as usize,
|
passes_enabled: preset.shader_count as usize,
|
||||||
parameters: preset.parameters.into_iter()
|
parameters: preset
|
||||||
.map(|param| (param.name, param.value)).collect(),
|
.parameters
|
||||||
|
.into_iter()
|
||||||
|
.map(|param| (param.name, param.value))
|
||||||
|
.collect(),
|
||||||
},
|
},
|
||||||
luts,
|
luts,
|
||||||
samplers,
|
samplers,
|
||||||
|
@ -150,7 +160,10 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the shader preset at the given path into a filter chain.
|
/// Load the shader preset at the given path into a filter chain.
|
||||||
pub fn load_from_path(path: impl AsRef<Path>, options: Option<&FilterChainOptions>) -> Result<Self> {
|
pub fn load_from_path(
|
||||||
|
path: impl AsRef<Path>,
|
||||||
|
options: Option<&FilterChainOptions>,
|
||||||
|
) -> Result<Self> {
|
||||||
// load passes from preset
|
// load passes from preset
|
||||||
let preset = ShaderPreset::try_parse(path)?;
|
let preset = ShaderPreset::try_parse(path)?;
|
||||||
Self::load_from_preset(preset, options)
|
Self::load_from_preset(preset, options)
|
||||||
|
@ -158,7 +171,7 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
|
|
||||||
fn load_preset(
|
fn load_preset(
|
||||||
passes: Vec<ShaderPassConfig>,
|
passes: Vec<ShaderPassConfig>,
|
||||||
textures: &[TextureConfig]
|
textures: &[TextureConfig],
|
||||||
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
|
||||||
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
|
||||||
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
|
||||||
|
@ -195,9 +208,11 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
librashader_runtime::semantics::insert_lut_semantics(textures,
|
librashader_runtime::semantics::insert_lut_semantics(
|
||||||
|
textures,
|
||||||
&mut uniform_semantics,
|
&mut uniform_semantics,
|
||||||
&mut texture_semantics);
|
&mut texture_semantics,
|
||||||
|
);
|
||||||
|
|
||||||
let semantics = ReflectSemantics {
|
let semantics = ReflectSemantics {
|
||||||
uniform_semantics,
|
uniform_semantics,
|
||||||
|
@ -254,8 +269,7 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
gl::UseProgram(program);
|
gl::UseProgram(program);
|
||||||
|
|
||||||
for (name, binding) in &glsl.context.sampler_bindings {
|
for (name, binding) in &glsl.context.sampler_bindings {
|
||||||
let location =
|
let location = gl::GetUniformLocation(program, name.as_str().as_ptr().cast());
|
||||||
gl::GetUniformLocation(program, name.as_str().as_ptr().cast());
|
|
||||||
if location >= 0 {
|
if location >= 0 {
|
||||||
// eprintln!("setting sampler {location} to sample from {binding}");
|
// eprintln!("setting sampler {location} to sample from {binding}");
|
||||||
gl::Uniform1i(location, *binding as GLint);
|
gl::Uniform1i(location, *binding as GLint);
|
||||||
|
@ -285,7 +299,8 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let uniform_storage = BufferStorage::new(reflection
|
let uniform_storage = BufferStorage::new(
|
||||||
|
reflection
|
||||||
.ubo
|
.ubo
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ubo| ubo.size as usize)
|
.map(|ubo| ubo.size as usize)
|
||||||
|
@ -294,38 +309,28 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
.push_constant
|
.push_constant
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|push| push.size as usize)
|
.map(|push| push.size as usize)
|
||||||
.unwrap_or(0)
|
.unwrap_or(0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
let mut uniform_bindings = FxHashMap::default();
|
let mut uniform_bindings = FxHashMap::default();
|
||||||
for param in reflection.meta.parameter_meta.values() {
|
for param in reflection.meta.parameter_meta.values() {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(
|
||||||
UniformBinding::Parameter(param.id.clone()),
|
UniformBinding::Parameter(param.id.clone()),
|
||||||
(
|
(Self::reflect_uniform_location(program, param), param.offset),
|
||||||
Self::reflect_uniform_location(program, param),
|
|
||||||
param.offset,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (semantics, param) in &reflection.meta.variable_meta {
|
for (semantics, param) in &reflection.meta.variable_meta {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(
|
||||||
UniformBinding::SemanticVariable(*semantics),
|
UniformBinding::SemanticVariable(*semantics),
|
||||||
(
|
(Self::reflect_uniform_location(program, param), param.offset),
|
||||||
Self::reflect_uniform_location(program, param),
|
|
||||||
param.offset,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (semantics, param) in &reflection.meta.texture_size_meta {
|
for (semantics, param) in &reflection.meta.texture_size_meta {
|
||||||
uniform_bindings.insert(
|
uniform_bindings.insert(
|
||||||
UniformBinding::TextureSize(*semantics),
|
UniformBinding::TextureSize(*semantics),
|
||||||
(
|
(Self::reflect_uniform_location(program, param), param.offset),
|
||||||
Self::reflect_uniform_location(program, param),
|
|
||||||
param.offset,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +352,7 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
uniform_storage,
|
uniform_storage,
|
||||||
uniform_bindings,
|
uniform_bindings,
|
||||||
source,
|
source,
|
||||||
config
|
config,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +428,13 @@ impl <T: GLInterface> FilterChain<T> {
|
||||||
/// Process a frame with the input image.
|
/// Process a frame with the input image.
|
||||||
///
|
///
|
||||||
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
/// When this frame returns, GL_FRAMEBUFFER is bound to 0.
|
||||||
pub fn frame(&mut self, count: usize, viewport: &Viewport<T::Framebuffer>, input: &GLImage, options: Option<&FrameOptions>) -> Result<()> {
|
pub fn frame(
|
||||||
|
&mut self,
|
||||||
|
count: usize,
|
||||||
|
viewport: &Viewport<T::Framebuffer>,
|
||||||
|
input: &GLImage,
|
||||||
|
options: Option<&FrameOptions>,
|
||||||
|
) -> Result<()> {
|
||||||
// limit number of passes to those enabled.
|
// limit number of passes to those enabled.
|
||||||
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
let passes = &mut self.passes[0..self.common.config.passes_enabled];
|
||||||
if let Some(options) = options {
|
if let Some(options) = options {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::marker::PhantomData;
|
use gl::types::{GLsizei, GLuint};
|
||||||
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
|
||||||
use librashader_reflect::back::cross::GlslangGlslContext;
|
use librashader_reflect::back::cross::GlslangGlslContext;
|
||||||
use librashader_reflect::back::ShaderCompilerOutput;
|
use librashader_reflect::back::ShaderCompilerOutput;
|
||||||
use librashader_reflect::reflect::ShaderReflection;
|
use librashader_reflect::reflect::ShaderReflection;
|
||||||
|
@ -7,19 +6,18 @@ use librashader_reflect::reflect::ShaderReflection;
|
||||||
use librashader_common::{ImageFormat, Size};
|
use librashader_common::{ImageFormat, Size};
|
||||||
use librashader_preprocess::ShaderSource;
|
use librashader_preprocess::ShaderSource;
|
||||||
use librashader_presets::ShaderPassConfig;
|
use librashader_presets::ShaderPassConfig;
|
||||||
use librashader_reflect::reflect::semantics::{BindingStage, MemberOffset, TextureBinding, TextureSemantics, UniformBinding, VariableSemantics};
|
use librashader_reflect::reflect::semantics::{
|
||||||
|
MemberOffset, TextureSemantics, UniformBinding, VariableSemantics,
|
||||||
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use librashader_runtime::uniforms::UniformStorage;
|
|
||||||
|
|
||||||
use crate::binding::{BufferStorage, GlUniformBinder, UniformLocation, VariableLocation};
|
use crate::binding::{BufferStorage, UniformLocation, VariableLocation};
|
||||||
use crate::filter_chain::FilterCommon;
|
use crate::filter_chain::FilterCommon;
|
||||||
use crate::framebuffer::Viewport;
|
use crate::framebuffer::Viewport;
|
||||||
use crate::gl::{BindTexture, Framebuffer, GLInterface, UboRing};
|
use crate::gl::{BindTexture, Framebuffer, GLInterface, UboRing};
|
||||||
use crate::render_target::RenderTarget;
|
use crate::render_target::RenderTarget;
|
||||||
use crate::samplers::SamplerSet;
|
|
||||||
use crate::texture::Texture;
|
|
||||||
use crate::util::{InlineRingBuffer, RingBuffer};
|
|
||||||
|
|
||||||
|
use crate::texture::Texture;
|
||||||
|
|
||||||
pub struct FilterPass<T: GLInterface> {
|
pub struct FilterPass<T: GLInterface> {
|
||||||
pub reflection: ShaderReflection,
|
pub reflection: ShaderReflection,
|
||||||
|
@ -44,7 +42,7 @@ impl<T:GLInterface> FilterPass<T> {
|
||||||
viewport: &Viewport<T::Framebuffer>,
|
viewport: &Viewport<T::Framebuffer>,
|
||||||
original: &Texture,
|
original: &Texture,
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
output: RenderTarget<T::Framebuffer>
|
output: RenderTarget<T::Framebuffer>,
|
||||||
) {
|
) {
|
||||||
let framebuffer = output.framebuffer;
|
let framebuffer = output.framebuffer;
|
||||||
|
|
||||||
|
@ -102,7 +100,6 @@ impl<T:GLInterface> FilterPass<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<T: GLInterface> FilterPass<T> {
|
impl<T: GLInterface> FilterPass<T> {
|
||||||
pub fn get_format(&self) -> ImageFormat {
|
pub fn get_format(&self) -> ImageFormat {
|
||||||
let mut fb_format = ImageFormat::R8G8B8A8Unorm;
|
let mut fb_format = ImageFormat::R8G8B8A8Unorm;
|
||||||
|
@ -117,7 +114,7 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
// framecount should be pre-modded
|
// framecount should be pre-modded
|
||||||
fn build_semantics(
|
fn build_semantics(
|
||||||
&mut self,
|
&mut self,
|
||||||
pass_index: usize,
|
_pass_index: usize,
|
||||||
parent: &FilterCommon,
|
parent: &FilterCommon,
|
||||||
mvp: &[f32; 16],
|
mvp: &[f32; 16],
|
||||||
frame_count: u32,
|
frame_count: u32,
|
||||||
|
@ -128,18 +125,18 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
source: &Texture,
|
source: &Texture,
|
||||||
) {
|
) {
|
||||||
// Bind MVP
|
// Bind MVP
|
||||||
if let Some((location, offset)) =
|
if let Some((location, offset)) = self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
||||||
self.uniform_bindings.get(&VariableSemantics::MVP.into())
|
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_mat4(*offset, mvp, location.location());
|
self.uniform_storage
|
||||||
|
.bind_mat4(*offset, mvp, location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind OutputSize
|
// bind OutputSize
|
||||||
if let Some((location, offset)) = self
|
if let Some((location, offset)) =
|
||||||
.uniform_bindings
|
self.uniform_bindings.get(&VariableSemantics::Output.into())
|
||||||
.get(&VariableSemantics::Output.into())
|
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset, fb_size, location.location());
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, fb_size, location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind FinalViewportSize
|
// bind FinalViewportSize
|
||||||
|
@ -147,7 +144,8 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&VariableSemantics::FinalViewport.into())
|
.get(&VariableSemantics::FinalViewport.into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset,viewport.output.size(), location.location());
|
self.uniform_storage
|
||||||
|
.bind_vec4(*offset, viewport.output.size(), location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind FrameCount
|
// bind FrameCount
|
||||||
|
@ -155,7 +153,8 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&VariableSemantics::FrameCount.into())
|
.get(&VariableSemantics::FrameCount.into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_scalar(*offset, frame_count, location.location());
|
self.uniform_storage
|
||||||
|
.bind_scalar(*offset, frame_count, location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind FrameDirection
|
// bind FrameDirection
|
||||||
|
@ -163,7 +162,8 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&VariableSemantics::FrameDirection.into())
|
.get(&VariableSemantics::FrameDirection.into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_scalar(*offset, frame_direction, location.location());
|
self.uniform_storage
|
||||||
|
.bind_scalar(*offset, frame_direction, location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind Original sampler
|
// bind Original sampler
|
||||||
|
@ -201,8 +201,8 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
.uniform_bindings
|
.uniform_bindings
|
||||||
.get(&TextureSemantics::Source.semantics(0).into())
|
.get(&TextureSemantics::Source.semantics(0).into())
|
||||||
{
|
{
|
||||||
self.uniform_storage.bind_vec4(*offset,
|
self.uniform_storage
|
||||||
source.image.size, location.location());
|
.bind_vec4(*offset, source.image.size, location.location());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(binding) = self
|
if let Some(binding) = self
|
||||||
|
@ -309,11 +309,7 @@ impl <T: GLInterface> FilterPass<T> {
|
||||||
.map(|f| f.initial)
|
.map(|f| f.initial)
|
||||||
.unwrap_or(0f32);
|
.unwrap_or(0f32);
|
||||||
|
|
||||||
let value = *parent
|
let value = *parent.config.parameters.get(id).unwrap_or(&default);
|
||||||
.config
|
|
||||||
.parameters
|
|
||||||
.get(id)
|
|
||||||
.unwrap_or(&default);
|
|
||||||
|
|
||||||
self.uniform_storage
|
self.uniform_storage
|
||||||
.bind_scalar(*offset, value, location.location());
|
.bind_scalar(*offset, value, location.location());
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
use crate::util;
|
use gl::types::{GLenum, GLuint};
|
||||||
use crate::texture::Texture;
|
use librashader_common::Size;
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
|
||||||
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
|
||||||
use crate::error::FilterChainError;
|
|
||||||
use crate::error::Result;
|
|
||||||
use crate::gl::Framebuffer;
|
use crate::gl::Framebuffer;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
|
||||||
use crate::gl::DrawQuad;
|
use crate::gl::DrawQuad;
|
||||||
|
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static QUAD_VBO_DATA: &[f32; 16] = &[
|
static QUAD_VBO_DATA: &[f32; 16] = &[
|
||||||
|
@ -74,4 +74,3 @@ impl DrawQuad for Gl3DrawQuad {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
use crate::error::{FilterChainError, Result};
|
||||||
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
|
use crate::gl::Framebuffer;
|
||||||
|
use crate::texture::Texture;
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_presets::Scale2D;
|
use librashader_presets::Scale2D;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
|
||||||
use crate::error::{FilterChainError, Result};
|
|
||||||
use crate::gl::Framebuffer;
|
|
||||||
use crate::texture::Texture;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Gl3Framebuffer {
|
pub struct Gl3Framebuffer {
|
||||||
|
@ -97,7 +97,8 @@ impl Framebuffer for Gl3Framebuffer {
|
||||||
return Ok(self.size);
|
return Ok(self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = librashader_runtime::scaling::scale(scaling, source.image.size, viewport.output.size);
|
let size =
|
||||||
|
librashader_runtime::scaling::scale(scaling, source.image.size, viewport.output.size);
|
||||||
|
|
||||||
if self.size != size {
|
if self.size != size {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
@ -294,7 +295,7 @@ impl Framebuffer for Gl3Framebuffer {
|
||||||
// self.init =
|
// self.init =
|
||||||
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
||||||
}
|
}
|
||||||
_ => return Err(FilterChainError::FramebufferInit(status))
|
_ => return Err(FilterChainError::FramebufferInit(status)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ use librashader_common::Size;
|
||||||
|
|
||||||
use crate::filter_chain::FilterChain;
|
use crate::filter_chain::FilterChain;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
use crate::gl::{Framebuffer, GLInterface};
|
|
||||||
use crate::gl::gl3::CompatibilityGL;
|
use crate::gl::gl3::CompatibilityGL;
|
||||||
|
use crate::gl::{Framebuffer, GLInterface};
|
||||||
|
|
||||||
const WIDTH: u32 = 900;
|
const WIDTH: u32 = 900;
|
||||||
const HEIGHT: u32 = 700;
|
const HEIGHT: u32 = 700;
|
||||||
|
@ -519,7 +519,8 @@ void main()
|
||||||
padded_size: Default::default(),
|
padded_size: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
filter.frame(framecount, &viewport, &rendered, None)
|
filter
|
||||||
|
.frame(framecount, &viewport, &rendered, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
use crate::error::Result;
|
||||||
|
use crate::framebuffer::GLImage;
|
||||||
|
use crate::gl::LoadLut;
|
||||||
|
use crate::texture::Texture;
|
||||||
use gl::types::{GLsizei, GLuint};
|
use gl::types::{GLsizei, GLuint};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
use librashader_presets::TextureConfig;
|
use librashader_presets::TextureConfig;
|
||||||
use crate::gl::LoadLut;
|
use rustc_hash::FxHashMap;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
|
||||||
use crate::texture::Texture;
|
|
||||||
use crate::error::Result;
|
|
||||||
|
|
||||||
pub struct Gl3LutLoad;
|
pub struct Gl3LutLoad;
|
||||||
impl LoadLut for Gl3LutLoad {
|
impl LoadLut for Gl3LutLoad {
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
mod lut_load;
|
|
||||||
mod draw_quad;
|
mod draw_quad;
|
||||||
mod ubo_ring;
|
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
mod texture_bind;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod hello_triangle;
|
pub mod hello_triangle;
|
||||||
|
mod lut_load;
|
||||||
|
mod texture_bind;
|
||||||
|
mod ubo_ring;
|
||||||
|
|
||||||
use lut_load::*;
|
|
||||||
use draw_quad::*;
|
|
||||||
use ubo_ring::*;
|
|
||||||
use framebuffer::*;
|
|
||||||
use texture_bind::*;
|
|
||||||
use crate::gl::GLInterface;
|
use crate::gl::GLInterface;
|
||||||
|
use draw_quad::*;
|
||||||
|
use framebuffer::*;
|
||||||
|
use lut_load::*;
|
||||||
|
use texture_bind::*;
|
||||||
|
use ubo_ring::*;
|
||||||
|
|
||||||
pub struct CompatibilityGL;
|
pub struct CompatibilityGL;
|
||||||
impl GLInterface for CompatibilityGL {
|
impl GLInterface for CompatibilityGL {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use librashader_reflect::reflect::semantics::TextureBinding;
|
|
||||||
use crate::gl::BindTexture;
|
use crate::gl::BindTexture;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::texture::Texture;
|
use crate::texture::Texture;
|
||||||
|
use librashader_reflect::reflect::semantics::TextureBinding;
|
||||||
|
|
||||||
pub struct Gl3BindTexture;
|
pub struct Gl3BindTexture;
|
||||||
|
|
||||||
|
@ -12,8 +12,10 @@ impl BindTexture for Gl3BindTexture {
|
||||||
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
||||||
|
|
||||||
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
|
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
|
||||||
gl::BindSampler(binding.binding,
|
gl::BindSampler(
|
||||||
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
|
binding.binding,
|
||||||
|
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
|
||||||
use librashader_reflect::reflect::semantics::UboReflection;
|
|
||||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
|
||||||
use crate::binding::UniformLocation;
|
use crate::binding::UniformLocation;
|
||||||
use crate::gl::UboRing;
|
use crate::gl::UboRing;
|
||||||
use crate::util::{InlineRingBuffer, RingBuffer};
|
use crate::util::{InlineRingBuffer, RingBuffer};
|
||||||
|
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
||||||
|
use librashader_reflect::reflect::semantics::UboReflection;
|
||||||
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
|
|
||||||
pub struct Gl3UboRing<const SIZE: usize> {
|
pub struct Gl3UboRing<const SIZE: usize> {
|
||||||
ring: InlineRingBuffer<GLuint, SIZE>
|
ring: InlineRingBuffer<GLuint, SIZE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
|
impl<const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
|
||||||
fn new(buffer_size: u32) -> Self {
|
fn new(buffer_size: u32) -> Self {
|
||||||
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
|
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
|
||||||
|
@ -26,12 +25,15 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
|
||||||
}
|
}
|
||||||
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
Gl3UboRing {
|
Gl3UboRing { ring }
|
||||||
ring
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_for_frame(&mut self, ubo: &UboReflection, ubo_location: &UniformLocation<GLuint>, storage: &impl UniformStorageAccess) {
|
fn bind_for_frame(
|
||||||
|
&mut self,
|
||||||
|
ubo: &UboReflection,
|
||||||
|
ubo_location: &UniformLocation<GLuint>,
|
||||||
|
storage: &impl UniformStorageAccess,
|
||||||
|
) {
|
||||||
let size = ubo.size;
|
let size = ubo.size;
|
||||||
let buffer = self.ring.current();
|
let buffer = self.ring.current();
|
||||||
|
|
||||||
|
@ -55,5 +57,3 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
|
||||||
self.ring.next()
|
self.ring.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
|
|
||||||
use crate::gl::DrawQuad;
|
use crate::gl::DrawQuad;
|
||||||
|
use gl::types::{GLint, GLsizeiptr, GLuint};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
static QUAD_VBO_DATA: &[f32; 16] = &[
|
static QUAD_VBO_DATA: &[f32; 16] = &[
|
||||||
|
@ -32,19 +32,20 @@ impl DrawQuad for Gl46DrawQuad {
|
||||||
gl::EnableVertexArrayAttrib(vao, 0);
|
gl::EnableVertexArrayAttrib(vao, 0);
|
||||||
gl::EnableVertexArrayAttrib(vao, 1);
|
gl::EnableVertexArrayAttrib(vao, 1);
|
||||||
|
|
||||||
gl::VertexArrayVertexBuffer(vao, 0,
|
gl::VertexArrayVertexBuffer(vao, 0, vbo, 0, 4 * std::mem::size_of::<f32>() as GLint);
|
||||||
vbo, 0, 4 * std::mem::size_of::<f32>() as GLint
|
|
||||||
);
|
|
||||||
|
|
||||||
gl::VertexArrayAttribFormat(vao, 0, 2,
|
gl::VertexArrayAttribFormat(vao, 0, 2, gl::FLOAT, gl::FALSE, 0);
|
||||||
gl::FLOAT, gl::FALSE, 0);
|
gl::VertexArrayAttribFormat(
|
||||||
gl::VertexArrayAttribFormat(vao, 1, 2,
|
vao,
|
||||||
gl::FLOAT, gl::FALSE,
|
1,
|
||||||
2 * std::mem::size_of::<f32>() as GLuint);
|
2,
|
||||||
|
gl::FLOAT,
|
||||||
|
gl::FALSE,
|
||||||
|
2 * std::mem::size_of::<f32>() as GLuint,
|
||||||
|
);
|
||||||
|
|
||||||
gl::VertexArrayAttribBinding(vao, 0, 0);
|
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||||
gl::VertexArrayAttribBinding(vao, 1, 0);
|
gl::VertexArrayAttribBinding(vao, 1, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self { vbo, vao }
|
Self { vbo, vao }
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
use crate::error::{FilterChainError, Result};
|
||||||
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
|
use crate::gl::Framebuffer;
|
||||||
|
use crate::texture::Texture;
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_presets::Scale2D;
|
use librashader_presets::Scale2D;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
|
||||||
use crate::error::{FilterChainError, Result};
|
|
||||||
use crate::gl::Framebuffer;
|
|
||||||
use crate::texture::Texture;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Gl46Framebuffer {
|
pub struct Gl46Framebuffer {
|
||||||
|
@ -17,7 +17,6 @@ pub struct Gl46Framebuffer {
|
||||||
is_raw: bool,
|
is_raw: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Framebuffer for Gl46Framebuffer {
|
impl Framebuffer for Gl46Framebuffer {
|
||||||
fn handle(&self) -> GLuint {
|
fn handle(&self) -> GLuint {
|
||||||
self.handle
|
self.handle
|
||||||
|
@ -96,7 +95,8 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
return Ok(self.size);
|
return Ok(self.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = librashader_runtime::scaling::scale(scaling, source.image.size, viewport.output.size);
|
let size =
|
||||||
|
librashader_runtime::scaling::scale(scaling, source.image.size, viewport.output.size);
|
||||||
|
|
||||||
if self.size != size {
|
if self.size != size {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
@ -114,9 +114,12 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
}
|
}
|
||||||
fn clear<const REBIND: bool>(&self) {
|
fn clear<const REBIND: bool>(&self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::ClearNamedFramebufferfv(self.handle,
|
gl::ClearNamedFramebufferfv(
|
||||||
gl::COLOR, 0,
|
self.handle,
|
||||||
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast());
|
gl::COLOR,
|
||||||
|
0,
|
||||||
|
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn copy_from(&mut self, image: &GLImage) -> Result<()> {
|
fn copy_from(&mut self, image: &GLImage) -> Result<()> {
|
||||||
|
@ -130,11 +133,20 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
|
||||||
gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
|
||||||
|
|
||||||
gl::BlitNamedFramebuffer(image.handle, self.handle,
|
gl::BlitNamedFramebuffer(
|
||||||
0, 0, image.size.width as GLint, image.size.height as GLint,
|
image.handle,
|
||||||
0, 0, self.size.width as GLint, self.size.height as GLint,
|
self.handle,
|
||||||
gl::COLOR_BUFFER_BIT, gl::NEAREST);
|
0,
|
||||||
|
0,
|
||||||
|
image.size.width as GLint,
|
||||||
|
image.size.height as GLint,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
self.size.width as GLint,
|
||||||
|
self.size.height as GLint,
|
||||||
|
gl::COLOR_BUFFER_BIT,
|
||||||
|
gl::NEAREST,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -149,12 +161,7 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
unsafe {
|
unsafe {
|
||||||
// reset the framebuffer image
|
// reset the framebuffer image
|
||||||
if self.image != 0 {
|
if self.image != 0 {
|
||||||
gl::NamedFramebufferTexture(
|
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, 0, 0);
|
||||||
self.handle,
|
|
||||||
gl::COLOR_ATTACHMENT0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
gl::DeleteTextures(1, &self.image);
|
gl::DeleteTextures(1, &self.image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,12 +190,7 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
size.height as GLsizei,
|
size.height as GLsizei,
|
||||||
);
|
);
|
||||||
|
|
||||||
gl::NamedFramebufferTexture(
|
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, self.image, 0);
|
||||||
self.handle,
|
|
||||||
gl::COLOR_ATTACHMENT0,
|
|
||||||
self.image,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER);
|
let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER);
|
||||||
if status != gl::FRAMEBUFFER_COMPLETE {
|
if status != gl::FRAMEBUFFER_COMPLETE {
|
||||||
|
@ -196,12 +198,7 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
gl::FRAMEBUFFER_UNSUPPORTED => {
|
gl::FRAMEBUFFER_UNSUPPORTED => {
|
||||||
eprintln!("unsupported fbo");
|
eprintln!("unsupported fbo");
|
||||||
|
|
||||||
gl::NamedFramebufferTexture(
|
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, 0, 0);
|
||||||
self.handle,
|
|
||||||
gl::COLOR_ATTACHMENT0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
gl::DeleteTextures(1, &self.image);
|
gl::DeleteTextures(1, &self.image);
|
||||||
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
|
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
|
||||||
|
|
||||||
|
@ -229,7 +226,7 @@ impl Framebuffer for Gl46Framebuffer {
|
||||||
// self.init =
|
// self.init =
|
||||||
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
||||||
}
|
}
|
||||||
_ => return Err(FilterChainError::FramebufferInit(status))
|
_ => return Err(FilterChainError::FramebufferInit(status)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ use librashader_common::Size;
|
||||||
|
|
||||||
use crate::filter_chain::FilterChain;
|
use crate::filter_chain::FilterChain;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
use crate::gl::{Framebuffer, GLInterface};
|
|
||||||
use crate::gl::gl46::DirectStateAccessGL;
|
use crate::gl::gl46::DirectStateAccessGL;
|
||||||
|
use crate::gl::{Framebuffer, GLInterface};
|
||||||
|
|
||||||
const WIDTH: u32 = 900;
|
const WIDTH: u32 = 900;
|
||||||
const HEIGHT: u32 = 700;
|
const HEIGHT: u32 = 700;
|
||||||
|
@ -216,20 +216,20 @@ void main()
|
||||||
gl::CreateVertexArrays(1, &mut vao);
|
gl::CreateVertexArrays(1, &mut vao);
|
||||||
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
||||||
|
|
||||||
gl::VertexArrayVertexBuffer(vao, 0,
|
gl::VertexArrayVertexBuffer(vao, 0, vbo, 0, 6 * std::mem::size_of::<f32>() as GLint);
|
||||||
vbo, 0, 6 * std::mem::size_of::<f32>() as GLint
|
|
||||||
);
|
|
||||||
|
|
||||||
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
|
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
|
||||||
gl::VertexArrayAttribFormat(vao, 0, 3,
|
gl::VertexArrayAttribFormat(vao, 0, 3, gl::FLOAT, gl::FALSE, 0);
|
||||||
gl::FLOAT, gl::FALSE, 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gl::EnableVertexArrayAttrib(vao, 1);
|
gl::EnableVertexArrayAttrib(vao, 1);
|
||||||
gl::VertexArrayAttribFormat(vao, 1, 3,
|
gl::VertexArrayAttribFormat(
|
||||||
gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::<f32>() as GLuint);
|
vao,
|
||||||
|
1,
|
||||||
|
3,
|
||||||
|
gl::FLOAT,
|
||||||
|
gl::FALSE,
|
||||||
|
3 * std::mem::size_of::<f32>() as GLuint,
|
||||||
|
);
|
||||||
|
|
||||||
gl::VertexArrayAttribBinding(vao, 0, 0);
|
gl::VertexArrayAttribBinding(vao, 0, 0);
|
||||||
gl::VertexArrayAttribBinding(vao, 1, 0);
|
gl::VertexArrayAttribBinding(vao, 1, 0);
|
||||||
|
@ -299,8 +299,16 @@ pub fn do_loop(
|
||||||
HEIGHT as GLsizei,
|
HEIGHT as GLsizei,
|
||||||
);
|
);
|
||||||
|
|
||||||
gl::TextureParameteri(rendered_texture, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
|
gl::TextureParameteri(
|
||||||
gl::TextureParameteri(rendered_texture, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
|
rendered_texture,
|
||||||
|
gl::TEXTURE_MAG_FILTER,
|
||||||
|
gl::NEAREST as GLint,
|
||||||
|
);
|
||||||
|
gl::TextureParameteri(
|
||||||
|
rendered_texture,
|
||||||
|
gl::TEXTURE_MIN_FILTER,
|
||||||
|
gl::NEAREST as GLint,
|
||||||
|
);
|
||||||
gl::TextureParameteri(
|
gl::TextureParameteri(
|
||||||
rendered_texture,
|
rendered_texture,
|
||||||
gl::TEXTURE_WRAP_S,
|
gl::TEXTURE_WRAP_S,
|
||||||
|
@ -464,7 +472,12 @@ void main()
|
||||||
unsafe {
|
unsafe {
|
||||||
// render to fb
|
// render to fb
|
||||||
|
|
||||||
gl::ClearNamedFramebufferfv(rendered_framebuffer, gl::COLOR, 0, [0.3f32, 0.4, 0.6, 1.0].as_ptr().cast());
|
gl::ClearNamedFramebufferfv(
|
||||||
|
rendered_framebuffer,
|
||||||
|
gl::COLOR,
|
||||||
|
0,
|
||||||
|
[0.3f32, 0.4, 0.6, 1.0].as_ptr().cast(),
|
||||||
|
);
|
||||||
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
||||||
gl::Viewport(0, 0, vp_width, vp_height);
|
gl::Viewport(0, 0, vp_width, vp_height);
|
||||||
|
|
||||||
|
@ -500,7 +513,8 @@ void main()
|
||||||
padded_size: Default::default(),
|
padded_size: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
filter.frame(framecount, &viewport, &rendered, None)
|
filter
|
||||||
|
.frame(framecount, &viewport, &rendered, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
|
use crate::error::Result;
|
||||||
|
use crate::framebuffer::GLImage;
|
||||||
|
use crate::gl::LoadLut;
|
||||||
|
use crate::texture::Texture;
|
||||||
use gl::types::{GLsizei, GLuint};
|
use gl::types::{GLsizei, GLuint};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use librashader_common::image::Image;
|
use librashader_common::image::Image;
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
use librashader_presets::TextureConfig;
|
use librashader_presets::TextureConfig;
|
||||||
use crate::gl::LoadLut;
|
use rustc_hash::FxHashMap;
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
|
||||||
use crate::texture::Texture;
|
|
||||||
use crate::error::Result;
|
|
||||||
|
|
||||||
pub struct Gl46LutLoad;
|
pub struct Gl46LutLoad;
|
||||||
impl LoadLut for Gl46LutLoad {
|
impl LoadLut for Gl46LutLoad {
|
||||||
|
@ -47,7 +47,9 @@ impl LoadLut for Gl46LutLoad {
|
||||||
|
|
||||||
gl::TextureSubImage2D(
|
gl::TextureSubImage2D(
|
||||||
handle,
|
handle,
|
||||||
0, 0, 0,
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
image.size.width as GLsizei,
|
image.size.width as GLsizei,
|
||||||
image.size.height as GLsizei,
|
image.size.height as GLsizei,
|
||||||
gl::RGBA,
|
gl::RGBA,
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
mod lut_load;
|
|
||||||
mod draw_quad;
|
mod draw_quad;
|
||||||
mod ubo_ring;
|
|
||||||
mod framebuffer;
|
mod framebuffer;
|
||||||
|
mod lut_load;
|
||||||
mod texture_bind;
|
mod texture_bind;
|
||||||
|
mod ubo_ring;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod hello_triangle;
|
pub mod hello_triangle;
|
||||||
|
|
||||||
use lut_load::*;
|
|
||||||
use draw_quad::*;
|
|
||||||
use ubo_ring::*;
|
|
||||||
use framebuffer::*;
|
|
||||||
use texture_bind::*;
|
|
||||||
use crate::gl::GLInterface;
|
use crate::gl::GLInterface;
|
||||||
|
use draw_quad::*;
|
||||||
|
use framebuffer::*;
|
||||||
|
use lut_load::*;
|
||||||
|
use texture_bind::*;
|
||||||
|
use ubo_ring::*;
|
||||||
|
|
||||||
pub struct DirectStateAccessGL;
|
pub struct DirectStateAccessGL;
|
||||||
impl GLInterface for DirectStateAccessGL {
|
impl GLInterface for DirectStateAccessGL {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use librashader_reflect::reflect::semantics::TextureBinding;
|
|
||||||
use crate::gl::BindTexture;
|
use crate::gl::BindTexture;
|
||||||
use crate::samplers::SamplerSet;
|
use crate::samplers::SamplerSet;
|
||||||
use crate::texture::Texture;
|
use crate::texture::Texture;
|
||||||
|
use librashader_reflect::reflect::semantics::TextureBinding;
|
||||||
|
|
||||||
pub struct Gl46BindTexture;
|
pub struct Gl46BindTexture;
|
||||||
|
|
||||||
|
@ -10,8 +10,10 @@ impl BindTexture for Gl46BindTexture {
|
||||||
unsafe {
|
unsafe {
|
||||||
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
||||||
gl::BindTextureUnit(binding.binding, texture.image.handle);
|
gl::BindTextureUnit(binding.binding, texture.image.handle);
|
||||||
gl::BindSampler(binding.binding,
|
gl::BindSampler(
|
||||||
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
|
binding.binding,
|
||||||
|
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
|
||||||
use librashader_reflect::reflect::semantics::UboReflection;
|
|
||||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
|
||||||
use crate::binding::UniformLocation;
|
use crate::binding::UniformLocation;
|
||||||
use crate::gl::UboRing;
|
use crate::gl::UboRing;
|
||||||
use crate::util::{InlineRingBuffer, RingBuffer};
|
use crate::util::{InlineRingBuffer, RingBuffer};
|
||||||
|
use gl::types::{GLsizei, GLsizeiptr, GLuint};
|
||||||
|
use librashader_reflect::reflect::semantics::UboReflection;
|
||||||
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
|
|
||||||
pub struct Gl46UboRing<const SIZE: usize> {
|
pub struct Gl46UboRing<const SIZE: usize> {
|
||||||
ring: InlineRingBuffer<GLuint, SIZE>
|
ring: InlineRingBuffer<GLuint, SIZE>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
|
impl<const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
|
||||||
fn new(buffer_size: u32) -> Self {
|
fn new(buffer_size: u32) -> Self {
|
||||||
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
|
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
|
||||||
|
@ -25,22 +24,20 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Gl46UboRing {
|
Gl46UboRing { ring }
|
||||||
ring
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_for_frame(&mut self, ubo: &UboReflection, ubo_location: &UniformLocation<GLuint>, storage: &impl UniformStorageAccess) {
|
fn bind_for_frame(
|
||||||
|
&mut self,
|
||||||
|
ubo: &UboReflection,
|
||||||
|
ubo_location: &UniformLocation<GLuint>,
|
||||||
|
storage: &impl UniformStorageAccess,
|
||||||
|
) {
|
||||||
let size = ubo.size;
|
let size = ubo.size;
|
||||||
let buffer = self.ring.current();
|
let buffer = self.ring.current();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::NamedBufferSubData(
|
gl::NamedBufferSubData(*buffer, 0, size as GLsizeiptr, storage.ubo_pointer().cast());
|
||||||
*buffer,
|
|
||||||
0,
|
|
||||||
size as GLsizeiptr,
|
|
||||||
storage.ubo_pointer().cast(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if ubo_location.vertex != gl::INVALID_INDEX {
|
if ubo_location.vertex != gl::INVALID_INDEX {
|
||||||
gl::BindBufferBase(gl::UNIFORM_BUFFER, ubo_location.vertex, *buffer);
|
gl::BindBufferBase(gl::UNIFORM_BUFFER, ubo_location.vertex, *buffer);
|
||||||
|
@ -52,5 +49,3 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
|
||||||
self.ring.next()
|
self.ring.next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
pub(crate) mod gl3;
|
pub(crate) mod gl3;
|
||||||
pub(crate) mod gl46;
|
pub(crate) mod gl46;
|
||||||
|
|
||||||
use gl::types::{GLenum, GLint, GLsizei, GLuint};
|
use crate::binding::UniformLocation;
|
||||||
use rustc_hash::FxHashMap;
|
use crate::error::Result;
|
||||||
|
use crate::framebuffer::{GLImage, Viewport};
|
||||||
|
use crate::samplers::SamplerSet;
|
||||||
|
use crate::texture::Texture;
|
||||||
|
use gl::types::{GLenum, GLuint};
|
||||||
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
use librashader_presets::{Scale2D, TextureConfig};
|
use librashader_presets::{Scale2D, TextureConfig};
|
||||||
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
|
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
|
||||||
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
|
use librashader_runtime::uniforms::UniformStorageAccess;
|
||||||
use crate::binding::UniformLocation;
|
use rustc_hash::FxHashMap;
|
||||||
use crate::texture::Texture;
|
|
||||||
use crate::error::{FilterChainError, Result};
|
|
||||||
use crate::framebuffer::{GLImage, Viewport};
|
|
||||||
use crate::samplers::SamplerSet;
|
|
||||||
|
|
||||||
pub trait LoadLut {
|
pub trait LoadLut {
|
||||||
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>>;
|
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>>;
|
||||||
|
@ -25,7 +25,12 @@ pub trait DrawQuad {
|
||||||
|
|
||||||
pub trait UboRing<const SIZE: usize> {
|
pub trait UboRing<const SIZE: usize> {
|
||||||
fn new(buffer_size: u32) -> Self;
|
fn new(buffer_size: u32) -> Self;
|
||||||
fn bind_for_frame(&mut self, ubo: &UboReflection, ubo_location: &UniformLocation<GLuint>, storage: &impl UniformStorageAccess);
|
fn bind_for_frame(
|
||||||
|
&mut self,
|
||||||
|
ubo: &UboReflection,
|
||||||
|
ubo_location: &UniformLocation<GLuint>,
|
||||||
|
storage: &impl UniformStorageAccess,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Framebuffer {
|
pub trait Framebuffer {
|
||||||
|
|
|
@ -8,11 +8,10 @@ mod framebuffer;
|
||||||
mod render_target;
|
mod render_target;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
mod gl;
|
||||||
|
pub mod options;
|
||||||
mod samplers;
|
mod samplers;
|
||||||
mod texture;
|
mod texture;
|
||||||
pub mod options;
|
|
||||||
mod gl;
|
|
||||||
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub use filter_chain::FilterChain;
|
pub use filter_chain::FilterChain;
|
||||||
|
@ -21,13 +20,19 @@ pub use framebuffer::Viewport;
|
||||||
pub mod gl3 {
|
pub mod gl3 {
|
||||||
pub use super::framebuffer::GLImage;
|
pub use super::framebuffer::GLImage;
|
||||||
pub type FilterChain = super::filter_chain::FilterChain<super::gl::gl3::CompatibilityGL>;
|
pub type FilterChain = super::filter_chain::FilterChain<super::gl::gl3::CompatibilityGL>;
|
||||||
pub type Viewport<'a> = super::framebuffer::Viewport<'a, <super::gl::gl3::CompatibilityGL as super::gl::GLInterface>::Framebuffer>;
|
pub type Viewport<'a> = super::framebuffer::Viewport<
|
||||||
|
'a,
|
||||||
|
<super::gl::gl3::CompatibilityGL as super::gl::GLInterface>::Framebuffer,
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod gl46 {
|
pub mod gl46 {
|
||||||
pub use super::framebuffer::GLImage;
|
pub use super::framebuffer::GLImage;
|
||||||
pub type FilterChain = super::filter_chain::FilterChain<super::gl::gl46::DirectStateAccessGL>;
|
pub type FilterChain = super::filter_chain::FilterChain<super::gl::gl46::DirectStateAccessGL>;
|
||||||
pub type Viewport<'a> = super::framebuffer::Viewport<'a, <super::gl::gl46::DirectStateAccessGL as super::gl::GLInterface>::Framebuffer>;
|
pub type Viewport<'a> = super::framebuffer::Viewport<
|
||||||
|
'a,
|
||||||
|
<super::gl::gl46::DirectStateAccessGL as super::gl::GLInterface>::Framebuffer,
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FrameOptions {
|
pub struct FrameOptions {
|
||||||
pub clear_history: bool
|
pub clear_history: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FilterChainOptions {
|
pub struct FilterChainOptions {
|
||||||
pub gl_version: u16
|
pub gl_version: u16,
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub(crate) struct RenderTarget<'a, T: Framebuffer> {
|
||||||
pub mvp: &'a [f32; 16],
|
pub mvp: &'a [f32; 16],
|
||||||
pub framebuffer: &'a T,
|
pub framebuffer: &'a T,
|
||||||
pub x: i32,
|
pub x: i32,
|
||||||
pub y: i32
|
pub y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Framebuffer> RenderTarget<'a, T> {
|
impl<'a, T: Framebuffer> RenderTarget<'a, T> {
|
||||||
|
|
|
@ -1,50 +1,40 @@
|
||||||
use gl::types::{GLenum, GLint, GLuint};
|
use gl::types::{GLenum, GLint, GLuint};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use librashader_common::{FilterMode, WrapMode};
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
pub struct SamplerSet {
|
pub struct SamplerSet {
|
||||||
// todo: may need to deal with differences in mip filter.
|
// todo: may need to deal with differences in mip filter.
|
||||||
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), GLuint>
|
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), GLuint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SamplerSet {
|
impl SamplerSet {
|
||||||
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mip: FilterMode) -> GLuint {
|
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mip: FilterMode) -> GLuint {
|
||||||
|
|
||||||
// eprintln!("{wrap}, {filter}, {mip}");
|
// eprintln!("{wrap}, {filter}, {mip}");
|
||||||
*self.samplers.get(&(wrap, filter, mip))
|
*self.samplers.get(&(wrap, filter, mip)).unwrap()
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_sampler(sampler: GLuint, wrap: WrapMode, filter: FilterMode, mip: FilterMode) {
|
fn make_sampler(sampler: GLuint, wrap: WrapMode, filter: FilterMode, mip: FilterMode) {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::SamplerParameteri(
|
gl::SamplerParameteri(sampler, gl::TEXTURE_WRAP_S, GLenum::from(wrap) as GLint);
|
||||||
sampler,
|
gl::SamplerParameteri(sampler, gl::TEXTURE_WRAP_T, GLenum::from(wrap) as GLint);
|
||||||
gl::TEXTURE_WRAP_S,
|
|
||||||
GLenum::from(wrap) as GLint,
|
|
||||||
);
|
|
||||||
gl::SamplerParameteri(
|
|
||||||
sampler,
|
|
||||||
gl::TEXTURE_WRAP_T,
|
|
||||||
GLenum::from(wrap) as GLint,
|
|
||||||
);
|
|
||||||
gl::SamplerParameteri(
|
gl::SamplerParameteri(
|
||||||
sampler,
|
sampler,
|
||||||
gl::TEXTURE_MAG_FILTER,
|
gl::TEXTURE_MAG_FILTER,
|
||||||
GLenum::from(filter) as GLint,
|
GLenum::from(filter) as GLint,
|
||||||
);
|
);
|
||||||
|
|
||||||
gl::SamplerParameteri(
|
gl::SamplerParameteri(sampler, gl::TEXTURE_MIN_FILTER, filter.gl_mip(mip) as GLint);
|
||||||
sampler,
|
|
||||||
gl::TEXTURE_MIN_FILTER,
|
|
||||||
GLenum::from(filter.gl_mip(mip)) as GLint,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> SamplerSet {
|
pub fn new() -> SamplerSet {
|
||||||
let mut samplers = FxHashMap::default();
|
let mut samplers = FxHashMap::default();
|
||||||
let wrap_modes =
|
let wrap_modes = &[
|
||||||
&[WrapMode::ClampToBorder, WrapMode::ClampToEdge, WrapMode::Repeat, WrapMode::MirroredRepeat];
|
WrapMode::ClampToBorder,
|
||||||
|
WrapMode::ClampToEdge,
|
||||||
|
WrapMode::Repeat,
|
||||||
|
WrapMode::MirroredRepeat,
|
||||||
|
];
|
||||||
for wrap_mode in wrap_modes {
|
for wrap_mode in wrap_modes {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut linear_linear = 0;
|
let mut linear_linear = 0;
|
||||||
|
@ -57,27 +47,51 @@ impl SamplerSet {
|
||||||
gl::GenSamplers(1, &mut nearest_linear);
|
gl::GenSamplers(1, &mut nearest_linear);
|
||||||
gl::GenSamplers(1, &mut nearest_nearest);
|
gl::GenSamplers(1, &mut nearest_nearest);
|
||||||
|
|
||||||
SamplerSet::make_sampler(linear_linear, *wrap_mode,
|
SamplerSet::make_sampler(
|
||||||
FilterMode::Linear, FilterMode::Linear);
|
linear_linear,
|
||||||
SamplerSet::make_sampler(linear_nearest, *wrap_mode,
|
*wrap_mode,
|
||||||
FilterMode::Linear, FilterMode::Nearest);
|
FilterMode::Linear,
|
||||||
SamplerSet::make_sampler(nearest_linear, *wrap_mode,
|
FilterMode::Linear,
|
||||||
FilterMode::Nearest, FilterMode::Linear);
|
);
|
||||||
SamplerSet::make_sampler(nearest_nearest, *wrap_mode,
|
SamplerSet::make_sampler(
|
||||||
FilterMode::Nearest, FilterMode::Nearest);
|
linear_nearest,
|
||||||
|
*wrap_mode,
|
||||||
|
FilterMode::Linear,
|
||||||
|
FilterMode::Nearest,
|
||||||
|
);
|
||||||
|
SamplerSet::make_sampler(
|
||||||
|
nearest_linear,
|
||||||
|
*wrap_mode,
|
||||||
|
FilterMode::Nearest,
|
||||||
|
FilterMode::Linear,
|
||||||
|
);
|
||||||
|
SamplerSet::make_sampler(
|
||||||
|
nearest_nearest,
|
||||||
|
*wrap_mode,
|
||||||
|
FilterMode::Nearest,
|
||||||
|
FilterMode::Nearest,
|
||||||
|
);
|
||||||
|
|
||||||
|
samplers.insert(
|
||||||
|
(*wrap_mode, FilterMode::Linear, FilterMode::Linear),
|
||||||
|
linear_linear,
|
||||||
|
);
|
||||||
|
samplers.insert(
|
||||||
|
(*wrap_mode, FilterMode::Linear, FilterMode::Nearest),
|
||||||
|
linear_nearest,
|
||||||
|
);
|
||||||
|
|
||||||
samplers.insert((*wrap_mode, FilterMode::Linear, FilterMode::Linear), linear_linear);
|
samplers.insert(
|
||||||
samplers.insert((*wrap_mode, FilterMode::Linear, FilterMode::Nearest), linear_nearest);
|
(*wrap_mode, FilterMode::Nearest, FilterMode::Nearest),
|
||||||
|
nearest_nearest,
|
||||||
samplers.insert((*wrap_mode, FilterMode::Nearest, FilterMode::Nearest), nearest_nearest);
|
);
|
||||||
samplers.insert((*wrap_mode, FilterMode::Nearest, FilterMode::Linear), nearest_linear);
|
samplers.insert(
|
||||||
|
(*wrap_mode, FilterMode::Nearest, FilterMode::Linear),
|
||||||
|
nearest_linear,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SamplerSet {
|
SamplerSet { samplers }
|
||||||
samplers
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use librashader_common::{FilterMode, WrapMode};
|
|
||||||
use crate::framebuffer::GLImage;
|
use crate::framebuffer::GLImage;
|
||||||
|
use librashader_common::{FilterMode, WrapMode};
|
||||||
|
|
||||||
#[derive(Default, Debug, Copy, Clone)]
|
#[derive(Default, Debug, Copy, Clone)]
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
|
@ -11,6 +11,6 @@ pub struct Texture {
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub fn is_bound(&self) -> bool {
|
pub fn is_bound(&self) -> bool {
|
||||||
return self.image.handle != 0
|
self.image.handle != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
use gl::types::{GLenum, GLint, GLuint};
|
use gl::types::{GLenum, GLuint};
|
||||||
use librashader_common::Size;
|
|
||||||
use librashader_reflect::back::cross::GlVersion;
|
use librashader_reflect::back::cross::GlVersion;
|
||||||
use librashader_reflect::reflect::semantics::BindingStage;
|
|
||||||
use librashader_runtime::uniforms::{BindUniform, UniformStorage, UniformScalar};
|
|
||||||
use crate::binding::UniformLocation;
|
|
||||||
|
|
||||||
pub trait RingBuffer<T> {
|
pub trait RingBuffer<T> {
|
||||||
fn current(&self) -> &T;
|
fn current(&self) -> &T;
|
||||||
|
@ -87,7 +84,7 @@ pub fn gl_get_version() -> GlVersion {
|
||||||
1 => GlVersion::V1_40,
|
1 => GlVersion::V1_40,
|
||||||
0 => GlVersion::V1_30,
|
0 => GlVersion::V1_30,
|
||||||
_ => GlVersion::V1_50,
|
_ => GlVersion::V1_50,
|
||||||
}
|
},
|
||||||
4 => match min_ver {
|
4 => match min_ver {
|
||||||
6 => GlVersion::V4_60,
|
6 => GlVersion::V4_60,
|
||||||
5 => GlVersion::V4_50,
|
5 => GlVersion::V4_50,
|
||||||
|
@ -96,11 +93,10 @@ pub fn gl_get_version() -> GlVersion {
|
||||||
2 => GlVersion::V4_20,
|
2 => GlVersion::V4_20,
|
||||||
1 => GlVersion::V4_10,
|
1 => GlVersion::V4_10,
|
||||||
0 => GlVersion::V4_00,
|
0 => GlVersion::V4_00,
|
||||||
_ => GlVersion::V1_50
|
_ => GlVersion::V1_50,
|
||||||
|
},
|
||||||
|
_ => GlVersion::V1_50,
|
||||||
}
|
}
|
||||||
_ => GlVersion::V1_50
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gl_u16_to_version(version: u16) -> GlVersion {
|
pub fn gl_u16_to_version(version: u16) -> GlVersion {
|
||||||
|
@ -116,6 +112,6 @@ pub fn gl_u16_to_version(version: u16) -> GlVersion {
|
||||||
440 => GlVersion::V4_40,
|
440 => GlVersion::V4_40,
|
||||||
450 => GlVersion::V4_50,
|
450 => GlVersion::V4_50,
|
||||||
460 => GlVersion::V4_60,
|
460 => GlVersion::V4_60,
|
||||||
_ => GlVersion::V1_50
|
_ => GlVersion::V1_50,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
|
pub mod scaling;
|
||||||
pub mod semantics;
|
pub mod semantics;
|
||||||
pub mod uniforms;
|
pub mod uniforms;
|
||||||
pub mod scaling;
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use std::ops::Mul;
|
|
||||||
use librashader_common::Size;
|
use librashader_common::Size;
|
||||||
use librashader_presets::{Scale2D, ScaleFactor, ScaleType, Scaling};
|
use librashader_presets::{Scale2D, ScaleFactor, ScaleType, Scaling};
|
||||||
use num_traits::AsPrimitive;
|
use num_traits::AsPrimitive;
|
||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
pub fn scale<T>(scaling: Scale2D, source: Size<T>, viewport: Size<T>) -> Size<T>
|
pub fn scale<T>(scaling: Scale2D, source: Size<T>, viewport: Size<T>) -> Size<T>
|
||||||
where T: Mul<ScaleFactor, Output=f32> + Copy + 'static,
|
where
|
||||||
|
T: Mul<ScaleFactor, Output = f32> + Copy + 'static,
|
||||||
f32: AsPrimitive<T>,
|
f32: AsPrimitive<T>,
|
||||||
{
|
{
|
||||||
let width: f32;
|
let width: f32;
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use librashader_presets::{ShaderPassConfig, TextureConfig};
|
use librashader_presets::{ShaderPassConfig, TextureConfig};
|
||||||
use rustc_hash::FxHashMap;
|
|
||||||
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, UniformSemantic};
|
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, UniformSemantic};
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
pub type UniformSemanticsMap = FxHashMap<String, UniformSemantic>;
|
pub type UniformSemanticsMap = FxHashMap<String, UniformSemantic>;
|
||||||
pub type TextureSemanticsMap = FxHashMap<String, SemanticMap<TextureSemantics>>;
|
pub type TextureSemanticsMap = FxHashMap<String, SemanticMap<TextureSemantics>>;
|
||||||
|
|
||||||
|
|
||||||
pub fn insert_pass_semantics(
|
pub fn insert_pass_semantics(
|
||||||
uniform_semantics: &mut UniformSemanticsMap,
|
uniform_semantics: &mut UniformSemanticsMap,
|
||||||
texture_semantics: &mut TextureSemanticsMap,
|
texture_semantics: &mut TextureSemanticsMap,
|
||||||
|
@ -55,9 +54,11 @@ pub fn insert_pass_semantics(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_lut_semantics(textures: &[TextureConfig],
|
pub fn insert_lut_semantics(
|
||||||
|
textures: &[TextureConfig],
|
||||||
uniform_semantics: &mut UniformSemanticsMap,
|
uniform_semantics: &mut UniformSemanticsMap,
|
||||||
texture_semantics: &mut TextureSemanticsMap) {
|
texture_semantics: &mut TextureSemanticsMap,
|
||||||
|
) {
|
||||||
for (index, texture) in textures.iter().enumerate() {
|
for (index, texture) in textures.iter().enumerate() {
|
||||||
texture_semantics.insert(
|
texture_semantics.insert(
|
||||||
texture.name.clone(),
|
texture.name.clone(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::marker::PhantomData;
|
|
||||||
use librashader_reflect::reflect::semantics::MemberOffset;
|
use librashader_reflect::reflect::semantics::MemberOffset;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub trait UniformScalar: Copy + bytemuck::Pod {}
|
pub trait UniformScalar: Copy + bytemuck::Pod {}
|
||||||
impl UniformScalar for f32 {}
|
impl UniformScalar for f32 {}
|
||||||
|
@ -36,13 +36,16 @@ pub struct UniformStorage<H=NoUniformBinder, C = Option<()>> {
|
||||||
pub ubo: Box<[u8]>,
|
pub ubo: Box<[u8]>,
|
||||||
pub push: Box<[u8]>,
|
pub push: Box<[u8]>,
|
||||||
_h: PhantomData<H>,
|
_h: PhantomData<H>,
|
||||||
_c: PhantomData<C>
|
_c: PhantomData<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, C> UniformStorage<H, C>
|
impl<H, C> UniformStorage<H, C>
|
||||||
where H: BindUniform<C, f32>, H: BindUniform<C, u32>, H: BindUniform<C, i32>,
|
where
|
||||||
|
H: BindUniform<C, f32>,
|
||||||
|
H: BindUniform<C, u32>,
|
||||||
|
H: BindUniform<C, i32>,
|
||||||
H: for<'a> BindUniform<C, &'a [f32; 4]>,
|
H: for<'a> BindUniform<C, &'a [f32; 4]>,
|
||||||
H: for <'a> BindUniform<C, &'a [f32; 16]>
|
H: for<'a> BindUniform<C, &'a [f32; 16]>,
|
||||||
{
|
{
|
||||||
pub fn new(ubo_size: usize, push_size: usize) -> Self {
|
pub fn new(ubo_size: usize, push_size: usize) -> Self {
|
||||||
UniformStorage {
|
UniformStorage {
|
||||||
|
@ -55,16 +58,17 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn write_scalar_inner<T: UniformScalar>(buffer: &mut [u8], value: T, ctx: C)
|
fn write_scalar_inner<T: UniformScalar>(buffer: &mut [u8], value: T, ctx: C)
|
||||||
where H: BindUniform<C, T>
|
where
|
||||||
|
H: BindUniform<C, T>,
|
||||||
{
|
{
|
||||||
if let None = H::bind_uniform(value, ctx) {
|
if H::bind_uniform(value, ctx).is_none() {
|
||||||
let buffer = bytemuck::cast_slice_mut(buffer);
|
let buffer = bytemuck::cast_slice_mut(buffer);
|
||||||
buffer[0] = value;
|
buffer[0] = value;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_mat4_inner(buffer: &mut [u8], mat4: &[f32; 16], ctx: C) {
|
fn write_mat4_inner(buffer: &mut [u8], mat4: &[f32; 16], ctx: C) {
|
||||||
if let None = H::bind_uniform(mat4, ctx) {
|
if H::bind_uniform(mat4, ctx).is_none() {
|
||||||
let mat4 = bytemuck::cast_slice(mat4);
|
let mat4 = bytemuck::cast_slice(mat4);
|
||||||
buffer.copy_from_slice(mat4);
|
buffer.copy_from_slice(mat4);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +76,7 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
|
||||||
|
|
||||||
fn write_vec4_inner(buffer: &mut [u8], vec4: impl Into<[f32; 4]>, ctx: C) {
|
fn write_vec4_inner(buffer: &mut [u8], vec4: impl Into<[f32; 4]>, ctx: C) {
|
||||||
let vec4 = vec4.into();
|
let vec4 = vec4.into();
|
||||||
if let None = H::bind_uniform(&vec4, ctx) {
|
if H::bind_uniform(&vec4, ctx).is_none() {
|
||||||
let vec4 = bytemuck::cast_slice(&vec4);
|
let vec4 = bytemuck::cast_slice(&vec4);
|
||||||
buffer.copy_from_slice(vec4);
|
buffer.copy_from_slice(vec4);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +87,11 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
|
||||||
MemberOffset::Ubo(offset) => (&mut self.ubo, offset),
|
MemberOffset::Ubo(offset) => (&mut self.ubo, offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
||||||
};
|
};
|
||||||
Self::write_mat4_inner(&mut buffer[offset..][..16 * std::mem::size_of::<f32>()], value, ctx);
|
Self::write_mat4_inner(
|
||||||
|
&mut buffer[offset..][..16 * std::mem::size_of::<f32>()],
|
||||||
|
value,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_vec4(&mut self, offset: MemberOffset, value: impl Into<[f32; 4]>, ctx: C) {
|
pub fn bind_vec4(&mut self, offset: MemberOffset, value: impl Into<[f32; 4]>, ctx: C) {
|
||||||
|
@ -92,17 +100,26 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::write_vec4_inner(&mut buffer[offset..][..4 * std::mem::size_of::<f32>()], value, ctx);
|
Self::write_vec4_inner(
|
||||||
|
&mut buffer[offset..][..4 * std::mem::size_of::<f32>()],
|
||||||
|
value,
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_scalar<T: UniformScalar>(&mut self, offset: MemberOffset, value: T, ctx: C)
|
pub fn bind_scalar<T: UniformScalar>(&mut self, offset: MemberOffset, value: T, ctx: C)
|
||||||
where H: BindUniform<C, T>
|
where
|
||||||
|
H: BindUniform<C, T>,
|
||||||
{
|
{
|
||||||
let (buffer, offset) = match offset {
|
let (buffer, offset) = match offset {
|
||||||
MemberOffset::Ubo(offset) => (&mut self.ubo, offset),
|
MemberOffset::Ubo(offset) => (&mut self.ubo, offset),
|
||||||
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
MemberOffset::PushConstant(offset) => (&mut self.push, offset),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::write_scalar_inner(&mut buffer[offset..][..std::mem::size_of::<T>()], value, ctx)
|
Self::write_scalar_inner(
|
||||||
|
&mut buffer[offset..][..std::mem::size_of::<T>()],
|
||||||
|
value,
|
||||||
|
ctx,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,17 +13,14 @@ pub mod reflect {
|
||||||
pub use librashader_reflect::error::*;
|
pub use librashader_reflect::error::*;
|
||||||
|
|
||||||
pub use librashader_reflect::reflect::{
|
pub use librashader_reflect::reflect::{
|
||||||
ReflectMeta, ReflectShader, semantics, ShaderReflection
|
semantics, ReflectMeta, ReflectShader, ShaderReflection,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use librashader_reflect::front::shaderc::GlslangCompilation;
|
|
||||||
pub use librashader_reflect::back::{
|
pub use librashader_reflect::back::{
|
||||||
CompileShader,
|
targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation,
|
||||||
FromCompilation,
|
|
||||||
ShaderCompilerOutput,
|
ShaderCompilerOutput,
|
||||||
CompilerBackend,
|
|
||||||
targets::OutputTarget,
|
|
||||||
};
|
};
|
||||||
|
pub use librashader_reflect::front::shaderc::GlslangCompilation;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod targets {
|
pub mod targets {
|
||||||
|
@ -32,11 +29,10 @@ pub mod targets {
|
||||||
/// Shader compiler target for GLSL.
|
/// Shader compiler target for GLSL.
|
||||||
pub use librashader_reflect::back::targets::GLSL;
|
pub use librashader_reflect::back::targets::GLSL;
|
||||||
|
|
||||||
|
|
||||||
/// Shader runtime for OpenGL.
|
/// Shader runtime for OpenGL.
|
||||||
pub mod runtime {
|
pub mod runtime {
|
||||||
pub use librashader_runtime_gl::options::*;
|
|
||||||
pub use librashader_runtime_gl::error;
|
pub use librashader_runtime_gl::error;
|
||||||
|
pub use librashader_runtime_gl::options::*;
|
||||||
pub use librashader_runtime_gl::FilterChain;
|
pub use librashader_runtime_gl::FilterChain;
|
||||||
pub use librashader_runtime_gl::Viewport;
|
pub use librashader_runtime_gl::Viewport;
|
||||||
|
|
||||||
|
@ -72,19 +68,18 @@ pub mod targets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use librashader_common::{
|
pub use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
|
||||||
FilterMode,
|
|
||||||
ImageFormat,
|
|
||||||
Size,
|
|
||||||
WrapMode
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod util {
|
pub mod util {
|
||||||
use librashader_preprocess::{PreprocessError, ShaderParameter, ShaderSource};
|
use librashader_preprocess::{PreprocessError, ShaderParameter, ShaderSource};
|
||||||
use librashader_presets::ShaderPreset;
|
use librashader_presets::ShaderPreset;
|
||||||
|
|
||||||
pub fn get_parameter_meta(preset: &ShaderPreset) -> Result<impl Iterator<Item = ShaderParameter>, PreprocessError> {
|
pub fn get_parameter_meta(
|
||||||
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset.shaders.iter()
|
preset: &ShaderPreset,
|
||||||
|
) -> Result<impl Iterator<Item = ShaderParameter>, PreprocessError> {
|
||||||
|
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset
|
||||||
|
.shaders
|
||||||
|
.iter()
|
||||||
.map(|s| ShaderSource::load(&s.name).map(|s| s.parameters))
|
.map(|s| ShaderSource::load(&s.name).map(|s| s.parameters))
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
Loading…
Reference in a new issue