How to use OpenGL on Zink, Mesa, MoltenVK, and macOS

Well, I haven’t figured out how to use Zink yet, but I did finally discover a way to use OpenGL on macOS 11.6:

gcc \
-lgl \
-lglut \
-L /opt/X11/lib \
-I /opt/X11/include \
-o build/01-03_spinning_square \
opengl-programming-guide-seventh-edition/01-03_spinning_square.c && \
echo compiled && \
build/01-03_spinning_square

I don’t remember where /opt/X11 came from but I read something that said /opt/X11/ is created when Xquartz is installed.

I made some progress on using Zink but I don’t think it’s fully working yet. Here’s what I do have. I did something like the following (I didn’t keep detailed notes):

In short:

I was expecting the output from glxgears with the -info option to include “zink” somewhere, but it doesn’t, so I think this might not actually be using zink, vulkan, or metal.

In long:

  1. Install VulkanSDK in ~/VulkanSDK using the installer downloaded from https://vulkan.lunarg.com/sdk/home

  2. Build zink (successfully, I think):

brew install meson ninja python flex bison
# Also brew install libxext? I forget.

mkdir ~/src

cd ~/src
git clone https://gitlab.freedesktop.org/mesa/mesa.git

cd ~/src/mesa
/usr/local/bin/python3 -m venv .venv  # need Python 3.5 or above according to mesa docs

cd ~/src/mesa
source .venv/bin/activate  # must always do this in shell before running pip3 or meson
pip3 install mako
meson --prefix=/tmp/zink -Dgallium-drivers=zink -Dmoltenvk-dir=/Users/<username>/VulkanSDK/1.2.198.1/MoltenVK -Dc_std=c11 build-zink
  1. Try to use zink (and fail, I think):
cd ~/src
git clone https://gitlab.freedesktop.org/mesa/demos.git

cd ~/src
mkdir build

# X is probably not the only way to get a window with OpenGL inside on macOS but Homebrew's freeglut also uses it and I haven't put any effort into investigating alternatives.
brew install libx11  # This way /usr/local/include and /usr/local/lib will include x11 stuff but not GL.
brew install --cask xquartz

cd ~/src
gcc \
\
-lgl \
-I /tmp/zink/include \
-L /tmp/zink/lib \
\
-lX11 \
\
-o build/glxgears \
glxgears.c && \
build/glxgears -info | head -3

That gcc is whatever macOS provides by default (or maybe it was installed along with Xcode, I’m not sure).

I was expecting the output from glxgears with the -info option to include “zink” somewhere, but it doesn’t, so I think this might not actually be using zink, vulkan, or metal. If zink was being used I think the OpenGL version would probably be 3 or higher, but it that reports GL_VERSION = 2.1 ATI-4.6.20.

macOS has this otool command… It says:

$ otool -L build/glxgears
build/glxgears:
	/tmp/zink/lib/libGL.1.dylib (compatibility version 4.0.0, current version 4.0.0)
	/usr/local/opt/libx11/lib/libX11.6.dylib (compatibility version 11.0.0, current version 11.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)

That makes it look like zink should be used. Hmm.

Okay, I’m pretty sure it’s not using Zink, because my output from glxinfo does not include “zink” for OpenGL renderer string like it does here and here, even when I run it like they did, with

__GLX_VENDOR_LIBRARY_NAME=mesa MESA_LOADER_DRIVER_OVERRIDE=zink GALLIUM_DRIVER=zink ./glxinfo

and even though otool -L glxinfo reports

glxinfo:
	/tmp/zink/lib/libGL.1.dylib (compatibility version 4.0.0, current version 4.0.0)
	/usr/local/opt/libx11/lib/libX11.6.dylib (compatibility version 11.0.0, current version 11.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)

I give up for now.

But like I said, I at least have a way to use OpenGL 2.1 now, and I think that will be enough for my needs for a while.

I put some of this on unix.stackexchange.com too: https://unix.stackexchange.com/questions/686173/how-to-use-opengl-on-zink-mesa-moltenvk-and-macos

Can you get the runtime to log the result of glGetString(GL_VERSION) and glGetString(GL_RENDERER)?
If the GL_RENDERER string says something like “… OpenGL Engine” then MESA is using the MacOS system version of OpenGL.
My information is a little dated at present, but last time I looked MESA was hardwired to not use the DRI and MESA drivers but just pass through to the MacOS OpenGL.framework installed on the system.

I’m keeping a close eye on this as well. I know that duncan has been involved with this a while and knows much more than me about the way that zink and the dri works in macos. I did have a brief look at the source code of zink a while ago and there was some custom stuff happening at the time to get an image on screen.

It will still take a bit of work I think for zink on macos to be a fully workable solution. Especially if we want to use windowing libraries like GLFW which do their own detection and setting up of windows in macos.

I’ve tried to dedicate some time to learning how it all fits together but I’ve just been busy with kids and work the last couple of years that I’ve been stabbing in the dark. There is a lot to learn.

If you would like help duncan, then I’m happy to be given a 101 on the high level structure of mac/moltenvk/zink/mesa and how dri works and take over any tasks you think need finished.

Can you get the runtime to log the result of glGetString(GL_VERSION) and glGetString(GL_RENDERER)?
If the GL_RENDERER string says something like “… OpenGL Engine” then MESA is using the MacOS system version of OpenGL.

Looks like it’s using the system OpenGL. I added those function calls near the end of glxinfo and this was the result:

