[OpenGL and Vulkan Interoperability on Linux] Part 7: Reusing a Vulkan vertex buffer from OpenGL

This is the 7th post on OpenGL and Vulkan Interoperability with EXT_external_objects. It’s about another EXT_external_objects use case implemented for Piglit as part of my work for Igalia‘s graphics team. In this case a vertex buffer is allocated and filled with data from Vulkan and then it’s used from OpenGL to render a pattern on screen.

The vk-vert-buf-update-errors test is implemented in Piglit‘s tests/spec/ext_external_objects/vk_vert_buf_update_errors.c and:

  • Creates an external vertex buffer with Vulkan and fills it with vertices that could form the white quads of a chess board
  • Imports the buffer in OpenGL and uses it as the vertex array at rendering
  • Attempts to overwrite the buffer data with new geometry
  • Validates that the geometry remained unchanged and renders a red-blue chessboard using OpenGL and the vertices

Step 1: An external Vulkan vertex buffer is created and filled with chess board quads

In piglit_init we call vk_init to initialize the Vulkan structs and there we create a Vulkan vertex buffer:

We fill it with quads that would correspond to the white quads of a chess board:

To do so we mapped the buffer’s memory and we generated the quads with gen_checkerboard_quads:

Now the vertex buffer is ready to be imported in OpenGL.

Step 2: The external Vulkan quad is imported in OpenGL

To import the vertex buffer we’ll do something similar to what we did in Part 5 to import the pixel buffer, but this time the target will be GL_ARRAY_BUFFER instead of GL_PIXEL_UNPACK_BUFFER:

After these steps the buffer is ready to be used by OpenGL. (We’ve explained gl_gen_buf_from_mem_obj in Part 5 and gl_create_mem_obj_from_vk_mem in Part 2).

Step 3: Using the external vertex buffer to draw a chessboard pattern with OpenGL

We bind the buffer as GL_ARRAY_BUFFER and we call glDrawArrays like we would call it with an OpenGL allocated vertex array:

We are using gl_prog to paint the vertices blue after we have cleared the framebuffer to red. The vertex and pixel shaders used to build gl_prog are quite minimal:

piglit_present_results shows the chess board pattern on screen.

Step 4: An attempt to overwrite the buffer should return Invalid Operation Error

Just to make sure that the reused vertex buffer cannot be overwritten by OpenGL we perform a check that calling glBufferSubData will return an error:

Then, we clear the framebuffer to red and use the same vertex data to perform another drawing:

At this point, the vertex data should be the ones written by Vulkan and piglit_present_results must display a red-blue chess board pattern.

And that’s it!

This test case was written to validate that we can create and fill a vertex buffer from Vulkan and use it to render with OpenGL. But also to see that we aren’t allowed to overwrite the external vertex buffer’s content from OpenGL!


Coming soon:

Next post will be about using an external vertex buffer to draw once from OpenGL and once from Vulkan to make sure it can be re-used several times. Stay tuned!

and see you next time!

Leave a Reply

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