Support for Multisampled Anti-Aliasing#213
Conversation
kvark
left a comment
There was a problem hiding this comment.
This is amazing work, thank you!
High quality, something that any open source project would cherish and greatly appreciate.
Very solid for the first contribution, I'm excited to see this finished.
|
|
||
| Self::BlitFramebuffer { from, to } => { | ||
| /* | ||
| TODO(ErikWDev): Validate |
There was a problem hiding this comment.
Please follow these instructions - https://github.com/kvark/blade/tree/main/blade-graphics#opengl-es
and let me know if something doesn't work!
There was a problem hiding this comment.
Sadly, I am unable to get it to work.
[2024-12-07T20:55:05Z ERROR blade_graphics::hal::platform] EGL 'eglCreatePlatformWindowSurface' code 0x300b: _eglCreateWindowSurfaceCommon
thread 'main' panicked at blade-graphics/src/gles/egl.rs:431:26:
called `Result::unwrap()` on an `Err` value: BadNativeWindowI have tried forcing X11 and Wayland and both return the same issue. I am running on Debian GNU/Linux 12 (bookworm) x86_64 with kernel 6.1.0-28-amd64.
I have libgles-dev 1.6.0-1 installed as well as libegl-dev 1.6.0-1
There was a problem hiding this comment.
Ok, good to know, thank you for trying!
This has probably regressed recently due to #203
I'll check on a few more devices I have...
|
|
||
| let target_from = match from.inner { | ||
| super::TextureInner::Renderbuffer { raw } => raw, | ||
| _ => panic!("Unsupported resolve between non-renderbuffers"), |
There was a problem hiding this comment.
Is this just a thing we want to leave for a follow-up, or you are seeing actual technical difficulty here? I think, handling a texture here should be straightforward.
There was a problem hiding this comment.
Nop, just unfamiliar with opengl. Found framebufferTexture2D so should be easy
There was a problem hiding this comment.
Think this should work
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(framebuf_from));
match from.inner {
super::TextureInner::Renderbuffer { raw } => {
gl.framebuffer_renderbuffer(
glow::READ_FRAMEBUFFER,
glow::COLOR_ATTACHMENT0, // NOTE: Assuming color attachment
glow::RENDERBUFFER,
Some(raw),
);
}
super::TextureInner::Texture { raw, target } => {
gl.framebuffer_texture_2d(
glow::READ_FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
target,
Some(raw),
0,
);
}
}There was a problem hiding this comment.
yep! if in doubt, we can also check wgpu-hal
| } | ||
|
|
||
| pub fn draw(&self, pass: &mut gpu::RenderCommandEncoder) { | ||
| pub fn draw(&self, pass: &mut gpu::RenderCommandEncoder, size: (u32, u32)) { |
There was a problem hiding this comment.
should we just get the aspect here?
There was a problem hiding this comment.
Used the size and sent it directly to the shader before but changed it to be the aspect ratio xP Maybe should be the input to the function now yeah since that is what is used
|
|
||
| mod particle; | ||
|
|
||
| // const SAMPLE_COUNT: u32 = 1; |
There was a problem hiding this comment.
would be useful to support SAMPLE_COUNT = 1 in the code here, which would mean - not creating the extra MSAA texture at all
There was a problem hiding this comment.
Usually do it that way. Should I make the SAMPLE_COUNT parameter dynamically changable in the UI as well? Should be possible but the pipeline needs recreating as well in that case
There was a problem hiding this comment.
it's a nice feature but it wouldn't block this PR from landing
Compared to having created this whole package for us to use and tinker with I don't think its much :) We will continue to evaluate blade for a period and my intention is to contribute if I make good changes. Can probably fix some of the open winit issues too since have been having to deal with their API changes as well for our game.. |
|
will re-request review when ready. Will get my hands on a mac and also try the metal as well as gles impl |
|
Don't know if related: For some reason I feel like the egui in blade is much more pixelated than I am used to. To the left is our game using wgpu and right is blade opened #215 |
e849398 to
a63bc0d
Compare
|
(force push from rebase on main) |
kvark
left a comment
There was a problem hiding this comment.
Looks great, let's get this in!
Just one question though - how do you see this being merged? Do you want to make a pass over commits to have a reasonable (and testable) history, or I can just squash it all together.
|
|
||
| [target.'cfg(target_arch = "wasm32")'.dev-dependencies] | ||
| # see https://github.com/emilk/egui/issues/4270 | ||
| egui-winit = { version="0.29", default-features=false, features=["links"] } |
There was a problem hiding this comment.
it's now the same dependency between wasm and normal, can we move it into a common block of dev dependencies?
| // ns_view always have a layer and don't need to verify that it exists. | ||
| let layer: *mut Object = msg_send![handle.ns_view.as_ptr(), layer]; | ||
| let layer: *mut Object = | ||
| msg_send![handle.ns_view.as_ptr() as *mut Object, layer]; |
There was a problem hiding this comment.
curious, does this cast do anything? I think the type is essentially erased at that point, anyway
There was a problem hiding this comment.
It didn't compile for me, msg_send![] required the thing to implement the "Message" trait and it wasn't implemented by a raw pointer. The cast fixed the compilation though ofc no guarantees
This made it compile, though I could still not get it to run :/
|
As for merging, I am totally fine with a squash. The reason I am still hesitant is I have not gotten the OpenGL version to run as the surface creation fail, so can only guess that my code is working in that path. I also still observe an issue on pipeline recreation on Mac for the new particle sample (when sample count changes), though will continue looking into it as I am working to get blade running on iOS |
Closes #20762 Release Notes: - N/A --- Enable MSAA for Anti-Aliasing to Path (`cx.paint_path`) for drawing a better vector graphics. ```bash cargo run -p gpui --example gradient --features macos-blade cargo run -p gpui --example gradient cargo run -p gpui --example painting --features macos-blade cargo run -p gpui --example painting ``` **Before** <img width="1089" alt="image" src="https://github.com/user-attachments/assets/0ae7240f-4ba9-4ef5-896c-e436c1282770" /> **After** <img width="944" alt="image" src="https://github.com/user-attachments/assets/71a07ae8-be54-452c-aacc-b8cec1f810c0" /> ## TODO - [x] Support Metal and Blade. - [x] Detect system support to set up sample count. - [x] Fix extra lines between Path vertices wait #22808 to merge. Ref kvark/blade#213 Ask @kvark to review. I am not sure if there is anything I missed. I modified it according to the [particle](https://github.com/kvark/blade/tree/main/examples/particle) example of Blade project. But the difference is that after the first MSAA render, I did not do it a second time, I tested it and found it was not necessary.
Closes #20762 Release Notes: - N/A --- Enable MSAA for Anti-Aliasing to Path (`cx.paint_path`) for drawing a better vector graphics. ```bash cargo run -p gpui --example gradient --features macos-blade cargo run -p gpui --example gradient cargo run -p gpui --example painting --features macos-blade cargo run -p gpui --example painting ``` **Before** <img width="1089" alt="image" src="https://github.com/user-attachments/assets/0ae7240f-4ba9-4ef5-896c-e436c1282770" /> **After** <img width="944" alt="image" src="https://github.com/user-attachments/assets/71a07ae8-be54-452c-aacc-b8cec1f810c0" /> ## TODO - [x] Support Metal and Blade. - [x] Detect system support to set up sample count. - [x] Fix extra lines between Path vertices wait #22808 to merge. Ref kvark/blade#213 Ask @kvark to review. I am not sure if there is anything I missed. I modified it according to the [particle](https://github.com/kvark/blade/tree/main/examples/particle) example of Blade project. But the difference is that after the first MSAA render, I did not do it a second time, I tested it and found it was not necessary.


closes #198
Changes
This PR introduces a
sample_count: u32toTextureDescas well as amultisample_state: MultisampleStateto theRenderPipelineDesc. Also addedalpha_to_coveragewhile at it.Together with the existing
FinishOp::ResolveTo(TextureView), a multisampled renderpass can now be described and executedImplementations
Vulkan
The rendering attachment needs to be told to resolve
The store_op is currently always set to
DONT_CAREas in many cases for msaa rendering the resolved texture is the only one required. Would be nice to be able to specify this behaviour in blade as well though:For the texture creation, a
SampleCountFlagsis constructed for thevk::ImageCreateInfo:and for the pipeline, I looked at how wgpu does it and came to the following code
Metal
The metal backend already had support for the `ResolveTo` finishop so no changes needed for the renderpipeline. The creation of the renderpipeline required description though:For the texture, only specifying the sample_count was required
OpenGL ES
This was the hardest one as I am very unfamiliar with msaa in opengl, but in summary the texture needs to be created with
renderbuffer_storage_multisampleif it is a rendertarget and with aglow::TEXTURE_2D_MULTISAMPLEtarget type if it is a normal texture.The sample count is then set with
tex_storage_2d_multisample, but there is now no-longer a way to specifymip_countso don't know if that is even possible.For the rendering, I use
blit_framebufferto blit the msaa texture onto the resolve target which required turning the renderbuffers into FBO:s. Currently, the FBO:s are created and deleted ad-hoc but could be saved as done in wgpu-hal. See #198Testing
The vulkan implementation has been validated on an AMD RX 6600 on debian, an integrated intel GPU on Fedora as well as a GTX 1050 on Windows and it all seems to work (the particle sample). After inspection in renderdoc the result is as expected.
The metal implementation has been tested on a Mac Mini M4 and works. However, particle example seems to break after the sample count is adjusted in runtime for some reason.
The Opengl ES implementation has not been tested!!!
Particle Example
I changed the particle example to now utilize msaa which requires it to keep a msaa texture with the desired
sample_countavailable and recreated upon resizing as well as a FinishOp::ResolveTo to resolve the msaa texture to the acquired frame texture as such:Egui
Furthermore, the
blade_eguirenderer also requires information about the multisample state since it has a pipeline that now needs information about the texture it's going to render to so it's initializer now takes a sample_count as well:Let me know what needs changing or if testing fails somewhere. Especially the Opengl ES implementation as I didn't know how to run using it