drm: Hook up Colorspace and HDR_OUTPUT_METADATA
This commit is contained in:
parent
b5bb169889
commit
70b74e73be
3 changed files with 106 additions and 15 deletions
78
src/drm.cpp
78
src/drm.cpp
|
@ -350,23 +350,25 @@ drm_hdr_parse_edid(drm_t *drm, struct connector *connector, drmModePropertyBlobR
|
|||
}
|
||||
}
|
||||
|
||||
struct hdr_metadata_infoframe *infoframe = &metadata->defaultHdrMetadata.hdmi_metadata_type1;
|
||||
|
||||
if (chroma) {
|
||||
metadata->defaultHdrMetadata.display_primaries[0].x = color_xy_to_u16(chroma->red_x);
|
||||
metadata->defaultHdrMetadata.display_primaries[0].y = color_xy_to_u16(chroma->red_y);
|
||||
metadata->defaultHdrMetadata.display_primaries[1].x = color_xy_to_u16(chroma->green_x);
|
||||
metadata->defaultHdrMetadata.display_primaries[1].y = color_xy_to_u16(chroma->green_y);
|
||||
metadata->defaultHdrMetadata.display_primaries[2].x = color_xy_to_u16(chroma->blue_x);
|
||||
metadata->defaultHdrMetadata.display_primaries[2].y = color_xy_to_u16(chroma->blue_y);
|
||||
metadata->defaultHdrMetadata.white_point.x = color_xy_to_u16(chroma->white_x);
|
||||
metadata->defaultHdrMetadata.white_point.y = color_xy_to_u16(chroma->white_y);
|
||||
infoframe->display_primaries[0].x = color_xy_to_u16(chroma->red_x);
|
||||
infoframe->display_primaries[0].y = color_xy_to_u16(chroma->red_y);
|
||||
infoframe->display_primaries[1].x = color_xy_to_u16(chroma->green_x);
|
||||
infoframe->display_primaries[1].y = color_xy_to_u16(chroma->green_y);
|
||||
infoframe->display_primaries[2].x = color_xy_to_u16(chroma->blue_x);
|
||||
infoframe->display_primaries[2].y = color_xy_to_u16(chroma->blue_y);
|
||||
infoframe->white_point.x = color_xy_to_u16(chroma->white_x);
|
||||
infoframe->white_point.y = color_xy_to_u16(chroma->white_y);
|
||||
}
|
||||
|
||||
if (hdr_static_metadata) {
|
||||
metadata->defaultHdrMetadata.max_display_mastering_luminance = nits_to_u16(hdr_static_metadata->desired_content_max_luminance);
|
||||
metadata->defaultHdrMetadata.min_display_mastering_luminance = nits_to_u16_dark(hdr_static_metadata->desired_content_min_luminance);
|
||||
infoframe->max_display_mastering_luminance = nits_to_u16(hdr_static_metadata->desired_content_max_luminance);
|
||||
infoframe->min_display_mastering_luminance = nits_to_u16_dark(hdr_static_metadata->desired_content_min_luminance);
|
||||
/* To be filled in by the app based on the scene, default to desired_content_max_luminance. */
|
||||
metadata->defaultHdrMetadata.max_cll = nits_to_u16(hdr_static_metadata->desired_content_max_luminance);
|
||||
metadata->defaultHdrMetadata.max_fall = nits_to_u16(hdr_static_metadata->desired_content_max_frame_avg_luminance);
|
||||
infoframe->max_cll = nits_to_u16(hdr_static_metadata->desired_content_max_luminance);
|
||||
infoframe->max_fall = nits_to_u16(hdr_static_metadata->desired_content_max_frame_avg_luminance);
|
||||
}
|
||||
|
||||
metadata->supportsST2084 =
|
||||
|
@ -374,6 +376,22 @@ drm_hdr_parse_edid(drm_t *drm, struct connector *connector, drmModePropertyBlobR
|
|||
colorimetry && colorimetry->bt2020_rgb &&
|
||||
hdr_static_metadata && hdr_static_metadata->eotfs && hdr_static_metadata->eotfs->pq;
|
||||
|
||||
if (metadata->supportsST2084) {
|
||||
metadata->defaultHdrMetadata.metadata_type = 0;
|
||||
infoframe->metadata_type = 0;
|
||||
infoframe->eotf = HDMI_EOTF_ST2084;
|
||||
|
||||
int ret = drmModeCreatePropertyBlob(drm->fd,
|
||||
&metadata->defaultHdrMetadata,
|
||||
sizeof(metadata->defaultHdrMetadata),
|
||||
&metadata->hdr10_metadata_blob);
|
||||
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "Failed to create blob for HDR_OUTPUT_METADATA. (%s) Falling back to null blob.\n", strerror(-ret));
|
||||
metadata->hdr10_metadata_blob = 0;
|
||||
}
|
||||
}
|
||||
|
||||
di_info_destroy(info);
|
||||
}
|
||||
|
||||
|
@ -486,6 +504,8 @@ static bool refresh_state( drm_t *drm )
|
|||
|
||||
free(conn->name);
|
||||
conn->name = nullptr;
|
||||
drmModeDestroyPropertyBlob(drm->fd, conn->metadata.hdr10_metadata_blob);
|
||||
conn->metadata.hdr10_metadata_blob = 0;
|
||||
drmModeFreeConnector(conn->connector);
|
||||
it = drm->connectors.erase(it);
|
||||
} else {
|
||||
|
@ -498,8 +518,11 @@ static bool refresh_state( drm_t *drm )
|
|||
// Re-probe connectors props and status
|
||||
for (auto &kv : drm->connectors) {
|
||||
struct connector *conn = &kv.second;
|
||||
if (conn->connector != nullptr)
|
||||
if (conn->connector != nullptr) {
|
||||
drmModeDestroyPropertyBlob(drm->fd, conn->metadata.hdr10_metadata_blob);
|
||||
conn->metadata.hdr10_metadata_blob = 0;
|
||||
drmModeFreeConnector(conn->connector);
|
||||
}
|
||||
|
||||
conn->connector = drmModeGetConnector(drm->fd, conn->id);
|
||||
if (conn->connector == nullptr) {
|
||||
|
@ -533,6 +556,8 @@ static bool refresh_state( drm_t *drm )
|
|||
drm_log.errorf_errno("drmModeConnectorGetPossibleCrtcs failed");
|
||||
|
||||
conn->current.crtc_id = conn->initial_prop_values["CRTC_ID"];
|
||||
conn->current.colorspace = conn->initial_prop_values["Colorspace"];
|
||||
conn->current.hdr_output_metadata = conn->initial_prop_values["HDR_OUTPUT_METADATA"];
|
||||
|
||||
conn->target_refresh = 0;
|
||||
|
||||
|
@ -1012,6 +1037,8 @@ void finish_drm(struct drm_t *drm)
|
|||
for ( auto &kv : drm->connectors ) {
|
||||
struct connector *conn = &kv.second;
|
||||
add_connector_property(req, conn, "CRTC_ID", 0);
|
||||
add_connector_property(req, conn, "Colorspace", 0);
|
||||
add_connector_property(req, conn, "HDR_OUTPUT_METADATA", 0);
|
||||
}
|
||||
for ( size_t i = 0; i < drm->crtcs.size(); i++ ) {
|
||||
add_crtc_property(req, &drm->crtcs[i], "MODE_ID", 0);
|
||||
|
@ -1752,6 +1779,14 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
int ret = add_connector_property( drm->req, conn, "CRTC_ID", 0 );
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = add_connector_property( drm->req, conn, "Colorspace", 0 );
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = add_connector_property( drm->req, conn, "HDR_OUTPUT_METADATA", 0 );
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
for ( size_t i = 0; i < drm->crtcs.size(); i++ ) {
|
||||
struct crtc *crtc = &drm->crtcs[i];
|
||||
|
@ -1805,6 +1840,16 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm->connector->pending.colorspace = g_bOutputHDREnabled ? DRM_MODE_COLORIMETRY_BT2020_RGB : DRM_MODE_COLORIMETRY_DEFAULT;
|
||||
ret = add_connector_property(drm->req, drm->connector, "Colorspace", drm->connector->pending.colorspace);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm->connector->pending.hdr_output_metadata = g_bOutputHDREnabled ? drm->connector->metadata.hdr10_metadata_blob : 0;
|
||||
ret = add_connector_property(drm->req, drm->connector, "HDR_OUTPUT_METADATA", drm->connector->pending.hdr_output_metadata);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = add_crtc_property(drm->req, drm->crtc, "MODE_ID", drm->pending.mode_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -2487,6 +2532,13 @@ bool drm_supports_st2084(struct drm_t *drm)
|
|||
return false;
|
||||
}
|
||||
|
||||
void drm_set_hdr_state(struct drm_t *drm, bool enabled) {
|
||||
if (drm->enable_hdr != enabled) {
|
||||
drm->needs_modeset = true;
|
||||
drm->enable_hdr = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
const char *drm_get_connector_name(struct drm_t *drm)
|
||||
{
|
||||
if ( !drm->connector )
|
||||
|
|
38
src/drm.hpp
38
src/drm.hpp
|
@ -78,8 +78,9 @@ struct crtc {
|
|||
};
|
||||
|
||||
struct connector_metadata_t {
|
||||
struct hdr_metadata_infoframe defaultHdrMetadata;
|
||||
bool supportsST2084;
|
||||
struct hdr_output_metadata defaultHdrMetadata = {};
|
||||
uint32_t hdr10_metadata_blob = 0;
|
||||
bool supportsST2084 = false;
|
||||
};
|
||||
|
||||
struct connector {
|
||||
|
@ -101,6 +102,8 @@ struct connector {
|
|||
|
||||
struct {
|
||||
uint32_t crtc_id;
|
||||
uint32_t colorspace;
|
||||
uint32_t hdr_output_metadata;
|
||||
} current, pending;
|
||||
};
|
||||
|
||||
|
@ -201,6 +204,7 @@ struct drm_t {
|
|||
std::unordered_map< std::string, int > connector_priorities;
|
||||
|
||||
bool force_internal = false;
|
||||
bool enable_hdr = false;
|
||||
|
||||
char *device_name = nullptr;
|
||||
};
|
||||
|
@ -271,5 +275,35 @@ const char *drm_get_connector_name(struct drm_t *drm);
|
|||
const char *drm_get_device_name(struct drm_t *drm);
|
||||
|
||||
std::pair<uint32_t, uint32_t> drm_get_connector_identifier(struct drm_t *drm);
|
||||
void drm_set_hdr_state(struct drm_t *drm, bool enabled);
|
||||
|
||||
extern bool g_bSupportsAsyncFlips;
|
||||
|
||||
/* from CTA-861-G */
|
||||
#define HDMI_EOTF_SDR 0
|
||||
#define HDMI_EOTF_TRADITIONAL_HDR 1
|
||||
#define HDMI_EOTF_ST2084 2
|
||||
#define HDMI_EOTF_HLG 3
|
||||
|
||||
/* For Default case, driver will set the colorspace */
|
||||
#define DRM_MODE_COLORIMETRY_DEFAULT 0
|
||||
/* CEA 861 Normal Colorimetry options */
|
||||
#define DRM_MODE_COLORIMETRY_NO_DATA 0
|
||||
#define DRM_MODE_COLORIMETRY_SMPTE_170M_YCC 1
|
||||
#define DRM_MODE_COLORIMETRY_BT709_YCC 2
|
||||
/* CEA 861 Extended Colorimetry Options */
|
||||
#define DRM_MODE_COLORIMETRY_XVYCC_601 3
|
||||
#define DRM_MODE_COLORIMETRY_XVYCC_709 4
|
||||
#define DRM_MODE_COLORIMETRY_SYCC_601 5
|
||||
#define DRM_MODE_COLORIMETRY_OPYCC_601 6
|
||||
#define DRM_MODE_COLORIMETRY_OPRGB 7
|
||||
#define DRM_MODE_COLORIMETRY_BT2020_CYCC 8
|
||||
#define DRM_MODE_COLORIMETRY_BT2020_RGB 9
|
||||
#define DRM_MODE_COLORIMETRY_BT2020_YCC 10
|
||||
/* Additional Colorimetry extension added as part of CTA 861.G */
|
||||
#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65 11
|
||||
#define DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER 12
|
||||
/* Additional Colorimetry Options added for DP 1.4a VSC Colorimetry Format */
|
||||
#define DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED 13
|
||||
#define DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT 14
|
||||
#define DRM_MODE_COLORIMETRY_BT601_YCC 15
|
||||
|
|
|
@ -5797,6 +5797,11 @@ steamcompmgr_main(int argc, char **argv)
|
|||
wlserver_unlock();
|
||||
}
|
||||
|
||||
if (g_bOutputHDREnabled != currentHDROutput)
|
||||
{
|
||||
drm_set_hdr_state(&g_DRM, g_bOutputHDREnabled);
|
||||
}
|
||||
|
||||
vulkan_remake_output_images();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue