fmt: run cargo fmt and clippy

This commit is contained in:
chyyran 2022-11-30 01:38:05 -05:00
parent f5c56895fb
commit 5088e1c55b
53 changed files with 1000 additions and 778 deletions

View file

@ -29,7 +29,7 @@ impl From<ImageFormat> for dxgi::DXGI_FORMAT {
ImageFormat::R16G16B16A16Sint => dxgi::DXGI_FORMAT_R16G16B16A16_SINT, ImageFormat::R16G16B16A16Sint => dxgi::DXGI_FORMAT_R16G16B16A16_SINT,
ImageFormat::R16G16B16A16Sfloat => dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT, ImageFormat::R16G16B16A16Sfloat => dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT,
ImageFormat::R32Uint => dxgi::DXGI_FORMAT_R32_UINT, ImageFormat::R32Uint => dxgi::DXGI_FORMAT_R32_UINT,
ImageFormat::R32Sint =>dxgi::DXGI_FORMAT_R32_SINT, ImageFormat::R32Sint => dxgi::DXGI_FORMAT_R32_SINT,
ImageFormat::R32Sfloat => dxgi::DXGI_FORMAT_R32_FLOAT, ImageFormat::R32Sfloat => dxgi::DXGI_FORMAT_R32_FLOAT,
ImageFormat::R32G32Uint => dxgi::DXGI_FORMAT_R32G32_UINT, ImageFormat::R32G32Uint => dxgi::DXGI_FORMAT_R32G32_UINT,
ImageFormat::R32G32Sint => dxgi::DXGI_FORMAT_R32G32_SINT, ImageFormat::R32G32Sint => dxgi::DXGI_FORMAT_R32G32_SINT,
@ -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,
} }
} }
} }

View file

@ -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;

View file

@ -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 {
[ [

View file

@ -0,0 +1 @@

View file

@ -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)?,
}) })

View file

@ -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> {

View file

@ -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) {

View file

@ -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() {

View file

@ -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)

View file

@ -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() {

View file

@ -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),

View file

@ -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(())
} }
} }

View file

@ -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 {

View file

@ -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 {

View file

@ -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()?;
} }

View file

@ -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();
} }
} }

View file

@ -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,
} },
] ]
} }
} }

View file

@ -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> {
} }
} }
} }

View file

@ -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
})
} }
} }

View file

@ -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,
} },
}) })
} }
} }

View file

@ -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>>;

View file

@ -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) {
@ -105,7 +105,7 @@ impl BindUniform<UniformLocation<GLint>, &[f32; 16]> for GlUniformBinder {
} }
} }
Some(()) Some(())
}else { } else {
None None
} }
} }

View file

@ -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>;

View file

@ -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,10 +51,10 @@ 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> {
fn reflect_uniform_location(pipeline: GLuint, meta: &impl UniformMeta) -> VariableLocation { fn reflect_uniform_location(pipeline: GLuint, meta: &impl UniformMeta) -> VariableLocation {
// todo: support both ubo and pushco // todo: support both ubo and pushco
// todo: fix this. // todo: fix this.
@ -88,13 +91,17 @@ 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 {

View file

@ -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,
@ -33,7 +31,7 @@ pub struct FilterPass<T: GLInterface> {
pub config: ShaderPassConfig, pub config: ShaderPassConfig,
} }
impl<T:GLInterface> FilterPass<T> { impl<T: GLInterface> FilterPass<T> {
// todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo) // todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo)
pub(crate) fn draw( pub(crate) fn draw(
&mut self, &mut self,
@ -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,8 +100,7 @@ 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;
if self.config.srgb_framebuffer { if self.config.srgb_framebuffer {
@ -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
@ -182,7 +182,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::Original.semantics(0).into()) .get(&TextureSemantics::Original.semantics(0).into())
{ {
self.uniform_storage self.uniform_storage
.bind_vec4(*offset,original.image.size, location.location()); .bind_vec4(*offset, original.image.size, location.location());
} }
// bind Source sampler // bind Source 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
@ -218,7 +218,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::OriginalHistory.semantics(0).into()) .get(&TextureSemantics::OriginalHistory.semantics(0).into())
{ {
self.uniform_storage self.uniform_storage
.bind_vec4(*offset,original.image.size, location.location()); .bind_vec4(*offset, original.image.size, location.location());
} }
for (index, output) in parent.history_textures.iter().enumerate() { for (index, output) in parent.history_textures.iter().enumerate() {
@ -240,7 +240,7 @@ impl <T: GLInterface> FilterPass<T> {
.into(), .into(),
) { ) {
self.uniform_storage self.uniform_storage
.bind_vec4(*offset,output.image.size, location.location()); .bind_vec4(*offset, output.image.size, location.location());
} }
} }
@ -263,7 +263,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::PassOutput.semantics(index).into()) .get(&TextureSemantics::PassOutput.semantics(index).into())
{ {
self.uniform_storage self.uniform_storage
.bind_vec4(*offset,output.image.size, location.location()); .bind_vec4(*offset, output.image.size, location.location());
} }
} }
@ -286,7 +286,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::PassFeedback.semantics(index).into()) .get(&TextureSemantics::PassFeedback.semantics(index).into())
{ {
self.uniform_storage self.uniform_storage
.bind_vec4(*offset,feedback.image.size, location.location()); .bind_vec4(*offset, feedback.image.size, location.location());
} }
} }
@ -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());

