VOGONS

Common searches


VIDEO Patch for pixel-perfect scaling (SDL1)

Topic actions

Reply 700 of 726, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

Ant_222,

I was thinking about your pixel-perfect strategy applied to an SDL2 implementation where SDL2 can perform non-uniform, hardware-accelerated scaling.

So instead of DOSBox internally scale=normal3x'ing and aspect=true'ing, we can pass the emulated video driver's raw 320x200 frame as-is to SDL2 and tell it to scale it to 1280x1000 (pixel perfect 4 x 5 scaling, texture or opengl nearest-neighbour), rendered unstretched to the screen's native or current desktop resolution (either fullscreen or a window sized to match).

Given this change in workflow, some of DOSBox's config elements could be simplified too.

This was just a thought exercise for me but am curious what your approach would be in an SDL2 scenario.

Reply 701 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
krcroft wrote on 2020-01-07, 22:38:

I was thinking about your pixel-perfect strategy applied to an SDL2 implementation where SDL2 can perform non-uniform, hardware-accelerated scaling.

What do you mean by non-uniform? In SDL2 you can pass integer scaling factors to SDL_RenderSetScale() and have hardware-accelerated pixel perfect scaling.

krcroft wrote on 2020-01-07, 22:38:

So instead of DOSBox internally scale=normal3x'ing and aspect=true'ing, we can pass the emulated video driver's raw 320x200 frame as-is to SDL2 and tell it to scale it to 1280x1000 (pixel perfect 4 x 5 scaling, texture or opengl nearest-neighbour), rendered unstretched to the screen's native or current desktop resolution (either fullscreen or a window sized to match).

Yes—and openglpp does exactly that in the current version of the patch, as does bladesk.

krcroft wrote on 2020-01-07, 22:38:

Given this change in workflow, some of DOSBox's config elements could be simplified too.

Yes, but we shall have to drop the near-perfect scaling and software surfaces.

krcroft wrote on 2020-01-07, 22:38:

This was just a thought exercise for me but am curious what your approach would be in an SDL2 scenario.

For now we have four options:

  1. Hardware-accelerated OpenGL's nearest-neighbor scaling with an output area precisely calculated to pixel-perfect scaling—available in my patch as openglpp.
  2. Software-based scaling for systems without a GPU—available in my patch as surfacepp.
  3. Scaling with SDL2's native SDL_RenderSetScale() function, with integer scaling factors.
  4. Pixel-perfect with a pixel shader.—should be possible in SDL2.

Reply 702 of 726, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

Thanks ant_222,

Yes, by non-uniform I mean allowing non 1-to-1 scaling of the x and y axis; so SDL2 itself can perform aspect correction instead of DOSBox's software technique of line-doubling.

In your list, could 1 and 2 be collapsed into number 3 in the SDL2-scenario? ie: your pp logic is used to configure SDL2, which then takes care of either hardware or software scaling.

Reply 703 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
krcroft wrote on 2020-01-08, 15:50:

Yes, by non-uniform I mean allowing non 1-to-1 scaling of the x and y axis; so SDL2 itself can perform aspect correction instead of DOSBox's software technique of line-doubling.

Yes, and my patch already does that.

krcroft wrote on 2020-01-08, 15:50:

In your list, could 1 and 2 be collapsed into number 3 in the SDL2-scenario? ie: your pp logic is used to configure SDL2, which then takes care of either hardware or software scaling.

Certainly!

Reply 704 of 726, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

Thanks ant_222; sounds like a plan to get pixel-perfect into DOSBox when it moves to the maintained instance of SDL.

I am seeing three upsides and no downsides:
- pixel-perfect scaling
- zero-distortion aspect-correction, and now hardware-accelerated
- fewer lines of code in DOSBox itself (elimination of all software-side code to perform aspect-correction and normal#x scaling by DOSBox)

Edit Another (big) one: hardware-acceleration of pixel-perfect for HW backends other than OpenGL such as Wayland, Vulkan, and OpenGLES 1 and 2 (on the Raspberry Pi series and other ARM SOCs).

Reply 705 of 726, by Delfino Furioso

User metadata
Rank Newbie
Rank
Newbie
krcroft wrote on 2020-01-07, 22:38:

So instead of DOSBox internally scale=normal3x'ing and aspect=true'ing, we can pass the emulated video driver's raw 320x200 frame as-is to SDL2 and tell it to scale it to 1280x1000 (pixel perfect 4 x 5 scaling, texture or opengl nearest-neighbour), rendered unstretched to the screen's native or current desktop resolution (either fullscreen or a window sized to match).

Ant_222 wrote on 2020-01-08, 14:33:

Yes—and openglpp does exactly that in the current version of the patch, as does bladesk.

it has been a while since I've toyed with the pp scaling - long enough for me to forget how it works
so I wanted to test the described behaviour with ECE r4301, using these 3 scenarios:
#1 : dos prompt @640x400
#2 : doom demo @320x200
#3 : quake demo @640x480

this is the relevant content of my config file:
machine=svga_s3
output=openglpp
fullscreen=false
fullborderless=false
fullresolution=desktop
windowresolution=desktop
aspect=true
scaler=none

these are the results when using a display set to a HD (720p) resolution:
640x400 (16:10) => upscaled (1x1) to 640x400 (16:10) => presented as 640x400 (16:10)
320x200 (16:10) => upscaled (3x3) to 960x600 (16:10) => presented as 960x600 (16:10)
640x480 (4:3) => upscaled (1x1) to 640x480 (4:3) => presented as 1280x960 (4:3)

these are the results when using a display set to a FHD (1080p) resolution:
640x400 (16:10) => upscaled (2x2) to 1280x800 (16:10) => presented as 1280x800 (16:10)
320x200 (16:10) => upscaled (4x5) to 1280x1000 (32:25) => presented as 1280x1000 (32:25)
640x480 (4:3) => upscaled (2x2) to 1280x960 (4:3) => presented as 1280x960 (4:3)

these would be the results (I'm unable to test in 4K) when using a display set to a UHD (2160p) resolution:
640x400 => upscaled (5x5) to 3200x2000 (16:10) => presented as 3200x2000 (16:10)
320x200 => upscaled (8x10) to 2560x2000 (32:25) => presented as 2560x2000 (32:25)
640x480 => upscaled (4x4) to 2560x1920 (4:3) => presented as 2560x1920 (4:3)

am I right in saying that basically openglpp:
- ignores the "aspect" setting
- performs only integer scaling
- avoid using scaling multipliers that would lead to an upscaled resolution bigger than the current display resolution

I also wonder if it would be possible to make it behave like this:
1) get the raw frame from the video driver
2) choose scaling multipliers that would: A) perform integer scaling, B) enable aspect ratio correction, C) upscale to a resolution bigger than the display
3) upscale the frame to a offscreen render target, using the chosen scaling multipliers
4) downscale the resulting frame to the size defined in fullresolution/windowresolution

the new behaviour would be, for both HD and FHD displays :
640x400 (16:10) => upscaled (5x6) to 3200x2400 (4:3) => presented as pillarboxed at desktop resolution (16:9)
320x200 (16:10) => upscaled (5x6) to 1600x1200 (4:3) => presented as pillarboxed at desktop resolution (16:9)
640x480 (4:3) => upscaled (5x5) to 3200x2400 (4:3) => presented as pillarboxed at desktop resolution (16:9)

the new behaviour would be, when using UHD displays :
640x400 (16:10) => upscaled (5x6) to 3200x2400 (4:3) => presented as pillarboxed at desktop resolution (16:9)
320x200 (16:10) => upscaled (10x12) to 3200x2400 (4:3) => presented as pillarboxed at desktop resolution (16:9)
640x480 (4:3) => upscaled (5x5) to 3200x2400 (4:3) => presented as pillarboxed at desktop resolution (16:9)

