2022-11-29 23:56:10 -05:00
|
|
|
use crate::error::{FilterChainError, Result};
|
2022-11-30 19:05:24 -05:00
|
|
|
use crate::framebuffer::GLImage;
|
2023-02-11 00:20:35 -05:00
|
|
|
use crate::gl::framebuffer::GLFramebuffer;
|
2022-11-30 17:21:32 -05:00
|
|
|
use crate::gl::FramebufferInterface;
|
2023-01-13 17:59:22 -05:00
|
|
|
use gl::types::{GLenum, GLint, GLsizei};
|
2023-02-07 02:19:37 -05:00
|
|
|
use librashader_common::{ImageFormat, Size};
|
2022-11-30 01:38:05 -05:00
|
|
|
use librashader_presets::Scale2D;
|
2022-12-21 21:13:35 -05:00
|
|
|
use librashader_runtime::scaling::{MipmapSize, ViewportSize};
|
2022-11-29 23:56:10 -05:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
2022-11-30 17:21:32 -05:00
|
|
|
pub struct Gl46Framebuffer;
|
2022-11-30 00:39:42 -05:00
|
|
|
|
2022-11-30 17:21:32 -05:00
|
|
|
impl FramebufferInterface for Gl46Framebuffer {
|
2023-02-11 00:20:35 -05:00
|
|
|
fn new(max_levels: u32) -> GLFramebuffer {
|
2022-11-29 23:56:10 -05:00
|
|
|
let mut framebuffer = 0;
|
|
|
|
unsafe {
|
2022-11-30 00:39:42 -05:00
|
|
|
gl::CreateFramebuffers(1, &mut framebuffer);
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
2023-02-11 00:20:35 -05:00
|
|
|
GLFramebuffer {
|
2022-11-29 23:56:10 -05:00
|
|
|
image: 0,
|
|
|
|
size: Size {
|
|
|
|
width: 1,
|
|
|
|
height: 1,
|
|
|
|
},
|
|
|
|
format: 0,
|
|
|
|
max_levels,
|
2022-11-30 17:21:32 -05:00
|
|
|
mip_levels: 0,
|
2023-02-11 00:20:35 -05:00
|
|
|
fbo: framebuffer,
|
2022-11-29 23:56:10 -05:00
|
|
|
is_raw: false,
|
|
|
|
}
|
|
|
|
}
|
2023-01-13 02:54:16 -05:00
|
|
|
|
2022-11-29 23:56:10 -05:00
|
|
|
fn scale(
|
2023-02-11 00:20:35 -05:00
|
|
|
fb: &mut GLFramebuffer,
|
2022-11-29 23:56:10 -05:00
|
|
|
scaling: Scale2D,
|
|
|
|
format: ImageFormat,
|
2023-02-07 02:12:47 -05:00
|
|
|
viewport_size: &Size<u32>,
|
2023-01-29 21:26:11 -05:00
|
|
|
source_size: &Size<u32>,
|
2024-02-12 01:02:46 -05:00
|
|
|
original_size: &Size<u32>,
|
2023-01-11 19:09:15 -05:00
|
|
|
mipmap: bool,
|
2022-11-29 23:56:10 -05:00
|
|
|
) -> Result<Size<u32>> {
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.is_raw {
|
|
|
|
return Ok(fb.size);
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
2024-02-12 01:02:46 -05:00
|
|
|
let size = source_size.scale_viewport(scaling, *viewport_size, *original_size);
|
2022-11-29 23:56:10 -05:00
|
|
|
|
2023-01-11 19:09:15 -05:00
|
|
|
if fb.size != size || (mipmap && fb.max_levels == 1) || (!mipmap && fb.max_levels != 1) {
|
2022-11-30 17:21:32 -05:00
|
|
|
fb.size = size;
|
2022-11-29 23:56:10 -05:00
|
|
|
|
2023-01-11 19:09:15 -05:00
|
|
|
if mipmap {
|
|
|
|
fb.max_levels = u32::MAX;
|
|
|
|
} else {
|
|
|
|
fb.max_levels = 1
|
|
|
|
}
|
|
|
|
|
2022-11-30 17:21:32 -05:00
|
|
|
Self::init(
|
|
|
|
fb,
|
2022-11-29 23:56:10 -05:00
|
|
|
size,
|
|
|
|
if format == ImageFormat::Unknown {
|
|
|
|
ImageFormat::R8G8B8A8Unorm
|
|
|
|
} else {
|
|
|
|
format
|
|
|
|
},
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
Ok(size)
|
|
|
|
}
|
2023-02-11 00:20:35 -05:00
|
|
|
fn clear<const REBIND: bool>(fb: &GLFramebuffer) {
|
2022-11-29 23:56:10 -05:00
|
|
|
unsafe {
|
2022-11-30 01:38:05 -05:00
|
|
|
gl::ClearNamedFramebufferfv(
|
2023-02-11 00:20:35 -05:00
|
|
|
fb.fbo,
|
2022-11-30 01:38:05 -05:00
|
|
|
gl::COLOR,
|
|
|
|
0,
|
|
|
|
[0.0f32, 0.0, 0.0, 0.0].as_ptr().cast(),
|
|
|
|
);
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
}
|
2024-03-05 18:45:18 -05:00
|
|
|
fn copy_from(fb: &mut GLFramebuffer, image: &GLImage) -> Result<()> {
|
2022-11-30 17:59:55 -05:00
|
|
|
// todo: confirm this behaviour for unbound image.
|
2024-03-05 18:45:18 -05:00
|
|
|
if image.size != fb.size || image.format != fb.format {
|
|
|
|
Self::init(fb, image.size, image.format)?;
|
|
|
|
}
|
|
|
|
|
2024-03-05 18:49:33 -05:00
|
|
|
if image.handle == 0 {
|
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
|
2022-11-29 23:56:10 -05:00
|
|
|
unsafe {
|
2022-11-30 17:21:32 -05:00
|
|
|
// gl::NamedFramebufferDrawBuffer(fb.handle, gl::COLOR_ATTACHMENT1);
|
2024-03-05 18:49:33 -05:00
|
|
|
gl::NamedFramebufferReadBuffer(fb.fbo, gl::COLOR_ATTACHMENT0);
|
|
|
|
gl::NamedFramebufferDrawBuffer(fb.fbo, gl::COLOR_ATTACHMENT1);
|
|
|
|
|
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT0, image.handle, 0);
|
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT1, fb.image, 0);
|
2022-11-29 23:56:10 -05:00
|
|
|
|
2022-11-30 01:38:05 -05:00
|
|
|
gl::BlitNamedFramebuffer(
|
2024-03-05 18:49:33 -05:00
|
|
|
fb.fbo,
|
2023-02-11 00:20:35 -05:00
|
|
|
fb.fbo,
|
2022-11-30 01:38:05 -05:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
image.size.width as GLint,
|
|
|
|
image.size.height as GLint,
|
|
|
|
0,
|
2024-03-05 18:45:18 -05:00
|
|
|
0,
|
2022-11-30 17:21:32 -05:00
|
|
|
fb.size.width as GLint,
|
2024-03-05 18:45:18 -05:00
|
|
|
fb.size.height as GLint,
|
2022-11-30 01:38:05 -05:00
|
|
|
gl::COLOR_BUFFER_BIT,
|
|
|
|
gl::NEAREST,
|
|
|
|
);
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2023-02-11 00:20:35 -05:00
|
|
|
fn init(fb: &mut GLFramebuffer, mut size: Size<u32>, format: impl Into<GLenum>) -> Result<()> {
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.is_raw {
|
2022-11-29 23:56:10 -05:00
|
|
|
return Ok(());
|
|
|
|
}
|
2022-11-30 17:21:32 -05:00
|
|
|
fb.format = format.into();
|
|
|
|
fb.size = size;
|
2022-11-29 23:56:10 -05:00
|
|
|
|
|
|
|
unsafe {
|
|
|
|
// reset the framebuffer image
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.image != 0 {
|
2023-02-11 00:20:35 -05:00
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT0, 0, 0);
|
2022-11-30 17:21:32 -05:00
|
|
|
gl::DeleteTextures(1, &fb.image);
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
2022-11-30 17:21:32 -05:00
|
|
|
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut fb.image);
|
2022-11-29 23:56:10 -05:00
|
|
|
|
|
|
|
if size.width == 0 {
|
|
|
|
size.width = 1;
|
|
|
|
}
|
|
|
|
if size.height == 0 {
|
|
|
|
size.height = 1;
|
|
|
|
}
|
|
|
|
|
2022-12-21 21:13:35 -05:00
|
|
|
fb.mip_levels = size.calculate_miplevels();
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.mip_levels > fb.max_levels {
|
|
|
|
fb.mip_levels = fb.max_levels;
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.mip_levels == 0 {
|
|
|
|
fb.mip_levels = 1;
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
2022-11-30 00:39:42 -05:00
|
|
|
gl::TextureStorage2D(
|
2022-11-30 17:21:32 -05:00
|
|
|
fb.image,
|
|
|
|
fb.mip_levels as GLsizei,
|
|
|
|
fb.format,
|
2022-11-29 23:56:10 -05:00
|
|
|
size.width as GLsizei,
|
|
|
|
size.height as GLsizei,
|
|
|
|
);
|
|
|
|
|
2023-02-11 00:20:35 -05:00
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT0, fb.image, 0);
|
2022-11-29 23:56:10 -05:00
|
|
|
|
|
|
|
let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER);
|
|
|
|
if status != gl::FRAMEBUFFER_COMPLETE {
|
|
|
|
match status {
|
|
|
|
gl::FRAMEBUFFER_UNSUPPORTED => {
|
2023-02-11 00:20:35 -05:00
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT0, 0, 0);
|
2022-11-30 17:21:32 -05:00
|
|
|
gl::DeleteTextures(1, &fb.image);
|
|
|
|
gl::CreateTextures(gl::TEXTURE_2D, 1, &mut fb.image);
|
2022-11-29 23:56:10 -05:00
|
|
|
|
2022-12-21 21:13:35 -05:00
|
|
|
fb.mip_levels = size.calculate_miplevels();
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.mip_levels > fb.max_levels {
|
|
|
|
fb.mip_levels = fb.max_levels;
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
2022-11-30 17:21:32 -05:00
|
|
|
if fb.mip_levels == 0 {
|
|
|
|
fb.mip_levels = 1;
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
|
2022-11-30 00:39:42 -05:00
|
|
|
gl::TextureStorage2D(
|
2022-11-30 17:21:32 -05:00
|
|
|
fb.image,
|
|
|
|
fb.mip_levels as GLsizei,
|
2022-11-29 23:56:10 -05:00
|
|
|
ImageFormat::R8G8B8A8Unorm.into(),
|
|
|
|
size.width as GLsizei,
|
|
|
|
size.height as GLsizei,
|
|
|
|
);
|
2023-02-11 00:20:35 -05:00
|
|
|
gl::NamedFramebufferTexture(fb.fbo, gl::COLOR_ATTACHMENT0, fb.image, 0);
|
2022-11-30 17:21:32 -05:00
|
|
|
// fb.init =
|
2022-11-29 23:56:10 -05:00
|
|
|
// gl::CheckFramebufferStatus(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE;
|
|
|
|
}
|
2022-11-30 01:38:05 -05:00
|
|
|
_ => return Err(FilterChainError::FramebufferInit(status)),
|
2022-11-29 23:56:10 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-06-14 17:18:43 -04:00
|
|
|
}
|