drm: Hook up BLEND_TF and stuff for proper space for degamma

This commit is contained in:
Joshua Ashton 2023-04-02 23:17:03 +01:00 committed by Joshie
parent 2e42bbfa08
commit 8a39621d3a
2 changed files with 53 additions and 8 deletions

View file

@ -633,6 +633,9 @@ static bool refresh_state( drm_t *drm )
crtc->has_vrr_enabled = crtc->props.contains( "VRR_ENABLED" );
if (!crtc->has_vrr_enabled)
drm_log.infof("CRTC %" PRIu32 " has no VRR_ENABLED support", crtc->id);
crtc->has_valve1_regamma_tf = crtc->props.contains( "VALVE1_CRTC_REGAMMA_TF" );
if (!crtc->has_valve1_regamma_tf)
drm_log.infof("CRTC %" PRIu32 " has no VALVE1_CRTC_REGAMMA_TF support", crtc->id);
crtc->lut3d_size = crtc->props.contains( "VALVE1_LUT3D_SIZE" ) ? uint32_t(crtc->initial_prop_values["VALVE1_LUT3D_SIZE"]) : 0;
crtc->shaperlut_size = crtc->props.contains( "VALVE1_SHAPER_LUT_SIZE" ) ? uint32_t(crtc->initial_prop_values["VALVE1_SHAPER_LUT_SIZE"]) : 0;
@ -640,6 +643,8 @@ static bool refresh_state( drm_t *drm )
crtc->current.active = crtc->initial_prop_values["ACTIVE"];
if (crtc->has_vrr_enabled)
drm->current.vrr_enabled = crtc->initial_prop_values["VRR_ENABLED"];
if (crtc->has_valve1_regamma_tf)
drm->current.output_tf = (drm_valve1_transfer_function) crtc->initial_prop_values["VALVE1_CRTC_REGAMMA_TF"];
}
for (size_t i = 0; i < drm->planes.size(); i++) {
@ -1142,6 +1147,8 @@ void finish_drm(struct drm_t *drm)
add_crtc_property(req, &drm->crtcs[i], "VALVE1_SHAPER_LUT", 0);
if ( drm->crtcs[i].has_vrr_enabled )
add_crtc_property(req, &drm->crtcs[i], "VRR_ENABLED", 0);
if ( drm->crtcs[i].has_valve1_regamma_tf )
add_crtc_property(req, &drm->crtcs[i], "VALVE1_CRTC_REGAMMA_TF", 0);
add_crtc_property(req, &drm->crtcs[i], "ACTIVE", 0);
}
for ( size_t i = 0; i < drm->planes.size(); i++ ) {
@ -1667,7 +1674,7 @@ struct LiftoffStateCacheEntry
uint32_t crtcX, crtcY, crtcW, crtcH;
drm_color_encoding colorEncoding;
drm_color_range colorRange;
uint32_t transferFunction;
GamescopeAppTextureColorspace colorspace;
} layerState[ k_nMaxLayers ];
bool operator == (const LiftoffStateCacheEntry& entry) const
@ -1694,7 +1701,7 @@ struct LiftoffStateCacheEntryKasher
hash_combine(hash, k.layerState[i].crtcH);
hash_combine(hash, k.layerState[i].colorEncoding);
hash_combine(hash, k.layerState[i].colorRange);
hash_combine(hash, k.layerState[i].transferFunction);
hash_combine(hash, k.layerState[i].colorspace);
}
return hash;
@ -1783,11 +1790,11 @@ LiftoffStateCacheEntry FrameInfoToLiftoffStateCacheEntry( struct drm_t *drm, con
{
entry.layerState[i].colorEncoding = drm_get_color_encoding( g_ForcedNV12ColorSpace );
entry.layerState[i].colorRange = drm_get_color_range( g_ForcedNV12ColorSpace );
entry.layerState[i].transferFunction = ColorSpaceToEOTFIndex( GAMESCOPE_APP_TEXTURE_COLORSPACE_SRGB );
entry.layerState[i].colorspace = GAMESCOPE_APP_TEXTURE_COLORSPACE_SRGB;
}
else
{
entry.layerState[i].transferFunction = ColorSpaceToEOTFIndex(frameInfo->layers[ i ].colorspace);
entry.layerState[i].colorspace = frameInfo->layers[ i ].colorspace;
}
}
@ -1860,9 +1867,11 @@ drm_prepare_liftoff( struct drm_t *drm, const struct FrameInfo_t *frameInfo, boo
liftoff_layer_set_property( drm->lo_layers[ i ], "COLOR_RANGE", entry.layerState[i].colorRange );
if ( drm_supports_color_mgmt( drm ) )
{
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_DEGAMMA_TF", DRM_VALVE1_TRANSFER_FUNCTION_BT709 );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_LUT", 0 );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_LUT3D", 0 );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_BLEND_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
}
}
else
@ -1871,9 +1880,11 @@ drm_prepare_liftoff( struct drm_t *drm, const struct FrameInfo_t *frameInfo, boo
liftoff_layer_unset_property( drm->lo_layers[ i ], "COLOR_RANGE" );
if ( drm_supports_color_mgmt( drm ) )
{
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_LUT", drm->pending.shaperlut_id[ entry.layerState[i].transferFunction ] );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_LUT3D", drm->pending.lut3d_id[ entry.layerState[i].transferFunction ] );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_DEGAMMA_TF", convert_colorspace_to_valve1_drm( entry.layerState[i].colorspace ) );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_LUT", drm->pending.shaperlut_id[ ColorSpaceToEOTFIndex( entry.layerState[i].colorspace ) ] );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_TF", convert_colorspace_to_valve1_drm( entry.layerState[i].colorspace ) );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_LUT3D", drm->pending.lut3d_id[ ColorSpaceToEOTFIndex( entry.layerState[i].colorspace ) ] );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_BLEND_TF", drm->pending.output_tf );
}
}
}
@ -1886,9 +1897,10 @@ drm_prepare_liftoff( struct drm_t *drm, const struct FrameInfo_t *frameInfo, boo
if ( drm_supports_color_mgmt( drm ) )
{
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_DEGAMMA_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_LUT", 0 );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_SHAPER_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_LUT3D", 0 );
liftoff_layer_set_property( drm->lo_layers[ i ], "VALVE1_PLANE_BLEND_TF", DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT );
}
}
}
@ -1969,6 +1981,17 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
}
}
if ( drm_supports_color_mgmt( &g_DRM ) )
{
drm->pending.output_tf = g_bOutputHDREnabled
? DRM_VALVE1_TRANSFER_FUNCTION_PQ
: DRM_VALVE1_TRANSFER_FUNCTION_SRGB;
}
else
{
drm->pending.output_tf = DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT;
}
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
// We do internal refcounting with these events
@ -2059,6 +2082,12 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
if (ret < 0)
return ret;
}
if (crtc->has_valve1_regamma_tf)
{
int ret = add_crtc_property(drm->req, crtc, "VALVE1_CRTC_REGAMMA_TF", 0);
if (ret < 0)
return ret;
}
ret = add_crtc_property(drm->req, crtc, "ACTIVE", 0);
if (ret < 0)
@ -2106,6 +2135,13 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
return ret;
}
if (drm->crtc->has_valve1_regamma_tf)
{
ret = add_crtc_property(drm->req, drm->crtc, "VALVE1_CRTC_REGAMMA_TF", drm->pending.output_tf);
if (ret < 0)
return ret;
}
ret = add_crtc_property(drm->req, drm->crtc, "ACTIVE", 1);
if (ret < 0)
return ret;
@ -2142,6 +2178,13 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
if (ret < 0)
return ret;
}
if ( drm->crtc->has_valve1_regamma_tf && drm->pending.output_tf != drm->current.output_tf )
{
int ret = add_crtc_property(drm->req, drm->crtc, "VALVE1_CRTC_REGAMMA_TF", drm->pending.output_tf );
if (ret < 0)
return ret;
}
}
}

View file

@ -108,6 +108,7 @@ struct crtc {
bool has_degamma_lut;
bool has_ctm;
bool has_vrr_enabled;
bool has_valve1_regamma_tf;
uint32_t lut3d_size;
uint32_t shaperlut_size;
@ -221,6 +222,7 @@ struct drm_t {
uint32_t shaperlut_id[ ColorHelpers_EOTFCount ];
enum drm_screen_type screen_type = DRM_SCREEN_TYPE_INTERNAL;
bool vrr_enabled = false;
drm_valve1_transfer_function output_tf = DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT;
} current, pending;
bool wants_vrr_enabled = false;