Wednesday, May 28, 2025

Gateware : The End of the Second Month

Another two weeks have passed since my last post, so it has now been two months since I started working. In the past two weeks, I have fully implemented a raytracing flag to the graphics options. Also in this blog, I will be reflecting on my overall time working on Gateware.

The main focus, as I previously mentioned, was implementing the raytracing flag as an option to make it easier for users to use raytracing, as it will set up all the extensions for them. This meant that the first thing I did was simply add the raytracing option to the graphics options enum in graphics define.

After that, I went into the GVulkanSurface_core.hpp and started by adding the if check for the flag and added the extensions if the if check was successful.

The next part I implemented was in the device creation. Again, we checked for the flag, and if it was true, then the needed extensions were implemented. These included:  

  • VkPhysicalDeviceRayTracingPipelineFeaturesKHR
  • VkPhysicalDeviceAccelerationStructureFeaturesKHR
  • VkPhysicalDeviceVulkan12Features
  • VkPhysicalDeviceFeatures2
After they were implemented, I also modified the get best gpu function to make it so that a gpu with raytracing support would be higher scored.
The last part was adding the unit test, which was a bit tricky as I thought it would be pretty much the same as the bindless one, but it actually required an extra check for extensions, otherwise it would fail on the CI/CD pipeline on all the runners except for one.

That leads us to the code review, which left me with a bit more to do before the feature was implemented. The problem now was that the additional extensions added to the device extension count were hardcoded, so I changed it to be based on the flags instead of hardcoding it to the max amount of possible extensions.
That finished off the raytracing flag addition, and it was finally ready to be implemented!

That now brings me to the end of my open portfolio classes and the end of my time here, so reflecting on the time I worked on Gateware, I can say that I learned a lot. It was my first time really working on such a large codebase. So, there were lots of things that I encountered for the first time and that were challenging to me, so it was a great learning experience, and it feels like I learned a lot that will be helpful moving forward, and when working in the industry. Overall, I am really grateful for this opportunity and am excited to see where these skills will take me next.

Friday, May 16, 2025

Gateware : The Start of the Second Month

Another two weeks have passed since my last post, so it has now been a month and a half since I started working. In the past two weeks, I have completed adding compute queue support to GVulkanSurface so you can now use compute shaders and also started to work on adding a raytracing flag to the graphics options.

The main focus of the last two weeks has been on fully implementing the compute queue support and the matching unit test, so let's start by going over that. The first thing I did was create a new function for getting the compute queue. This was quite simple as it followed the same pattern as getting the graphics or present queue. 

Then I also updated the function that got all of the queue family indexes (more on that later). The last thing to update before working on the unit testing side was to update the get gpu function to add more weight to a gpu that had compute queue support.

To test the compute queue support I had to write a glsl shader, for the compute queue test I was told to test it away from graphics, so I focused on testing with actual computing/math by writing my shader to take an input buffer square the values and return them in an output buffer. I chose to use two seperate buffers instead of just one for better readability.

The test was a success! Which meant I had successfully written compute queue support for Vulkan, and a successful unit test as well. After a code review, I just needed to add back a deprecated version of a function using Doxygen's deprecated feature to prevent any problems on the back end. And then the merge was successful! Meaning that Gateware now supports compute queues and shaders in Vulkan.

Now That leaves us with what I am currently working on which is adding a raytracing flag to the graphics options so that it will be easier to work with raytracing using Gateware. I just started this so I haven't got much to say yet, but will be posting about that in the next post!

Thursday, May 1, 2025

Gateware: the first month

Two weeks have passed since my last post, making the total time working in Gateware one month!! In the past two weeks I have worked on various things, including finishing up the derive a plane from a given point + normal, and also fixed an issue where the GVulkanSurface test for checking for compute queue support was failing.

Starting with the math function implementation, I was able to finish of the function and unit testing in the first few days following my last post. The main thing I had left to write and clean up was the unit testing itself. Following that the merge request went into code review and after getting some feedback I cleaned up the function itself by removing a redundant magnitude check and changing the formatting a bit for clarity. I also added more fail tests to cover more cases to ensure a full test suite for the function.
After that, another code review left me with some changes I forgot to make to the Doxygen documentation, which was luckily really quick, and then the merge request was approved!

After that was successfully merged, I started work on a new issue, which was GVulkanSurface not allowing compute queue support. The test was already written to check, but it was crashing. There were two main problems in the code, firstly there was a cleanup call at the end of the create function that was deallocating everything, which was causing GetDevice to fail. After commenting that out, the GetDevice succeeded, I was able to identify the next problem. The queueFamilyIndex was being used without being initialized. This was causing problems because it was being used to get the index of an array. Luckily, the fix for this was simple! I just needed to add a for loop to loop through the queueFamilyCount and then set the queueFamilyIndex equal to the current iteration and then it was able to be successfully used. The test was now running with no crashes and succeeding.
And that has been the past two weeks! I am now going to be working on actually adding the compute queues and so look out for that in another two weeks!


Friday, April 18, 2025

Gateware: The first two weeks

 It has been two weeks since I started working with Gatware, and time definitely moves fast it feels like it has been only a few days. But I have been very productive over these two weeks, with my introduction being just a simple change by adding the OUT_OF_BOUNDS failure code. My first real task was reviewing the bmp addition to the GBlitter. The issue said there was a memory leak, however there were none when I looked through the code. Although this did lead to the discovery of a problem with the UWP runner, as the pipeline kept failing. So I helped try and look into that issue with the other members of the team. It was successfully resolved towards the end of the first week. I then looked through the remaining comments/threads left on the merge request and fixed up some messy commits and then added macros to replace the magic number if checks for the decompression in GBlitter to finish off my work with the bmp addition to the GBlitter.



Then for the remaining time in the second week I started working on an issue from four years ago to derive a plane from given point and a normal, I have gotten it pretty much finished and will be going through and cleaning it up a bit before sending it to be reviewed. The logic was relatively simple, though I almost forgot the magnitude 0 check, lol! But besides that it went pretty smoothly. I have written the unit tests out and tested them a couple times and they are all passing, yay!



Friday, May 3, 2024

Month 5 - Week 4 - Fixing Arch Linux X11 Bug

 Last week we touched upon a bug that was occurring with X11 for Arch Linux. The bug was specifically when creating a window for a test. The window would fail to create and now show up at all, failing the test. I was only modifying the unit tests at the time but took time this week to look more deeply into the actual code to see what could be going wrong.

One of the first things I decided to do was enable the macros inside of GWindow to see the X11 debug output. This would allow me to watch in real time what was failing, and better help towards finding the problem child in the code.


As you can see, the errors being reported are talking about a bad window. This normally means that the pixel map for the internal window is bad, or the window itself failed to create and can’t have anything done to it. I knew immediately the first place to check was the create function for GWindow.


Here we see two functions are called. The first function is just initializing some basic fields, the second function, however, is the one we’re interested in. `OpenWindow()` is the function responsible for creating the window and initializing all the information that GWindow needs to properly manage it.

Remember, we can’t debug, or the error won’t occur. So, instead, I decided to inspect some documentation and play around with the code, probing it to see which function was giving problems. Upon inspection, I noticed that anytime I messed with the `XInitThreads()` function, it had a change in the functionality itself. It seems this might be the problem child I mentioned earlier. I decided to put a `std::this_thread::sleep_for()` call right after calling for the initialization of threads. The sleep time was small, only 10ms, however, doing just this resulted in all of my tests passing consistently.


I found the bug that was occurring. So, how do I fix this then? Well, the moment I discovered this, I made a commit with the sleep call change as the fix. However, using this kind of call to fix the bug isn’t exactly good. Some issues can occur. For example:

  • How would this code react on faster or slower hardware? We can’t be certain that this sleep fix will work for all systems, it might even only work on mine.
  • Is this truly a threading issue, or a mutex issue? The display for X11 is multithreading capable, so if I don’t lock it, it could be other X11 functions are modifying or trying to modify the variable I’m reading immediately.
  • Lastly, what if this fix is temporary like the event system bug months prior? This is a real concern; it would not be the first time I “fixed” a bug only to have it come back spontaneously because I wasn’t doing the idiomatic approach expected.

So, what I have to do is test for different solutions and see what I can find. This was, unfortunately, all I could do for now. I wanted to do more but was constrained on time with due dates and graduation fast approaching. While this is going to be my last blog post, it will not be the last of the changes I make to Gateware. I have full intention of continuing work on Gateware to not only fix this bug, but also to see what I can do to fix, implement, and update features for the project. This is in the hope that I learn more from it over time, that and I simply enjoy working at a low level. So, with that, this is my last blog post.

Sunday, April 28, 2024