opengl-app$ otool -L build/glxinfo
build/glxinfo:
    /Users/dwiniecki/src/opengl-app/local_zink/lib/libGL.1.dylib (compatibility version 4.0.0, current version 4.0.0)
    /usr/local/opt/libx11/lib/libX11.6.dylib (compatibility version 11.0.0, current version 11.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
opengl-app$ 
opengl-app$ 
opengl-app$ 
opengl-app$ __GLX_VENDOR_LIBRARY_NAME=mesa MESA_LOADER_DRIVER_OVERRIDE=zink GALLIUM_DRIVER=zink build/glxinfo
...
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: AMD Radeon Pro 555X OpenGL Engine
OpenGL version string: 2.1 ATI-4.6.21
...
OpenGL extensions:
    GL_APPLE_aux_depth_stencil, GL_APPLE_client_storage,
    GL_APPLE_element_array, GL_APPLE_fence, GL_APPLE_float_pixels,
    GL_APPLE_flush_buffer_range, GL_APPLE_flush_render,
    GL_APPLE_object_purgeable, GL_APPLE_packed_pixels, GL_APPLE_pixel_buffer,
    GL_APPLE_rgb_422, GL_APPLE_row_bytes, GL_APPLE_specular_vector,
    GL_APPLE_texture_range, GL_APPLE_transform_hint,
    GL_APPLE_vertex_array_object, GL_APPLE_vertex_array_range,
    GL_APPLE_vertex_point_size, GL_APPLE_vertex_program_evaluators,
    GL_APPLE_ycbcr_422, GL_ARB_color_buffer_float, GL_ARB_depth_buffer_float,
    ...

...

2.1 ATI-4.6.21
AMD Radeon Pro 555X OpenGL Engine
opengl-app$ 

My information is a little dated at present, but last time I looked MESA was hardwired to not use the DRI and MESA drivers but just pass through to the MacOS OpenGL.framework installed on the system.

Thanks for the tip! Maybe I’ll try to learn more about this.

@cki
Sorry about that, it caught me out for a while as well. IIRC Windows does the same thing.
I know you have to heavily patch the code to get it to pass through to the Zink driver.

@danmarell
I have a similar issue with too much to do and not enough time to do it all. :smiley:
Thanks for the offer, I have already worked my way through the structure of the code. Just need to get on with it some more.

Thanks for the information. I’m just doing some OpenGL for fun, and I have OpenGL 2.1 now so I should be fine. I’m still curious about Zink and I think it would be cool if this thread ended with an answer for others that find this. I tried reading some code in the Mesa repo but so far I understand very little of it (if any, really).

:+1:

As it sits today, you cannot get Zink to work on MacOS. You can get MESA to work but it will use the system’s OpenGL.framework library.
People have had MESA/Zink + MoltenVk working on MacOS, but those patches have not made it to the public repos, yet.

@cki You need to configure mesa with -Dglx=xlib for it to work with X11.

Thanks @cki, I have been following your discussion a bit with the hope we may reach the ability to keep OpenGL working on macOS despite the deprecation.

On my side I am mainly interested for now by software rendering with Mesa. I can get it working on Ubuntu and Linux but unfortunately not on macOS, see “Failing to load Mesa3D on macOS instead of macOS provided OpenGL library”. Would you tell me how you got Mesa working on macOS?

@DuncanHopkinsFoundry

You can get MESA to work but it will use the system’s OpenGL.framework library.

How can you state this? Is there really no way to bypass the OS GL framework?

I unfortunately was only able to figure out how to use the system GL:

My messages (above) from January 16th show how I built and ran programs using Mesa, but as noted those still just used the system GL.

1 Like

The present public code, on MacOS, fills the GL function pointers from the OpenGL.framework. Where as the Linux builds use the _mesa_gl*() functions.
Once you have that fixed you would also them have to re-enable the MESA drivers (old and/or Gallium) code path in the DRI handling code. All of which is presently hardwired behaviour in the code. (I have not had chnage to double check this in the last 6 month, so it might have changed)

1 Like

Thanks, this explain why system GL is used.

Is this is also the case for software rendering? My goal here is to only rely on CPU rendering.

May I ask you a pointer to better locate which mesa .c files should be modified to get Apple device use mesa GL instead of system GL?

Is this is also the case for software rendering?

Software rendering is just a backend driver. Once you have them working you can select what ever you like. Admittedly there is little point in select something like the INTEL or AMD drivers, but software rasterisers or Zink are then possible.

May I ask you a pointer to better locate which mesa .c files should be modified to get Apple device use mesa GL instead of system GL?

I would have to go and look up what I did internally, the list is not short. There is a platform define that ends in APPLEGL, IIRC, that would give you an idea of how much code you would need to hack. This would still leave an X11 dependency on MESA on MacOS.

Software rendering is just a backend driver. Once you have them working you can select what ever you like. Admittedly there is little point in select something like the INTEL or AMD drivers, but software rasterisers or Zink are then possible.

My goal is to compute OpenGL with a C/C++ software that will only run in CPU and provide an image to display in an app. This works well on Ubuntu and Windows for which I get a llvmpipe renderer. The point is to use Mesa’s software rasterizer when JOGL (a Java OpenGL binding) fail to access native/OS GL.

There is a platform define that ends in APPLEGL, IIRC

I indeed found
GLX_USE_APPLEGL in src/glx/apple_glx.c and several src/glx/apple/apple_glx_*.c files. The flag is set there, which let me think that Mesa won’t call Apple GL if compilation has options with_glx == 'xlib' or with_glx == 'gallium-xlib' (which is conform to what the doc says).

I however exactly followed these instructions and built mesa with -Dosmesa=true -Dglx=xlib -Dgallium-drivers=swrast, so I would expect the whole Apple GL code to be bypassed, which is not

# Force my mesa build before Apple's one
export DYLD_INSERT_LIBRARIES=/Users/martin/Dev/jzy3d/external/osmesa/lib/libGL.dylib
# Force CPU rendering
export LIBGL_ALWAYS_SOFTWARE=true
# Print info on selected GL renderer
glxinfo | head -n 50

yields to the following output

client glx vendor string: Mesa Project and SGI
client glx version string: 1.4
...
OpenGL vendor string: Apple Inc.
OpenGL renderer string: Apple Software Renderer
OpenGL version string: 2.1 APPLE-18.5.9
OpenGL shading language version string: 1.20

whereas I would expect

OpenGL renderer string: llvmpipe

I found no IIRC string in the project.

IIRC was not a string in the code, it was a “If I Remember Correctly” (IIRC) comment. Sorry. :grinning:

The GLX_USE_APPLEGL will get you the control over the display system. There is extra that also needs to be done to switch the GL function pointers and use the MESA drivers, but I really need to look it up to figure out what those changes are. As I can never remember and it always takes me a while to find the change again.

1 Like

I have not had chance to check the new code, but this article claims Windows is calling through to Zink. Hopefully MacOS code is either also working or just needs a similar set of tweeks.

https://www.phoronix.com/scan.php?page=news_item&px=Zink-Windows-Kopper-Progress

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.