Closed dividuum closed 2 months ago
Can you post the original image? I can guess at what it should look like, but would be useful to confirm.
It half looks like the chroma planes are getting scaled by twice the factor desired, but it's tricky to say for definite. At a guess I'd put it down to the SCALER_PPF_NOINTERP flag at https://github.com/raspberrypi/linux/blob/rpi-6.6.y/drivers/gpu/drm/vc4/vc4_plane.c#L617 My other note is that you're upscaling (560x320 to 640x480 for luma, and 280x160 to 640x480 for chroma). Does it do the same on downscaling?
Nearest neighbour is less useful for video planes - it's good for the blocky graphics of retro games emulation, but that's all going to be RGB rather than YUV.
Can you post the original image? I can guess at what it should look like, but would be useful to confirm.
Sure. Sorry. Here you go:
The bar at the bottom in both screenshots is a GL RGBA overlay rendering fine.
My other note is that you're upscaling (560x320 to 640x480 for luma, and 280x160 to 640x480 for chroma). Does it do the same on downscaling?
Not sure. Might take a moment to try it out.
Here's the result of downscaling a FullHD video to 640x360:
plane[126]: plane-6
crtc=crtc-2
fb=332
allocated by = info-beamer
refcount=2
format=YU12 little-endian (0x32315559)
modifier=0x0
size=1920x1080
layers:
size[0]=1920x1080
pitch[0]=1920
offset[0]=0
obj[0]:
name=0
refcount=3
start=00100968
size=3256320
imported=yes
dma_addr=0x0000000a7f000000
vaddr=0000000000000000
size[1]=960x540
pitch[1]=960
offset[1]=2150400
obj[1]:
name=0
refcount=3
start=00100968
size=3256320
imported=yes
dma_addr=0x0000000a7f000000
vaddr=0000000000000000
size[2]=960x540
pitch[2]=960
offset[2]=2703360
obj[2]:
name=0
refcount=3
start=00100968
size=3256320
imported=yes
dma_addr=0x0000000a7f000000
vaddr=0000000000000000
crtc-pos=640x360+0+60
src-pos=1920.000000x1080.000000+0.000000+0.000000
rotation=1
normalized-zpos=0
color-encoding=ITU-R BT.709 YCbCr
color-range=YCbCr full range
"Default"
:
"Nearest Neighbor"
:
Hmm, I think something is just totally wrong. Even RGB images are being scaled incorrectly for me on Pi4.
On my system with HDMI-A-1, I get weird outputs using modetest
modetest -M vc4 -w 91:"SCALING_FILTER":1
modetest -M vc4 -P 91@102:720x1280*2@XB24
(replace 91 and 102 with the relevant primary plane and crtc for your display).
My images are coming through at approx half size, with the right and bottom-most pixels repeated.
I'm going to have to check whether the filter actually works in the firmware.
My early guess of the SCALER_PPF_NOINTERP bit appears to be correct. If enabled, then no scaling appears to happen. YUV 420 shows more issue as the luma and chroma planes have different scaling factors, so the colours are all totally wrong.
Even without that flag, a x8 scaling (modetest -M vc4 -P 91@102:480x480*4@XB24
on a 4k screen) shows definite jagged lines which I'd expect. YU12 shows a colour artifact on one of the edges.
@popcornmix Do you have any further knowledge on this? It was you who pointed out the interpolate flag on the original PR.
I'm tempted to just drop the interpolate flag for now rather than investigate much further.
I could have a look. I did implement a similar feature on the firmware side, which does set SCALER_PPF_NO_INTERPOLATE
in the display list.
But that was a while ago (git says over ten years...) so it may take a while to work out what is needed.
I could have a look. I did implement a similar feature on the firmware side, which does set
SCALER_PPF_NO_INTERPOLATE
in the display list.But that was a while ago (git says over ten years...) so it may take a while to work out what is needed.
4k monitor, disabling the KMS driver and using
framebuffer_width=640
framebuffer_height=400
scaling_kernel=8
gives me a very blocky console (as expected). Now to extract the dlist to analyse....
Doh, operator precendence
vc4_dlist_write(vc4_state,
no_interpolate ? SCALER_PPF_NOINTERP : 0 |
SCALER_PPF_AGC |
VC4_SET_FIELD(scale, SCALER_PPF_SCALE) |
/*
* The register layout documentation is slightly
* different to setup the phase in the BCM2712,
* but they seem equivalent.
*/
VC4_SET_FIELD(phase, SCALER_PPF_IPHASE));
?:
is lower precedence than |
, so we get just SCALER_PPF_NOINTERP
when in no_interpolate mode.
Time for a pair of parenthesises.
Can confirm that it now works as expected. Thanks!
Describe the bug
I toyed around with the new scaling filter feature recently added. Something weird is going on when using YU12 or NV12 framebuffers. Here's how it looks for a 560x320 video on a 640x480 display:
Here's the corresponding plane configuration:
This only happens when using
"Nearest Neighbor"
as scaling filter."Default"
works fine. It also doesn't seem to happen with RGBA framebuffers.Steps to reproduce the behaviour
Apply
"Nearest Neighbor"
value to the SCALING_FILTER property for a YU12 (software decoded H264) or NV12 (HW decoded HEVC) plane.I haven't tried to reproduce this on Bookworm because kernel 6.6.51 doesn't seem to be officially available yet via APT.
Device (s)
Raspberry Pi 5
System
Logs
No response
Additional context
No response