-
-
Notifications
You must be signed in to change notification settings - Fork 72
Vulkan in Processing (draft) #948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Wow, @TeoJT , this is an amazing PR!!! Thank you for your hard work here. It looks like your PGraphicsVulkan class inherits from PGraphicsOpenGL to benefit from all of the geometry and style functionality as well as the tessellation code, and then intercepts what would otherwise go through PGL to use Vulkan instead. Is that correct? You mention mouse events, does it handle keyboard events also? How much testing have you done? In general, does it work well? I can't wait to give this a try! |
Thanks for the kind words @hx2A :) You're correct; I effectively haven't touched any (or at least most) of the PGraphicsOpenGL code and linked PGL to GL2VK, which uses Vulkan instead. It only uses some quick 'n dirty code for mouse events and there's no keyboard or scrollwheel events sadly. The window also cannot be resized yet. I've mostly tested using the performance example sketches; It generally works well on basic sketches as long as you don't use PGraphics, and make sure you call Let me know how it goes for you! |
Update- just added mouse clicking and keyboard input just now with GLFW. |
Hi @TeoJT, stumbled across this pr. Wow! This is a pretty awesome exploration and implementing even a portion of OpenGL in Vulkan is pretty impressive. I'm wondering if you've looked at prior art here like Zink in Gallium? I'm not super familiar with their work, but it might be a good source of inspiration. I'm also wondering about running on MoltenVK which would be essential for macOS and might be a pain for managing the Vulkan dependency. Looking at the code, I'm noticing some synchronization problems that may cause issues. For example,
There are also some synchronization issues on the CPU. For example, in The idea of doing some kind of OpenGL translation is really cool. Given the dependency Processing has on OpenGL it would definitely be an awesome way to ensure that people can migrate to a new rendering backend without too many breaking changes. I'm definitely curious to know if other people have had success with this strategy in other contexts? Full OpenGL conformance may be a big task. This is the kind of migration that would definitely benefit from learning from other projects. Hope you keep up with graphics work post graduation. It's a really fun space to work in. |
Also worth noting that there's been some active movement on Java Vulkan bindings in https://github.com/chuigda/vulkan4j which I've been following. |
Thanks for the feedback tychedelia, I've definitely learned quite a bit just from your message alone! I did avoid synchronisation to avoid potential slowdowns, since my goal was speed. My attempted solution was to make a separate VBO instead of waiting for a previous buffering operation/draw call to complete. It's brittle and it's no wonder it crashes all the time, haha. I haven't looked much at Zink but I have looked into Google ANGLE. Speaking of, I'm going to try using ANGLE to move the core away from JOGL; it's not going to be faster than native OpenGL (previous studies seem to suggest that), but it's definitely going to be more stable, especially with sketches that use PGL. One idea I have is to try to access Vulkan directly from ANGLE, skipping the translation, hopefully getting both backward compatibility (e.g. sketches that use PGL) and performance (the renderer can be rewritten to use Vulkan directly). But I have no idea where to start or if it's even possible given that I'm still quite new to Vulkan. If not, I'll continue working on this renderer as a separate library rather than a replacement to OpenGL. Also I think it's worth pointing out that during benchmarking, a big bottleneck was single-threaded parts like the tessellator, which I didn't make multithreaded since it wasn't the focus in my study, but that could potentially make things like immediate mode rendering much faster. Again thanks for the feedback and please do let me know if you spot anything else or know of any other frameworks/libraries that could help! |
Yup, tessellation is also a huge bottleneck in Nannou, which has a very similar immediate mode architecture to Processing. This has always been the big point of slowness compared to anything we do on the GPU. Modern hardware is designed to render billions of blades of grass in AAA games or whatever and most of the stuff that creative coding throws at it is pretty trivial in that respect. One thing I've been wondering about for Nannou is GPU driven tessellation using compute shaders. So basically, we'd just send the paths for each draw primitive to the GPU and populate the vertex buffer there. Linebender has been doing a lot of research into GPU driven font rendering and I've often wondered if we could learn anything from their work in this respect. Me and my colleagues have also discussed switching from a path tessellation strategy to sending SDFs, but this would represent a pretty substantial breaking change to the rendering model obviously! I love the idea of a Processing-like library for raymarching though.
So awesome that you're continuing to look into rendering stuff! One thing I'm really curious about is using WebGPU (either via dawn or wgpu). I'm most familiar with wgpu, but it handles most of the complicated resource tracking and while WASM as a Java compilation target isn't fully baked yet, I think it represents the best truly cross-platform replacement for OpenGL. |
(I'm new to PRs so let me know if you see any mistakes ^^")
This is my attempt at making a Vulkan-based renderer for Processing, using LWJGL to access a Vulkan binding. It's part of my final year dissertation where I compare OpenGL and Vulkan renderer speeds so a lot of code is still very messy.
I was also originally planning to release it as a library for Processing, but it appears that moving away from JOGL/OpenGL is now on Processing's roadmap (#881)
The new renderer can be accessed by using
PV2D
/PV3D
in thesize()
function:It works by translating OpenGL commands (through the PGL abstraction layer) to Vulkan commands through a thin OpenGL-to-Vulkan translation layer (under a new package named GL2VK). This layer is optimised for Processing (mostly the immediate and retained modes in Processing). These commands are passed to separate threads (called ThreadNodes) which offload the main thread from potentially expensive operations.
There is also a shader converter which translates OpenGL shaders to Vulkan shaders.
Also, it uses GLFW to create a window and receive mouse inputs... no AWT!