Created
September 8, 2022 19:21
-
-
Save bigfarts/b1f3759e61afb62b41c0a88e2e1602d2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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