Reply 707 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Delfino Furioso wrote on 2020-01-09, 14:53:
this is the relevant content of my config file: machine=svga_s3 output=openglpp fullscreen=false fullborderless=false fullresolu […]
Show full quote

this is the relevant content of my config file:
machine=svga_s3
output=openglpp
fullscreen=false
fullborderless=false
fullresolution=desktop
windowresolution=desktop
aspect=true
scaler=none

OK.

Delfino Furioso wrote on 2020-01-09, 14:53:

am I right in saying that basically openglpp:
- ignores the "aspect" setting

No. Which test case made you think so?

Delfino Furioso wrote on 2020-01-09, 14:53:

- performs only integer scaling
- avoid using scaling multipliers that would lead to an upscaled resolution bigger than the current display resolution

That is true, but the apsect-ratio approximation algorithm is a bit more complicated.

Delfino Furioso wrote on 2020-01-09, 14:53:
I also wonder if it would be possible to make it behave like this: 1) get the raw frame from the video driver 2) choose scaling […]
Show full quote

I also wonder if it would be possible to make it behave like this:
1) get the raw frame from the video driver
2) choose scaling multipliers that would: A) perform integer scaling, B) enable aspect ratio correction, C) upscale to a resolution bigger than the display
3) upscale the frame to a offscreen render target, using the chosen scaling multipliers
4) downscale the resulting frame to the size defined in fullresolution/windowresolution

Yes, but that would not be pixel-perfect. The current patch has a slow implementation of this method via surfacenp and surfacenp-sharpness, but a faster implementation is possible if one lets the hardware perform the final step.

It is easier in your algorithm to set the target aspect ratio at the final step only—no need to fine-tune the integer multipliers.

Reply 708 of 726, by Soothe

User metadata
Rank Newbie
Rank
Newbie

Hey folks, I'm running the latest DOSBox ECE and testing DOOM II.
I have a few questions, so there is this "source port" called Crispy Doom that is a fork of the accurate port called Chocolate Doom.
So acording to the https://doomwiki.org/wiki/Aspect_ratio"This meant that the 320x200 display, with a 16:10 logical ratio, was stretched vertically - each pixel was 20% taller than it was wide". Crispy Doom seems to do this type of correction.
But this patch renders it a little different, like a little bit more stretched.
Now I'm curious, which one the "right one"? Or is there no difference?

Attachments

  • crispy_doom.png
    Filename
    crispy_doom.png
    File size
    74.78 KiB
    Views
    237 views
    File comment
    Crispy Doom
    File license
    Public domain
  • dosbox.png
    Filename
    dosbox.png
    File size
    322.97 KiB
    Views
    237 views
    File comment
    DOSBox ECE
    File license
    Public domain

Reply 709 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Soothe wrote on 2020-01-09, 19:05:

So acording to the wiki "This meant that the 320x200 display, with a 16:10 logical ratio, was stretched vertically - each pixel was 20% taller than it was wide". Crispy Doom seems to do this type of correction.
But this patch renders it a little different, like a little bit more stretched.
Now I'm curious, which one the "right one"? Or is there no difference?

Cryspy Doom is playing a trick on you by forcing the aspect ratio to the required 4:3 by means of nearest-neighbor interpolation. It is not pixel-perfect. My patch, on the other hand, enlarges all pixels in the same scale of 4:5, so it is pixel-perfect but slightly off the right aspect ratio—because the correct pixel proportion is 5:6. With your resolution it is a matter of compromise: either you get pixel-perfect magnification or the exact aspect ratio. If you had a monitor of at least 1600x1200, my patch would give you both pixel-perfect magnification and the exact aspect ratio.

Reply 710 of 726, by Delfino Furioso

User metadata
Rank Newbie
Rank
Newbie
jmarsh wrote on 2020-01-09, 14:56:

