GL_ARB_gl_spirv and GL_ARB_spirv_extensions

GL_ARB_gl_spirv is an OpenGL extension whose purpose is to enable an OpenGL program to consume SPIR-V shaders. In the case of GL_ARB_spirv_extensions, it provides a mechanism by which an OpenGL implementation would be able to announce which particular SPIR-V extensions it supports, which is a nice complement to GL_ARB_gl_spirv.

As both extensions, GL_ARB_gl_spirv and GL_ARB_spirv_extensions, are core functionality in OpenGL 4.6, the drivers need to provide them in order to be compliant with that version.

Although Igalia picked up the already started implementation of these extensions in Mesa back in 2017, 2018 is a year in which we put a big deal of work to provide the needed push to have all the remaining bits in place. Much of this effort provides general support to all the drivers under the Mesa umbrella but, in particular, Igalia implemented the backend code for Intel‘s i965 driver (gen7+). Assuming that the review process for the remaining patches goes without important bumps, it is expected that the whole implementation will land in Mesa during the beginning of 2019.

ETC2/EAC

The ETC and EAC formats are lossycompressed texture formats used mostly in embedded devices. OpenGL implementations of the versions 4.3 and upwards, and OpenGL/ES implementations of the versions 3.0 and upwards must support them in order to be conformant with the standard.

Most modern GPUs are able to work directly with the ETC2/EAC formats. Implementations for older GPUs that don’t have that support but want to be conformant with the latest versions of the specs need to provide that functionality through the software parts of the driver.

During 2018, Igalia implemented the missing bits to support GL_OES_copy_image in Intel’s i965 for gen7+, while gen8+ was already complying through its HW support. As we were writing this entry, the work has finally landed.

VK_KHR_16bit_storage

This extension allows the use of 16-bit types (half floats, 16-bit ints, and 16-bit uints) in push constant blocks, and buffers (shader storage buffer objects). This feature can help to reduce the memory bandwith for Uniform and Storage Buffer data accessed from the shaders and / or optimize Push Constant space, of which there are only a few bytes available, making it a precious shader resource.

shaderInt16

Igalia added Vulkan’s optional feature shaderInt16 to Intel’s Anvil driver. This new functionality provides the means to operate with 16-bit integers inside a shader which, ideally, would lead to better performance when you don’t need a full 32-bit range. However, not all HW platforms may have native support, still needing to run in 32-bit and, hence, not benefiting from this feature. Such is the case for operations associated with integer division in the case of Intel platforms.

SPV_KHR_8bit_storage and VK_KHR_8bit_storage

SPV_KHR_8bit_storage is a SPIR-V extension that complements the VK_KHR_8bit_storage Vulkan extension to allow the use of 8-bit types in uniform and storage buffers, and push constant blocks. Similarly to the the VK_KHR_16bit_storage extension, this feature can help to reduce the needed memory bandwith.

In theory, applications that do not need the range and precision of regular 32-bit floating point and integers, can use these new types to improve performance. Additionally, its implementation is mostly API agnostic, so most of the work we did should also help to have a proper mediump implementation for GLSL ES shaders in the future.

The review process for the implementation is still ongoing and is on its way to land in Mesa.

VK_KHR_shader_float_controls

VK_KHR_shader_float_controls is a Vulkan extension which allows applications to query and override the implementation’s default floating point behavior for rounding modes, denormals, signed zero and infinity.

Igalia has coded its support into Intel’s Anvil driver and it is currently under review before being merged into Mesa.

VkRunner

VkRunner is a Vulkan shader tester based on shader_runner in Piglit. Its goal is to make it feasible to test scripts as similar as possible to Piglit’s shader_test format.

Igalia initially created VkRunner as a tool to get more test coverage during the implementation of GL_ARB_gl_spirv. Soon, it was clear that it was useful way beyond the implementation of this specific extension but as a generic way of testing SPIR-V shaders.

Since then, VkRunner has been enabled as an external dependency to run new tests added to the Piglit and VK-GL-CTS suites.

freedreno

During 2018, Igalia has also started contributing to the freedreno Mesa driver for Qualcomm GPUs. Among the work done, we have tackled multiple bugs identified through the usual testing suites used in the graphic drivers development: Piglit and VK-GL-CTS.

