Skip to content

Commit dab58ec

Browse files
6by9rajeshkumarwr
authored andcommitted
drm/vc4: plane: Use nearest neighbour filter with YUV444 workaround
As a follow-up to commit ef79eea9e4b8 ("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 c9a6542 commit dab58ec

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ struct vc4_plane_state {
460460
enum vc4_scaling_mode x_scaling[2], y_scaling[2];
461461
bool is_unity;
462462
bool is_yuv;
463+
/* Allows use of nearest neighbour scaling filter when doing unity YUV444
464+
* workaround
465+
*/
466+
bool is_yuv444_unity;
463467

464468
/* Our allocation in LBM for temporary storage during scaling. */
465469
struct drm_mm_node lbm;

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
}
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

@@ -855,6 +856,10 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
855856
{
856857
struct vc4_dev *vc4 = to_vc4_dev(state->plane->dev);
857858
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
859+
bool no_interpolate = state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR;
860+
861+
if (vc4_state->is_yuv444_unity)
862+
no_interpolate = 1;
858863

859864
WARN_ON_ONCE(vc4->gen > VC4_GEN_6_D);
860865

@@ -863,15 +868,15 @@ static void vc4_write_scaling_parameters(struct drm_plane_state *state,
863868
vc4_write_ppf(vc4_state, vc4_state->src_w[channel],
864869
vc4_state->crtc_w, vc4_state->src_x, channel,
865870
state->chroma_siting_h,
866-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
871+
no_interpolate);
867872
}
868873

869874
/* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
870875
if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
871876
vc4_write_ppf(vc4_state, vc4_state->src_h[channel],
872877
vc4_state->crtc_h, vc4_state->src_y, channel,
873878
state->chroma_siting_v,
874-
state->scaling_filter == DRM_SCALING_FILTER_NEAREST_NEIGHBOR);
879+
no_interpolate);
875880
vc4_dlist_write(vc4_state, 0xc0c0c0c0);
876881
}
877882

@@ -1805,12 +1810,19 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
18051810
if (vc4_state->x_scaling[0] == VC4_SCALING_NONE) {
18061811
vc4_state->x_scaling[0] = VC4_SCALING_PPF;
18071812
vc4_state->is_unity = false;
1813+
vc4_state->is_yuv444_unity = true;
18081814
}
18091815

18101816
if (vc4_state->y_scaling[0] == VC4_SCALING_NONE) {
18111817
vc4_state->y_scaling[0] = VC4_SCALING_PPF;
18121818
vc4_state->is_unity = false;
1819+
} else {
1820+
/* Ensure that resizing vertically but not horizontally
1821+
* doesn't switch the scaling filter.
1822+
*/
1823+
vc4_state->is_yuv444_unity = false;
18131824
}
1825+
18141826
}
18151827

18161828
if (!vc4_state->src_w[0] || !vc4_state->src_h[0] ||
@@ -2137,6 +2149,9 @@ static int vc6_plane_mode_set(struct drm_plane *plane,
21372149
filter = &vc4->hvs->nearest_neighbour_filter;
21382150
break;
21392151
}
2152+
if (vc4_state->is_yuv444_unity)
2153+
filter = &vc4->hvs->nearest_neighbour_filter;
2154+
21402155
u32 kernel = VC4_SET_FIELD(filter->start,
21412156
SCALER_PPF_KERNEL_OFFSET);
21422157

0 commit comments

Comments
 (0)