V3DV + Zink

During my presentation at the X Developers Conference I stated that we had been mostly using the Khronos Vulkan Conformance Test suite (aka Vulkan CTS) to validate our Vulkan driver for Raspberry Pi 4 (aka V3DV). While the CTS is an invaluable resource for driver testing and validation, it doesn’t exactly compare to actual real world applications, and so, I made the point that we should try to do more real world testing for the driver after completing initial Vulkan 1.0 support.

To be fair, we had been doing a little bit of this already when I worked on getting the Vulkan ports of all 3 Quake game classics to work with V3DV, which allowed us to identify and fix a few driver bugs during development. The good thing about these games is that we could get the source code and compile them natively for ARM platforms, so testing and debugging was very convenient.

Unfortunately, there are not a plethora of Vulkan applications and games like these that we can easily test and debug on a Raspberry Pi as of today, which posed a problem. One way to work around this limitation that was suggested after my presentation at XDC was to use Zink, the OpenGL to Vulkan layer in Mesa. Using Zink, we can take existing OpenGL applications that are currently available for Raspberry Pi and use them to test our Vulkan implementation a bit more thoroughly, expanding our options for testing while we wait for the Vulkan ecosystem on Raspberry Pi 4 to grow.

So last week I decided to get hands on with that. Zink requires a few things from the underlying Vulkan implementation depending on the OpenGL version targeted. Currently, Zink only targets desktop OpenGL versions, so that limits us to OpenGL 2.1, which is the maximum version of desktop OpenGL that Raspbery Pi 4 can support (we support up to OpenGL ES 3.1 though). For that desktop OpenGL version, Zink required a few optional Vulkan 1.0 features that we were missing in V3DV, namely:

  • Logic operations.
  • Alpha to one.
  • VK_KHR_maintenance1.

The first two were trivial: they were already implemented and we only had to expose them in the driver. Notably, when I was testing these features with the relevant CTS tests I found a bug in the alpha to one tests, so I proposed a fix to Khronos which is currently in review.

I also noticed that Zink was also implicitly requiring support for timestamp queries, so I also implemented that in V3DV and then also wrote a patch for Zink to handle this requirement better.

Finally, Zink doesn’t use Vulkan swapchains, instead it creates presentable images directly, which was problematic for us because our platform needs to handle allocations for presentable images specially, so a patch for Zink was also required to address this.

As of the writing of this post, all this work has been merged in Mesa and it enables Zink to run OpenGL 2.1 applications over V3DV on Raspberry Pi 4. Here are a few screenshots of Quake3 taken with the native OpenGL driver (V3D), with the native Vulkan driver (V3DV) and with Zink (over V3DV). There is a significant performance hit with Zink at present, although that is probably not too unexpected at this stage, but otherwise it seems to be rendering correctly, which is what we were really interested to see:


Quake3 Vulkan renderer (V3DV)

Quake3 OpenGL renderer (V3D)

Quake3 OpenGL renderer (Zink + V3DV)

Note: you’ll notice that the Vulkan screenshot is darker than the OpenGL versions. As I reported in another post, that is a feature of the Vulkan port of Quake3 and is unrelated to the driver.

Going forward, we expect to use Zink to test more applications and hopefully identify driver bugs that help us make V3DV better.

21 comments

    • Hi Mike, not really. Rpi4 cannot meet the requirements for OpenGL 3.0 (particularly, that version requires that we can have more than 4 active render targets, which we can’t), and that’s not something that Zink can do for us. Also, we don’t meet Zink’s Vulkan feature requirements for OpenGL 3.0 (at least not at present).

      • Dumb question, but would it be possible to kind of emulate additional render targets? I have noticed that with some OpenGL 3.0 applications, forcing the OpenGL version causes them to actually work ok.

        • Hi Chris,

          we actually considered that some time ago, but the short answer is that it would be difficult, we would have to do a lot of nasty things in the driver and there would be a lot of corner cases that would probably make it really hard if not impossible to make it conformant (and maintaining all those hacks going forward would probably be nightmarish).

          There may be a lot of GL3 apps that will work by forcing the GL version, so long as they don’t require features that are not implemented, like requiring than 4 render targets. I guess there are a lot of GL3 apss that don’t require more than 4.

          • Not that I’m advocating, but I’m aware of at least one (proprietary) driver maintaining such a stack of hacks 😉

      • Since I want to see Blender 2.90 running on a raspberry PI, how likely is it that future raspberry PIs will support more than 8 render targets(and other OpenGL 3 requirments), is it hard to implement for Bradcom?

        • Hi Alexander,
          I don’t have any insight on future Broadcom or Raspberry Pi products, so I can’t really say, however, I’d guess this is more about cost than it is about difficulty.

  1. I have been following the development of Zink closely. Is there any external pressure pushing Zink at this phase? Or is it still mostly a play toy? Using Zink to test a Vulkan implementation with existing OpenGL code is really clever. I’ve seen scenarios like this where there’s potential to elucidate pieces of either mechanism

    • Hi Michael, I guess you should ask Zink developers about that, I am not familiar with their agenda or goals, but I as far as I know, Zink is not intended to be just a play toy, but rather a tool to provide OpenGL acceleration on any platform with a native Vulkan driver, without requiring a native OpenGL implementation from the platform vendor.

  2. Hi, Iago! Here’s another spanish graphics programmer (not a master as you are, but always learning and enjoying, which I take you also do).
    I am very interested in V3DV working without X, on MESA’s drm platform. Its it possible or should it be possible anytime soon?
    I did the SDL2 ATOMIC KMSDRM backend this summer, and SDL2 works wonderfully outside X for embedded-like scenarios where a small kernel an no unneeded services is enough and boots in 1 second. I am eagerly waiting for Vulkan availibility outside X, too! 🙂

    Having Vulkan trapped inside X is kind of… almost there, but not there yet 😛

      • That’s good news, indeed! I will try his code and report.

        Also, there is something I would like to tell you: there seems to be ONE nasty bug in current GLES implementation regarding shaders, and it seems you may have not seen this one. It’s currently affecting DuckStation and YABUSE emulators, which only fail to render properly on VC6, while they render perfectly on Intel, AMD and Panfrost platforms (that I have tested).

        This bug affects shaders that take look up palette index from one texture, and an do indirect load from the second.
        Like this:
        ” vec4 txindex = texelFetch( s_texture, ivec2(int(v_texcoord.x),int(v_texcoord.y)) ,0 );\n”
        ” vec4 txcol = texelFetch( s_color, ivec2( ( int(txindex.g*65280.0) | int(txindex.r*255.0)) ,0 ) , 0 );\n”

        Here’s a shader failing due to this:
        https://github.com/devmiyax/yabause/blob/master/yabause/src/yglshaderes.c

        Maybe I should open an issue in GitLab for this but, what repo/branch would be better for the issue?

      • I would have to agree with Manuel too. The majority of users that play games on the Pi 4 are doing it through the KMS/DRM environment. X11 just adds too much overhead with OpenGL. Although I’ve used Vulkan in X11 and experienced better performance it does leave one to wonder how that translates in KMS/DRM.

        Once this is possible you will see more bug reporting in Mesa Gitlab. The devs of RetroPie will not add Vulkan support until it is supported in KMS/DRM because RetroPie is only supported in KMS/DRM for the Pi.

  3. What Vulkan version will the Pi4 allow for? As some of us are trying out various 3D emulators some of them require Vulkan 1.1 or higher.

    • As far as I know Vulkan didn’t introduce new hardware requirements since Vulkan 1.0, so I think we might be able to target Vulkan 1.2, haven’t checked in detail though, so don’t quote me on that 😉

  4. Wow! This is very impressive on both the V3DV and Zink fronts. It’s pretty exciting to see where this goes in the future. 🙂

    I’ve been playing around with V3DV in my game and it works great. 🙂 https://twitter.com/slembcke/status/1328864185745281024

    Other than some 32 bit fixes to my code, and splitting my lightfield pass to work with the 4 render target limit, it ran as is at a solid 60 fps. Color me impressed! 😀 It’s so satisfying to be able to support the pi with my unmodified desktop code.

  5. I know you and Alejandro are still busy fixing bugs and improving performance on the v3dv driver but I’m looking for some help on a Dreamcast emulator that is giving me segfaults using the Vulkan implementation.

    Here is the source code and the exact function I’m getting the segfault:
    https://github.com/libretro/flycast/blob/master/core/rend/vulkan/vulkan_context.cpp#L171

    In my spare time, I’ve been learning the Vulkan API so any helpful pointers would be great!

Leave a Reply

Your email address will not be published. Required fields are marked *