gl: fix sampler binding
This commit is contained in:
parent
d49fa5307a
commit
090df176c8
|
@ -7,7 +7,7 @@ use crate::reflect::ReflectShader;
|
|||
|
||||
pub type GlVersion = spirv_cross::glsl::Version;
|
||||
pub struct GlslangGlslContext {
|
||||
pub texture_fixups: Vec<u32>,
|
||||
pub sampler_bindings: Vec<u32>,
|
||||
pub compiler: CompiledAst<spirv_cross::glsl::Target>
|
||||
}
|
||||
impl FromCompilation<GlslangCompilation> for GLSL {
|
||||
|
|
|
@ -810,7 +810,7 @@ impl CompileShader<GLSL> for CrossReflect<glsl::Target> {
|
|||
vertex: self.vertex.compile()?,
|
||||
fragment: self.fragment.compile()?,
|
||||
context: GlslangGlslContext {
|
||||
texture_fixups,
|
||||
sampler_bindings: texture_fixups,
|
||||
compiler: CompiledAst {
|
||||
vertex: self.vertex,
|
||||
fragment: self.fragment
|
||||
|
|
|
@ -24,7 +24,6 @@ pub struct FilterPass {
|
|||
pub uniform_buffer: Box<[u8]>,
|
||||
pub push_buffer: Box<[u8]>,
|
||||
pub variable_bindings: FxHashMap<UniformBinding, (VariableLocation, MemberOffset)>,
|
||||
pub framebuffer: Framebuffer,
|
||||
pub feedback_framebuffer: Framebuffer,
|
||||
pub source: ShaderSource,
|
||||
pub config: ShaderPassConfig
|
||||
|
@ -86,8 +85,8 @@ impl FilterPass {
|
|||
|
||||
fn bind_texture(binding: &TextureImage, texture: &Texture) {
|
||||
unsafe {
|
||||
// eprintln!("binding {} = texture {}", binding.binding, texture.image.handle);
|
||||
gl::ActiveTexture((gl::TEXTURE0 + binding.binding) as GLenum);
|
||||
// eprintln!("setting {} to texunit {}", texture.image.handle, binding.binding);
|
||||
gl::ActiveTexture(gl::TEXTURE0 + binding.binding);
|
||||
gl::BindTexture(gl::TEXTURE_2D, texture.image.handle);
|
||||
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, GLenum::from(texture.filter) as GLint);
|
||||
|
@ -97,87 +96,25 @@ impl FilterPass {
|
|||
}
|
||||
}
|
||||
|
||||
fn scale_framebuffer(&mut self, format: ShaderFormat, viewport: &Viewport, original: &Texture, source: &Texture) -> Size {
|
||||
let mut width = 0f32;
|
||||
let mut height = 0f32;
|
||||
|
||||
match self.config.scaling.x {
|
||||
Scaling {
|
||||
scale_type: ScaleType::Input,
|
||||
factor
|
||||
} => {
|
||||
width = source.image.size.width * factor
|
||||
},
|
||||
Scaling {
|
||||
scale_type: ScaleType::Absolute,
|
||||
factor
|
||||
} => {
|
||||
width = factor.into()
|
||||
}
|
||||
Scaling {
|
||||
scale_type: ScaleType::Viewport,
|
||||
factor
|
||||
} => {
|
||||
width = viewport.size.width * factor
|
||||
}
|
||||
};
|
||||
|
||||
match self.config.scaling.y {
|
||||
Scaling {
|
||||
scale_type: ScaleType::Input,
|
||||
factor
|
||||
} => {
|
||||
height = source.image.size.height * factor
|
||||
},
|
||||
Scaling {
|
||||
scale_type: ScaleType::Absolute,
|
||||
factor
|
||||
} => {
|
||||
height = factor.into()
|
||||
}
|
||||
Scaling {
|
||||
scale_type: ScaleType::Viewport,
|
||||
factor
|
||||
} => {
|
||||
height = viewport.size.height * factor
|
||||
}
|
||||
};
|
||||
|
||||
let size = Size {
|
||||
width: width.round() as u32,
|
||||
height: height.round() as u32
|
||||
};
|
||||
|
||||
if self.framebuffer.size != size {
|
||||
self.framebuffer.size = size;
|
||||
|
||||
self.framebuffer.init(size,if format == ShaderFormat::Unknown {
|
||||
ShaderFormat::R8G8B8A8Unorm
|
||||
} else {
|
||||
format
|
||||
});
|
||||
}
|
||||
size
|
||||
}
|
||||
|
||||
// todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo)
|
||||
pub fn build_commands(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32, frame_direction: i32, viewport: &Viewport, original: &Texture, source: &Texture) {
|
||||
pub fn get_format(&self) -> ShaderFormat {
|
||||
let mut fb_format = ShaderFormat::R8G8B8A8Unorm;
|
||||
if self.config.srgb_framebuffer {
|
||||
fb_format = ShaderFormat::R8G8B8A8Srgb;
|
||||
} else if self.config.float_framebuffer {
|
||||
fb_format = ShaderFormat::R16G16B16A16Sfloat;
|
||||
}
|
||||
fb_format
|
||||
}
|
||||
|
||||
let fb_size = self.scale_framebuffer(fb_format, viewport, original, source);
|
||||
|
||||
// println!("[frame] Using framebuffer {}, image {}", self.framebuffer.framebuffer, self.framebuffer.image);
|
||||
// todo: fix rendertargets (i.e. non-final pass is internal, final pass is user provided fbo)
|
||||
pub fn draw(&mut self, parent: &FilterCommon, mvp: Option<&[f32]>, frame_count: u32,
|
||||
frame_direction: i32, viewport: &Viewport, original: &Texture, source: &Texture, output: &Framebuffer) {
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer.framebuffer);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, output.framebuffer);
|
||||
gl::UseProgram(self.program);
|
||||
}
|
||||
|
||||
self.build_semantics(parent, mvp, frame_count, frame_direction, fb_size, viewport, original, source);
|
||||
self.build_semantics(parent, mvp, frame_count, frame_direction, output.size, viewport, original, source);
|
||||
// shader_gl3:1514
|
||||
|
||||
if self.ubo_location.vertex != gl::INVALID_INDEX && self.ubo_location.fragment != gl::INVALID_INDEX {
|
||||
|
@ -205,14 +142,14 @@ impl FilterPass {
|
|||
// todo: final pass?
|
||||
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, self.framebuffer.framebuffer);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, output.framebuffer);
|
||||
gl::ColorMask(gl::TRUE, gl::TRUE, gl::TRUE, gl::TRUE);
|
||||
gl::ClearColor(0.0f32, 0.0f32, 0.0f32, 0.0f32);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
//
|
||||
gl::Viewport(0, 0, fb_size.width as GLsizei, fb_size.height as GLsizei);
|
||||
gl::Viewport(0, 0, output.size.width as GLsizei, output.size.height as GLsizei);
|
||||
|
||||
if self.framebuffer.format == gl::SRGB8_ALPHA8 {
|
||||
if output.format == gl::SRGB8_ALPHA8 {
|
||||
gl::Enable(gl::FRAMEBUFFER_SRGB);
|
||||
} else {
|
||||
gl::Disable(gl::FRAMEBUFFER_SRGB);
|
||||
|
@ -280,7 +217,7 @@ impl FilterPass {
|
|||
MemberOffset::Ubo(offset) => (&mut self.uniform_buffer, *offset),
|
||||
MemberOffset::PushConstant(offset) => (&mut self.push_buffer, *offset)
|
||||
};
|
||||
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], viewport.size)
|
||||
FilterPass::build_vec4(location.location(), &mut buffer[offset..][..4], viewport.output.size)
|
||||
}
|
||||
|
||||
if let Some((location, offset)) = self.variable_bindings.get(&VariableSemantics::FrameCount.into()) {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use gl::types::{GLenum, GLsizei, GLuint};
|
||||
use librashader::ShaderFormat;
|
||||
use librashader::{FilterMode, ShaderFormat, WrapMode};
|
||||
use librashader_presets::{Scale2D, ScaleType, Scaling};
|
||||
use crate::util;
|
||||
use crate::util::Size;
|
||||
use crate::util::{GlImage, Size, Texture, Viewport};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Framebuffer {
|
||||
pub image: GLuint,
|
||||
pub size: Size,
|
||||
|
@ -33,7 +35,96 @@ impl Framebuffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn init(&mut self, mut size: Size, mut format: impl Into<GLenum>) {
|
||||
pub fn new_from_raw(texture: GLuint, handle: GLuint, format: GLenum, size: Size, miplevels: u32) -> Framebuffer {
|
||||
Framebuffer {
|
||||
image: texture,
|
||||
size,
|
||||
format,
|
||||
max_levels: miplevels,
|
||||
levels: miplevels,
|
||||
framebuffer: handle,
|
||||
init: true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_texture(&self, filter: FilterMode, wrap_mode: WrapMode) -> Texture {
|
||||
Texture {
|
||||
image: GlImage {
|
||||
handle: self.image,
|
||||
format: self.format,
|
||||
size: self.size,
|
||||
padded_size: Default::default()
|
||||
},
|
||||
filter,
|
||||
mip_filter: filter,
|
||||
wrap_mode
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale(&mut self, scaling: Scale2D, format: ShaderFormat, viewport: &Viewport, original: &Texture, source: &Texture) -> Size {
|
||||
let mut width = 0f32;
|
||||
let mut height = 0f32;
|
||||
|
||||
match scaling.x {
|
||||
Scaling {
|
||||
scale_type: ScaleType::Input,
|
||||
factor
|
||||
} => {
|
||||
width = source.image.size.width * factor
|
||||
},
|
||||
Scaling {
|
||||
scale_type: ScaleType::Absolute,
|
||||
factor
|
||||
} => {
|
||||
width = factor.into()
|
||||
}
|
||||
Scaling {
|
||||
scale_type: ScaleType::Viewport,
|
||||
factor
|
||||
} => {
|
||||
width = viewport.output.size.width * factor
|
||||
}
|
||||
};
|
||||
|
||||
match scaling.y {
|
||||
Scaling {
|
||||
scale_type: ScaleType::Input,
|
||||
factor
|
||||
} => {
|
||||
height = source.image.size.height * factor
|
||||
},
|
||||
Scaling {
|
||||
scale_type: ScaleType::Absolute,
|
||||
factor
|
||||
} => {
|
||||
height = factor.into()
|
||||
}
|
||||
Scaling {
|
||||
scale_type: ScaleType::Viewport,
|
||||
factor
|
||||
} => {
|
||||
height = viewport.output.size.height * factor
|
||||
}
|
||||
};
|
||||
|
||||
let size = Size {
|
||||
width: width.round() as u32,
|
||||
height: height.round() as u32
|
||||
};
|
||||
|
||||
if self.size != size {
|
||||
self.size = size;
|
||||
|
||||
self.init(size,if format == ShaderFormat::Unknown {
|
||||
ShaderFormat::R8G8B8A8Unorm
|
||||
} else {
|
||||
format
|
||||
});
|
||||
}
|
||||
size
|
||||
}
|
||||
|
||||
fn init(&mut self, mut size: Size, mut format: impl Into<GLenum>) {
|
||||
self.format = format.into();
|
||||
self.size = size;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use gl;
|
|||
use gl::types::{GLchar, GLenum, GLint, GLsizei, GLuint};
|
||||
use glfw::Key::P;
|
||||
use crate::FilterChain;
|
||||
use crate::framebuffer::Framebuffer;
|
||||
use crate::util::{GlImage, Size, Viewport};
|
||||
|
||||
const WIDTH: u32 = 900;
|
||||
|
@ -145,6 +146,10 @@ void main()
|
|||
}";
|
||||
let shader_program = compile_program(VERT_SHADER, FRAG_SHADER);
|
||||
|
||||
unsafe {
|
||||
gl::ObjectLabel(gl::SHADER, shader_program, -1, b"color_shader\0".as_ptr().cast());
|
||||
}
|
||||
|
||||
let vertices = &[
|
||||
// positions // colors
|
||||
0.5f32, -0.5, 0.0, 1.0, 0.0, 0.0, // bottom right
|
||||
|
@ -154,6 +159,8 @@ void main()
|
|||
let mut vbo: gl::types::GLuint = 0;
|
||||
unsafe {
|
||||
gl::GenBuffers(1, &mut vbo);
|
||||
gl::ObjectLabel(gl::BUFFER, vbo, -1, b"triangle_vbo\0".as_ptr().cast());
|
||||
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -172,6 +179,8 @@ void main()
|
|||
let mut vao: gl::types::GLuint = 0;
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut vao);
|
||||
gl::ObjectLabel(gl::VERTEX_ARRAY, vao, -1, b"triangle_vao\0".as_ptr().cast());
|
||||
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -216,20 +225,28 @@ void main()
|
|||
(glfw, window, events, shader_program, vao)
|
||||
}
|
||||
|
||||
pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, WindowEvent)>, triangle_program: GLuint, vao: GLuint, filter: &mut FilterChain) {
|
||||
let mut framebuffer_handle = 0;
|
||||
pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, WindowEvent)>, triangle_program: GLuint, triangle_vao: GLuint, filter: &mut FilterChain) {
|
||||
let mut rendered_framebuffer = 0;
|
||||
let mut rendered_texture = 0;
|
||||
let mut quad_vbuf = 0;
|
||||
|
||||
let mut output_texture = 0;
|
||||
let mut output_framebuffer_handle = 0;
|
||||
let mut output_quad_vbuf = 0;
|
||||
|
||||
unsafe {
|
||||
// do frmaebuffer
|
||||
gl::GenFramebuffers(1, &mut framebuffer_handle);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer_handle);
|
||||
gl::GenFramebuffers(1, &mut rendered_framebuffer);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
||||
|
||||
gl::ObjectLabel(gl::FRAMEBUFFER, rendered_framebuffer, -1, b"rendered_framebuffer\0".as_ptr().cast());
|
||||
|
||||
// make tetxure
|
||||
gl::GenTextures(1, &mut rendered_texture);
|
||||
gl::BindTexture(gl::TEXTURE_2D, rendered_texture);
|
||||
|
||||
gl::ObjectLabel(gl::TEXTURE, rendered_texture, -1, b"rendered_texture\0".as_ptr().cast());
|
||||
|
||||
// empty image
|
||||
gl::TexStorage2D(gl::TEXTURE_2D, 1, gl::RGBA8, WIDTH as GLsizei, HEIGHT as GLsizei);
|
||||
|
||||
|
@ -267,6 +284,56 @@ pub fn do_loop(mut glfw: Glfw, mut window: Window, events: Receiver<(f64, Window
|
|||
);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
// do frmaebuffer
|
||||
gl::GenFramebuffers(1, &mut output_framebuffer_handle);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, output_framebuffer_handle);
|
||||
|
||||
gl::ObjectLabel(gl::FRAMEBUFFER, output_framebuffer_handle, -1, b"output_framebuffer\0".as_ptr().cast());
|
||||
|
||||
// make tetxure
|
||||
gl::GenTextures(1, &mut output_texture);
|
||||
gl::BindTexture(gl::TEXTURE_2D, output_texture);
|
||||
|
||||
gl::ObjectLabel(gl::TEXTURE, output_texture, -1, b"output_texture\0".as_ptr().cast());
|
||||
|
||||
// empty image
|
||||
gl::TexStorage2D(gl::TEXTURE_2D, 1, gl::RGBA8, WIDTH as GLsizei, HEIGHT as GLsizei);
|
||||
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as GLint);
|
||||
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as GLint);
|
||||
|
||||
// set color attachment
|
||||
gl::FramebufferTexture2D(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, gl::TEXTURE_2D, output_texture, 0);
|
||||
|
||||
let buffers = [gl::COLOR_ATTACHMENT0];
|
||||
gl::DrawBuffers(1, buffers.as_ptr());
|
||||
|
||||
if gl::CheckFramebufferStatus(gl::FRAMEBUFFER) != gl::FRAMEBUFFER_COMPLETE {
|
||||
panic!("failed to create fbo")
|
||||
}
|
||||
|
||||
let fullscreen_fbo = [
|
||||
-1.0f32, -1.0, 0.0,
|
||||
1.0, -1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
-1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
];
|
||||
|
||||
gl::GenBuffers(1, &mut output_quad_vbuf);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, output_quad_vbuf);
|
||||
gl::BufferData(
|
||||
gl::ARRAY_BUFFER, // 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
|
||||
);
|
||||
}
|
||||
|
||||
const VERT_SHADER: &str = r"#version 150 core
|
||||
out vec2 v_tex;
|
||||
|
||||
|
@ -299,6 +366,11 @@ void main()
|
|||
gl::GenVertexArrays(1, &mut quad_vao);
|
||||
}
|
||||
|
||||
let fb = Framebuffer::new_from_raw(output_texture, output_framebuffer_handle, gl::RGBA8, Size {
|
||||
width: WIDTH,
|
||||
height: HEIGHT
|
||||
}, 1);
|
||||
|
||||
while !window.should_close() {
|
||||
glfw.poll_events();
|
||||
for (_, event) in glfw::flush_messages(&events) {
|
||||
|
@ -307,7 +379,7 @@ void main()
|
|||
|
||||
unsafe {
|
||||
// render to fb
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, framebuffer_handle);
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, rendered_framebuffer);
|
||||
// gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
|
@ -321,7 +393,7 @@ void main()
|
|||
// do the drawing
|
||||
gl::UseProgram(triangle_program);
|
||||
// select vertices
|
||||
gl::BindVertexArray(vao);
|
||||
gl::BindVertexArray(triangle_vao);
|
||||
|
||||
// draw to bound target
|
||||
gl::DrawArrays(gl::TRIANGLES, 0, 3);
|
||||
|
@ -337,14 +409,16 @@ void main()
|
|||
// eprintln!("[core] rendered texture is {rendered_texture}");
|
||||
|
||||
// do offscreen passes
|
||||
|
||||
// unsafe {
|
||||
// gl::ActiveTexture(gl::TEXTURE0);
|
||||
// gl::BindTexture(gl::TEXTURE_2D, rendered_texture);
|
||||
// }
|
||||
unsafe {
|
||||
filter.frame(0, &Viewport {
|
||||
x: 0,
|
||||
y: 0,
|
||||
size: Size {
|
||||
width: WIDTH,
|
||||
height: HEIGHT
|
||||
}
|
||||
output: &fb
|
||||
}, GlImage {
|
||||
handle: rendered_texture,
|
||||
format: gl::RGBA8,
|
||||
|
@ -363,14 +437,16 @@ void main()
|
|||
|
||||
// map quad to screen
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::UseProgram(quad_programid);
|
||||
|
||||
|
||||
|
||||
gl::ActiveTexture(gl::TEXTURE0);
|
||||
gl::BindTexture(gl::TEXTURE_2D, rendered_texture);
|
||||
gl::BindTexture(gl::TEXTURE_2D, output_texture);
|
||||
|
||||
gl::UseProgram(quad_programid);
|
||||
gl::BindVertexArray(quad_vao);
|
||||
|
||||
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4)
|
||||
gl::DrawArrays(gl::TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
window.swap_buffers();
|
||||
|
|
|
@ -10,6 +10,7 @@ mod binding;
|
|||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::iter::Filter;
|
||||
use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
use gl::types::{GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
|
||||
use glfw::Key::P;
|
||||
|
@ -37,7 +38,6 @@ unsafe fn gl_compile_shader(stage: GLenum, source: &str) -> GLuint {
|
|||
let shader = gl::CreateShader(stage);
|
||||
gl::ShaderSource(shader, 1, &source.as_bytes().as_ptr().cast(), std::ptr::null());
|
||||
gl::CompileShader(shader);
|
||||
|
||||
let mut compile_status = 0;
|
||||
gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut compile_status);
|
||||
|
||||
|
@ -137,8 +137,8 @@ pub struct FilterCommon {
|
|||
history: Vec<Texture>,
|
||||
feedback: Vec<Texture>,
|
||||
luts: FxHashMap<usize, Texture>,
|
||||
outputs: Vec<Framebuffer>,
|
||||
pub quad_vbo: GLuint,
|
||||
pub input_framebuffer: Framebuffer,
|
||||
}
|
||||
|
||||
impl FilterChain {
|
||||
|
@ -192,6 +192,7 @@ impl FilterChain {
|
|||
};
|
||||
|
||||
let mut filters = Vec::new();
|
||||
let mut output_framebuffers = Vec::new();
|
||||
|
||||
// initialize passes
|
||||
for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() {
|
||||
|
@ -227,23 +228,22 @@ impl FilterChain {
|
|||
panic!("failed to link program")
|
||||
}
|
||||
|
||||
for binding in &glsl.context.texture_fixups {
|
||||
gl::UseProgram(program);
|
||||
|
||||
for binding in &glsl.context.sampler_bindings {
|
||||
let loc_name = format!("LIBRA_TEXTURE_{}\0", *binding);
|
||||
unsafe {
|
||||
let location = gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast());
|
||||
if location >= 0 {
|
||||
gl::Uniform1i(location, *binding as GLint);
|
||||
}
|
||||
let location = gl::GetUniformLocation(program, loc_name.as_str().as_ptr().cast());
|
||||
if location >= 0 {
|
||||
// eprintln!("setting sampler {location} to sample from {binding}");
|
||||
gl::Uniform1i(location, *binding as GLint);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gl::UseProgram(0);
|
||||
(program, UniformLocation {
|
||||
vertex: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_VERTEX\0".as_ptr().cast()),
|
||||
fragment: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_FRAGMENT\0".as_ptr().cast()),
|
||||
})
|
||||
}
|
||||
gl::UseProgram(0);
|
||||
(program, UniformLocation {
|
||||
vertex: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_VERTEX\0".as_ptr().cast()),
|
||||
fragment: gl::GetUniformBlockIndex(program, b"LIBRA_UBO_FRAGMENT\0".as_ptr().cast()),
|
||||
})
|
||||
};
|
||||
|
||||
let ubo_ring = if let Some(ubo) = &reflection.ubo {
|
||||
|
@ -282,12 +282,13 @@ impl FilterChain {
|
|||
(FilterChain::reflect_uniform_location(program, param), param.offset));
|
||||
}
|
||||
|
||||
|
||||
// need output framebuffers.
|
||||
output_framebuffers.push(Framebuffer::new(1));
|
||||
|
||||
// eprintln!("{:#?}", semantics);
|
||||
eprintln!("{:#?}", reflection.meta);
|
||||
eprintln!("{:#?}", locations);
|
||||
eprintln!("{:#?}", reflection.push_constant);
|
||||
// eprintln!("{:#?}", reflection.meta);
|
||||
// eprintln!("{:#?}", locations);
|
||||
// eprintln!("{:#?}", reflection.push_constant);
|
||||
// eprintln!("====fragment====");
|
||||
// eprintln!("{:#}", glsl.fragment);
|
||||
// eprintln!("====vertex====");
|
||||
|
@ -305,32 +306,11 @@ impl FilterChain {
|
|||
source,
|
||||
// no idea if this works.
|
||||
// retroarch checks if feedback frames are used but we'll just init it tbh.
|
||||
framebuffer: Framebuffer::new(1),
|
||||
feedback_framebuffer: Framebuffer::new(1),
|
||||
config: config.clone()
|
||||
});
|
||||
}
|
||||
|
||||
eprintln!("{:?}", filters.iter().map(|f| f.program).collect::<Vec<_>>());
|
||||
// let mut glprogram: Vec<GLuint> = Vec::new();
|
||||
// for compilation in &compiled {
|
||||
// // compilation.context.compiler.vertex
|
||||
// }
|
||||
|
||||
// eprintln!("{:#?}", reflections);
|
||||
|
||||
// eprintln!("{:#?}", compiled./);
|
||||
// eprintln!("{:?}", preset);
|
||||
// eprintln!("{:?}", reflect.reflect(&ReflectOptions {
|
||||
// pass_number: i as u32,
|
||||
// uniform_semantics,
|
||||
// non_uniform_semantics: Default::default(),
|
||||
// }));
|
||||
|
||||
// todo: apply shader pass
|
||||
// gl3.cpp: 1942
|
||||
|
||||
|
||||
// load luts
|
||||
let mut luts = FxHashMap::default();
|
||||
|
||||
|
@ -415,7 +395,6 @@ impl FilterChain {
|
|||
gl::GenVertexArrays(1, &mut quad_vao);
|
||||
}
|
||||
|
||||
// todo: split params
|
||||
Ok(FilterChain {
|
||||
passes: filters,
|
||||
quad_vao,
|
||||
|
@ -426,8 +405,8 @@ impl FilterChain {
|
|||
history: vec![],
|
||||
feedback: vec![],
|
||||
luts,
|
||||
outputs: output_framebuffers,
|
||||
quad_vbo,
|
||||
input_framebuffer: Framebuffer::new(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -455,37 +434,34 @@ impl FilterChain {
|
|||
|
||||
let mut source = original.clone();
|
||||
|
||||
for passes in &mut self.passes {
|
||||
passes.build_commands(&self.common, None, count, 1, vp, &original, &source);
|
||||
let passes_len = self.passes.len();
|
||||
let (pass, last) = self.passes.split_at_mut(passes_len - 1);
|
||||
|
||||
for (index, pass) in pass.iter_mut().enumerate() {
|
||||
{
|
||||
let target = &mut self.common.outputs[index];
|
||||
let framebuffer_size = target.scale(pass.config.scaling.clone(), pass.get_format(), vp, &original, &source);
|
||||
}
|
||||
let target = &self.common.outputs[index];
|
||||
pass.draw(&self.common, None, count, 1, vp, &original, &source, &target);
|
||||
let target = target.as_texture(pass.config.filter, pass.config.wrap_mode);
|
||||
|
||||
// todo: update-pass-outputs
|
||||
source = target;
|
||||
// passes.build_semantics(&self, None, count, 1, vp, &original, &source);
|
||||
}
|
||||
|
||||
assert_eq!(last.len(), 1);
|
||||
for pass in last {
|
||||
source.filter = pass.config.filter;
|
||||
source.mip_filter = pass.config.filter;
|
||||
pass.draw(&self.common, None, count, 1, vp, &original, &source, &vp.output);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
gl::BindFramebuffer(gl::FRAMEBUFFER, 0);
|
||||
gl::BindVertexArray(0);
|
||||
}
|
||||
// todo: deal with the mess that is frame history
|
||||
}
|
||||
|
||||
pub fn do_final_pass(&mut self, count: u64, vp: &Viewport, input: GlImage, clear: bool, mvp: &[f32]) {
|
||||
|
||||
// todo: make copy
|
||||
|
||||
// todo: get filter info from pass data.
|
||||
let filter = self.common.preset.shaders.first().map(|f| f.filter).unwrap_or_default();
|
||||
let wrap_mode = self.common.preset.shaders.first().map(|f| f.wrap_mode).unwrap_or_default();
|
||||
let original = Texture {
|
||||
image: input,
|
||||
filter,
|
||||
mip_filter: filter,
|
||||
wrap_mode
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// todo: deal with the mess that is frame history
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use gl::types::{GLenum, GLint, GLuint};
|
||||
use librashader::{FilterMode, WrapMode};
|
||||
use crate::framebuffer::Framebuffer;
|
||||
|
||||
pub fn calc_miplevel(width: u32, height: u32) -> u32 {
|
||||
let mut size = std::cmp::max(width, height);
|
||||
|
@ -21,10 +22,10 @@ pub struct Texture {
|
|||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Viewport {
|
||||
pub struct Viewport<'a> {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
pub size: Size,
|
||||
pub output: &'a Framebuffer,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
|
||||
|
|
Loading…
Reference in a new issue