English Amiga Board


Go Back   English Amiga Board > Support > support.WinUAE

 
 
Thread Tools
Old 11 April 2017, 19:53   #1
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
Off-by-one scaling error

WinUAE 3.4.0 on Windows 10 64-bit 1703. AMD FirePro W5100 graphics card.

The attached config uses Direct3D, null filter, "No scaling", Horiz. size and Vert. size both set to 2x. The image looks like it's being scaled to one (Windows desktop) pixel shorter than it should be.
Attached Thumbnails
Click image for larger version

Name:	WB_off-by-one_scaling_out.png
Views:	175
Size:	27.6 KB
ID:	52781  
Attached Files
File Type: zip my_test_JIT_uaegfx.uae.zip (2.6 KB, 77 views)
mark_k is offline  
Old 12 April 2017, 00:32   #2
rsn8887
Registered User
 
rsn8887's Avatar
 
Join Date: Oct 2006
Location: USA
Posts: 1,058
I wonder if this is related to my problems getting a perfect user-made "null filter" to work with exact 1:1 pixels.
rsn8887 is offline  
Old 12 April 2017, 14:12   #3
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
Hmm... I tried using the -nod3d9shader option, which means WinUAE doesn't use its built-in winuae.fx shader. No change.

Then I set Integer scaling, and made the window large enough so the image was scaled 2×. The problem went away then.

Edit to add: Maybe there's an incorrectly-rounded floating point to integer conversion in the no scaling (with 2x H&V size) code path, but not in the integer scaling one?

Last edited by mark_k; 12 April 2017 at 18:29.
mark_k is offline  
Old 14 April 2017, 12:35   #4
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
There most likely is something but I have no idea where and what...
Toni Wilen is offline  
Old 14 April 2017, 16:25   #5
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
I'll have a look through the code but I'm sure nothing will jump out.

This problem isn't driver-specific, though perhaps the manifestation could differ between drivers. I checked with my laptop (Nvidia driver). Setting h. and v. size controls to 2×, the issue was still present. At varying window sizes there were sometimes both horizontal and vertical "glitch lines". Same for 3×.

Attached pics taken on my laptop.
Attached Thumbnails
Click image for larger version

Name:	2x_two_bad_2.png
Views:	135
Size:	11.3 KB
ID:	52806   Click image for larger version

Name:	3x_bad_2.png
Views:	149
Size:	20.2 KB
ID:	52807  
mark_k is offline  
Old 14 April 2017, 23:18   #6
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
I'm probablyalmost certainly barking up the wrong tree here, but...

extraw and extrah are of type int

win32_scaler.cpp:95
Code:
static void sizeoffset (RECT *dr, RECT *zr, int w, int h)
{
	dr->right -= w;
	dr->bottom -= h;
	OffsetRect (zr, w / 2, h / 2);
}
win32_scaler.cpp:164
Code:
float filter_horiz_zoom_mult = currprefs.gf[picasso_on].gfx_filter_horiz_zoom_mult;
float filter_vert_zoom_mult = currprefs.gf[picasso_on].gfx_filter_vert_zoom_mult;
win32_scaler.cpp:188 near start of getfilterrect2():
Code:
extraw = -aws * (filter_horiz_zoom - currprefs.gf[picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f;
extrah = -ahs * (filter_vert_zoom - currprefs.gf[picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f;
Later on in an if (scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) {...} statement, you have (line 309):
Code:
	extraw = 0;
	extrah = 0;
After that if statement's closing brace, there is this (line 571):
Code:
cont:
if (!filter_horiz_zoom_mult && !filter_vert_zoom_mult) {
	sizeoffset (dr, zr, extraw, extrah);
	...
So in the case where scalemode is 0 (AUTOSCALE_NONE), extraw and extrah are set by the lines near 188.

Maybe worth adding some logging there???

Also, how are conditions like if (!filter_horiz_zoom_mult && !filter_vert_zoom_mult) evaluated? Because filter_horiz_zoom_mult and filter_vert_zoom_mult are of type float, should you really check whether they are (very) small enough rather than (effectively) compare with zero?
mark_k is offline  
Old 15 April 2017, 11:22   #7
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
Quote:
Maybe worth adding some logging there???
No. I don't add logging that repeats every frame.

Get Visual Studio community edition and start debugging

Quote:
Also, how are conditions like if (!filter_horiz_zoom_mult && !filter_vert_zoom_mult) evaluated? Because filter_horiz_zoom_mult and filter_vert_zoom_mult are of type float, should you really check whether they are (very) small enough rather than (effectively) compare with zero?
It is working as designed, value is specifically set to zero when it needs to be zero.
Toni Wilen is offline  
Old 16 May 2017, 19:08   #8
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
Some more info, maybe this could help? Screenmode is HIGHGFX:1024×768 interlaced. This is with AMD W5100 graphics card/driver.

The missing horizontal line seems to occur only when the window height (as shown in the Windowed numerical box in the screen section of the display settings page) is odd.

I'll check with Nvidia driver and report back. (Since there were in some cases two missing horizontal and two vertical lines.)
mark_k is offline  
Old 17 May 2017, 23:08   #9
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
Here are some notes on code in win32_scaler.cpp. If/when I ever finish getting WinUAE into a buildable state I can try this change myself...
Code:
	OffsetRect (zr, (int)(-filter_horiz_offset * aws), 0);	// filter_horiz_offset is float, aws is int
	OffsetRect (zr, 0, (int)(-filter_vert_offset * ahs));	// filter_vert_offset is float, ahs is int

	xs = dst_width;				// Both int
	if (xmult)				// xmult is float
		xs -= dst_width / xmult;	// int -= int / float;
	ys = dst_height;			// Both int
	if (ymult)				// ymult is float
		ys -= dst_height / ymult;	// int -= int / float;
	sizeoffset (dr, zr, xs, ys);

	filterxmult = xmult;			// Both float
	filterymult = ymult;			// Both float
	filteroffsetx += (dst_width - aw / filterxmult) / 2;	// float += (int - int / float) / 2;
	filteroffsety += (dst_height - ah / filterymult) / 2;	// float += (int - int / float) / 2;

end:

	if (getscalerect (&mrmx, &mrmy, &mrsx, &mrsy)) {
		sizeoffset (dr, zr, mrmx, mrmy);	// 3rd and 4th args are int but mrsx & mrsy are float
		OffsetRect (dr, mrsx, mrsy);		// 2nd and 3rd args are int but mrsx & mrsy are float
	}
To account for truncation when converting float to it, could/should some or all of these be changed, like this:
Code:
// NOTE: I'm just adding 0.5 here but you might need to properly
// round when a float can be either positive or negative

	OffsetRect (zr, (int)(-filter_horiz_offset * aws + 0.5), 0);	// Probably need to round here?
	OffsetRect (zr, 0, (int)(-filter_vert_offset * ahs + 0.5));	// Probably need to round here?

	xs = dst_width;
	if (xmult)
		xs -= dst_width / xmult + 0.5;
	ys = dst_height;
	if (ymult)
		ys -= dst_height / ymult + 0.5;
	sizeoffset (dr, zr, xs, ys);
	...
end:

	if (getscalerect (&mrmx, &mrmy, &mrsx, &mrsy)) {
		sizeoffset (dr, zr, mrmx + 0.5, mrmy + 0.5);
		OffsetRect (dr, mrsx + 0.5, mrsy + 0.5);
	}
getscalerect() just returns false if mask2texture is 0. [So is that statement relevant to this off-by-one issue?]

About sizeoffset()...
Suppose you call sizeoffset() with mrmx = 3.9 say. Then 3.9 (float) is truncated to 3 (int) for the function call.
Then the "int w" argument to sizeoffset() is 3, which means sizeoffset() calls OffsetRect() with 2nd arg 1.
Code:
static void sizeoffset (RECT *dr, RECT *zr, int w, int h)
{
	dr->right -= w;
	dr->bottom -= h;
	OffsetRect (zr, w / 2, h / 2);
}
mark_k is offline  
Old 18 May 2017, 19:56   #10
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
Above changes done. If no replies or side-effects: it gets removed in next beta, it is too late for random changes at this point.
Toni Wilen is offline  
Old 18 May 2017, 20:48   #11
DamienD
Banned
 
DamienD's Avatar
 
Join Date: Aug 2005
Location: London / Sydney
Age: 47
Posts: 20,420
Quote:
Originally Posted by Toni Wilen View Post
it is too late for random changes at this point.
Awesome; I read the above meaning the 3.4.1 release is coming shortly
DamienD is offline  
Old 18 May 2017, 21:40   #12
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,333
Very quick test with the config I used for the first post.
Code:
Window size	341b8			latest winuae.7z
2170×1625	1 column missing	1 row + 1 column missing
2170×1626	good			2 rows + 1 column missing
2170×1627	1 column missing	1 row + 1 column missing
2170×1628	good			2 rows + 1 column missing
2170×1629	1 column missing	1 row + 1 column missing
2170×1630	good			2 rows + 1 column missing
So the changes had some effect, but not a beneficial one. Maybe some rounding in the wrong direction??? Maybe if I can get to understand what the code is trying to do, that will make things clearer.
mark_k is offline  
Old 19 May 2017, 19:37   #13
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
As I said: too late now.
Toni Wilen is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Pre-Scaling before Bilinear Scaling? rsn8887 request.UAE Wishlist 6 05 September 2015 19:13
Off-by-one error with RTG image scaling? mark_k support.WinUAE 10 01 December 2013 19:18
Off-by-one problem with 2x scaling mark_k support.WinUAE 0 05 February 2013 22:41
Integer Scaling FreakyDan support.WinUAE 3 12 May 2012 15:43
scaling and scanlines AxelFoley support.WinUAE 9 17 October 2009 00:13

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:51.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.24869 seconds with 16 queries