Khronos Conformance

The Khronos conformance program is intended to ensure that products that implement Khronos standards (such as OpenGL or Vulkan drivers) do what they are supposed to do and they do it consistently across implementations from the same or different vendors.

This is achieved by producing an extensive test suite, the Conformance Test Suite (VK-GL-CTS or CTS for short), which aims to verify that the semantics of the standard are properly implemented by as many vendors as possible.

In 2018, Igalia has continued its work ensuring that the Intel Mesa drivers for both Vulkan and OpenGL are conformant. This work included reviewing and testing patches submitted for inclusion in VK-GL-CTS and continuously checking that the drivers passed the tests. When failures were encountered we provided patches to correct the problem either in the tests or in the drivers, depending on the outcome of our analysis or, even, brought a discussion forward when the source of the problem was incomplete, ambiguous or incorrect spec language.

The most important result out of this significant dedication has been successfully passing conformance applications.

OpenGL 4.6

Igalia helped making Intel’s i965 driver conformant with OpenGL 4.6 since day zero. This was a significant achievement since, besides Intel Mesa, only nVIDIA managed to do this too.

Mesa Releases

Igalia continued the work that was already carrying on in Mesa’s Release Team throughout 2018. This effort involved a continuous dedication to track the general status of Mesa against the usual test suites and benchmarks but also to react quickly upon detected regressions, specially coordinating with the Mesa developers and the distribution packagers.

The work was obviously visible by releasing multiple bugfix releases as well as doing the branching and creating a feature release.

CI

Continuous Integration is a must in any serious SW project. In the case of API implementations it is even critical since there are many important variables that need to be controlled to avoid regressions and track the progress when including new features: agnostic tests that can be used by different implementations, different OS platforms, CPU architectures and, of course, different GPU architectures and generations.

Igalia has kept a sustained effort to keep Mesa (and Piglit) CI integrations in good health with an eye on the reported regressions to act immediately upon them. This has been a key tool for our work around Mesa releases and the experience allowed us to push the initial proposal for a new CI integration when the FreeDesktop projects decided to start its migration to GitLab.

Since A Coruña is the town in which the company originated and where we have our headquarters, Igalia had a key role in the organization, which was greatly benefited by our vast experience running events. Moreover, several Igalians joined the conference crew and, as mentioned above, we delivered talks around GL_ARB_gl_spirv, VkRunner, and Mesa releases and CI testing.

The feedback from the attendees was very rewarding and we believe the conference was a great event. Here you can see the Closing Session speech given by Samuel Iglesias:

Other activities

Conferences

As usual, Igalia was present in many graphics related conferences during the year:

When you are working in the console of an Un*x system you always have the possibility of using some kind of notification system to warn you when a task has completed. Quite typically, that would involve an email that could arrive to your box’ local inbox or, if you have a mail agent properly configure, to some other inbox in the Internet.

With the arriving of the Instant Messaging systems you could somehow move from the good old email notification to some other fancy service. That has been my prefered method for quite a while since I understand email as a “non-instant” messaging system. Basically, I do not want to get instant notifications when a mail arrives. Add to that the hassle of setting some kind of filter criteria to get the notifications only for specific mail rules and the not yet universally supported IMAP4 push method, instead of pulling for newly arrived mail …

Anyway, long story short, for some time now we are using [matrix] as our Instant Messaging service at Igalia so, why not getting notifications there when a task is completed?

Yes, you have guessed correctly, that’s possible and, actually, it’s very easy to set up, specially with the help of matrix-send.

First, you need an account that will send you the notification(s). Ideally, that would be a bot user, but it could be any account. Then, you have get an access token with such user so you can interact with the matrix server from the command line as if it would be any other ordinary matrix client. Finally, you need to create a chat room between that user and your own in order to keep the communication ongoing. All this is explained in matrix’ client-server API documentation but, to make things easier, it would go as follows:

Now, from your regular matrix client, invite the bot user to a conversation in a new room. Check in the configuration of the new room for its internal ID. It would be something like!<internal-id>:<home-server>.

All that is left is to configure matrix-send and start using it. Mind you, I’ve done a small addition that it has not been merged yet so I would just clone from my fork.

The configuration file would look like this:

Shell

1

2

3

4

5

6

$cat~/.config/matrix-send/config.ini

[DEFAULT]

endpoint=https://<matrix-server>/_matrix/

access_token=<access-token>

channel_id=!<internal-room-id>:<home-server>

msgtype=m.text

The interesting addition from my own is the msgtype field. By default, in matrix-send its value is m.notice which, depending on the configuration, quite typically won’t trigger a notification in your matrix client.

This is mostly a note pad for myself with quick instructions about how to create a bug report for Debian and edit it and send it with Evolution.

reportbug is Debian’s tool for sending bug reports. Although it is a nice tool that automatizes most of this process, it only supports some email clients for the final steps of editing the message (and send it). Among these programs is not Evolution, my preferred mail application.

Fortunately, there is a way to work around this problem. The way of doing it is by placing the mbox file created by reportbug into Evolution’s local Drafts folder. As we can read on its manual, Evolution stores the user’s data files at $HOME/.local/share/evolution.

By doing a simple check around that path, we can conclude the following solution: first, we generate the bug report and place the output in the proper location, as in this command:

After finishing walking through reportbug‘s wizard, the only action left is launching Evolution and opening a new email that has appeared in the local Drafts folder, finish editing it (attaching files, etc.) and send it.

This is mostly a note pad for myself with quick instructions about how to add subtitles streams to an existent video.

Although I’m personally more in favor of using Ogg, reality is that Matroska is the one that is getting the biggest support among the Open Source container formats and it also has a great deal of features.

Also, because of widespread adoption, in spite of not having a really formal syntax and many features, SubRip is my chosen format for subtitles.

Now, I’m the owner of a Samsung 3D SmartTV which allows external SubRip .srt files. However, it also supports Matroska files with embedded subtitles and having the subtitles in the same container than the audio and video streams have some advantages. The main one is that I would be able to play such file through UPnP, with subtitles included, meanwhile that’s not possible with some UPnP servers if the subtitles are in a different file than the video. That’s the case, for example, with BubbleUPnP for Android, which I use from a tablet.

Anyway, enough introduction.

For creating a Matroska file from an existing video and a SubRip file I would use the MKVToolNix package. In a Debian based system you can install it with the following command:

Shell

1

root$apt-getinstall mkvtoolnix

In order to merge video and a subtitles (actually, many multiple streams), the proper command for this would be mkvmerge. Its usage is quite straight forward:

That’s basically it. With this command we will get, from a .mp4 and a .srt file, a .mkv file with both merged together. Now, if we would be wanting to add more languages we could have done something like this:

This is mostly a note pad for myself with quick instructions about how to add a “cover” tag to audio files.

I usually add covers to every individual audio file from my albums so I can nicely see them when playing the file either in my computer or mobile. Often, I just use the fantastic Ex Falso application not just to add more advanced tags to my audio files but also for downloading covers from different providers.

Whenever I cannot easily find the cover I’m looking for, I would just scan it and finally save it as a 500×500 pixels JPEG file named as cover.jpg in the same directory than the audio files.

Having this into account, let’s see how to embed the cover as a tag.

MP3 or, rather, id3 tags

For id3 tags I would use the eyeD3 tool. It can be done as easily as running:

Shell

1

$eyeD3--add-image=cover.jpg:FRONT_COVER*.mp3

OGG Vorbis

In the case of OGG Vorbis files I follow a little bit more complex steps. I’m sure I could just simplify this in a single step but, by now, I’m too lazy to spend 5 minutes improving this O:)

First, I would add the cover into an individual OGG Vorbis file using the EasyTag application. I could just save the same cover on every file but I wanted to show how to do that in batch mode from the command line.

Therefore, as I said, I just save the cover into and individual file an extract all the tags from such file using the vorbiscomment tool:

Shell

1

$vorbiscomment-l<file>.oga>comments.txt

Then, I would modify the comments.txt file so it will only contain the needed art cover tags and append them to the rest of the files:

Shell

1

$vorbiscomment-a-ccomments.txt<other_file>.oga

Hopefully, I will update this in the future with a single command to do it in a go and will also review how to be able to just link the proper cover from the audio files. Also, I will try to explain the logic for the naming of the covers in the local directory without having to add the tag to any file so crawlers like Tracker will just do the work for us.