Then it wouldn't be pixel-perfect...

oops that's right
it would become a combo of "pixel perfect upscaling" and "<insert your algorithm here> downscaling"
I guess it should be called openglnp then..
I still see its usefulness, though: performing "pp upscaling + linear downscaling" should in theory give better results than the "linear upscaling" that the standard opengl output implements

Ant_222 wrote on 2020-01-09, 15:07:
Delfino Furioso wrote on 2020-01-09, 14:53:

am I right in saying that basically openglpp:
- ignores the "aspect" setting

No. Which test case made you think so?

using output=opengl & aspect=true, a 16:10 frame would be scaled to a 4:3 frame by stretching the image
using output=openglpp & aspect=true, a 16:10 frame would not result in a 4:3 frame

I guess I'm spoiled by how aspect ratio correction is dealt with in other software such as scummvm (which correct to a 4:3 ratio)
(the same goes for @Soothe with Crispy Doom, it seems)

Reply 711 of 726, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie
Delfino Furioso wrote on 2020-01-09, 22:33:

I still see its usefulness, though: performing "pp upscaling + linear downscaling" should in theory give better results than the "linear upscaling" that the standard opengl output implements

Regular DOSBox can already do the same thing using "scaler=normal?x forced" to upscale beyond the output resolution and "output=opengl" for linear downscaling.

Reply 712 of 726, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie
jmarsh wrote on 2020-01-09, 23:24:
Delfino Furioso wrote on 2020-01-09, 22:33:

I still see its usefulness, though: performing "pp upscaling + linear downscaling" should in theory give better results than the "linear upscaling" that the standard opengl output implements

Regular DOSBox can already do the same thing using "scaler=normal?x forced" to upscale beyond the output resolution and "output=opengl" for linear downscaling.

The most I can do is normal3x, so with a 320x200 game it becomes 960x600 non-aspect or 960x720 w/ aspect (and that's scaling done in software by DOSBox prior to handoff to SDL, correct?); both are still is smaller than an old school 1024x768 CRT.

I guess the forced means it will do this for SVGA games using modes greater than 320x2##? So a 640x480 game would be cranked up to 1920x1440 (DOSBox-side), and then scaled linearly by SDL (possibly using hardware-accel) to fit the desired output resolution.

Reply 713 of 726, by Soothe

User metadata
Rank Newbie
Rank
Newbie
Ant_222 wrote on 2020-01-09, 21:29:
Soothe wrote on 2020-01-09, 19:05:

So acording to the wiki "This meant that the 320x200 display, with a 16:10 logical ratio, was stretched vertically - each pixel was 20% taller than it was wide". Crispy Doom seems to do this type of correction.
But this patch renders it a little different, like a little bit more stretched.
Now I'm curious, which one the "right one"? Or is there no difference?

Cryspy Doom is playing a trick on you by forcing the aspect ratio to the required 4:3 by means of nearest-neighbor interpolation. It is not pixel-perfect. My patch, on the other hand, enlarges all pixels in the same scale of 4:5, so it is pixel-perfect but slightly off the right aspect ratio—because the correct pixel proportion is 5:6. With your resolution it is a matter of compromise: either you get pixel-perfect magnification or the exact aspect ratio. If you had a monitor of at least 1600x1200, my patch would give you both pixel-perfect magnification and the exact aspect ratio.

Zoomed to check and you're correct. Thanks for creating this patch, seems like a bunch of software isn't doing aspect correction + pixel perfect correctly.

Reply 714 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Delfino Furioso wrote on 2020-01-09, 22:33:

I still see its usefulness, though: performing "pp upscaling + linear downscaling" should in theory give better results than the "linear upscaling" that the standard opengl output implements

I agree. This algorithm, similar to surfacenp, can be efficiently implemented in a pixel shader.

Delfino Furioso wrote on 2020-01-09, 22:33:
Ant_222 wrote on 2020-01-09, 15:07:
Delfino Furioso wrote on 2020-01-09, 14:53:

am I right in saying that basically openglpp:
- ignores the "aspect" setting

No. Which test case made you think so?

using output=opengl & aspect=true, a 16:10 frame would be scaled to a 4:3 frame by stretching the image
using output=openglpp & aspect=true, a 16:10 frame would not result in a 4:3 frame

But you did not specify the exact test case, with the input and output resolutions.

Ant_222 wrote on 2020-01-09, 15:07:

I guess I'm spoiled by how aspect ratio correction is dealt with in other software such as scummvm (which correct to a 4:3 ratio)
(the same goes for @Soothe with Crispy Doom, it seems)

In my opinion, ScummVM, is even worse, because it has a mode called pixel-perfect that in fact uses nearest-neighbor interpolation along the vertical axis. That is misinformation of the users.

Reply 715 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
krcroft wrote on 2020-01-09, 23:59:

I guess the forced means it will do this for SVGA games using modes greater than 320x2##? So a 640x480 game would be cranked up to 1920x1440 (DOSBox-side), and then scaled linearly by SDL (possibly using hardware-accel) to fit the desired output resolution.

forced causes DOSBox to upscale the image even if the result will be larger than the output area. It works for 320x200, too, and may be required for small monitors.

Reply 716 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Soothe wrote on 2020-01-10, 03:25:

Thanks for creating this patch, seems like a bunch of software isn't doing aspect correction + pixel perfect correctly.

None that I know of. I even have to run ZX Spectrum and SNES emulatros from within DOSBox!

Reply 717 of 726, by Delfino Furioso

User metadata
Rank Newbie
Rank
Newbie
jmarsh wrote on 2020-01-09, 23:24:

Regular DOSBox can already do the same thing using "scaler=normal?x forced" to upscale beyond the output resolution and "output=opengl" for linear downscaling.

that's the way I usually setup dosbox, and I'm under the impression that it would lead to less accurate results because the aspect ratio correction is performed by adding lines instead of making the single pixel taller

this image explain my understanding of the "aspect=true & scaler=normal5x" inner workings
https://i.postimg.cc/s2nXy3ns/aspect-normal5x.png

this image tries to exemplify the new approach I am interested in
https://i.postimg.cc/HxqTsnbD/openglnp.png

am I missing something?

Reply 718 of 726, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Delfino Furioso wrote on 2020-01-10, 12:53:

that's the way I usually setup dosbox, and I'm under the impression that it would lead to less accurate results because the aspect ratio correction is performed by adding lines instead of making the single pixel taller

this image explain my understanding of the "aspect=true & scaler=normal5x" inner workings
https://i.postimg.cc/s2nXy3ns/aspect-normal5x.png

I fear that is true. The DOSBox built-in aspect-ratio correction doubles certain rows in the original image before futher processing. But does it work that way with hardware outputs—opengl and ddraw?

Delfino Furioso wrote on 2020-01-10, 12:53:

this image tries to exemplify the new approach I am interested in
https://i.postimg.cc/HxqTsnbD/openglnp.png

No—that shows pixel-perfect scaling with aspect ratio correction. My patch already works that way if the output resolution is large enough. Why don't you run a game with surfacenp and a zero surfacenp-sharpness and post a 10x magnified fragment? It would show what you need.

Reply 719 of 726, by Soothe

User metadata
Rank Newbie
Rank
Newbie
Ant_222 wrote on 2020-01-10, 12:30:
Soothe wrote on 2020-01-10, 03:25:

Thanks for creating this patch, seems like a bunch of software isn't doing aspect correction + pixel perfect correctly.

None that I know of. I even have to run ZX Spectrum and SNES emulatros from within DOSBox!

Wait SNES emulators?
Even stuff like bsnes / higan isn't doing it correctly?
Have you ever tried using something like RetroArch?