Month 5 - Week 3 - X11 Fullscreen Bug

 After the final touches to audio, my focus has now shifted to a new and rather interesting bug involving X11 window events and, arguably more importantly, Arch Linux. This bug has shown itself to me for a little while but was largely inconsistent in how it appeared. It would show in the unit tests ~80% of the time, and the source of it seems to be unknown currently. This bug will be my last bug to fix for the project as part of FSU, however, if I can't fix this bug by the deadline, I will be continuing work to fix it after. This is largely because this is the only bug left to fix to finally add Arch Linux as a fully supported platform. This will be brief as I didn't have a lot of time to fully inspect the bug like I wanted to, but there will be enough here to mark my current progress. So, with that, let's get started.

The first thing to note is the description of the bug.


Here are the things to note:

  • The bug has a visual aspect (the window will sometimes show, sometimes stay hidden, or show completely but be transparent).
  • It fails specifically when the check is run to see if the window is fullscreen.
  • Previous calls in the said test don't do anything.

Here is the test.


We can see on the overview that the window is initially created with a basic position (0, 0) and dimension (800, 500). It then reconfigures itself to a different position with different dimensions. Something else you might have taken notice of is the usage of `GiveWindowTimeBeforeRequiringPass`. From what I've gathered, this is here because sometimes X11 requires a bit of time to process events before it can check for what we want. So this is here to effectively wait out the processing of events to check if a function has passed properly. From here, this is where I started testing.

First off, breakpoint debugging is useless for this bug. Because if I placed a breakpoint and walked the function line by line, nothing would go wrong. Debugging would mainly be useful here if I could catch the bug failing in action, however, I'm not able to do that here. So, this leads me to test a little more conventionally. The thing I checked for immediately was timing. It could be that the code is going too quick and preventing X11 from processing everything in time. So I added small delays to check for this, however, it did not work. I also tried using the exact delays used in other tests, but the results were the same.

Interestingly enough, if I duplicated the exact same test and ran the full unit test suite, only the first test would fail, with the duplicate passing. Odd behavior.


From the discord messages above (which are posted in the Gateware Development channel), I described my difficulties with this bug as well as what I feel the bug is.

I feel this bug is a timing bug. Basically, one thread is doing things so quickly that the other thread can't keep up in time. This would explain the odd behavior, and why the test doesn't always fail. Of course, there is more testing and inspecting of the code that will be needed, but in total, this seems to be the main issue. So now, what has to happen, is we have to specialize the probes for this bug to target the timing over the functionality. If I can pinpoint that it is timing-related, then I focus my efforts on fixing that. However, if this isn't the case, I will have to inspect further to see what is exactly happening.

Currently, this is all that I have done for this bug. Next week should hopefully go into a deeper discussion on how I found the fix for it. But for now, this is all.

Sunday, April 21, 2024

Month 5 - Week 2 - Final Touches

 Last week, we discussed finishing the WAV file reader and getting the overall status for it marked as completed. There were some final changes. Moving over to GFile for UWP was a big step, but there was still some branching in the code, primarily due to Linux and Windows differences. I decided to focus my energy on getting these rounded out and fixed. This will be a light post, and step through everything fairly quickly.

The thing to really focus on and correct is how Linux and Windows structure the WAV header. Internally, Linux structures a WAV fairly simple, and this is due to it not requiring the extra data that was later attached when Microsoft extended the WAV format. Windows contains many things, however. It contains the primary information which is the same as Linux, but a union that holds additional information. This is also paired with a GUID. The purpose of the union and GUID is unknown to me, but to bridge compatibility with platforms, I had to move away from a platform-specific definition and move to an internal definition, which is exactly what I did.


If you have a keen eye with the Windows API, you will notice immediately that this new structure setup for WavReader is the exact same as Windows's definition. I did this for a simple reason: to support Windows and allow support for Linux. If I used the Windows definition, it wouldn't be able to compile for Linux due to obvious reasons (Windows API not being available for other OSes). After moving to the new structure, it was now the process of hooking everything up and removing old branching.





After making these changes, now WavReader no longer branches and works on every platform universally. Additionally, it acts as a wonderful introduction to what is possible with the library, as all of the heavy lifting for data handling is done by library code (GFile). So a lot of beginners just getting into Gateware could learn a fair bit by reading through the source code of WavReader.

This marks this merge request as complete. I marked my name in the list of contributors, and let the merge get reviewed again. It was merged. The last thing I did for audio was make two merge requests, one focusing on some simple Windows refactors, and the other focusing on UWP refactors. Effectively syncing both to the same modern standard as Linux. In total, everything is now completed.

What now? Now I find a new issue I can tackle, a bug or possible feature that will take only two weeks to implement. With my time almost finished with Gateware, I'm no longer able to tackle such large issues as I have in the past, so that will be left up to others. However, I will try to provide supporting changes here and there, and see what I can do with the time I have left for finals.