This is mostly a note pad for myself with quick instructions about how to extract, cut, join and merge audio and video streams.

In Igalia we often hold meetings with several parties attending remotely. The easy setting of such meetings usually involve a shared desktop through VNC and a SIP call in a multi user room hold in our Asterisk installation.

When some of my Igalian mates cannot attend we may want to record the meeting so they can play it later. Fortunately, GNOME Shell provides integrated desktop recording out of the box and we have Asterisk set to record automatically our calls in specific multi user rooms.

So, all what it is left after a meeting is just to get both files, edit them slightly and sync them to merge them in a single multimedia container.

Usually, I would use Kdenlive in my video editing tasks. However, Kdenlive doesn’t support “video edition” without re-encoding and I would really like not to re-encode the whole stuff. Specially, the video stream. Therefore, I still will use Kdenlive for the task of syncing both streams and looking for the cutting points for both, the video and the audio file.

For most of this “without re-encoding” actions I will use the great avconv tool.

First, I will cut the video in the time 00:07:45 as starting point and 02:05:20 as ending point:

This command basically demuxes the WebM container and extract the video stream between those two points to mux it again into a Matroska container.

Then, I will cut the audio in the starting point 00:02:13 and ending point 01:59:48. For editing OGG files we can use Oggscissors or OGG Video Tools’ oggCut .

You won’t find Oggscissors in Debian (the distribution I use). Therefore, you will have to download it and install pyvorbis and pyogg and, maybe, modify slightly the script to use the proper python interpreter. You can install the missing packages like this:

Shell

1

root$apt-getinstall python-pyvorbis

Once with Oggscissors working, we can get the interesting audio chunk like:

Shell

1

$oggscissors.py--from=133--upto=7188conf-call.oggcut-confcall.ogg

or, with oggCut, like:

Shell

1

$oggCut-s133000-e7188000conf-call.oggcut-conf-call.ogg

It may happen that we actually want to extract the audio from another video file. This has happened to us, eventually, when wanting to use the audio from a synced file into another video with higher quality.

We will also use avconv for this:

Shell

1

$avconv-isynced-video.ogv-map0:1-c:acopy synced-audio-output.ogg

It may also happen that we want to join a couple of OGG files since our SIP conf-calls sometimes have hiccups. With Oggscissors this will be done as follows:

Shell

1

$oggscissors.py--joinfirst.oggsecond.oggjoint-output.ogg

With oggCat this will be done like:

Shell

1

$oggCat joint-output.oggfirst.oggsecond.ogg

Finally, we will merge or mux the resulting video and audio files into a single media container. Again, with avconv this will be done like:

So lately I’ve been devoting my time in Igalia around the GNU/Linux graphics stack focusing, more specifically, in Mesa, the most popular open-source implementation of the OpenGL specification.

When working in Mesa and piglit, its testing suite, quite often you would like to compare the results obtained when running a specific OpenGL code with one driver or another.

In the case of nVIDIA graphic cards we have the chance of comparing the default open source driver provided by Mesa, nouveau, or the proprietary driver provided by nVIDIA. For installing the nVIDIA driver you will have to run something like:

Changing from one driver to another involves several steps so I decided to create a dirty script for helping with this.

The actions done by this script are:

Instruct your X Server to use the adequate X driver.
These instructions apply to the X.org server only.
When using the default nouveau driver in Debian, the X.org server is able to configure itself automatically. However, when using the nVIDIA driver you most probably will have to instruct the proper settings to X.org.
nVIDIA provides the package nvidia-xconfig. This package provides a tool of the same name that will generate a X.org configuration file suitable to work with the nVIDIA X driver:

Shell

1

2

3

4

5

6

7

8

9

root$nvidia-xconfig

WARNING:Unable tolocate/openXconfiguration file.

Packagexorg-server was notfound inthe pkg-config search path.

Perhaps you should add the directory containing`xorg-server.pc'

tothe PKG_CONFIG_PATH environment variable

No package'xorg-server'found

NewXconfiguration filewritten to'/etc/X11/xorg.conf'

I have embedded this generated file into the provided custom script since it is suitable for my system:

Alternate nouveau and nVIDIA proprietary OpenGL driver

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

echo'Section"ServerLayout"

Identifier"Layout0"

Screen0"Screen0"

InputDevice"Keyboard0""CoreKeyboard"

InputDevice"Mouse0""CorePointer"

EndSection

Section"Files"

EndSection

Section"InputDevice"

# generated from default

Identifier"Mouse0"

Driver"mouse"

Option"Protocol""auto"

Option"Device""/dev/psaux"

Option"Emulate3Buttons""no"

Option"ZAxisMapping""4 5"

EndSection

Section"InputDevice"

# generated from default

Identifier"Keyboard0"

Driver"kbd"

EndSection

Section"Monitor"

Identifier"Monitor0"

VendorName"Unknown"

ModelName"Unknown"

HorizSync28.0-33.0

VertRefresh43.0-72.0

Option"DPMS"

EndSection

Section"Device"

Identifier"Device0"

Driver"nvidia"

VendorName"NVIDIA Corporation"

EndSection

Section"Screen"

Identifier"Screen0"

Device"Device0"

Monitor"Monitor0"

DefaultDepth24

SubSection"Display"

Depth24

EndSubSection

EndSection

'&gt;/etc/X11/xorg.conf

I would recommend you to substitute this with another configuration file generated with nvidia-xconfig on your system.

Select the proper GLX library.
Fortunately, Debian provides the alternatives mechanism to select between one or the other.

Alternate nouveau and nVIDIA proprietary OpenGL driver

Shell

1

ALTERNATIVE=""

…

Alternate nouveau and nVIDIA proprietary OpenGL driver

Shell

1

ALTERNATIVE="/usr/lib/mesa-diverted"

…

Alternate nouveau and nVIDIA proprietary OpenGL driver

Shell

1

ALTERNATIVE="/usr/lib/nvidia"

…

Alternate nouveau and nVIDIA proprietary OpenGL driver

Shell

1

update-alternatives--set glx"${ALTERNATIVE}"

Black list the module we don’t want the Linux kernel to load on start up.
Again, in Debian, the nVIDIA driver package installs the file /etc/nvidia/nvidia-blacklists-nouveau.conf that is linked, then, from /etc/modprobe.d/nvidia-blacklists-nouveau.conf instructing that the open source nouveau kernel driver for the graphic card should be avoided.
When selecting nouveau, this script removes the soft link creating a new file which, instead of black listing nouveau’s driver, does it for the nVIDIA proprietary one:

It is recommended to reboot the system although theoretically you could unload the kernel driver and restart the X.org server. The reason is that it has been reported that unloading the nVIDIA kernel driver and loading a different one is not always working correctly.

Motivation

I’m a long time user of Jabber and Empathy. I use it for every day’s communications and, in Igalia, we have several internal rooms in which we coordinate ourselves. Because of the amount of rooms in which I am as a regular basis, Empathy’s chat window is unable to display the tabs of each of them in the top bar of the conversations.

This forces me either to split in different windows or just to navigate among them every now and then to check if there is any interesting update. Quite annoying 🙂 .

Some time ago, #586145 was filed requesting the possibility of having the chat room tabs not only displayed on top but also in other positions, specially in the side.

Hence, I decided to take the existing patch and perform some small changes to the work done by Neil Roberts in order to be able to have these side tabs.

With this new feature, you can change the position of the tabs just by changing a setting, as the position property is bond to it. If you want to set the tabs at ‘top’, ‘left’, ‘bottom’ or ‘right’, you should run, respectively:

Now, I’ve uploaded a new version of the patch and I’m waiting to pass the review process and land it.

This is a tiny enhancement on top of the great work that several GNOME developers have done in Empathy over the years. However, it is really making a difference to me so I’ve decided to share it quickly in case someone else would find it useful since it will take a while to come into the main distributions. Hence, I’ve ported it to the Empathy version I’m using in the Ubuntu Saucy 13.10 running on my desktop.

If you want to give it a try, just follow the instructions I’ve written at the beginning of this post.

Final notes

In addition to Empathy, you will be able to find in my PPAs:

A working (and custom) version of the faulty official icecc package with patches fixing LP#1182491.

A custom version of webkitgtk with patches fixing WK#115650 which will speed up opening new tabs in Web.

This is more a note pad for myself with quick instructions about how to upload a (usually patched) package to my own PPAs.

Patching an existing package

First thing is downloading the sources of the package from the repository that is providing the buggy binary package installed in my system.

For example, when patching webkitgtk, if my installed package is from a vanilla Ubuntu release, I only have to check that I have the source from the official Ubuntu repositories. However, if my installed package is from another PPA, I will have to check that I have the source from it or, if not, I would have to download the needed packages manually. Let’s assume my installed package is coming from the GNOME3 Team Ubuntu PPA:

Shell

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

$cd~/ppa/&&mkdir-pwebkitgtk/gnome3&&cdwebkitgtk/gnome3

$apt-getsource webkitgtk

Reading packagelists...Done

Building dependency tree

Reading state information...Done

NOTICE:'webkitgtk'packaging ismaintained inthe'Git'version control system at:

Just in case, something I like to do is to add the code from the downloaded package to a local git:

Shell

1

2

3

4

$git init

$git add*

$git commit-m"Initial commit"

...

Then, it is time to apply the needed changes to the source code. This is the reason why git comes handy, in case these changes are not trivial and they need actually some more work. When we are done with the changes, we have to add them to the debian package as an additional patch to the original source. We use dpkg-source for this:

Finally, we modify the release information adding or increasing the non-maintainer digit. For example, in this case the downloaded source version was 2.3.2-1ubuntu6~saucy1, so I’m setting 2.3.2-1ubuntu6~saucy1.1. Also, remember to provide the proper distribution name or to modify it when writing down the log of the changes. In this case, we are using saucy. Check also that you are using the proper email for the log. In my PPAs I use my personal one:

Importing patch alternative

Maybe this is a cleaner and quicker way of patching the downloaded sources. Instead of modifying the sources and running dpkg-source –commit, we can just import an existent patch that would apply on the source code.

To do this, we just have to run:

Shell

1

$quilt import/<path_to_original_patch>/my_patch.patch

This will also work in Debian packages for which version dpkg-source –commit won’t work. In addition, is the quickest way to reuse a patch from a package in a previous Ubuntu distribution into a newer one, for example.

From here we will retake the same steps than above to add the release information.

Building the source package

We just have to take into account that, when you have more than one GPG key available, the signature of the package will fail during the process, as in:

In addition, if the sources used for the package are not coming from one of the official Ubuntu repositories you will need to provide also the sources when uploading to the PPA. For this, you have to pass the -sa parameter. For the used example, as we are taking the source from the GNOME3 Team Ubuntu PPA, we will pass this parameter as in:

Shell

1

$debuild-S-sa-rfakeroot-k3FEA1034

While for other packages which we modify directly from the sources of the official packages provided by Ubuntu, we just use:

Shell

1

$debuild-S-rfakeroot-k3FEA1034

Optional local build

A local build is not really necessary but it will tell you if your applied changes are breaking or not the compilation of the package.

The best way of doing a trustful local build is using pbuilder.

When using pbuilder we have to be sure that we are using the proper packages not only from Ubuntu’s official repositories but also from the PPAs our target PPA depends on and also our own PPA itself.

I’ve already created the tarballs with the chroot distributions for my own PPAs. However, in order to show an example, we would be using a line like the following one for creating a new tarball for my gnome3 PPA which depends in my ppa PPA and also in GNOME3 Team’s gnome3 PPA:

Uploading to your PPA

The final step is uploading the package with the new changes to your PPA.

I actually have one sandbox PPA per each stable PPA. These PPAs are not intended for the general users but for being able to play with the changes until I feel they are stable enough to be published in the stable PPAs. Hence, I have 4 PPAs:

ppa: Where I keep changes from official Ubuntu packages that are useful to me.

ppa-next: Not intended for general users. Where I keep unstable packages with the changes that I will move to the ppa one once I feel they are stable enough.

gnome3: Where I keep changes on packages which source has been obtained from the GNOME3 Team PPA.

gnome3-next: Not intended for general users. Where I keep unstable packages with the changes that I will move to the gnome3 one once I feel they are stable enough.

With this, during the first cycles of development I will be uploading the changes to my unstable PPAs before uploading them to the stables. For this example, I would be uploading first to the gnome3-next one: