Posts

Relatively stable code

Just a random thought that I had while investigating some stability issues with Job Manager. I generally try to build a lockless solution that will work performantly and stably. Anyone writing lockless code knows that it is not an easy feat. Still, I try to do it the right way. Analyzing the algorithm on paper, writing unit tests, adding stress tests, and running everything under Address Sanitizer just to be sure. I got to the point where I thought: I have a relatively stable solution, then came realisation. "I have relatively stable code" is a funny term. So we have "good" code because it runs how we want for the majority of the time, and only in some cases is broken and does not do what we want, or just crashes. Sounds to me a little like: it works on my machine because you know I never saw it failing while I developed it. I do not believe that code can be stable and broken at the same time. I know that for some, "I have relatively stable code" will be g...

An issue with embedding in Qt, an external window

Another very specific issue that I encountered while working on tooling for White Rabbit Engine. This one cost me three evenings to figure out :(  For a while in the tooling, we are using a multi-process approach: Hub (Qt application) <-> Client (Qt application) Hub is the main process using QT. Inside it, we have QMainWindow to which we embed the client window. The code to do that is very simple: auto clientWindow = QWindow::fromWinId(clientWindowsId); auto widget = QWidget::createWindowContainer( clientWindow , this); setCenterWidget(widget); You can find this example almost everywhere. The problem I encountered was that my client window had keyboard input only once when a window was created. If I lost focus nothing related to the keyboard worked. Neither shortcuts, neither textboxes, nothing.  While investigating I noticed that  QWidget::createWindowContainer  internally created QWindowContainer that never received QEvent::FocusIn which I assumed was a prob...

OpenGL - Sparse Textures

If you work with OpenGL (like me) you sometimes find it hard to get some more modern examples of code. I recently was looking around for an example of ARB_bindless_texture and never really found it. And because I managed to write one I will share it:  GLuint hwTexture; GLint patchSize = 1024;    // Size of single patch GLint pageSizesCount = 1; // Number of page sizes to choose from  GLint pageSizeX = 0, pageSizeY = 0, pageSizeZ = 0; // Size of page. // Create texture and mark it as sparse glCreateTextures(GL_TEXTURE_2D, 1, &hwTexture); glTextureParameteri(hwTexture, GL_TEXTURE_SPARSE_ARB, GL_TRUE); // Get numbers of available  VIRTUAL_PAGE_SIZE_...   glGetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, & pageSizesCount ); // For simplicity of example I get here only the first one.   glGetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &pageSizeX); glGetInternalformativ(GL_TEX...

Mixing libraries

Image
Let us try blogging again. If you search L.B.A. Tribute news you can find them at coffemonsters.com Here we will be focusing on more technical stuff.   These days I'm tracking some delay in the processing of interaction between my UI (Qt) and Backend (custom code). Generally still far from resolving issues but slowly digging through problems. One of them hit me as an interesting one: QtTimer. I'm using them because they are the most efficient way of injecting some processing into Qt. If this claim is true I'm not sure but they for sure work better than anything I tested so far.  Generally, my whole tooling is based on multiple processes that communicate with each other. I got a little bit more into the details in the presentation that I did recently: This setup result that I have multiple Qt event queues processing at the same time. One in the base process and one in the sub-process. It is really important, that they are processed efficiently because I discovered the hard...

Hierarchy - UI improvement

Image
This time light topic of UI designing :] But before this let's discuss how the hierarchy in the engine works. So it was easier to understand these, let's look at the tooling of it:    We have there: World (ID:0) Loaded Stream (Citadel Island) Loaded SubStream (CI.Citadel) Unloaded SubStream (CI.Logic) Folders (f.ex. Park) Entities (f.ex. Ferry) If you are curious what a Stream is, you can think about it as a scene or a level. Now that we know all of this let's look a little bit closer at what we have.  Streams and SubStreams are exactly the same  I change the name based on their position in the hierarchy. The  Folders  may look different than Entities but they are exactly the same. They are  Entities  with a folder component. If we go this way streams are also just  Entities  with a Stream Component. This leaves us with a bunch of the entities under the World . Which as you can suspect is just an  Entity with ID equal to 0....

Nvidia - unsigned integer issues

Image
Yesterday I experienced another bunch of fun while using my laptop. My normal working environment is a desktop with an AMD graphics card, while choosing a laptop it was important for me to get some Nvidia GPU so I could test code on both machines. This was a smart decision as there are so many differences between them. This time I encounter another one. History Like always a little bit of the background: while doing tooling you need to think about nice interactive objects selections. The beginning was rough as I decided to use a physics ray-trace system to execute picking. This was a simple system where I was sanding a ray thru the world and tried to pick objects that collide with it.  The issue was: every object needed to have a collision body  it did not work very well with objects that had an alpha mask  did not support geometry that was deformed in shaders. I did not like any of these limitations so I decided one day to change the whole thing. I took this time a diffe...

Resource Center - High CPU usage

This is one of the recent issues that I was tracking This issue is pretty simple but because of that, its solution is not so trivial. So let's dig into it. The resource center is a standalone app that: Is a remote file system server  Integrate with Version Control System (currently P4) Is a resource server that is responsible for building resources Manage remote resource builders.  Manage the creation of game build Have UI which allows to browse the file system and trigger compilation of resources and build.   All communication uses TCP/IP sockets and most operations are async for performance reasons.  Recently I was doing changes to speed up the remote file system. I decided to switch all calls into async processing. While doing that I was put in front of the decision: Should I put all processing of connection read/write operations to a single thread? or maybe I should create a separate thread for each of them? I naively decided to go with a sing...

Configuration scripts - part 3

In  Part 1  I described the configuration system in the engine. In Part 2  I described the reason and thoughts behind the topic: Designing intuitive API that makes sense. Now time for Part 3. This time we will analyze changes in script and reason behind it.  Compute shader script Let's start with the simplest compute shader script that doing anything : Compute {      ShaderFile  =   "sys://Shaders/ComputeShader.glsl" } New version: Compute {      Shader .Bind ( "sys://Shaders/ComputeShader.glsl" ); } This may look like a small change but it brings consistency to script. From now on there is only function style calls with ';' at the end. Defines Let's now add Define to script. In original format this would look like this: Compute {     Define ( "MY_DEFINE" )      ShaderFile  =   "sys://Shaders/ComputeShader.glsl" } The new one is more flexible and allows to do it i...

Configuration scripts - part 2

In Part 1  I described how my configuration script system works. Part 2 will focus more on the real reason why I decided to write this post: Designing intuitive API that makes sense. The more I code and work on complex systems the more I see how important good API is. There is of course 1001 articles describing how to do that and if you are searching for one of them you are not in the right place.  My focus will be on my personal evolution in a way how I think about API. Whole thought came from improving compute shader scripts. They had a really simple form: Compute {      Define ( "MY_DEFINE" )     Reg (0) = UserImage (0, "Write" , 0)      Reg (1) = UserTexture (4)      Reg (2) = UserTexture (5)      Reg (3) = UserTexture (6)      Reg (4) = Texture ( "sys://Textures/Texture.dds" )      Reg (5) =  UserTexture (7)      ShaderFile ...

Configuration scripts - part 1

This may sound weird in days where everything needs to have some kind of UI but the recent time I spend upgrading some of my configurations scripts. My current workflow is to define parsing rules and generate from them parser. To give you an idea what I talk about this is simple rules for the logging configuration file: %name     = LogConfig   %% .input : /* empty */        | LogAllow .input        | LogBlock .input        | AllLogBlock .input        | AllLogAllow .input ; LogAllow        : 'LogAllow' '(' $(CStringID) ')' ';' ; LogBlock        : 'LogBlock' '(' $(CStringID) ')' ';' ; AllLogBlock        : 'AllLogBlock' '(' ')' ';' ; AllLogAllow        : 'AllLogAllow' '(' ')' ';' ; %% It allows me then to parse a file that looks like this: LogAllow("Crash"); LogAllow("Assert"); LogBlock("Scripts"); Lo...

Hobby or Work

Interesting topic for a post came recently to my mind when one of my friends commented on me taking a day off from work to relax as: "Anyway, you will wake up that day and work." This was, of course, comment on me developing LBA remake in my free time. What is interesting about it I'm not fully sure what to think about it. Because how what I doing in my free time is different than other people's hobbies? On another hand how it is different than what I do in a work? What is a hobby? All of this thinking brought me to this simple question on which I don't have really a definite answer. In the end, what is a hobby for one person can be a work for others. There is a lot of examples of that:  riding a bike, skateboarding, painting, drawing, writing stories, creating graphics, woodworking, restoration of items, fixing electronics, traveling, singing, dancing and even stuff like cosplay.  All of that and a lot more can be a hobby but at the same time, it c...

constexpr

Image
https://gcc.godbolt.org/z/sGd-Dp I recently were introducing friends to constexpr and I'm super surprise how inconsistently it works between different compilers. I will need to look more into my code to assure that its do what I want. 

Clean design ...

Image
I would love to say you a story how awesome my code designing skills are but with time I learned that I still have long way to go. Now we know what this story won't be about and focus on what we will be talking about: My recent issue and how I solved it. Introduction The story taking place in one of many days when I was doing something for project. I was working on content an once again stumble upon problem with editing multiple terrain groups. I knew about it and delayed it already few times but this time it finally blocked me from further progress. This meant only one thing: fixing day arrived.  "Cool" I thought and started checking what going wrong. Destiny wanted that in meantime of testing some irritating issue surfaced: I was not able to display in inspector properties of  World Terrain System.  I was trying to select it in hierarchy but only level properties were displayed.  And this will be topic of my story: How I approached fi...

How the fate like to play with us (3rd generation of RTTI)

Life bring to us surprises everyday but today I was impressed how fate works. Whole story started few years ago when I decided to make my own RTTI system for White Rabbit Engine. Then I was still young and naive and thought like everybody at this age that I know how to write complicated systems. This experience teach me that I really can write complicate systems ... but not necessarily should. System was working fine but was over complicated and resulted in lot of stability issues. This realization lead to the series of improvement. I like to call it 2nd generation of RTTI system. Changes are covered by  on of my posts . This was already big step: system was simpler, easier and what most important more stable. This sentence could probably end this story if not the fact that I always felt that it is still not final form of this piece of code. This wasn't what I fully wanted. There was one particular feature that I struggled to add but failed to achieve: virtua...

Little -> Monster

Image
Often when I do coding I asking myself how this small modification that I wanted to do converted into this monster that I working on ...  Good example is my recent decision to add regressions tests. I want to validating that I'm still able load some of the resources.  Spoiler alert : I spend already few hours and still don't have this tests. 

Catching up

There is so much going on this year that I don’t have too much time to write posts. For this who don’t follow my other blog this is some summary of most important changes: In February I started working for Unity Technologies. Engine slowly transit to Physics Base Rendering (PBR). I released new video https://youtu.be/q6Ql9MX4baM with game progress. Been at Unity HackWeek XII (I’m even on one of photos at blog, find me if you can :P) Dropping kinematic character physics in game. Now that I think about it each of this points could be separate post. But well there is no point in thinking about past and let’s focus on present and topics I work on in the same time: PBR transition. Physics changes. Game not working smooth. PBR transition This slow down a little bit because I try to read in free time recommended by friend moving frostbite to pbr . I start to see how much knowledge I missing to do it properly. There is all this sections about lights par...