Bug 94816 - Nearest neighbor scaling?
Summary: Nearest neighbor scaling?
Status: RESOLVED MOVED
Alias: None
Product: xorg
Classification: Unclassified
Component: Driver/intel (show other bugs)
Version: unspecified
Hardware: All All
: medium enhancement
Assignee: Chris Wilson
QA Contact: Intel GFX Bugs mailing list
URL:
Whiteboard:
Keywords:
: 94815 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-04-04 14:42 UTC by N. W.
Modified: 2019-11-27 13:43 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
Select nearest neighbour scaling for exact pixel fitting (3.41 KB, patch)
2016-04-04 15:58 UTC, Chris Wilson
no flags Details | Splinter Review

Description N. W. 2016-04-04 14:42:38 UTC
Hello,

would it be possible that you add a nearest-neighbor scaling mode to the driver, so that one could display 1920x1080 natively on a 3840x2160 monitor or 1280x720 natively on a 2560x1440 monitor and so on (one pixel becomes four pixels)?

There is some information on this topic over there:

https://forums.geforce.com/default/topic/844905/geforce-drivers/integer-scaling-mode/

Regards
Comment 1 Chris Wilson 2016-04-04 14:49:05 UTC
So automatically reduce the bilinear filtering to nearest if pixel-exact transformation. I'm convinced - that will only work with the randr transform, if you want to change the panel fitting filter that's a little trickier.
Comment 2 N. W. 2016-04-04 15:03:05 UTC
(In reply to Chris Wilson from comment #1)
> So automatically reduce the bilinear filtering to nearest if pixel-exact
> transformation. I'm convinced - that will only work with the randr
> transform, if you want to change the panel fitting filter that's a little
> trickier.

Thanks a lot for the swift reply, but I don't really understand. Are you saying this is already possible?

Or are you just thinking out aloud about how this could be implemented?
Comment 3 Chris Wilson 2016-04-04 15:23:22 UTC
Actually the CRTC transform + filter is already controlled by the user, so it is inappropriate for the driver to override an explicitly set scaling mode. The default should be to use FilterNearest. That's if using RandR to do the transformation rather than panel fitting.
Comment 4 N. W. 2016-04-04 15:36:17 UTC
(In reply to Chris Wilson from comment #3)
> Actually the CRTC transform + filter is already controlled by the user, so
> it is inappropriate for the driver to override an explicitly set scaling
> mode. The default should be to use FilterNearest. That's if using RandR to
> do the transformation rather than panel fitting.

Sorry if it sounds stupid, but when I google for "randr FilterNearest" I don't find anything at all.
Comment 5 Chris Wilson 2016-04-04 15:58:48 UTC
Created attachment 122704 [details] [review]
Select nearest neighbour scaling for exact pixel fitting

Afaict no one has ever used the filter property of RandR transformations, it is not even exposed via xrandr! It is printed as part of xrandr --verbose, but you can't set it (unless I am blind).


The attached should automatically use nearest neighbour with the panel fitter.
Comment 6 Chris Wilson 2016-04-04 16:01:29 UTC
Hmm, looks like more work is involved to disable filtering on gen4+ (i.e. anything in the last decade). :|
Comment 7 Chris Wilson 2016-04-04 16:04:01 UTC
diff --git a/xrandr.c b/xrandr.c
index dcfdde0..4248a62 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -1303,7 +1303,8 @@ set_output_info (output_t *output, RROutput xid, XRROutput
Info *output_info)
            output->transform.transform.matrix[0][0] = XDoubleToFixed (sx);
            output->transform.transform.matrix[1][1] = XDoubleToFixed (sy);
            output->transform.transform.matrix[2][2] = XDoubleToFixed (1.0);
-           if (sx != 1 || sy != 1)
+           if (output->transform.transform.matrix[0][0] & 0xffff ||
+               output->transform.transform.matrix[1][1] & 0xffff)
                output->transform.filter = "bilinear";
            else
                output->transform.filter = "nearest";

Should fix xrandr to automatically choose nearest for pixel-exact transforms.
Comment 8 N. W. 2016-04-04 16:17:49 UTC
(In reply to Chris Wilson from comment #5)
> but you can't set it (unless I am blind).

Would it make sense to submit a issue/feature request for this?

And could you please point me to which component I should file a feature request against?

Any of those:

App/xrandr
Lib/XrandR
Lib/XrandrUtils
Server/Ext/RandR

Which one?

> The attached should automatically use nearest neighbour with the panel
> fitter.

Thank you. Sorry for sounding stupid again, but could you please tell me how I could test this when running Ubuntu for example?

And would this also allow playing 3D games with nearest neighbor scaling (i.e. running a game natively at 1920x1080 on a 3840x2160 display)?

Regards
Comment 9 Chris Wilson 2016-04-04 20:56:50 UTC
(In reply to nw9165-3201 from comment #8)
> (In reply to Chris Wilson from comment #5)
> > but you can't set it (unless I am blind).
> 
> Would it make sense to submit a issue/feature request for this?

It's underway: https://patchwork.freedesktop.org/patch/79564/

> > The attached should automatically use nearest neighbour with the panel
> > fitter.
> 
> Thank you. Sorry for sounding stupid again, but could you please tell me how
> I could test this when running Ubuntu for example?

You would use xrandr --output DP1 --mode 3840x2160 --scale-from 1920x1080 (with an updated xrandr).

> And would this also allow playing 3D games with nearest neighbor scaling
> (i.e. running a game natively at 1920x1080 on a 3840x2160 display)?

In theory, yes. In practice, I imagine the games will be querying the list of monitor resolutions and do something different. Ideally, the games would do the upscaling themselves (that also allows for something like the UI overlay being high definition for sharp text, whilst upscaling the heavy content). Doing the upscaling late in the chain incurs an additional step (that is less likely to be as efficient as doing it earlier in the client).

With the panel fitter it is even easier as we just use xrandr --output eDP1 --mode 1920x1080 and the hardware scales automatically to the native resolution of the panel from the source buffer (but we still want to ideally disable the filter here even though the hardware should be using a higher quality filter than bilinear).
Comment 10 N. W. 2016-04-04 22:54:47 UTC
(In reply to Chris Wilson from comment #9)
> It's underway: https://patchwork.freedesktop.org/patch/79564/
> [...]
> You would use xrandr --output DP1 --mode 3840x2160 --scale-from 1920x1080
> (with an updated xrandr).

Awesome, thank you :). Some questions though:

As far as I can tell from your xrandr patch, the user can now select between auto, bilinear and nearest (neighbor) filtering, right?

On the xrandr command line you have posted I do not see "--filter nearest" though.

Does that mean that in addition to adding a "--filter" option, your patch also makes nearest neighbor filtering the new default for 960x540 @ 1920x1080, 1280x720 @ 2560x1440, 1920x1080 @ 3840x2160 and so on without the user having to specify "--filter nearest"?

> In theory, yes. In practice, I imagine the games will be querying the list
> of monitor resolutions and do something different. Ideally, the games would
> do the upscaling themselves (that also allows for something like the UI
> overlay being high definition for sharp text, whilst upscaling the heavy
> content). Doing the upscaling late in the chain incurs an additional step
> (that is less likely to be as efficient as doing it earlier in the client).

Hm, yes, ideally. But in reality I don't think there are a lot of games that do upscaling on their own. And I doubt any of them are using nearest neighbor scaling.

Unreal Engine 4 for example has a "Screen Percentage" option which "renders the scene at a lower resolution and then scales it up", see:

https://docs.unrealengine.com/latest/INT/Resources/ContentExamples/PostProcessing/1_13/index.html

But it uses bilinear filtering and the devs either do not seem to understand or not care about nearest neighbor filtering, at least judging from the following thread over there, see:

https://answers.unrealengine.com/questions/110547/rendering-at-320x180px-and-point-scaling-up.html

And Unreal Engine 4 is just one example.

Unfortunately it looks like most people don't really think about the advantages of nearest neighbor scaling on high DPI screens.

As far as I know most UHD-TVs do not even have an option to scale 1920x1080 to 3840x2160 via nearest neighbor. The only brand that I know of which does offer this option on their UHD-TVs is Panasonic. Panasonic has an option called "1080p Pixel by 4pixels" which, if enabled, scales 1920x1080 to 3840x2160 via nearest neighbor.

UHD PC monitors on the other hand do not offer such an option at all (none that I know of).

> With the panel fitter it is even easier as we just use xrandr --output eDP1
> --mode 1920x1080 and the hardware scales automatically to the native
> resolution of the panel from the source buffer (but we still want to ideally
> disable the filter here even though the hardware should be using a higher
> quality filter than bilinear).

Could you please explain to me what a "panel fitter" is? Is it a hardware scaler on Intel GPUs that scales the image in hardware?

And is "panel fitter" an Intel specific name or is it a generic term?

Does the hardware image scaler inside Intel GPU have a specific name?

It would be really interesting to know more about the hardware image scaler inside the Intel GPUs (if there is one).

> (but we still want to ideally
> disable the filter here even though the hardware should be using a higher
> quality filter than bilinear).

Yes, wouldn't it be possible to use the hardware image scaler inside the Intel GPUs to upscale the image with nearest neighbor instead of using xrandr (software)?

> even though the hardware should be using a higher quality filter than
> bilinear).

So what kind of filter is it using if not bilinear? And maybe the hardware can be told to use another filter, like nearest neighbor for example (see above)?

Sorry for bothering you with all those questions, but I am really interested in this (IMHO important) topic, especially due to high DPI displays becoming more and more common.
Comment 11 Michel Dänzer 2016-04-05 03:56:44 UTC
*** Bug 94815 has been marked as a duplicate of this bug. ***
Comment 12 Michel Dänzer 2016-04-05 03:57:07 UTC
*** Bug 94820 has been marked as a duplicate of this bug. ***
Comment 13 N. W. 2016-04-07 17:50:25 UTC
Not intending to hustle anyone, but any update on this? And will the xrandr patch be merged anytime soon?

Looks like it wasn't merged yet:

https://cgit.freedesktop.org/xorg/app/xrandr/log/

?
Comment 14 ubitux 2017-01-16 13:31:59 UTC
I tried that patch, but I needed to add a "continue" in the --filter option handling scope.

Also not sure I was using it correctly but it seems to do the work with --mode 3840x2160 --scale 0.5x0.5 --filter nearest

My cursor is still glitchy but that's probably another problem.
Comment 15 ubitux 2017-01-16 13:33:19 UTC
Oh, and it doesn't reload the transform if I switch the --filter, I had to switch mode between tests to force the change of scaling filter.
Comment 16 Martin Peres 2019-11-27 13:43:55 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/xorg/driver/xf86-video-intel/issues/103.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.