Skip to content

Commit 1ea4143

Browse files
6by9popcornmix
authored andcommitted
drm/vc4: plane: Use nearest neighbour filter with YUV444 workaround
As a follow-up to commit ef79eea ("drm/vc4: plane: Enable scaler for YUV444 on GEN6"), the image looks a little soft when rendering at 1:1 due to the scaling filter being enabled. Switch to using the nearest neighbour filter automatically when not scaling in YUV444 to compensate. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
1 parent 74760a2 commit 1ea4143

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,10 @@ struct vc4_plane_state {
475475
enum vc4_scaling_mode x_scaling[2], y_scaling[2];
476476
bool is_unity;
477477
bool is_yuv;
478+
/* Allows use of nearest neighbour scaling filter when doing unity YUV444
479+
* workaround
480+
*/
481+
bool is_yuv444_unity;
478482

479483
/* Our allocation in LBM for temporary storage during scaling. */
480484
unsigned int lbm_handle;

drivers/gpu/drm/vc4/vc4_plane.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
302302
refcount_inc(&hvs->lbm_refcounts[vc4_state->lbm_handle].refcount);
303303

304304
vc4_state->dlist_initialized = 0;
305+
vc4_state->is_yuv444_unity = false;
305306

306307
__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
307308

@@ -874,6 +875,10 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
874875
{
875876
struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
876877
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
878+
bool no_interpolate = state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR;
879+
880+
if (vc4_state->is_yuv444_unity)
881+
no_interpolate = 1;
877882

878883
WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D);
879884

@@ -882,15 +887,15 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
882887
vc4_write_ppf(vc4_state, vc4_state->src_w[channel],
883888
vc4_state->crtc_w, vc4_state->src_x, channel,
884889
state->chroma_siting_h,
885-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
890+
no_interpolate);
886891
}
887892

888893
/* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
889894
if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
890895
vc4_write_ppf(vc4_state, vc4_state->src_h[channel],
891896
vc4_state->crtc_h, vc4_state->src_y, channel,
892897
state->chroma_siting_v,
893-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
898+
no_interpolate);
894899
vc4_dlist_write(vc4_state, 0xc0c0c0c0);
895900
}
896901

@@ -1870,12 +1875,19 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18701875
if (vc4_state->x_scaling[0] == VC4_SCALING_NONE) {
18711876
vc4_state->x_scaling[0] = VC4_SCALING_PPF;
18721877
vc4_state->is_unity = false;
1878+
vc4_state->is_yuv444_unity = true;
18731879
}
18741880

18751881
if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) {
18761882
vc4_state->y_scaling[0] = VC4_SCALING_PPF;
18771883
vc4_state->is_unity = false;
1884+
} else {
1885+
/* Ensure that resizing vertically but not horizontally
1886+
* doesn't switch the scaling filter.
1887+
*/
1888+
vc4_state->is_yuv444_unity = false;
18781889
}
1890+
18791891
}
18801892

18811893
if (!vc4_state->src_w[0] || !vc4_state->src_h[0] ||
@@ -2202,6 +2214,9 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
22022214
filter = &vc4->hvs->nearest_neighbour_filter;
22032215
break;
22042216
}
2217+
if (vc4_state->is_yuv444_unity)
2218+
filter = &vc4->hvs->nearest_neighbour_filter;
2219+
22052220
u32 kernel = VC4_SET_FIELD(filter->start,
22062221
SCALER_PPF_KERNEL_OFFSET);
22072222

0 commit comments

Comments
 (0)