Thursday, May 31, 2018

The role of the graphics card driver in real-time rendering

Common computer wisdom accentuates the importance of having the graphics card driver for your computer always up to date. Updates to this driver can fix bugs and misbehavior in games, and sometimes even make games run faster.

However, have you ever wondered why that is, especially in the case of the latter? Shouldn't it be the graphics card itself (in addition to your other hardware) that solely determines how fast a game runs? Why does the graphics card driver sometimes have such a great impact on the rendering speed of a video game? What role does it play in the whole process, and why is it so crucial?

On a more fundamental level, what exactly does a graphics card driver do?

(Note that the explanation below is a simplification, perhaps even an oversimplification. But it is so for the sake of brevity and clarity, even if it might not be technically 100% accurate in every single detail.)

Most typically, a program like a video game uses a graphical application program interface definition like DirectX, OpenGL, or Vulkan. These are not program libraries per se, but rather they are API specifications. In essence, what this means that the program will have code to make certain system function calls for different types of tasks related to rendering, such as loading a bunch of vertices into the graphics card memory, or compiling a fragment shader.

The implementations of these functions will be provided either by the running operating system (eg. Windows), or the graphics driver. Essentially, what's happening eg. in the case of DirectX, is this:


The program executable binary will have metadata that tells to the operating system "I need to call these system functions from these locations within myself". When the operating system loads the binary in order to be run, it modifies it in order to redirect those calls to the appropriate system implementation.

If the graphics card driver provides an implementation for a specific function, it will direct the program binary to call that. In some cases the implementation is not in the driver, and thus a kind of default implementation is provided by the DirectX runtime, which the operating system is running. (Sometimes if a graphics driver doesn't provide an implementation for something, the DirectX runtime essentially needs to emulate that feature. This is why there needs to be a DirectX library in the system at all.) With some implementations the DirectX implementation may call the implementation in the graphics driver.

So it ends up like this:


For most functions, the graphics driver needs to provide an implementation because only it knows how exactly to interact with the graphics card hardware, and what kind of data it needs.

For example, the graphics card driver has a compiler implementation that compiles vertex and fragment shaders into the machine code that the graphics card uses.

In the case of DirectX and Vulkan (and some other APIs, like Metal), the original shader source code is compiled into a hardware-independent intermediate bytecode form, when the program binary itself is being built. At runtime this intermediate form is sent to the graphics driver, which produces from it the actual machine code used by the graphics card.

In the case of OpenGL, and its shading language (glsl), OpenGL doesn't specify any such intermediate form, and the graphics card driver literally has a compiler implementation that takes the original glsl source code in textual form and compiles it into machine code.

This explains why the graphics card driver has such an important role in the entire process, and also why it has such a big impact in the performance of games. Oftentimes graphics card manufacturers will publish an updated driver that's specifically optimized for a particular new video game, and will make it run measurably faster (eg. several frames per second faster than with the old driver).

How? What they do is that they examine what kind of calls the game is doing, and with what kind of data. For example, they may notice that the game is doing a lot of calls with certain data in a certain way, and that if the graphics driver reorganizes that data in a certain manner, it makes it more efficient for the graphics card hardware to handle (without changing the behavior).

Likewise they may notice that the game uses certain types of shader code quite a lot and heavily, and may notice that the shader compiler can optimize that code to shave off a few clock cycles (again without changing its behavior), which may end up speeding up the overall rendering by several frames per second.

Tuesday, May 15, 2018

How many times can the same position repeat in chess?

Most official chess tournaments have a so-called "three-fold repetition" rule, which in short means that if the same board position is repeated three times, the game can be declared as draw. (In human tournaments declaring it as draw is optional and up to the players, even though many tournaments have an additional rule that says that if the same position repeats five times, the tournament referee can declare it a draw. In computer chess tournaments three-fold repetition is invariably declared a draw automatically.)

So the answer appears to be pretty obvious: Three times, duh.

Except it's actually not that simple. You see, there are additional rules with respect to what is considered the "same board position". Even though all the pieces might be on the exact same squares as in a previous position, for the purposes of this rule it might not be considered the "same position".

For starters, castling rights are taken into consideration when defining whether a position is the same as a previous one. Even if all the pieces are on the same squares as before, if however now one of the players has lost the castling right to either side, which he had in that previous position, it will be considered a different position.

So, how many times can the same arrangement of pieces repeat in this light? (We don't need to worry about how realistic in actual games this is. We are just pondering what the theoretical absolute maximum is.)

So, this is theoretically possible: Both players have castling rights to both sides. The same position repeats twice. Then one of the players loses one of these castling rights, after which the same position repeats an additional two times. And so on with the remaining three castling rights. Then, after the last one, the position can repeat a third time, and it will be draw.

So 2 initial times + 2 for each lost castling right (ie. times 4) + 1 final time = 11 times?

Nope! There are more conditions we haven't touched! You see, the rule also states that it has to be the same player to play, in order for it to be considered the "same" position, in the context of this rule.

Thus, we can actually repeat each of the above positions twice, except for the very last one, as long as it's the other player's turn each second time. (The last one can't be repeated with the other player having the turn, because the last one already makes it a draw immediately.)

Thus 21 times?

Still no! There's still one additional rule: Having en-passant right vs. not having it is considered yet another aspect that makes the position different.

How many times can we repeat the same position with en-passant? Only once. This is because this condition requires a pawn move, and can't be repeated with all pieces ending up on the same squares. Thus we have to start the whole sequence with having a player have en-passant right, after which it's lost, and we can proceed with the rest of the sequence above.

So the final answer is 22 times.

Wednesday, May 2, 2018

Indirect protection in chess

Consider the following position:


Black has just played the bishop from f5 to c2, attacking the a4 pawn.

Seemingly there is no way to protect that pawn. It's gone, and we simply have to accept this loss, which is rather significant in this part of the game, with this few pieces left. A pawn advantage at this stage is extremely important, but we just lost it.

Or did we?

There is a way to protect the pawn from being captured, but it's a rather sneaky indirect way of protection. Play the knight to b7!


How does this protect the pawn? The knight isn't directly protecting it. However, it is protecting it indirectly. If the bishop were to now capture the a4 pawn, we can fork the king and the bishop, and gain the bishop:


The a4 pawn cannot be captured. We could later protect the pawn directly by moving the knight to c5, but as long as the black king remains at d7, there is no hurry. If black moves something else, we can afford to likewise do something else. If the black king moves anywhere, we can then play the knight to c5, safely protecting the a4 pawn directly.

This is one of the tactical aspects of chess that can be difficult for many beginners to see and learn to read.