rendervulkan, drm: Apply 709 -> 2020 CTM for scRGB

Get this in the right space!
This commit is contained in:
Joshua Ashton 2023-10-25 04:52:27 +01:00
parent 06532b071c
commit d6f2ecdf62
3 changed files with 32 additions and 0 deletions

View file

@ -891,3 +891,11 @@ bool approxEqual( const glm::vec3 & a, const glm::vec3 & b, float flTolerance =
glm::vec3 v = glm::abs(a - b);
return ( v.x < flTolerance && v.y < flTolerance && v.z < flTolerance );
}
const glm::mat3 k_xyz_from_709 = normalised_primary_matrix( displaycolorimetry_709.primaries, displaycolorimetry_709.white, 1.f );
const glm::mat3 k_709_from_xyz = glm::inverse( k_xyz_from_709 );
const glm::mat3 k_xyz_from_2020 = normalised_primary_matrix( displaycolorimetry_2020.primaries, displaycolorimetry_2020.white, 1.f );
const glm::mat3 k_2020_from_xyz = glm::inverse( k_xyz_from_2020 );
const glm::mat3 k_2020_from_709 = k_2020_from_xyz * k_xyz_from_709;

View file

@ -472,3 +472,12 @@ static constexpr displaycolorimetry_t displaycolorimetry_2020
.primaries = { { 0.708f, 0.292f }, { 0.170f, 0.797f }, { 0.131f, 0.046f } },
.white = { 0.3127f, 0.3290f }, // D65
};
extern const glm::mat3 k_xyz_from_709;
extern const glm::mat3 k_709_from_xyz;
extern const glm::mat3 k_xyz_from_2020;
extern const glm::mat3 k_2020_from_xyz;
extern const glm::mat3 k_2020_from_709;

View file

@ -130,6 +130,7 @@ extern float g_flHDRItmTargetNits;
extern std::atomic<uint64_t> g_lastVblank;
static std::shared_ptr<wlserver_ctm> s_scRGB709To2020Matrix;
std::string clipboard;
std::string primarySelection;
@ -1944,6 +1945,7 @@ void MouseCursor::paint(steamcompmgr_win_t *window, steamcompmgr_win_t *fit, str
layer->filter = cursor_scale != 1.0f ? GamescopeUpscaleFilter::LINEAR : GamescopeUpscaleFilter::NEAREST;
layer->blackBorder = false;
layer->ctm = nullptr;
layer->colorspace = GAMESCOPE_APP_TEXTURE_COLORSPACE_SRGB;
}
@ -1991,6 +1993,9 @@ paint_cached_base_layer(const std::shared_ptr<commit_t>& commit, const BaseLayer
layer->opacity = base.opacity * flOpacityScale;
layer->colorspace = commit->colorspace();
layer->ctm = nullptr;
if (layer->colorspace == GAMESCOPE_APP_TEXTURE_COLORSPACE_SCRGB)
layer->ctm = s_scRGB709To2020Matrix;
layer->tex = commit->vulkanTex;
layer->fbid = commit->fb_id;
@ -2195,6 +2200,9 @@ paint_window(steamcompmgr_win_t *w, steamcompmgr_win_t *scaleW, struct FrameInfo
layer->filter = (w->isOverlay || w->isExternalOverlay) ? GamescopeUpscaleFilter::LINEAR : g_upscaleFilter;
layer->colorspace = lastCommit->colorspace();
layer->ctm = nullptr;
if (layer->colorspace == GAMESCOPE_APP_TEXTURE_COLORSPACE_SCRGB)
layer->ctm = s_scRGB709To2020Matrix;
if (layer->filter == GamescopeUpscaleFilter::PIXEL)
{
@ -2675,6 +2683,7 @@ paint_all(bool async)
baseLayer->applyColorMgmt = false;
baseLayer->filter = GamescopeUpscaleFilter::NEAREST;
baseLayer->ctm = nullptr;
baseLayer->colorspace = g_bOutputHDREnabled ? GAMESCOPE_APP_TEXTURE_COLORSPACE_HDR10_PQ : GAMESCOPE_APP_TEXTURE_COLORSPACE_SRGB;
g_bWasPartialComposite = false;
@ -2702,6 +2711,7 @@ paint_all(bool async)
overlayLayer->filter = GamescopeUpscaleFilter::NEAREST;
// Partial composition stuff has the same colorspace.
// So read that from the composite frame info
overlayLayer->ctm = nullptr;
overlayLayer->colorspace = compositeFrameInfo.layers[0].colorspace;
}
else
@ -7465,6 +7475,11 @@ steamcompmgr_main(int argc, char **argv)
update_screenshot_color_mgmt();
// Transpose to get this 3x3 matrix into the right state for applying as a 3x4
// on DRM + the Vulkan side.
// ie. color.rgb = color.rgba * u_ctm[offsetLayerIdx];
s_scRGB709To2020Matrix = drm_create_ctm(&g_DRM, glm::mat3x4(glm::transpose(k_2020_from_709)));
for (;;)
{
bool vblank = false;