View file

@ -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)]

View file

@ -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 {
} }
} }
} }

View file

@ -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)),
} }
} }

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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),
);
} }
} }
} }

View file

@ -1,16 +1,15 @@
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();
unsafe { unsafe {
@ -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()
} }
} }

View file

@ -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 }

View file

@ -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,16 +161,11 @@ 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);
} }
gl::CreateTextures(gl::TEXTURE_2D,1, &mut self.image); gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
if size.width == 0 { if size.width == 0 {
size.width = 1; size.width = 1;
@ -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)),
} }
} }
} }

View file

@ -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);
@ -281,7 +281,7 @@ pub fn do_loop(
); );
// make tetxure // make tetxure
gl::CreateTextures(gl::TEXTURE_2D,1, &mut rendered_texture); gl::CreateTextures(gl::TEXTURE_2D, 1, &mut rendered_texture);
gl::ObjectLabel( gl::ObjectLabel(
gl::TEXTURE, gl::TEXTURE,
@ -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,
@ -353,7 +361,7 @@ pub fn do_loop(
); );
// make tetxure // make tetxure
gl::CreateTextures(gl::TEXTURE_2D,1, &mut output_texture); gl::CreateTextures(gl::TEXTURE_2D, 1, &mut output_texture);
gl::ObjectLabel( gl::ObjectLabel(
gl::TEXTURE, gl::TEXTURE,
@ -371,7 +379,7 @@ pub fn do_loop(
HEIGHT as GLsizei, HEIGHT as GLsizei,
); );
gl::TextureParameteri(output_texture,gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint); gl::TextureParameteri(output_texture, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
gl::TextureParameteri(output_texture, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint); gl::TextureParameteri(output_texture, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
gl::TextureParameteri( gl::TextureParameteri(
output_texture, output_texture,
@ -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 {

View file

@ -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 {
@ -32,7 +32,7 @@ impl LoadLut for Gl46LutLoad {
let mut handle = 0; let mut handle = 0;
unsafe { unsafe {
gl::CreateTextures(gl::TEXTURE_2D,1, &mut handle); gl::CreateTextures(gl::TEXTURE_2D, 1, &mut handle);
gl::TextureStorage2D( gl::TextureStorage2D(
handle, handle,
@ -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,

View file

@ -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 {

View file

@ -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),
);
} }
} }
} }

View file

@ -1,16 +1,15 @@
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();
unsafe { unsafe {
@ -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()
} }
} }

View file

@ -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 {

View file

@ -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)]

View file

@ -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,
} }

View file

@ -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> {

View file

@ -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
}
} }
} }

View file

@ -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
} }
} }

View file

@ -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,
} }
} }

View file

@ -1,3 +1,3 @@
pub mod scaling;
pub mod semantics; pub mod semantics;
pub mod uniforms; pub mod uniforms;
pub mod scaling;

View file

@ -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;

View file

@ -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(),

View file

@ -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 {}
@ -7,7 +7,7 @@ impl UniformScalar for i32 {}
impl UniformScalar for u32 {} impl UniformScalar for u32 {}
pub struct NoUniformBinder; pub struct NoUniformBinder;
impl <T> BindUniform<Option<()>, T> for NoUniformBinder { impl<T> BindUniform<Option<()>, T> for NoUniformBinder {
fn bind_uniform(_: T, _: Option<()>) -> Option<()> { fn bind_uniform(_: T, _: Option<()>) -> Option<()> {
None None
} }
@ -22,7 +22,7 @@ pub trait UniformStorageAccess {
fn push_pointer(&self) -> *const u8; fn push_pointer(&self) -> *const u8;
} }
impl <T, H> UniformStorageAccess for UniformStorage<T, H> { impl<T, H> UniformStorageAccess for UniformStorage<T, H> {
fn ubo_pointer(&self) -> *const u8 { fn ubo_pointer(&self) -> *const u8 {
self.ubo.as_ptr() self.ubo.as_ptr()
} }
@ -32,17 +32,20 @@ impl <T, H> UniformStorageAccess for UniformStorage<T, H> {
} }
} }
pub struct UniformStorage<H=NoUniformBinder, C = Option<()>> { 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: for <'a> BindUniform<C, &'a [f32; 4]>, H: BindUniform<C, f32>,
H: for <'a> BindUniform<C, &'a [f32; 16]> H: BindUniform<C, u32>,
H: BindUniform<C, i32>,
H: for<'a> BindUniform<C, &'a [f32; 4]>,
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,
)
} }
} }

View file

@ -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();