First post, by ZenJu
I have been busy lately implementing high quality image scaling support for a different emulator, MAME, which in its raw form has only very basic image enhancements like scanlines, ect.
At first I thought I should go for HQx which I believed to be the state of the art, only to learn shortly after, that there is a new far superior image scaling technique available, that can be used in real-time emulation:
Based on Hyllians xBR filter I created a modified scaler version, named xBRZ, with further graphical advancements, full support for multi-core CPUs and 64 bit architectures.
In case you have not seen this type of filter before, here is a comparison between HQx and xBRZ (click images to show in full size):
If you want to see how xBRZ scaling looks in comparison to HQx on different images, have a look at the "ScalerTest" application (download link below) and just drag&drop your own test images. This little app also allows for some xBRZ parameter tuning - so if someone finds a better setup than what is currently the default, let me know!
But let's get to the main point: I would *love* to see support for xBRZ in DOSBox!
From a technical standpoint it's not trivial. xBRZ's API takes full images as input and output, rather than operating on individual lines only like all the scalers implemented in DOSBox currently do. I saw in the source code that DOSBox is using special rewrites of these algorithms for single line scaling.
xBRZ on the other hand supports processing image slices, which can be used for concurrent image scaling. On modern multi-core CPUs this allows for tremendous speedups: In it's raw form xBRZ shows similar performance characteristics like HQx. However when taking advantage of multithreading it scales by factors faster while providing a much better result at the same time.
I went ahead and implemented a working prototype of xBRZ into DOSBox. It is based on DOSBox 0.74 with support for save states.
The source code is implementing the xBRZ scaler from my other project HqMame:
Due to the technical issues mentioned above, a few considerations apply:
(Note: the updated version v3 will automatically apply these setttings. So you can simply copy the .exe into your Dosbox directory and start it.)
dosbox.conf should be setup with the following configuation:
The reasons are the following:
- The xBRZ scaling is implemented only for output "surface". Additionally it requires a 32-bit output device with BGRA byte order. I believe this is the default screen mode today.
xBRZ works the following way:
1. it lets DOSBox scale the raw low resolution image into a temporary buffer.
2. it calulates a scaling factor. E.g. if output screen width is 1024 pixel and the raw image with is 320 pixel, then we ideally need a scaling factor of 3.2. This factor is rounded to 3 and a 3xBRZ scaling is applied.
3. the xBRZ-scaled image is scaled into the output surface using a nearest neighbor algorithm. Since both images are "roughly" the same size, this can be done with minimal quality drawbacks, but more importantly, this step is very fast (and is also executed in parallel on all available CPU cores)
Due to this approach we need to make sure that the raw image is not scaled => "scaler=none".
Additionally DOSBox' aspect ratio correction introduces some artifacts to the raw image by duplicating every few lines in order to stretch. For the DOSBox version below we do not need this, since the nearest neighbor scaling in step 3 preserves input aspect ratio correctly when scaling to full screen size (=> no black bars anymore if you have a 16:10 monitor and a 320x200 dos game!). => let xBRZ do the complete scaling => "aspect=false"
Since the DOSBox prototype calculates the best scaling factor automatically (up to 5x scaling!) you will get the best quality if the output screen size matches your desktop resolution => "fullresolution=original"
Note that the scaling factor can become quite high. E.g. you have a 1680 desktop width and a game has 320 raw image width, then this gives a required scaling factor of 5.25, so 5xBRZ will be used. This sounds much, but from my extensive performance measurements I learned that the bottleneck of the xBRZ scaler is not the output image size, but the input image size. So 5xBRZ is not significantly slower than 2xBRZ, but of course looks much better.
I hope that my prototype can give some motivation to "officially" implement the xBRZ scaler into DOSBox. If you have technical questions about the scaler, feel free to ask me.
Until then, have fun with the prototype!
xBRZ scaler source code for C++:
Compare different scalers (HQx, xBR, xBRZ, nearest neighbor) for your own sample images:
DOSBox v0.74 + xBRZ + Save States support: