Skip to content

Instantly share code, notes, and snippets.

@bigfarts
Created September 8, 2022 19:21
Show Gist options
  • Select an option

  • Save bigfarts/b1f3759e61afb62b41c0a88e2e1602d2 to your computer and use it in GitHub Desktop.

Select an option

Save bigfarts/b1f3759e61afb62b41c0a88e2e1602d2 to your computer and use it in GitHub Desktop.
diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs
index bf11afe8..f2e29b55 100644
--- a/wgpu-hal/src/gles/egl.rs
+++ b/wgpu-hal/src/gles/egl.rs
@@ -854,7 +854,9 @@ impl crate::Instance<super::Api> for Instance {
config: inner.config,
presentable: inner.supports_native_window,
raw_window_handle,
+ present_program: None,
swapchain: None,
+ texture: None,
srgb_kind: inner.srgb_kind,
})
}
@@ -929,14 +931,11 @@ impl super::Device {
pub struct Swapchain {
surface: egl::Surface,
wl_window: Option<*mut raw::c_void>,
- framebuffer: glow::Framebuffer,
- renderbuffer: glow::Renderbuffer,
- /// Extent because the window lies
- extent: wgt::Extent3d,
- format: wgt::TextureFormat,
- format_desc: super::TextureFormatDesc,
- #[allow(unused)]
- sample_type: wgt::TextureSampleType,
+ pub(crate) extent: wgt::Extent3d,
+ // pub(crate) channel: f::ChannelType,
+ pub(super) format: wgt::TextureFormat,
+ pub(super) framebuffer: glow::Framebuffer,
+ pub(super) format_desc: super::TextureFormatDesc,
}
#[derive(Debug)]
@@ -944,10 +943,12 @@ pub struct Surface {
egl: EglContext,
wsi: WindowSystemInterface,
config: egl::Config,
- pub(super) presentable: bool,
raw_window_handle: RawWindowHandle,
- swapchain: Option<Swapchain>,
srgb_kind: SrgbFrameBufferKind,
+ pub(super) swapchain: Option<Swapchain>,
+ texture: Option<glow::Texture>,
+ pub(super) presentable: bool,
+ present_program: Option<glow::Program>,
}
unsafe impl Send for Surface {}
@@ -974,27 +975,18 @@ impl Surface {
crate::SurfaceError::Lost
})?;
- gl.disable(glow::SCISSOR_TEST);
- gl.color_mask(true, true, true, true);
-
gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
- gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(sc.framebuffer));
- // Note the Y-flipping here. GL's presentation is not flipped,
- // but main rendering is. Therefore, we Y-flip the output positions
- // in the shader, and also this blit.
- gl.blit_framebuffer(
- 0,
- sc.extent.height as i32,
- sc.extent.width as i32,
- 0,
- 0,
- 0,
- sc.extent.width as i32,
- sc.extent.height as i32,
- glow::COLOR_BUFFER_BIT,
- glow::NEAREST,
- );
- gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
+ gl.bind_sampler(0, None);
+ gl.active_texture(glow::TEXTURE0);
+ gl.bind_texture(glow::TEXTURE_2D, self.texture);
+ gl.use_program(self.present_program);
+ gl.disable(glow::DEPTH_TEST);
+ gl.disable(glow::STENCIL_TEST);
+ gl.disable(glow::SCISSOR_TEST);
+ gl.disable(glow::BLEND);
+ gl.disable(glow::CULL_FACE);
+ gl.draw_buffers(&[glow::BACK]);
+ gl.draw_arrays(glow::TRIANGLES, 0, 3);
self.egl
.instance
@@ -1014,14 +1006,40 @@ impl Surface {
Ok(())
}
+ unsafe fn create_present_program(gl: &glow::Context) -> glow::Program {
+ let program = gl
+ .create_program()
+ .expect("Could not create shader program");
+ let vertex = gl
+ .create_shader(glow::VERTEX_SHADER)
+ .expect("Could not create shader");
+ gl.shader_source(vertex, include_str!("./shaders/present.vert"));
+ gl.compile_shader(vertex);
+ let fragment = gl
+ .create_shader(glow::FRAGMENT_SHADER)
+ .expect("Could not create shader");
+ gl.shader_source(fragment, include_str!("./shaders/present.frag"));
+ gl.compile_shader(fragment);
+ gl.attach_shader(program, vertex);
+ gl.attach_shader(program, fragment);
+ gl.link_program(program);
+ gl.delete_shader(vertex);
+ gl.delete_shader(fragment);
+ gl.bind_texture(glow::TEXTURE_2D, None);
+
+ program
+ }
+
unsafe fn unconfigure_impl(
&mut self,
device: &super::Device,
) -> Option<(egl::Surface, Option<*mut raw::c_void>)> {
let gl = &device.shared.context.lock();
+ if let Some(renderbuffer) = self.texture.take() {
+ gl.delete_texture(renderbuffer);
+ }
match self.swapchain.take() {
Some(sc) => {
- gl.delete_renderbuffer(sc.renderbuffer);
gl.delete_framebuffer(sc.framebuffer);
Some((sc.surface, sc.wl_window))
}
@@ -1180,36 +1198,61 @@ impl crate::Surface<super::Api> for Surface {
);
}
- let format_desc = device.shared.describe_texture_format(config.format);
let gl = &device.shared.context.lock();
- let renderbuffer = gl.create_renderbuffer().unwrap();
- gl.bind_renderbuffer(glow::RENDERBUFFER, Some(renderbuffer));
- gl.renderbuffer_storage(
- glow::RENDERBUFFER,
- format_desc.internal,
- config.extent.width as _,
- config.extent.height as _,
+
+ if let Some(swapchain) = self.swapchain.take() {
+ // delete all frame buffers already allocated
+ gl.delete_framebuffer(swapchain.framebuffer);
+ }
+
+ if self.present_program.is_none() {
+ self.present_program = Some(Self::create_present_program(gl));
+ }
+
+ if let Some(texture) = self.texture.take() {
+ gl.delete_texture(texture);
+ }
+
+ self.texture = Some(gl.create_texture().unwrap());
+
+ let desc = device.shared.describe_texture_format(config.format);
+ gl.bind_texture(glow::TEXTURE_2D, self.texture);
+ gl.tex_parameter_i32(
+ glow::TEXTURE_2D,
+ glow::TEXTURE_MIN_FILTER,
+ glow::NEAREST as _,
);
+ gl.tex_parameter_i32(
+ glow::TEXTURE_2D,
+ glow::TEXTURE_MAG_FILTER,
+ glow::NEAREST as _,
+ );
+ gl.tex_storage_2d(
+ glow::TEXTURE_2D,
+ 1,
+ desc.internal,
+ config.extent.width as i32,
+ config.extent.height as i32,
+ );
+
let framebuffer = gl.create_framebuffer().unwrap();
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuffer));
- gl.framebuffer_renderbuffer(
+ gl.framebuffer_texture_2d(
glow::READ_FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
- glow::RENDERBUFFER,
- Some(renderbuffer),
+ glow::TEXTURE_2D,
+ self.texture,
+ 0,
);
- gl.bind_renderbuffer(glow::RENDERBUFFER, None);
- gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
+ gl.bind_texture(glow::TEXTURE_2D, None);
self.swapchain = Some(Swapchain {
surface,
wl_window,
- renderbuffer,
framebuffer,
extent: config.extent,
format: config.format,
- format_desc,
- sample_type: wgt::TextureSampleType::Float { filterable: false },
+ format_desc: desc,
});
Ok(())
@@ -1240,8 +1283,9 @@ impl crate::Surface<super::Api> for Surface {
) -> Result<Option<crate::AcquiredSurfaceTexture<super::Api>>, crate::SurfaceError> {
let sc = self.swapchain.as_ref().unwrap();
let texture = super::Texture {
- inner: super::TextureInner::Renderbuffer {
- raw: sc.renderbuffer,
+ inner: super::TextureInner::Texture {
+ raw: self.texture.unwrap(),
+ target: glow::TEXTURE_2D,
},
array_layer_count: 1,
mip_level_count: 1,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment