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

@ -1,5 +1,5 @@
use crate::{FilterMode, ImageFormat, WrapMode};
use windows::Win32::Graphics::Direct3D11;
use windows::Win32::Graphics::Direct3D11;
use windows::Win32::Graphics::Dxgi::Common as dxgi;
use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT;
@ -29,7 +29,7 @@ impl From<ImageFormat> for dxgi::DXGI_FORMAT {
ImageFormat::R16G16B16A16Sint => dxgi::DXGI_FORMAT_R16G16B16A16_SINT,
ImageFormat::R16G16B16A16Sfloat => dxgi::DXGI_FORMAT_R16G16B16A16_FLOAT,
ImageFormat::R32Uint => dxgi::DXGI_FORMAT_R32_UINT,
ImageFormat::R32Sint =>dxgi::DXGI_FORMAT_R32_SINT,
ImageFormat::R32Sint => dxgi::DXGI_FORMAT_R32_SINT,
ImageFormat::R32Sfloat => dxgi::DXGI_FORMAT_R32_FLOAT,
ImageFormat::R32G32Uint => dxgi::DXGI_FORMAT_R32G32_UINT,
ImageFormat::R32G32Sint => dxgi::DXGI_FORMAT_R32G32_SINT,
@ -75,7 +75,7 @@ impl From<DXGI_FORMAT> for ImageFormat {
dxgi::DXGI_FORMAT_R32G32B32A32_UINT => ImageFormat::R32G32B32A32Uint,
dxgi::DXGI_FORMAT_R32G32B32A32_SINT => ImageFormat::R32G32B32A32Sint,
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 {
match value {
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 width = image.width();
let pitch = image.sample_layout().height_stride.max(
image.sample_layout().width_stride
);
let pitch = image
.sample_layout()
.height_stride
.max(image.sample_layout().width_stride);
Ok(Image {
bytes: image.into_raw(),
pitch,
size: Size {
height,
width,
}
size: Size { 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")]
pub mod d3d11;
#[cfg(feature = "opengl")]
pub mod gl;
pub mod image;
pub mod runtime;
use num_traits::AsPrimitive;
use std::convert::Infallible;
use std::str::FromStr;
use num_traits::AsPrimitive;
#[repr(u32)]
#[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
@ -146,7 +145,8 @@ impl<T> Size<T> {
}
impl<T> From<Size<T>> for [f32; 4]
where T: Copy + AsPrimitive<f32>
where
T: Copy + AsPrimitive<f32>,
{
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::{CompilerBackend, CompileShader, FromCompilation};
use crate::back::{CompileShader, CompilerBackend, FromCompilation};
use crate::error::ShaderReflectError;
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::cross::{CompiledProgram, GlslReflect, HlslReflect};
@ -15,14 +15,12 @@ impl FromCompilation<GlslangCompilation> for GLSL {
type Target = GLSL;
type Options = GlVersion;
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(
compile: GlslangCompilation,
) -> Result<
CompilerBackend<Self::Output>,
ShaderReflectError,
> {
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
Ok(CompilerBackend {
backend: GlslReflect::try_from(compile)?,
})
@ -33,19 +31,16 @@ pub struct GlslangHlslContext {
pub compiler: CompiledProgram<spirv_cross::hlsl::Target>,
}
impl FromCompilation<GlslangCompilation> for HLSL {
type Target = HLSL;
type Options = Option<()>;
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(
compile: GlslangCompilation,
) -> Result<
CompilerBackend<Self::Output>,
ShaderReflectError,
> {
) -> Result<CompilerBackend<Self::Output>, ShaderReflectError> {
Ok(CompilerBackend {
backend: HlslReflect::try_from(compile)?,
})

View file

@ -1,11 +1,11 @@
pub mod cross;
pub mod targets;
use std::fmt::Debug;
use crate::back::targets::OutputTarget;
use crate::error::{ShaderCompileError, ShaderReflectError};
use crate::reflect::{ReflectShader, ShaderReflection};
use crate::reflect::semantics::ReflectSemantics;
use crate::reflect::{ReflectShader, ShaderReflection};
use std::fmt::Debug;
#[derive(Debug)]
pub struct ShaderCompilerOutput<T, Context = ()> {
@ -45,14 +45,10 @@ pub trait FromCompilation<T> {
type Options;
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(
compile: T,
) -> Result<
CompilerBackend<Self::Output>,
ShaderReflectError,
>;
fn from_compilation(compile: T) -> Result<CompilerBackend<Self::Output>, ShaderReflectError>;
}
pub struct CompilerBackend<T> {

View file

@ -18,8 +18,8 @@ impl OutputTarget for SPIRV {
}
mod test {
use crate::back::FromCompilation;
use crate::back::targets::GLSL;
use crate::back::FromCompilation;
use crate::front::shaderc::GlslangCompilation;
#[allow(dead_code)]
pub fn test_compile(value: GlslangCompilation) {

View file

@ -19,6 +19,8 @@ pub fn compile_spirv(source: &ShaderSource) -> Result<NagaCompilation, ShaderCom
#[cfg(test)]
mod test {
use crate::front::naga::compile_spirv;
use crate::front::shaderc::GlslangCompilation;
use librashader_preprocess::ShaderSource;
use naga::back::glsl::{PipelineOptions, Version};
use naga::back::spv::{Capability, WriterFlags};
use naga::front::glsl::{Options, Parser};
@ -26,8 +28,6 @@ mod test {
use naga::valid::{Capabilities, ValidationFlags};
use naga::{FastHashSet, ShaderStage};
use rspirv::binary::Disassemble;
use librashader_preprocess::ShaderSource;
use crate::front::shaderc::GlslangCompilation;
#[test]
pub fn compile_naga_test() {
@ -46,7 +46,7 @@ mod test {
#[test]
pub fn compile_shader() {
let result = ShaderSource::load(
let result = ShaderSource::load(
"../test/slang-shaders/blurs/shaders/royale/blur3x3-last-pass.slang",
)
.unwrap();
@ -56,7 +56,7 @@ mod test {
#[test]
pub fn compile_shader_roundtrip() {
let result = ShaderSource::load("../test/basic.slang").unwrap();
let result = ShaderSource::load("../test/basic.slang").unwrap();
let cross = GlslangCompilation::compile(&result).unwrap();
let naga_fragment =
naga::front::spv::parse_u8_slice(cross.fragment.as_binary_u8(), &SpvOptions::default())

View file

@ -8,7 +8,6 @@ pub struct GlslangCompilation {
}
impl GlslangCompilation {
/// Tries to compile SPIR-V from the provided shader source.
pub fn compile(source: &ShaderSource) -> Result<Self, ShaderCompileError> {
compile_spirv(source)

View file

@ -1,18 +1,22 @@
use std::ops::Deref;
use crate::error::{SemanticsErrorKind, ShaderCompileError, ShaderReflectError};
use crate::front::shaderc::GlslangCompilation;
use crate::reflect::semantics::{BindingStage, MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, MemberOffset, PushReflection, ReflectSemantics, ShaderReflection, 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 std::ops::Deref;
use spirv_cross::hlsl::ShaderModel;
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::targets::{GLSL, HLSL};
use crate::back::{CompileShader, ShaderCompilerOutput};
pub struct CrossReflect<T>
where
T: spirv_cross::spirv::Target,
@ -478,7 +482,7 @@ where
Self::get_ubo_data(&self.fragment, fragment_ubo, SemanticErrorBlame::Fragment)?;
Ok(Some(UboReflection {
binding: fragment_ubo.binding,
size: align_uniform_size(fragment_ubo.size),
size: align_uniform_size(fragment_ubo.size),
stage_mask: BindingStage::FRAGMENT,
}))
}
@ -847,8 +851,8 @@ impl CompileShader<HLSL> for CrossReflect<hlsl::Target> {
context: GlslangHlslContext {
compiler: CompiledProgram {
vertex: CompiledAst(self.vertex),
fragment: CompiledAst(self.fragment)
}
fragment: CompiledAst(self.fragment),
},
},
})
}
@ -861,11 +865,13 @@ mod test {
use rustc_hash::FxHashMap;
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 spirv_cross::glsl;
use spirv_cross::glsl::{CompilerOptions, Version};
use crate::front::shaderc::GlslangCompilation;
#[test]
pub fn test_into() {

View file

@ -36,4 +36,4 @@ pub use semantics::ShaderReflection;
/// Give a size aligned to 16 byte boundary
const fn align_uniform_size(size: u32) -> u32 {
(size + 0xf) & !0xf
}
}

View file

@ -328,7 +328,6 @@ pub struct ReflectSemantics {
pub texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>>,
}
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
pub enum UniformBinding {
Parameter(String),

View file

@ -1,24 +1,22 @@
use std::collections::VecDeque;
use crate::texture::{DxImageView, OwnedTexture, Texture};
use librashader_common::image::Image;
use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::{ShaderPassConfig, ShaderPreset, TextureConfig};
use librashader_reflect::back::cross::GlslangHlslContext;
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::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 rustc_hash::FxHashMap;
use std::collections::VecDeque;
use std::error::Error;
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::framebuffer::{OutputFramebuffer, OwnedFramebuffer};
use crate::quad_render::DrawQuad;
@ -26,6 +24,13 @@ use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use crate::util;
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
type ShaderPassMeta<'a> = (
@ -64,14 +69,17 @@ impl FilterChain {
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result<ID3D11Buffer> {
eprintln!("{size}");
unsafe {
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
ByteWidth: size,
Usage: D3D11_USAGE_DYNAMIC,
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
StructureByteStride: 0,
}, None)?;
let buffer = device.CreateBuffer(
&D3D11_BUFFER_DESC {
ByteWidth: size,
Usage: D3D11_USAGE_DYNAMIC,
BindFlags: D3D11_BIND_CONSTANT_BUFFER,
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
StructureByteStride: 0,
},
None,
)?;
Ok(buffer)
}
@ -81,8 +89,7 @@ impl FilterChain {
device: &ID3D11Device,
passes: Vec<ShaderPassMeta>,
semantics: &ReflectSemantics,
) -> util::Result<Vec<FilterPass>>
{
) -> util::Result<Vec<FilterPass>> {
// let mut filters = Vec::new();
let mut filters = Vec::new();
@ -90,25 +97,26 @@ impl FilterChain {
let reflection = reflect.reflect(index, semantics)?;
let hlsl = reflect.compile(None)?;
let vertex_dxil = util::d3d_compile_shader(
hlsl.vertex.as_bytes(),
b"main\0",
b"vs_5_0\0"
let vertex_dxil =
util::d3d_compile_shader(hlsl.vertex.as_bytes(), b"main\0", b"vs_5_0\0")?;
let vs = d3d11_compile_bound_shader(
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 vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxil)?;
let fragment_dxil = util::d3d_compile_shader(
hlsl.fragment.as_bytes(),
b"main\0",
b"ps_5_0\0"
let fragment_dxil =
util::d3d_compile_shader(hlsl.fragment.as_bytes(), b"main\0", b"ps_5_0\0")?;
let ps = d3d11_compile_bound_shader(
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 buffer = FilterChain::create_constant_buffer(device, ubo.size)?;
@ -134,37 +142,30 @@ impl FilterChain {
None
};
let uniform_storage = UniformStorage::new(reflection
.ubo
.as_ref()
.map(|ubo| ubo.size as usize)
.unwrap_or(0),
reflection
.push_constant
.as_ref()
.map(|push| push.size as usize)
.unwrap_or(0));
let uniform_storage = UniformStorage::new(
reflection
.ubo
.as_ref()
.map(|ubo| ubo.size as usize)
.unwrap_or(0),
reflection
.push_constant
.as_ref()
.map(|push| push.size as usize)
.unwrap_or(0),
);
let mut uniform_bindings = FxHashMap::default();
for param in reflection.meta.parameter_meta.values() {
uniform_bindings.insert(
UniformBinding::Parameter(param.id.clone()),
param.offset,
);
uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset);
}
for (semantics, param) in &reflection.meta.variable_meta {
uniform_bindings.insert(
UniformBinding::SemanticVariable(*semantics),
param.offset
);
uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset);
}
for (semantics, param) in &reflection.meta.texture_size_meta {
uniform_bindings.insert(
UniformBinding::TextureSize(*semantics),
param.offset
);
uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset);
}
filters.push(FilterPass {
@ -184,7 +185,10 @@ impl FilterChain {
Ok(filters)
}
/// 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 samplers = SamplerSet::new(device)?;
@ -200,15 +204,29 @@ impl FilterChain {
// initialize output framebuffers
let mut output_framebuffers = Vec::new();
output_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm).unwrap());
output_framebuffers.resize_with(filters.len(), || {
OwnedFramebuffer::new(
device,
&device_context,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
)
.unwrap()
});
let mut output_textures = Vec::new();
output_textures.resize_with(filters.len(), || None);
//
// // initialize feedback framebuffers
let mut feedback_framebuffers = Vec::new();
feedback_framebuffers.resize_with(filters.len(), || OwnedFramebuffer::new(device, &device_context, Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm).unwrap());
feedback_framebuffers.resize_with(filters.len(), || {
OwnedFramebuffer::new(
device,
&device_context,
Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm,
)
.unwrap()
});
let mut feedback_textures = Vec::new();
feedback_textures.resize_with(filters.len(), || None);
@ -218,7 +236,6 @@ impl FilterChain {
let (history_framebuffers, history_textures) =
FilterChain::init_history(device, &device_context, &filters);
let draw_quad = DrawQuad::new(device, &device_context)?;
// todo: make vbo: d3d11.c 1376
@ -231,7 +248,7 @@ impl FilterChain {
common: FilterCommon {
d3d11: Direct3D11 {
device: device.clone(),
device_context
device_context,
},
luts,
samplers,
@ -245,7 +262,6 @@ impl FilterChain {
})
}
fn init_history(
device: &ID3D11Device,
context: &ID3D11DeviceContext,
@ -284,8 +300,10 @@ impl FilterChain {
eprintln!("[history] using frame history with {required_images} images");
let mut framebuffers = VecDeque::with_capacity(required_images);
framebuffers.resize_with(required_images, || OwnedFramebuffer::new(device, &context, Size::new(1, 1),
ImageFormat::R8G8B8A8Unorm).unwrap());
framebuffers.resize_with(required_images, || {
OwnedFramebuffer::new(device, context, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm)
.unwrap()
});
let mut history_textures = Vec::new();
history_textures.resize_with(required_images, || None);
@ -322,7 +340,6 @@ impl FilterChain {
Ok(())
}
fn load_luts(
device: &ID3D11Device,
textures: &[TextureConfig],
@ -344,15 +361,18 @@ impl FilterChain {
..Default::default()
};
let mut texture = OwnedTexture::new(device, &image, desc,
texture.filter_mode, texture.wrap_mode)?;
let texture =
OwnedTexture::new(device, &image, desc, texture.filter_mode, texture.wrap_mode)?;
luts.insert(index, texture);
}
Ok(luts)
}
/// 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
let preset = ShaderPreset::try_parse(path)?;
Self::load_from_preset(device, preset)
@ -385,7 +405,8 @@ impl FilterChain {
Ok::<_, Box<dyn Error>>((shader, source, reflect))
})
.into_iter()
.collect::<util::Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>()?;
.collect::<util::Result<Vec<(&ShaderPassConfig, ShaderSource, CompilerBackend<_>)>>>(
)?;
for details in &passes {
librashader_runtime::semantics::insert_pass_semantics(
@ -394,9 +415,11 @@ impl FilterChain {
details.0,
)
}
librashader_runtime::semantics::insert_lut_semantics(&preset.textures,
&mut uniform_semantics,
&mut texture_semantics);
librashader_runtime::semantics::insert_lut_semantics(
&preset.textures,
&mut uniform_semantics,
&mut texture_semantics,
);
let semantics = ReflectSemantics {
uniform_semantics,
@ -406,8 +429,13 @@ impl FilterChain {
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;
if passes.is_empty() {
@ -449,19 +477,30 @@ impl FilterChain {
let passes_len = passes.len();
let (pass, last) = passes.split_at_mut(passes_len - 1);
for (index, pass) in pass.iter_mut().enumerate() {
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 {
count % pass.config.frame_count_mod as usize
} else {
count
} as u32, 1, viewport, &original, &source, RenderTarget::new(target.as_output_framebuffer().unwrap(), None))?;
pass.draw(
index,
&self.common,
if pass.config.frame_count_mod > 0 {
count % pass.config.frame_count_mod as usize
} else {
count
} as u32,
1,
viewport,
&original,
&source,
RenderTarget::new(target.as_output_framebuffer().unwrap(), None),
)?;
source = Texture {
view: DxImageView { handle: target.create_shader_resource_view().unwrap(), size },
view: DxImageView {
handle: target.create_shader_resource_view().unwrap(),
size,
},
filter,
wrap_mode,
};
@ -479,7 +518,12 @@ impl FilterChain {
} else {
count
} 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.
break;
@ -496,6 +540,5 @@ impl FilterChain {
self.push_history(&input)?;
Ok(())
}
}

View file

@ -1,22 +1,25 @@
use std::array;
use crate::filter_chain::FilterCommon;
use crate::texture::{Texture, OwnedTexture};
use crate::texture::Texture;
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
use librashader_presets::ShaderPassConfig;
use librashader_reflect::back::cross::GlslangHlslContext;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::semantics::{BindingStage, 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 rustc_hash::FxHashMap;
use std::error::Error;
use windows::core::ConstBuffer;
use windows::Win32::Graphics::Direct3D::ID3DBlob;
use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout};
use windows::Win32::Graphics::Gdi::NULL_PEN;
use librashader_runtime::uniforms::UniformStorage;
use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD,
};
use crate::render_target::RenderTarget;
use crate::samplers::SamplerSet;
use librashader_runtime::uniforms::UniformStorage;
pub struct ConstantBufferBinding {
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 :(
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] =
&[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None];
const NULL_TEXTURES: &[Option<ID3D11ShaderResourceView>; 16] = &[
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
];
// slang_process.cpp 229
impl FilterPass {
@ -66,13 +70,14 @@ impl FilterPass {
texture: &Texture,
) {
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
fn build_semantics(
&mut self,
pass_index: usize,
_pass_index: usize,
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
@ -81,7 +86,10 @@ impl FilterPass {
viewport_size: Size<u32>,
original: &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 samplers: [Option<ID3D11SamplerState>; 16] = std::array::from_fn(|_| None);
@ -116,7 +124,8 @@ impl FilterPass {
.uniform_bindings
.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
@ -126,7 +135,13 @@ impl FilterPass {
.texture_meta
.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
@ -134,7 +149,8 @@ impl FilterPass {
.uniform_bindings
.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
@ -145,7 +161,13 @@ impl FilterPass {
.get(&TextureSemantics::Source.semantics(0))
{
// 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
@ -153,7 +175,8 @@ impl FilterPass {
.uniform_bindings
.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
@ -162,14 +185,21 @@ impl FilterPass {
.texture_meta
.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
.uniform_bindings
.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() {
@ -210,14 +240,21 @@ impl FilterPass {
.texture_meta
.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
.uniform_bindings
.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
.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
.uniform_bindings
.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
.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
.uniform_bindings
.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,
output: RenderTarget,
) -> std::result::Result<(), Box<dyn Error>> {
let device = &parent.d3d11.device;
let _device = &parent.d3d11.device;
let context = &parent.d3d11.device_context;
unsafe {
context.IASetInputLayout(&self.vertex_layout);
@ -316,16 +367,27 @@ impl FilterPass {
context.PSSetShader(&self.pixel_shader, None);
}
let (textures, samplers) = self.build_semantics(pass_index, parent, output.mvp, frame_count, frame_direction,
output.output.size, *viewport, original, source);
let (textures, samplers) = self.build_semantics(
pass_index,
parent,
output.mvp,
frame_count,
frame_direction,
output.output.size,
*viewport,
original,
source,
);
if let Some(ubo) = &self.uniform_buffer {
// upload uniforms
unsafe {
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);
}
@ -345,7 +407,11 @@ impl FilterPass {
// upload push constants
unsafe {
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);
}
@ -371,7 +437,7 @@ impl FilterPass {
context.PSSetSamplers(0, Some(&samplers));
context.OMSetRenderTargets(Some(&[Some(output.output.rtv.clone())]), None);
context.RSSetViewports(Some(&[output.output.viewport.clone()]))
context.RSSetViewports(Some(&[output.output.viewport]))
}
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 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::texture::Texture;
use crate::util;
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)]
pub struct OwnedFramebuffer {
@ -14,14 +23,24 @@ pub struct OwnedFramebuffer {
pub format: DXGI_FORMAT,
device: ID3D11Device,
context: ID3D11DeviceContext,
is_raw: bool
is_raw: bool,
}
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 {
let format = d3d11_get_closest_format(device, DXGI_FORMAT::from(format),
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
let format = d3d11_get_closest_format(
device,
DXGI_FORMAT::from(format),
D3D11_FORMAT_SUPPORT_TEXTURE2D.0
| D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0
| D3D11_FORMAT_SUPPORT_RENDER_TARGET.0,
);
eprintln!("{format:?}");
let desc = default_desc(size, format);
let texture = device.CreateTexture2D(&desc, None)?;
@ -71,9 +90,13 @@ impl OwnedFramebuffer {
return Ok(());
}
let format = d3d11_get_closest_format(&self.device, DXGI_FORMAT::from(format),
D3D11_FORMAT_SUPPORT_TEXTURE2D.0 |
D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0);
let format = d3d11_get_closest_format(
&self.device,
DXGI_FORMAT::from(format),
D3D11_FORMAT_SUPPORT_TEXTURE2D.0
| D3D11_FORMAT_SUPPORT_SHADER_SAMPLE.0
| D3D11_FORMAT_SUPPORT_RENDER_TARGET.0,
);
let desc = default_desc(size, format);
unsafe {
@ -88,30 +111,34 @@ impl OwnedFramebuffer {
pub fn create_shader_resource_view(&self) -> util::Result<ID3D11ShaderResourceView> {
unsafe {
Ok(self.device.CreateShaderResourceView(&self.texture, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: self.format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX,
}
},
}))?)
Ok(self.device.CreateShaderResourceView(
&self.texture,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: self.format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX,
},
},
}),
)?)
}
}
pub fn create_render_target_view(&self) -> util::Result<ID3D11RenderTargetView> {
unsafe {
Ok(self.device.CreateRenderTargetView(&self.texture, Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: self.format,
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_RTV {
MipSlice: 0,
}
},
}))?)
Ok(self.device.CreateRenderTargetView(
&self.texture,
Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: self.format,
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
},
}),
)?)
}
}
@ -119,22 +146,29 @@ impl OwnedFramebuffer {
Ok(OutputFramebuffer {
rtv: self.create_render_target_view()?,
size: self.size,
viewport: default_viewport(self.size)
viewport: default_viewport(self.size),
})
}
pub fn copy_from(&self, image: &ID3D11Resource) -> util::Result<()> {
unsafe {
self.context.CopySubresourceRegion(&self.texture, 0, 0, 0, 0,
image, 0, Some(&D3D11_BOX {
left: 0,
top: 0,
front: 0,
right: self.size.width,
bottom: self.size.height,
back: 1,
}))
self.context.CopySubresourceRegion(
&self.texture,
0,
0,
0,
0,
image,
0,
Some(&D3D11_BOX {
left: 0,
top: 0,
front: 0,
right: self.size.width,
bottom: self.size.height,
back: 1,
}),
)
}
Ok(())
}
@ -143,7 +177,7 @@ impl OwnedFramebuffer {
pub struct OutputFramebuffer {
pub rtv: ID3D11RenderTargetView,
pub size: Size<u32>,
pub viewport: D3D11_VIEWPORT
pub viewport: D3D11_VIEWPORT,
}
fn default_desc(size: Size<u32>, format: DXGI_FORMAT) -> D3D11_TEXTURE2D_DESC {
@ -172,4 +206,4 @@ pub const fn default_viewport(size: Size<u32>) -> D3D11_VIEWPORT {
MinDepth: 0.0,
MaxDepth: 1.0,
}
}
}

View file

@ -1,5 +1,3 @@
use std::sync::mpsc::Receiver;
const WIDTH: i32 = 900;
const HEIGHT: i32 = 700;
const TITLE: &str = "librashader DirectX 11";
@ -7,11 +5,10 @@ const TITLE: &str = "librashader DirectX 11";
use windows::{
core::*, Win32::Foundation::*, Win32::Graphics::Direct3D::Fxc::*, Win32::Graphics::Direct3D::*,
Win32::Graphics::Direct3D11::*, Win32::Graphics::Dxgi::Common::*, Win32::Graphics::Dxgi::*,
Win32::System::LibraryLoader::*, Win32::System::Threading::*,
Win32::System::WindowsProgramming::*, Win32::UI::WindowsAndMessaging::*,
Win32::System::LibraryLoader::*, Win32::UI::WindowsAndMessaging::*,
};
static VERTEX_SHADER: &'static [u8] = b"
static VERTEX_SHADER: &[u8] = b"
cbuffer cb : register(b0)
{
row_major float4x4 projectionMatrix : packoffset(c0);
@ -44,7 +41,7 @@ VertexOutput main(VertexInput vertexInput)
return output;
}\0";
static PIXEL_SHADER: &'static [u8] = b"
static PIXEL_SHADER: &[u8] = b"
struct PixelInput
{
float3 color : COLOR;
@ -224,15 +221,15 @@ struct TriangleUniforms {
}
pub mod d3d11_hello_triangle {
use std::path::Path;
use super::*;
use gfx_maths::{Quaternion, Vec3};
use std::slice;
use std::time::Instant;
use librashader_common::Size;
use std::path::Path;
use crate::filter_chain::FilterChain;
use crate::framebuffer::OutputFramebuffer;
use crate::texture::DxImageView;
use librashader_common::Size;
use std::slice;
use std::time::Instant;
const FRAME_COUNT: u32 = 2;
@ -279,8 +276,6 @@ pub mod d3d11_hello_triangle {
}
}
impl DXSample for Sample {
fn bind_to_window(&mut self, hwnd: &HWND) -> Result<()> {
let swapchain = create_swapchain(&self.dxgi_factory, &self.device, *hwnd)?;
let (rtv, backbuffer) = create_rtv(&self.device, &swapchain)?;
@ -317,7 +312,6 @@ pub mod d3d11_hello_triangle {
self.context.RSSetState(&raster_state);
}
self.resources = Some(Resources {
swapchain,
rtv,
@ -343,7 +337,7 @@ pub mod d3d11_hello_triangle {
MaxDepth: D3D11_MAX_DEPTH,
},
shader_output: None,
frame_count: 0usize
frame_count: 0usize,
});
Ok(())
@ -364,7 +358,7 @@ pub mod d3d11_hello_triangle {
}
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::identity();
@ -437,61 +431,77 @@ pub mod d3d11_hello_triangle {
unsafe {
let mut tex2d_desc = Default::default();
resources.backbuffer.GetDesc(&mut tex2d_desc);
let backup = self.device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
..tex2d_desc
}, None)?;
let backup = self.device.CreateTexture2D(
&D3D11_TEXTURE2D_DESC {
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
..tex2d_desc
},
None,
)?;
self.context.CopyResource(&backup, &resources.backbuffer);
let srv = self.device.CreateShaderResourceView(&backup, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: tex2d_desc.Format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX,
}
},
}))?;
let srv = self.device.CreateShaderResourceView(
&backup,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: tex2d_desc.Format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX,
},
},
}),
)?;
let shader_out = self.device.CreateTexture2D(&tex2d_desc, None)?;
let rtv = self.device.CreateRenderTargetView(&shader_out, Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: tex2d_desc.Format,
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_RTV {
MipSlice: 0,
}
}
}))?;
let _rtv = self.device.CreateRenderTargetView(
&shader_out,
Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: tex2d_desc.Format,
ViewDimension: D3D11_RTV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_RENDER_TARGET_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
},
}),
)?;
//
self.filter.frame(resources.frame_count, &Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
}, DxImageView { handle: srv, size: Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
} }, OutputFramebuffer {
rtv: resources.rtv.clone(),
// rtv,
size: Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
},
viewport: resources.viewport
// viewport: D3D11_VIEWPORT {
// TopLeftX: 0.0,
// TopLeftY: 0.0,
// Width: tex2d_desc.Width as f32,
// Height: tex2d_desc.Height as f32,
// MinDepth: 0.0,
// MaxDepth: 1.0,
// },
}).unwrap();
self.filter
.frame(
resources.frame_count,
&Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
},
DxImageView {
handle: srv,
size: Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
},
},
OutputFramebuffer {
rtv: resources.rtv.clone(),
// rtv,
size: Size {
width: tex2d_desc.Width,
height: tex2d_desc.Height,
},
viewport: resources.viewport, // viewport: D3D11_VIEWPORT {
// TopLeftX: 0.0,
// TopLeftY: 0.0,
// Width: tex2d_desc.Width as f32,
// Height: tex2d_desc.Height as f32,
// MinDepth: 0.0,
// MaxDepth: 1.0,
// },
},
)
.unwrap();
// self.context.CopyResource(&resources.backbuffer, &backup);
}
@ -755,7 +765,7 @@ pub mod d3d11_hello_triangle {
let mut swap_chain = None;
unsafe {
fac.CreateSwapChain(&*device, &swapchain_desc, &mut swap_chain)
fac.CreateSwapChain(device, &swapchain_desc, &mut swap_chain)
.ok()?;
}

View file

@ -3,43 +3,31 @@
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 framebuffer;
#[cfg(test)]
mod hello_triangle;
mod quad_render;
mod render_target;
mod samplers;
mod texture;
mod util;
mod samplers;
mod render_target;
mod framebuffer;
mod quad_render;
#[cfg(test)]
mod tests {
use crate::hello_triangle::DXSample;
use super::*;
#[test]
fn triangle_d3d11() {
// let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap();
let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/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();
hello_triangle::main(sample).unwrap();
}
}

View file

@ -1,39 +1,40 @@
use crate::util;
use bytemuck::offset_of;
use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_VERTEX_BUFFER, D3D11_BUFFER_DESC, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_SUBRESOURCE_DATA, D3D11_USAGE_IMMUTABLE, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext};
use windows::Win32::Graphics::Direct3D::{D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED};
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
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 crate::util;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default)]
struct D3D11Vertex {
position: [f32; 2],
texcoord: [f32; 2],
color: [f32; 4]
color: [f32; 4],
}
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 {
position: [0.0, 0.0],
texcoord: [0.0, 1.0],
color: CLEAR,
},
D3D11Vertex {
position: [0.0, 1.0],
texcoord: [0.0, 0.0],
color: CLEAR,
},
D3D11Vertex {
position: [1.0, 0.0],
texcoord: [1.0, 1.0],
color: CLEAR,
},
D3D11Vertex {
position: [1.0, 1.0],
texcoord: [1.0, 0.0],
@ -51,33 +52,42 @@ pub(crate) struct DrawQuad {
impl DrawQuad {
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> util::Result<DrawQuad> {
unsafe {
let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC {
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
Usage: D3D11_USAGE_IMMUTABLE,
BindFlags: D3D11_BIND_VERTEX_BUFFER,
CPUAccessFlags: Default::default(),
MiscFlags: Default::default(),
StructureByteStride: 0,
}, Some(&D3D11_SUBRESOURCE_DATA {
pSysMem: QUAD_VBO_DATA.as_ptr().cast(),
SysMemPitch: 0,
SysMemSlicePitch: 0,
}))?;
let buffer = device.CreateBuffer(
&D3D11_BUFFER_DESC {
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
Usage: D3D11_USAGE_IMMUTABLE,
BindFlags: D3D11_BIND_VERTEX_BUFFER,
CPUAccessFlags: Default::default(),
MiscFlags: Default::default(),
StructureByteStride: 0,
},
Some(&D3D11_SUBRESOURCE_DATA {
pSysMem: QUAD_VBO_DATA.as_ptr().cast(),
SysMemPitch: 0,
SysMemSlicePitch: 0,
}),
)?;
Ok(DrawQuad {
buffer,
context: context.clone(),
offset: 0,
stride: std::mem::size_of::<D3D11Vertex>() as u32
stride: std::mem::size_of::<D3D11Vertex>() as u32,
})
}
}
pub fn bind_vertices(&self) {
unsafe {
self.context.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
self.context.IASetVertexBuffers(0, 1, Some(&Some(self.buffer.clone())),
Some(&self.stride), Some(&self.offset));
self.context
.IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
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,
InputSlotClass: D3D11_INPUT_PER_VERTEX_DATA,
InstanceDataStepRate: 0,
}
},
]
}
}
}

View file

@ -1,6 +1,4 @@
use windows::Win32::Graphics::Direct3D11::ID3D11RenderTargetView;
use librashader_common::Size;
use crate::framebuffer::{OutputFramebuffer};
use crate::framebuffer::OutputFramebuffer;
#[rustfmt::skip]
static DEFAULT_MVP: &[f32; 16] = &[
@ -13,7 +11,7 @@ static DEFAULT_MVP: &[f32; 16] = &[
#[derive(Debug, Clone)]
pub struct RenderTarget<'a> {
pub mvp: &'a [f32; 16],
pub output: OutputFramebuffer
pub output: OutputFramebuffer,
}
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 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 {
samplers: FxHashMap<(WrapMode, FilterMode), ID3D11SamplerState>
samplers: FxHashMap<(WrapMode, FilterMode), ID3D11SamplerState>,
}
impl SamplerSet {
pub fn get(&self, wrap: WrapMode, filter: FilterMode) -> &ID3D11SamplerState {
self.samplers.get(&(wrap, filter))
.unwrap()
self.samplers.get(&(wrap, filter)).unwrap()
}
pub fn new(device: &ID3D11Device) -> Result<SamplerSet> {
let mut samplers = FxHashMap::default();
let wrap_modes =
&[WrapMode::ClampToBorder, WrapMode::ClampToEdge, WrapMode::Repeat, WrapMode::MirroredRepeat];
let wrap_modes = &[
WrapMode::ClampToBorder,
WrapMode::ClampToEdge,
WrapMode::Repeat,
WrapMode::MirroredRepeat,
];
for wrap_mode in wrap_modes {
unsafe {
let linear = device.CreateSamplerState(&D3D11_SAMPLER_DESC {
@ -48,9 +54,6 @@ impl SamplerSet {
}
}
Ok(SamplerSet {
samplers
})
Ok(SamplerSet { 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 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;
#[derive(Debug, Clone)]
@ -29,7 +36,13 @@ pub struct 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 {
Width: source.size.width,
Height: source.size.height,
@ -80,17 +93,19 @@ impl OwnedTexture {
unsafe {
let handle = device.CreateTexture2D(&desc, None).unwrap();
let srv = device.CreateShaderResourceView(&handle, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: desc.Format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX
}
},
}))?;
let srv = device.CreateShaderResourceView(
&handle,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: desc.Format,
ViewDimension: D3D_SRV_DIMENSION_TEXTURE2D,
Anonymous: D3D11_SHADER_RESOURCE_VIEW_DESC_0 {
Texture2D: D3D11_TEX2D_SRV {
MostDetailedMip: 0,
MipLevels: u32::MAX,
},
},
}),
)?;
let mut context = None;
device.GetImmediateContext(&mut context);
@ -99,41 +114,50 @@ impl OwnedTexture {
let context = context.unwrap();
// need a staging texture to defer mipmap generation
let staging = device.CreateTexture2D(&D3D11_TEXTURE2D_DESC {
MipLevels: 1,
BindFlags: D3D11_BIND_FLAG(0),
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
Usage: D3D11_USAGE_STAGING,
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
..desc
}, Some(&D3D11_SUBRESOURCE_DATA {
pSysMem: source.bytes.as_ptr().cast(),
SysMemPitch: source.pitch as u32,
SysMemSlicePitch: 0
}))?;
let staging = device.CreateTexture2D(
&D3D11_TEXTURE2D_DESC {
MipLevels: 1,
BindFlags: D3D11_BIND_FLAG(0),
MiscFlags: D3D11_RESOURCE_MISC_FLAG(0),
Usage: D3D11_USAGE_STAGING,
CPUAccessFlags: D3D11_CPU_ACCESS_WRITE,
..desc
},
Some(&D3D11_SUBRESOURCE_DATA {
pSysMem: source.bytes.as_ptr().cast(),
SysMemPitch: source.pitch as u32,
SysMemSlicePitch: 0,
}),
)?;
// todo: do format conversion (leverage image crate..?
// is this necessary with CopySubresourceRegion)...
context.CopySubresourceRegion(&handle, 0, 0, 0, 0,
&staging, 0, Some(&D3D11_BOX {
context.CopySubresourceRegion(
&handle,
0,
0,
0,
0,
&staging,
0,
Some(&D3D11_BOX {
left: 0,
top: 0,
front: 0,
right: source.size.width,
bottom: source.size.height,
back: 1,
}));
}),
);
if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
context.GenerateMips(&srv)
context.GenerateMips(&srv)
}
// let mut subresource = context.Map(staging, 0, D3D11_MAP_WRITE, 0)?;
// staging.Upd
Ok(OwnedTexture {
handle,
// staging,
@ -144,8 +168,8 @@ impl OwnedTexture {
size: source.size,
},
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::slice;
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::Direct3D11::*;
use windows::Win32::Graphics::Dxgi::Common::*;
/// wtf retroarch?
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,
) -> DXGI_FORMAT {
let default_list = [format, DXGI_FORMAT_UNKNOWN];
let format_support_list = d3d11_format_fallback_list(format)
.unwrap_or(&default_list);
let format_support_list = d3d11_format_fallback_list(format).unwrap_or(&default_list);
let format_support_mask = format_support_mask as u32;
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> {
@ -130,39 +129,42 @@ pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> Result
}
}
pub type ShaderFactory<'a, L, T>
= unsafe fn (&'a ID3D11Device, &[u8], linkage: L) -> windows::core::Result<T>;
pub type ShaderFactory<'a, L, 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>)
-> Result<T>
where L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,{
pub fn d3d11_compile_bound_shader<'a, T, L>(
device: &'a ID3D11Device,
blob: &ID3DBlob,
linkage: L,
factory: ShaderFactory<'a, L, T>,
) -> Result<T>
where
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>,
{
unsafe {
// SAFETY: slice as valid for as long as vs_blob is alive.
let dxil = slice::from_raw_parts(
blob.GetBufferPointer().cast::<u8>(),
blob.GetBufferSize(),
);
let dxil =
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize());
let compiled = factory(device, dxil, linkage)?;
Ok(compiled)
}
}
pub fn d3d11_create_input_layout(device: &ID3D11Device, desc: &[D3D11_INPUT_ELEMENT_DESC], blob: &ID3DBlob) -> Result<ID3D11InputLayout> {
pub fn d3d11_create_input_layout(
device: &ID3D11Device,
desc: &[D3D11_INPUT_ELEMENT_DESC],
blob: &ID3DBlob,
) -> Result<ID3D11InputLayout> {
unsafe {
// SAFETY: slice as valid for as long as vs_blob is alive.
let dxil = slice::from_raw_parts(
blob.GetBufferPointer().cast::<u8>(),
blob.GetBufferSize(),
);
let dxil =
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize());
let compiled =
device.CreateInputLayout(desc, dxil)?;
let compiled = device.CreateInputLayout(desc, dxil)?;
Ok(compiled)
}
}
// todo: d3d11.c 2097
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;

View file

@ -1,6 +1,6 @@
use gl::types::GLint;
use librashader_reflect::reflect::semantics::BindingStage;
use librashader_runtime::uniforms::{BindUniform, UniformStorage, UniformScalar};
use librashader_runtime::uniforms::{BindUniform, UniformScalar, UniformStorage};
#[derive(Debug)]
pub enum VariableLocation {
@ -37,7 +37,6 @@ impl UniformLocation<GLint> {
pub(crate) type BufferStorage = UniformStorage<GlUniformBinder, UniformLocation<GLint>>;
pub trait GlUniformScalar: UniformScalar {
const FACTORY: unsafe fn(GLint, Self) -> ();
}
@ -56,7 +55,8 @@ impl GlUniformScalar for u32 {
pub(crate) struct GlUniformBinder;
impl<T> BindUniform<UniformLocation<GLint>, T> for GlUniformBinder
where T: GlUniformScalar
where
T: GlUniformScalar,
{
fn bind_uniform(value: T, location: UniformLocation<GLint>) -> Option<()> {
if location.is_valid(BindingStage::VERTEX | BindingStage::FRAGMENT) {
@ -105,8 +105,8 @@ impl BindUniform<UniformLocation<GLint>, &[f32; 16]> for GlUniformBinder {
}
}
Some(())
}else {
} else {
None
}
}
}
}

View file

@ -20,7 +20,7 @@ pub enum FilterChainError {
#[error("shader reflect error")]
ShaderReflectError(#[from] ShaderReflectError),
#[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::error::{FilterChainError, Result};
use crate::filter_pass::FilterPass;
use crate::framebuffer::{GLImage, Viewport};
use crate::render_target::RenderTarget;
use crate::util;
use crate::util::{gl_get_version, gl_u16_to_version, InlineRingBuffer};
use crate::error::{FilterChainError, Result};
use crate::util::{gl_get_version, gl_u16_to_version};
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
use librashader_common::image::Image;
use librashader_common::{FilterMode, Size, WrapMode};
use gl::types::{GLint, GLuint};
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_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::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 rustc_hash::FxHashMap;
use spirv_cross::spirv::Decoration;
use std::collections::VecDeque;
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> {
passes: Box<[FilterPass<T>]>,
@ -48,10 +51,10 @@ pub struct FilterCommon {
pub struct FilterMutable {
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 {
// todo: support both ubo and pushco
// 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`.
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 version = options.map(|o| gl_u16_to_version(o.gl_version))
.unwrap_or_else(|| gl_get_version());
let version = options
.map(|o| gl_u16_to_version(o.gl_version))
.unwrap_or_else(gl_get_version);
// initialize passes
let filters = Self::init_passes(version, passes, &semantics)?;
@ -137,8 +144,11 @@ impl <T: GLInterface> FilterChain<T> {
common: FilterCommon {
config: FilterMutable {
passes_enabled: preset.shader_count as usize,
parameters: preset.parameters.into_iter()
.map(|param| (param.name, param.value)).collect(),
parameters: preset
.parameters
.into_iter()
.map(|param| (param.name, param.value))
.collect(),
},
luts,
samplers,
@ -150,7 +160,10 @@ impl <T: GLInterface> FilterChain<T> {
}
/// 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
let preset = ShaderPreset::try_parse(path)?;
Self::load_from_preset(preset, options)
@ -158,7 +171,7 @@ impl <T: GLInterface> FilterChain<T> {
fn load_preset(
passes: Vec<ShaderPassConfig>,
textures: &[TextureConfig]
textures: &[TextureConfig],
) -> Result<(Vec<ShaderPassMeta>, ReflectSemantics)> {
let mut uniform_semantics: FxHashMap<String, UniformSemantic> = Default::default();
let mut texture_semantics: FxHashMap<String, SemanticMap<TextureSemantics>> =
@ -195,9 +208,11 @@ impl <T: GLInterface> FilterChain<T> {
)
}
librashader_runtime::semantics::insert_lut_semantics(textures,
&mut uniform_semantics,
&mut texture_semantics);
librashader_runtime::semantics::insert_lut_semantics(
textures,
&mut uniform_semantics,
&mut texture_semantics,
);
let semantics = ReflectSemantics {
uniform_semantics,
@ -254,8 +269,7 @@ impl <T: GLInterface> FilterChain<T> {
gl::UseProgram(program);
for (name, binding) in &glsl.context.sampler_bindings {
let location =
gl::GetUniformLocation(program, name.as_str().as_ptr().cast());
let location = gl::GetUniformLocation(program, name.as_str().as_ptr().cast());
if location >= 0 {
// eprintln!("setting sampler {location} to sample from {binding}");
gl::Uniform1i(location, *binding as GLint);
@ -285,47 +299,38 @@ impl <T: GLInterface> FilterChain<T> {
None
};
let uniform_storage = BufferStorage::new(reflection
.ubo
.as_ref()
.map(|ubo| ubo.size as usize)
.unwrap_or(0),
reflection
.push_constant
.as_ref()
.map(|push| push.size as usize)
.unwrap_or(0)
let uniform_storage = BufferStorage::new(
reflection
.ubo
.as_ref()
.map(|ubo| ubo.size as usize)
.unwrap_or(0),
reflection
.push_constant
.as_ref()
.map(|push| push.size as usize)
.unwrap_or(0),
);
let mut uniform_bindings = FxHashMap::default();
for param in reflection.meta.parameter_meta.values() {
uniform_bindings.insert(
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 {
uniform_bindings.insert(
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 {
uniform_bindings.insert(
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_bindings,
source,
config
config,
});
}
@ -423,7 +428,13 @@ impl <T: GLInterface> FilterChain<T> {
/// Process a frame with the input image.
///
/// 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.
let passes = &mut self.passes[0..self.common.config.passes_enabled];
if let Some(options) = options {

View file

@ -1,5 +1,4 @@
use std::marker::PhantomData;
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
use gl::types::{GLsizei, GLuint};
use librashader_reflect::back::cross::GlslangGlslContext;
use librashader_reflect::back::ShaderCompilerOutput;
use librashader_reflect::reflect::ShaderReflection;
@ -7,19 +6,18 @@ use librashader_reflect::reflect::ShaderReflection;
use librashader_common::{ImageFormat, Size};
use librashader_preprocess::ShaderSource;
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 librashader_runtime::uniforms::UniformStorage;
use crate::binding::{BufferStorage, GlUniformBinder, UniformLocation, VariableLocation};
use crate::binding::{BufferStorage, UniformLocation, VariableLocation};
use crate::filter_chain::FilterCommon;
use crate::framebuffer::Viewport;
use crate::gl::{BindTexture, Framebuffer, GLInterface, UboRing};
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 reflection: ShaderReflection,
@ -33,7 +31,7 @@ pub struct FilterPass<T: GLInterface> {
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)
pub(crate) fn draw(
&mut self,
@ -44,7 +42,7 @@ impl<T:GLInterface> FilterPass<T> {
viewport: &Viewport<T::Framebuffer>,
original: &Texture,
source: &Texture,
output: RenderTarget<T::Framebuffer>
output: RenderTarget<T::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 {
let mut fb_format = ImageFormat::R8G8B8A8Unorm;
if self.config.srgb_framebuffer {
@ -117,7 +114,7 @@ impl <T: GLInterface> FilterPass<T> {
// framecount should be pre-modded
fn build_semantics(
&mut self,
pass_index: usize,
_pass_index: usize,
parent: &FilterCommon,
mvp: &[f32; 16],
frame_count: u32,
@ -128,18 +125,18 @@ impl <T: GLInterface> FilterPass<T> {
source: &Texture,
) {
// Bind MVP
if let Some((location, offset)) =
self.uniform_bindings.get(&VariableSemantics::MVP.into())
if let Some((location, offset)) = 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
if let Some((location, offset)) = self
.uniform_bindings
.get(&VariableSemantics::Output.into())
if let Some((location, offset)) =
self.uniform_bindings.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
@ -147,7 +144,8 @@ impl <T: GLInterface> FilterPass<T> {
.uniform_bindings
.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
@ -155,7 +153,8 @@ impl <T: GLInterface> FilterPass<T> {
.uniform_bindings
.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
@ -163,7 +162,8 @@ impl <T: GLInterface> FilterPass<T> {
.uniform_bindings
.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
@ -182,7 +182,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::Original.semantics(0).into())
{
self.uniform_storage
.bind_vec4(*offset,original.image.size, location.location());
.bind_vec4(*offset, original.image.size, location.location());
}
// bind Source sampler
@ -201,8 +201,8 @@ impl <T: GLInterface> FilterPass<T> {
.uniform_bindings
.get(&TextureSemantics::Source.semantics(0).into())
{
self.uniform_storage.bind_vec4(*offset,
source.image.size, location.location());
self.uniform_storage
.bind_vec4(*offset, source.image.size, location.location());
}
if let Some(binding) = self
@ -218,7 +218,7 @@ impl <T: GLInterface> FilterPass<T> {
.get(&TextureSemantics::OriginalHistory.semantics(0).into())
{
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() {
@ -240,7 +240,7 @@ impl <T: GLInterface> FilterPass<T> {
.into(),
) {
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())
{
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())
{
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)
.unwrap_or(0f32);
let value = *parent
.config
.parameters
.get(id)
.unwrap_or(&default);
let value = *parent.config.parameters.get(id).unwrap_or(&default);
self.uniform_storage
.bind_scalar(*offset, value, location.location());

View file

@ -1,10 +1,6 @@
use crate::util;
use crate::texture::Texture;
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 gl::types::{GLenum, GLuint};
use librashader_common::Size;
use crate::gl::Framebuffer;
#[derive(Debug, Copy, Clone)]

View file

@ -1,5 +1,5 @@
use gl::types::{GLsizei, GLsizeiptr, GLuint};
use crate::gl::DrawQuad;
use gl::types::{GLsizei, GLsizeiptr, GLuint};
#[rustfmt::skip]
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 librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D;
use crate::framebuffer::{GLImage, Viewport};
use crate::error::{FilterChainError, Result};
use crate::gl::Framebuffer;
use crate::texture::Texture;
#[derive(Debug)]
pub struct Gl3Framebuffer {
@ -97,7 +97,8 @@ impl Framebuffer for Gl3Framebuffer {
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 {
self.size = size;
@ -294,7 +295,7 @@ impl Framebuffer for Gl3Framebuffer {
// self.init =
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
}
_ => return Err(FilterChainError::FramebufferInit(status))
_ => return Err(FilterChainError::FramebufferInit(status)),
}
}
@ -317,4 +318,4 @@ impl Drop for Gl3Framebuffer {
}
}
}
}
}

View file

@ -9,8 +9,8 @@ use librashader_common::Size;
use crate::filter_chain::FilterChain;
use crate::framebuffer::{GLImage, Viewport};
use crate::gl::{Framebuffer, GLInterface};
use crate::gl::gl3::CompatibilityGL;
use crate::gl::{Framebuffer, GLInterface};
const WIDTH: u32 = 900;
const HEIGHT: u32 = 700;
@ -519,7 +519,8 @@ void main()
padded_size: Default::default(),
};
filter.frame(framecount, &viewport, &rendered, None)
filter
.frame(framecount, &viewport, &rendered, None)
.unwrap();
unsafe {
@ -563,4 +564,4 @@ fn glfw_handle_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
Event::Size(width, height) => window.set_size(width, height),
_ => {}
}
}
}

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 rustc_hash::FxHashMap;
use librashader_common::image::Image;
use librashader_common::Size;
use librashader_presets::TextureConfig;
use crate::gl::LoadLut;
use crate::framebuffer::{GLImage, Viewport};
use crate::texture::Texture;
use crate::error::Result;
use rustc_hash::FxHashMap;
pub struct Gl3LutLoad;
impl LoadLut for Gl3LutLoad {
@ -82,4 +82,4 @@ impl LoadLut for Gl3LutLoad {
};
Ok(luts)
}
}
}

View file

@ -1,17 +1,17 @@
mod lut_load;
mod draw_quad;
mod ubo_ring;
mod framebuffer;
mod texture_bind;
#[cfg(test)]
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 draw_quad::*;
use framebuffer::*;
use lut_load::*;
use texture_bind::*;
use ubo_ring::*;
pub struct CompatibilityGL;
impl GLInterface for CompatibilityGL {

View file

@ -1,7 +1,7 @@
use librashader_reflect::reflect::semantics::TextureBinding;
use crate::gl::BindTexture;
use crate::samplers::SamplerSet;
use crate::texture::Texture;
use librashader_reflect::reflect::semantics::TextureBinding;
pub struct Gl3BindTexture;
@ -12,8 +12,10 @@ impl BindTexture for Gl3BindTexture {
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
gl::BindSampler(binding.binding,
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
gl::BindSampler(
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::gl::UboRing;
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> {
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 {
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
unsafe {
@ -26,12 +25,15 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
}
gl::BindBuffer(gl::UNIFORM_BUFFER, 0);
}
Gl3UboRing {
ring
}
Gl3UboRing { 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 buffer = self.ring.current();
@ -55,5 +57,3 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl3UboRing<SIZE> {
self.ring.next()
}
}

View file

@ -1,5 +1,5 @@
use gl::types::{GLint, GLsizei, GLsizeiptr, GLuint};
use crate::gl::DrawQuad;
use gl::types::{GLint, GLsizeiptr, GLuint};
#[rustfmt::skip]
static QUAD_VBO_DATA: &[f32; 16] = &[
@ -32,19 +32,20 @@ impl DrawQuad for Gl46DrawQuad {
gl::EnableVertexArrayAttrib(vao, 0);
gl::EnableVertexArrayAttrib(vao, 1);
gl::VertexArrayVertexBuffer(vao, 0,
vbo, 0, 4 * std::mem::size_of::<f32>() as GLint
);
gl::VertexArrayVertexBuffer(vao, 0, vbo, 0, 4 * std::mem::size_of::<f32>() as GLint);
gl::VertexArrayAttribFormat(vao, 0, 2,
gl::FLOAT, gl::FALSE, 0);
gl::VertexArrayAttribFormat(vao, 1, 2,
gl::FLOAT, gl::FALSE,
2 * std::mem::size_of::<f32>() as GLuint);
gl::VertexArrayAttribFormat(vao, 0, 2, gl::FLOAT, gl::FALSE, 0);
gl::VertexArrayAttribFormat(
vao,
1,
2,
gl::FLOAT,
gl::FALSE,
2 * std::mem::size_of::<f32>() as GLuint,
);
gl::VertexArrayAttribBinding(vao, 0, 0);
gl::VertexArrayAttribBinding(vao, 1, 0);
}
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 librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_presets::Scale2D;
use crate::framebuffer::{GLImage, Viewport};
use crate::error::{FilterChainError, Result};
use crate::gl::Framebuffer;
use crate::texture::Texture;
#[derive(Debug)]
pub struct Gl46Framebuffer {
@ -17,7 +17,6 @@ pub struct Gl46Framebuffer {
is_raw: bool,
}
impl Framebuffer for Gl46Framebuffer {
fn handle(&self) -> GLuint {
self.handle
@ -96,7 +95,8 @@ impl Framebuffer for Gl46Framebuffer {
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 {
self.size = size;
@ -114,9 +114,12 @@ impl Framebuffer for Gl46Framebuffer {
}
fn clear<const REBIND: bool>(&self) {
unsafe {
gl::ClearNamedFramebufferfv(self.handle,
gl::COLOR, 0,
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast());
gl::ClearNamedFramebufferfv(
self.handle,
gl::COLOR,
0,
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast(),
);
}
}
fn copy_from(&mut self, image: &GLImage) -> Result<()> {
@ -130,11 +133,20 @@ impl Framebuffer for Gl46Framebuffer {
gl::NamedFramebufferReadBuffer(image.handle, gl::COLOR_ATTACHMENT0);
gl::NamedFramebufferDrawBuffer(self.handle, gl::COLOR_ATTACHMENT1);
gl::BlitNamedFramebuffer(image.handle, self.handle,
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);
gl::BlitNamedFramebuffer(
image.handle,
self.handle,
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(())
@ -149,16 +161,11 @@ impl Framebuffer for Gl46Framebuffer {
unsafe {
// reset the framebuffer image
if self.image != 0 {
gl::NamedFramebufferTexture(
self.handle,
gl::COLOR_ATTACHMENT0,
0,
0,
);
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, 0, 0);
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 {
size.width = 1;
@ -183,12 +190,7 @@ impl Framebuffer for Gl46Framebuffer {
size.height as GLsizei,
);
gl::NamedFramebufferTexture(
self.handle,
gl::COLOR_ATTACHMENT0,
self.image,
0,
);
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, self.image, 0);
let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER);
if status != gl::FRAMEBUFFER_COMPLETE {
@ -196,12 +198,7 @@ impl Framebuffer for Gl46Framebuffer {
gl::FRAMEBUFFER_UNSUPPORTED => {
eprintln!("unsupported fbo");
gl::NamedFramebufferTexture(
self.handle,
gl::COLOR_ATTACHMENT0,
0,
0,
);
gl::NamedFramebufferTexture(self.handle, gl::COLOR_ATTACHMENT0, 0, 0);
gl::DeleteTextures(1, &self.image);
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut self.image);
@ -229,7 +226,7 @@ impl Framebuffer for Gl46Framebuffer {
// self.init =
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
}
_ => return Err(FilterChainError::FramebufferInit(status))
_ => return Err(FilterChainError::FramebufferInit(status)),
}
}
}
@ -248,4 +245,4 @@ impl Drop for Gl46Framebuffer {
}
}
}
}
}

View file

@ -9,8 +9,8 @@ use librashader_common::Size;
use crate::filter_chain::FilterChain;
use crate::framebuffer::{GLImage, Viewport};
use crate::gl::{Framebuffer, GLInterface};
use crate::gl::gl46::DirectStateAccessGL;
use crate::gl::{Framebuffer, GLInterface};
const WIDTH: u32 = 900;
const HEIGHT: u32 = 700;
@ -216,20 +216,20 @@ void main()
gl::CreateVertexArrays(1, &mut vao);
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
gl::VertexArrayVertexBuffer(vao, 0,
vbo, 0, 6 * std::mem::size_of::<f32>() as GLint
);
gl::VertexArrayVertexBuffer(vao, 0, vbo, 0, 6 * std::mem::size_of::<f32>() as GLint);
gl::EnableVertexArrayAttrib(vao, 0); // this is "layout (location = 0)" in vertex shader
gl::VertexArrayAttribFormat(vao, 0, 3,
gl::FLOAT, gl::FALSE, 0);
gl::VertexArrayAttribFormat(vao, 0, 3, gl::FLOAT, gl::FALSE, 0);
gl::EnableVertexArrayAttrib(vao, 1);
gl::VertexArrayAttribFormat(vao, 1, 3,
gl::FLOAT, gl::FALSE, 3 * std::mem::size_of::<f32>() as GLuint);
gl::VertexArrayAttribFormat(
vao,
1,
3,
gl::FLOAT,
gl::FALSE,
3 * std::mem::size_of::<f32>() as GLuint,
);
gl::VertexArrayAttribBinding(vao, 0, 0);
gl::VertexArrayAttribBinding(vao, 1, 0);
@ -281,7 +281,7 @@ pub fn do_loop(
);
// make tetxure
gl::CreateTextures(gl::TEXTURE_2D,1, &mut rendered_texture);
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut rendered_texture);
gl::ObjectLabel(
gl::TEXTURE,
@ -299,8 +299,16 @@ pub fn do_loop(
HEIGHT as GLsizei,
);
gl::TextureParameteri(rendered_texture, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
gl::TextureParameteri(rendered_texture, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
gl::TextureParameteri(
rendered_texture,
gl::TEXTURE_MAG_FILTER,
gl::NEAREST as GLint,
);
gl::TextureParameteri(
rendered_texture,
gl::TEXTURE_MIN_FILTER,
gl::NEAREST as GLint,
);
gl::TextureParameteri(
rendered_texture,
gl::TEXTURE_WRAP_S,
@ -334,7 +342,7 @@ pub fn do_loop(
gl::CreateBuffers(1, &mut quad_vbuf);
gl::NamedBufferData(
quad_vbuf, // target
quad_vbuf, // target
(fullscreen_fbo.len() * std::mem::size_of::<f32>()) as gl::types::GLsizeiptr, // size of data in bytes
fullscreen_fbo.as_ptr() as *const gl::types::GLvoid, // pointer to data
gl::STATIC_DRAW, // usage
@ -353,7 +361,7 @@ pub fn do_loop(
);
// make tetxure
gl::CreateTextures(gl::TEXTURE_2D,1, &mut output_texture);
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut output_texture);
gl::ObjectLabel(
gl::TEXTURE,
@ -371,7 +379,7 @@ pub fn do_loop(
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,
@ -464,7 +472,12 @@ void main()
unsafe {
// 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::Viewport(0, 0, vp_width, vp_height);
@ -500,7 +513,8 @@ void main()
padded_size: Default::default(),
};
filter.frame(framecount, &viewport, &rendered, None)
filter
.frame(framecount, &viewport, &rendered, None)
.unwrap();
unsafe {
@ -508,7 +522,7 @@ void main()
// draw quad to screen
gl::UseProgram(quad_programid);
gl::BindTextureUnit(0, output_texture);
gl::BindTextureUnit(0, output_texture);
gl::BindVertexArray(quad_vao);
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
@ -543,4 +557,4 @@ fn glfw_handle_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
Event::Size(width, height) => window.set_size(width, height),
_ => {}
}
}
}

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 rustc_hash::FxHashMap;
use librashader_common::image::Image;
use librashader_common::Size;
use librashader_presets::TextureConfig;
use crate::gl::LoadLut;
use crate::framebuffer::{GLImage, Viewport};
use crate::texture::Texture;
use crate::error::Result;
use rustc_hash::FxHashMap;
pub struct Gl46LutLoad;
impl LoadLut for Gl46LutLoad {
@ -32,7 +32,7 @@ impl LoadLut for Gl46LutLoad {
let mut handle = 0;
unsafe {
gl::CreateTextures(gl::TEXTURE_2D,1, &mut handle);
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut handle);
gl::TextureStorage2D(
handle,
@ -47,7 +47,9 @@ impl LoadLut for Gl46LutLoad {
gl::TextureSubImage2D(
handle,
0, 0, 0,
0,
0,
0,
image.size.width as GLsizei,
image.size.height as GLsizei,
gl::RGBA,
@ -82,4 +84,4 @@ impl LoadLut for Gl46LutLoad {
};
Ok(luts)
}
}
}

View file

@ -1,18 +1,18 @@
mod lut_load;
mod draw_quad;
mod ubo_ring;
mod framebuffer;
mod lut_load;
mod texture_bind;
mod ubo_ring;
#[cfg(test)]
pub mod hello_triangle;
use lut_load::*;
use draw_quad::*;
use ubo_ring::*;
use framebuffer::*;
use texture_bind::*;
use crate::gl::GLInterface;
use draw_quad::*;
use framebuffer::*;
use lut_load::*;
use texture_bind::*;
use ubo_ring::*;
pub struct DirectStateAccessGL;
impl GLInterface for DirectStateAccessGL {
@ -21,4 +21,4 @@ impl GLInterface for DirectStateAccessGL {
type DrawQuad = Gl46DrawQuad;
type LoadLut = Gl46LutLoad;
type BindTexture = Gl46BindTexture;
}
}

View file

@ -1,7 +1,7 @@
use librashader_reflect::reflect::semantics::TextureBinding;
use crate::gl::BindTexture;
use crate::samplers::SamplerSet;
use crate::texture::Texture;
use librashader_reflect::reflect::semantics::TextureBinding;
pub struct Gl46BindTexture;
@ -10,8 +10,10 @@ impl BindTexture for Gl46BindTexture {
unsafe {
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
gl::BindTextureUnit(binding.binding, texture.image.handle);
gl::BindSampler(binding.binding,
samplers.get(texture.wrap_mode, texture.filter, texture.mip_filter));
gl::BindSampler(
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::gl::UboRing;
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> {
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 {
let mut ring: InlineRingBuffer<GLuint, SIZE> = InlineRingBuffer::new();
unsafe {
@ -25,22 +24,20 @@ impl <const SIZE: usize> UboRing<SIZE> for Gl46UboRing<SIZE> {
}
};
Gl46UboRing {
ring
}
Gl46UboRing { 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 buffer = self.ring.current();
unsafe {
gl::NamedBufferSubData(
*buffer,
0,
size as GLsizeiptr,
storage.ubo_pointer().cast(),
);
gl::NamedBufferSubData(*buffer, 0, size as GLsizeiptr, storage.ubo_pointer().cast());
if ubo_location.vertex != gl::INVALID_INDEX {
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()
}
}

View file

@ -1,17 +1,17 @@
pub(crate) mod gl3;
pub(crate) mod gl46;
use gl::types::{GLenum, GLint, GLsizei, GLuint};
use rustc_hash::FxHashMap;
use crate::binding::UniformLocation;
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_presets::{Scale2D, TextureConfig};
use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
use librashader_runtime::uniforms::{UniformStorage, UniformStorageAccess};
use crate::binding::UniformLocation;
use crate::texture::Texture;
use crate::error::{FilterChainError, Result};
use crate::framebuffer::{GLImage, Viewport};
use crate::samplers::SamplerSet;
use librashader_runtime::uniforms::UniformStorageAccess;
use rustc_hash::FxHashMap;
pub trait LoadLut {
fn load_luts(textures: &[TextureConfig]) -> Result<FxHashMap<usize, Texture>>;
@ -25,7 +25,12 @@ pub trait DrawQuad {
pub trait UboRing<const SIZE: usize> {
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 {
@ -65,4 +70,4 @@ pub trait GLInterface {
type DrawQuad: DrawQuad;
type LoadLut: LoadLut;
type BindTexture: BindTexture;
}
}

View file

@ -8,11 +8,10 @@ mod framebuffer;
mod render_target;
mod util;
mod gl;
pub mod options;
mod samplers;
mod texture;
pub mod options;
mod gl;
pub mod error;
pub use filter_chain::FilterChain;
@ -21,13 +20,19 @@ pub use framebuffer::Viewport;
pub mod gl3 {
pub use super::framebuffer::GLImage;
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 use super::framebuffer::GLImage;
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)]
@ -39,8 +44,8 @@ mod tests {
fn triangle_gl() {
let (glfw, window, events, shader, vao) = gl::gl3::hello_triangle::setup();
let mut filter =
FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp", None)
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp", None)
// FilterChain::load_from_path("../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", None)
.unwrap();
gl::gl3::hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter);
}

View file

@ -1,11 +1,11 @@
#[repr(C)]
#[derive(Debug, Clone)]
pub struct FrameOptions {
pub clear_history: bool
pub clear_history: bool,
}
#[repr(C)]
#[derive(Debug, Clone)]
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 framebuffer: &'a T,
pub x: i32,
pub y: i32
pub y: i32,
}
impl<'a, T: Framebuffer> RenderTarget<'a, T> {

View file

@ -1,50 +1,40 @@
use gl::types::{GLenum, GLint, GLuint};
use rustc_hash::FxHashMap;
use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap;
pub struct SamplerSet {
// todo: may need to deal with differences in mip filter.
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), GLuint>
samplers: FxHashMap<(WrapMode, FilterMode, FilterMode), GLuint>,
}
impl SamplerSet {
pub fn get(&self, wrap: WrapMode, filter: FilterMode, mip: FilterMode) -> GLuint {
// eprintln!("{wrap}, {filter}, {mip}");
*self.samplers.get(&(wrap, filter, mip))
.unwrap()
*self.samplers.get(&(wrap, filter, mip)).unwrap()
}
fn make_sampler(sampler: GLuint, wrap: WrapMode, filter: FilterMode, mip: FilterMode) {
unsafe {
gl::SamplerParameteri(
sampler,
gl::TEXTURE_WRAP_S,
GLenum::from(wrap) as GLint,
);
gl::SamplerParameteri(
sampler,
gl::TEXTURE_WRAP_T,
GLenum::from(wrap) as GLint,
);
gl::SamplerParameteri(sampler, gl::TEXTURE_WRAP_S, GLenum::from(wrap) as GLint);
gl::SamplerParameteri(sampler, gl::TEXTURE_WRAP_T, GLenum::from(wrap) as GLint);
gl::SamplerParameteri(
sampler,
gl::TEXTURE_MAG_FILTER,
GLenum::from(filter) as GLint,
);
gl::SamplerParameteri(
sampler,
gl::TEXTURE_MIN_FILTER,
GLenum::from(filter.gl_mip(mip)) as GLint,
);
gl::SamplerParameteri(sampler, gl::TEXTURE_MIN_FILTER, filter.gl_mip(mip) as GLint);
}
}
pub fn new() -> SamplerSet {
let mut samplers = FxHashMap::default();
let wrap_modes =
&[WrapMode::ClampToBorder, WrapMode::ClampToEdge, WrapMode::Repeat, WrapMode::MirroredRepeat];
let wrap_modes = &[
WrapMode::ClampToBorder,
WrapMode::ClampToEdge,
WrapMode::Repeat,
WrapMode::MirroredRepeat,
];
for wrap_mode in wrap_modes {
unsafe {
let mut linear_linear = 0;
@ -57,27 +47,51 @@ impl SamplerSet {
gl::GenSamplers(1, &mut nearest_linear);
gl::GenSamplers(1, &mut nearest_nearest);
SamplerSet::make_sampler(linear_linear, *wrap_mode,
FilterMode::Linear, FilterMode::Linear);
SamplerSet::make_sampler(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);
SamplerSet::make_sampler(
linear_linear,
*wrap_mode,
FilterMode::Linear,
FilterMode::Linear,
);
SamplerSet::make_sampler(
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((*wrap_mode, FilterMode::Linear, FilterMode::Nearest), linear_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::Nearest),
nearest_nearest,
);
samplers.insert(
(*wrap_mode, FilterMode::Nearest, FilterMode::Linear),
nearest_linear,
);
}
}
SamplerSet {
samplers
}
SamplerSet { samplers }
}
}

View file

@ -1,5 +1,5 @@
use librashader_common::{FilterMode, WrapMode};
use crate::framebuffer::GLImage;
use librashader_common::{FilterMode, WrapMode};
#[derive(Default, Debug, Copy, Clone)]
pub struct Texture {
@ -11,6 +11,6 @@ pub struct Texture {
impl Texture {
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 librashader_common::Size;
use gl::types::{GLenum, GLuint};
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> {
fn current(&self) -> &T;
@ -87,7 +84,7 @@ pub fn gl_get_version() -> GlVersion {
1 => GlVersion::V1_40,
0 => GlVersion::V1_30,
_ => GlVersion::V1_50,
}
},
4 => match min_ver {
6 => GlVersion::V4_60,
5 => GlVersion::V4_50,
@ -96,11 +93,10 @@ pub fn gl_get_version() -> GlVersion {
2 => GlVersion::V4_20,
1 => GlVersion::V4_10,
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 {
@ -116,6 +112,6 @@ pub fn gl_u16_to_version(version: u16) -> GlVersion {
440 => GlVersion::V4_40,
450 => GlVersion::V4_50,
460 => GlVersion::V4_60,
_ => GlVersion::V1_50
_ => GlVersion::V1_50,
}
}

View file

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

View file

@ -1,11 +1,12 @@
use std::ops::Mul;
use librashader_common::Size;
use librashader_presets::{Scale2D, ScaleFactor, ScaleType, Scaling};
use num_traits::AsPrimitive;
use std::ops::Mul;
pub fn scale<T>(scaling: Scale2D, source: Size<T>, viewport: Size<T>) -> Size<T>
where T: Mul<ScaleFactor, Output=f32> + Copy + 'static,
f32: AsPrimitive<T>,
where
T: Mul<ScaleFactor, Output = f32> + Copy + 'static,
f32: AsPrimitive<T>,
{
let width: f32;
let height: f32;
@ -55,4 +56,4 @@ pub fn calc_miplevel(size: Size<u32>) -> u32 {
}
levels
}
}

View file

@ -1,11 +1,10 @@
use librashader_presets::{ShaderPassConfig, TextureConfig};
use rustc_hash::FxHashMap;
use librashader_reflect::reflect::semantics::{SemanticMap, TextureSemantics, UniformSemantic};
use rustc_hash::FxHashMap;
pub type UniformSemanticsMap = FxHashMap<String, UniformSemantic>;
pub type TextureSemanticsMap = FxHashMap<String, SemanticMap<TextureSemantics>>;
pub fn insert_pass_semantics(
uniform_semantics: &mut UniformSemanticsMap,
texture_semantics: &mut TextureSemanticsMap,
@ -55,9 +54,11 @@ pub fn insert_pass_semantics(
);
}
pub fn insert_lut_semantics(textures: &[TextureConfig],
uniform_semantics: &mut UniformSemanticsMap,
texture_semantics: &mut TextureSemanticsMap) {
pub fn insert_lut_semantics(
textures: &[TextureConfig],
uniform_semantics: &mut UniformSemanticsMap,
texture_semantics: &mut TextureSemanticsMap,
) {
for (index, texture) in textures.iter().enumerate() {
texture_semantics.insert(
texture.name.clone(),

View file

@ -1,5 +1,5 @@
use std::marker::PhantomData;
use librashader_reflect::reflect::semantics::MemberOffset;
use std::marker::PhantomData;
pub trait UniformScalar: Copy + bytemuck::Pod {}
impl UniformScalar for f32 {}
@ -7,7 +7,7 @@ impl UniformScalar for i32 {}
impl UniformScalar for u32 {}
pub struct NoUniformBinder;
impl <T> BindUniform<Option<()>, T> for NoUniformBinder {
impl<T> BindUniform<Option<()>, T> for NoUniformBinder {
fn bind_uniform(_: T, _: Option<()>) -> Option<()> {
None
}
@ -22,7 +22,7 @@ pub trait UniformStorageAccess {
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 {
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 push: Box<[u8]>,
_h: PhantomData<H>,
_c: PhantomData<C>
_c: PhantomData<C>,
}
impl <H, C> UniformStorage<H, C>
where H: BindUniform<C, f32>, H: BindUniform<C, u32>, H: BindUniform<C, i32>,
H: for <'a> BindUniform<C, &'a [f32; 4]>,
H: for <'a> BindUniform<C, &'a [f32; 16]>
impl<H, C> UniformStorage<H, C>
where
H: BindUniform<C, f32>,
H: BindUniform<C, u32>,
H: BindUniform<C, i32>,
H: for<'a> BindUniform<C, &'a [f32; 4]>,
H: for<'a> BindUniform<C, &'a [f32; 16]>,
{
pub fn new(ubo_size: usize, push_size: usize) -> Self {
UniformStorage {
@ -55,16 +58,17 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
#[inline(always)]
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);
buffer[0] = value;
};
}
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);
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) {
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);
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::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) {
@ -92,17 +100,26 @@ H: for <'a> BindUniform<C, &'a [f32; 16]>
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)
where H: BindUniform<C, T>
where
H: BindUniform<C, T>,
{
let (buffer, offset) = match offset {
MemberOffset::Ubo(offset) => (&mut self.ubo, 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::reflect::{
ReflectMeta, ReflectShader, semantics, ShaderReflection
semantics, ReflectMeta, ReflectShader, ShaderReflection,
};
pub use librashader_reflect::front::shaderc::GlslangCompilation;
pub use librashader_reflect::back::{
CompileShader,
FromCompilation,
targets::OutputTarget, CompileShader, CompilerBackend, FromCompilation,
ShaderCompilerOutput,
CompilerBackend,
targets::OutputTarget,
};
pub use librashader_reflect::front::shaderc::GlslangCompilation;
}
pub mod targets {
@ -32,11 +29,10 @@ pub mod targets {
/// Shader compiler target for GLSL.
pub use librashader_reflect::back::targets::GLSL;
/// Shader runtime for OpenGL.
pub mod runtime {
pub use librashader_runtime_gl::options::*;
pub use librashader_runtime_gl::error;
pub use librashader_runtime_gl::options::*;
pub use librashader_runtime_gl::FilterChain;
pub use librashader_runtime_gl::Viewport;
@ -72,19 +68,18 @@ pub mod targets {
}
}
pub use librashader_common::{
FilterMode,
ImageFormat,
Size,
WrapMode
};
pub use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
pub mod util {
use librashader_preprocess::{PreprocessError, ShaderParameter, ShaderSource};
use librashader_presets::ShaderPreset;
pub fn get_parameter_meta(preset: &ShaderPreset) -> Result<impl Iterator<Item = ShaderParameter>, PreprocessError> {
let iters: Result<Vec<Vec<ShaderParameter>>, PreprocessError> = preset.shaders.iter()
pub fn get_parameter_meta(
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))
.into_iter()
.collect();