Skip to content

Commit cfe137c

Browse files
6by9pelwell
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 <[email protected]>
1 parent ef79eea commit cfe137c

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

@@ -871,6 +872,10 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
871872
{
872873
struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
873874
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
875+
bool no_interpolate = state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR;
876+
877+
if (vc4_state->is_yuv444_unity)
878+
no_interpolate = 1;
874879

875880
WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D);
876881

@@ -879,15 +884,15 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
879884
vc4_write_ppf(vc4_state, vc4_state->src_w[channel],
880885
vc4_state->crtc_w, vc4_state->src_x, channel,
881886
state->chroma_siting_h,
882-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
887+
no_interpolate);
883888
}
884889

885890
/* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
886891
if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
887892
vc4_write_ppf(vc4_state, vc4_state->src_h[channel],
888893
vc4_state->crtc_h, vc4_state->src_y, channel,
889894
state->chroma_siting_v,
890-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
895+
no_interpolate);
891896
vc4_dlist_write(vc4_state, 0xc0c0c0c0);
892897
}
893898

@@ -1867,12 +1872,19 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18671872
if (vc4_state->x_scaling[0] == VC4_SCALING_NONE) {
18681873
vc4_state->x_scaling[0] = VC4_SCALING_PPF;
18691874
vc4_state->is_unity = false;
1875+
vc4_state->is_yuv444_unity = true;
18701876
}
18711877

18721878
if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) {
18731879
vc4_state->y_scaling[0] = VC4_SCALING_PPF;
18741880
vc4_state->is_unity = false;
1881+
} else {
1882+
/* Ensure that resizing vertically but not horizontally
1883+
* doesn't switch the scaling filter.
1884+
*/
1885+
vc4_state->is_yuv444_unity = false;
18751886
}
1887+
18761888
}
18771889

18781890
if (!vc4_state->src_w[0] || !vc4_state->src_h[0] ||
@@ -2199,6 +2211,9 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
21992211
filter = &vc4->hvs->nearest_neighbour_filter;
22002212
break;
22012213
}
2214+
if (vc4_state->is_yuv444_unity)
2215+
filter = &vc4->hvs->nearest_neighbour_filter;
2216+
22022217
u32 kernel = VC4_SET_FIELD(filter->start,
22032218
SCALER_PPF_KERNEL_OFFSET);
22042219

0 commit comments

Comments
 (0)