fmt: run cargo fmt and clippy
This commit is contained in:
parent
f5c56895fb
commit
5088e1c55b
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
pub use image::ImageError;
|
||||
|
|
|
@ -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 {
|
||||
[
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -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)?,
|
||||
})
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(())
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()?;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>>;
|
||||
|
||||
|
|
|
@ -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,7 +105,7 @@ impl BindUniform<UniformLocation<GLint>, &[f32; 16]> for GlUniformBinder {
|
|||
}
|
||||
}
|
||||
Some(())
|
||||
}else {
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pub mod scaling;
|
||||
pub mod semantics;
|
||||
pub mod uniforms;
|
||||
pub mod scaling;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue