Coding

CMake polishing

I needed to update my CMake files to work properly with my BBB. It turned out that there is no OpenGL on the Imagination image for BBB and just EGL + GLES. Therefore I had to write my own FindEGL.cmake which would not depend on OpenGL. I was long baffled by undefined references in my code, until I realized that I need to import system libraries as UNKNOWN IMPORTED like this:

if (NOT TARGET EGL::EGL)
    add_library(EGL::EGL UNKNOWN IMPORTED)
    set_target_properties(EGL::EGL PROPERTIES
        IMPORTED_LOCATION "${EGL_LIBRARY}")
endif()

I also had to specify custom location for include directories for the EGL and GLES libraries (in FindX.cmake files) like this:

if (NOT DEFINED GLES2_INCLUDE_DIR)
    set(GLES2_INCLUDE_DIR "/opt/Native_SDK/include")
endif()

set_target_properties(OpenGLES2::OpenGLES2 PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES "${GLES2_INCLUDE_DIR}")

And then export these libraries by the main library by adding them to target_include_directories, since we are probably not using them from the default system include directories.

It turned out that the BBB with Imagination image does not support the EXT extensions to EGL I was using on my host to enumerate possible devices to render to, so I decided to try my luck with two supported extensions allowing for creation of custom contexts.

In case you are interested, there is an official document listing the supported extensions on PowerVR platforms.

For now I am trying rendering using a concept known as render nodes which are special wrappers over regular device files for graphic cards. These allow for using the cards without creating a display - ideal solution for this project, GPGPU.

In order to use these nodes we need to create GBM which is a Generic Buffer Management system, used to tie the high-level API calls to driver-specific calls. This requires usage of several extensions which fortunately are available on PowerVR SGX5xx platforms. Both the GBM device and a rendering surface are created using this API and then bound to the EGL rendering context via eglMakeCurrent call.


Since getting the context to work on BBB is tedious and may require more work which is not directly related to the library, I am developing the functionality of different API calls on the host and then I will port it to the target platform.


The next part of coding this week, is creating a scaffolding which will be used by every API call, such as creating shaders, compiling and linking them, creating the Framebuffer Objects, textures and finally running the actual computation.

More details about how it is done are present in the (upcoming) blog post as for a person not used to complexity of OpenGL it is fairly confusing.

In brief, we are using textures as input data and the framebuffer as our output data. Each pixel (which corresponds to a data quadruplet - RGBA) is then computed in parallel using the fragment shader code and output to the framebuffer.


A significant part of this week was spent on getting OpenGL to do what I want and to start doing something. I managed to do it after several hours of head scratching and googling non-descriptive errors. Probably the most difficult one was with any shader related call causing GL_INVALID_OPERATION and which was caused by invalid EGL context settings, and is described in this forum post, which states that the context has to be GLES 2.0 compatible.

What is more, it seems like my earlier approach of doing GL_FLOAT textures will not work on both my host and on the BBB due to GLES 2.0 limitations and extensions only allowing for 16-bit float processing. Therefore, I will be using GL_UNSIGNED_BYTE and transform the input so that it is represented as unsigned chars.

This also requires some modifications in shaders which will operate on scaled float values instead of arbitrary ones (as with GL_FLOAT). This article is a good source of information about that.

Reading

The context tackled this week requires even more knowledge on my part (especially polishing my rusty OpenGL skills) I read through following resources:

  • https://computer-graphics.se/multicore/pdf/2014/13b%20glsl.pdf
  • https://faculty.kaust.edu.sa/sites/markushadwiger/Documents/CS380_spring2013_lecture_03.pdf
  • https://www.seas.upenn.edu/~cis565/fbo.htm

Blog

I am writing a blog which details how the scaffolding of the project works and what components of Linux/GL are necessary to make GPGPU computing a thing with OpenGL ES 2.0.