[OpenGL and Vulkan Interoperability on Linux] Part 8: Using a Vulkan vertex buffer from OpenGL and then from Vulkan

This is the 8th post on OpenGL and Vulkan Interoperability with EXT_external_objects and EXT_external_objects_fd where I explain some example use cases of the extensions I’ve implemented for Piglit as part of my work for Igalia. In this example, a Vulkan vertex buffer is created and filled with vertices and then it’s used to render the same chess board pattern once with OpenGL and once with Vulkan.

The Piglit test where I’ve implemented this use case is named vk-vert-buf-reuse and it’s source code can be found in piglit/tests/spec/ext_external_objects/vk_vert_buf_reuse.c (you must clone the Piglit master branch).

The vk-vert-buf-reuse test:

  • Allocates a Vulkan vertex buffer and fills it with vertices that could form the white quads of a chess board like the ones we’ve seen in Part 7.
  • Imports and uses the vertex buffer from OpenGL to draw the pattern on screen (like in Part 7).
  • Reuses the vertex buffer to draw the same image with Vulkan.
  • Copies the Vulkan render target image to a buffer to take a pointer to data and displays them with OpenGL

The expected result is the same red-blue chessboard pattern we’ve seen in Part 7:

Step 1: Allocating and filling the Vulkan vertex buffer

This step is similar to the one we’ve seen in Part 7. In vk_init of piglit_init we create an external vertex buffer and we fill it vertices that could be used to draw the white quads of a chess board using gen_checkerboard_quads.

all the functions of the snippet above have already been explained in the previous post.

Step 2: Using the Vulkan vertex buffer in OpenGL rendering

We use the vertex buffer in piglit_display to render the geometry in blue after we clear the framebuffer to red using a pair of shaders that we’ve also explained in Part 7. Then we validate that what is displayed on the screen is indeed a red-blue chessboard by calling check_red_blue_chess_pattern:

The function check_red_blue_chess_pattern only probes the middle pixel’s color for each red or blue quad using built-in piglit testing functions:

Step 3: The vertex buffer is used from Vulkan to draw the same chess board pattern

To draw with Vulkan we’ve first initialized some required Vulkan structs in vk_init that is called inside piglit_init. We used vk_init_vulkan_drawing for that:

This function creates a Vulkan “renderer” (an abstract struct I use to render different scenes with the Piglit Vulkan framework). It also creates the color and depth attachments, the shaders and the vertex buffer that will be used at drawing. The shaders do more or less the same thing the OpenGL ones did in Part 7 and their code can be found in tests/spec/ext_external_objects/vk_blue.vert and tests/spec/ext_external_objects/vk_blue.frag files of the piglit master branch (the test is upstream).

After this required step, the rendering can be performed by calling vk_draw_checkerboard in piglit_display. This function renders the checkerboard pattern to the Vulkan renderer’s render target. After it’s called we only need a pointer to its pixels and we can use it with a new OpenGL texture to display and validate that the pattern is the same.

[Note!] the reason we display the pixels with OpenGL is that this code is part of the piglit testing framework where we can only draw pixels using OpenGL. In a different application someone could simply visualize the renderer’s renderpass render target with Vulkan.

The Vulkan function that draws the chess board pattern is simply a call to vk_draw we’ve seen in previous examples:

And that was it!

In this test we’ve allocated a Vulkan vertex buffer, we’ve used it to draw with OpenGL and then we reused it to draw with Vulkan. At the end, we displayed the pixels of the Vulkan render target with OpenGL to validate they form a blue and red chess board pattern.


What’s next:

Next post will be about reusing an external Vulkan depth buffer from OpenGL and there will be one more about reusing the stencil buffer. Stay tuned!

and see you next time!

Leave a Reply

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