color_helpers, steamcompmgr: Avoid allocation of LUTs every time we re-setup color mgmt

This commit is contained in:
Joshua Ashton 2023-05-09 15:08:27 +00:00 committed by Joshie
parent 36c120901a
commit f9e47a612f
4 changed files with 89 additions and 96 deletions

View file

@ -611,7 +611,7 @@ void calcColorTransform( uint16_t * pRgbxData1d, int nLutSize1d,
destColorLinear = glm::mix( destColorLinear, sourceColorLinear, amount );
// Apply night mode
destColorLinear = vNightModeMultLinear * destColorLinear * glm::vec3( flGain );
destColorLinear = vNightModeMultLinear * destColorLinear * flGain;
// Apply dest EOTF
glm::vec3 destColorEOTFEncoded = calcLinearToEOTF( destColorLinear, destEOTF, tonemapping );

View file

@ -2590,18 +2590,18 @@ bool drm_update_color_mgmt(struct drm_t *drm)
for ( uint32_t i = 0; i < EOTF_Count; i++ )
{
if ( g_ColorMgmtLuts[i].lut1d.empty() || g_ColorMgmtLuts[i].lut3d.empty() )
if ( !g_ColorMgmtLuts[i].HasLuts() )
continue;
uint32_t shaper_blob_id = 0;
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut1d.data(), sizeof(uint16_t) * g_ColorMgmtLuts[i].lut1d.size(), &shaper_blob_id) != 0) {
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut1d, sizeof(g_ColorMgmtLuts[i].lut1d), &shaper_blob_id) != 0) {
drm_log.errorf_errno("Unable to create SHAPERLUT property blob");
return false;
}
drm->pending.shaperlut_id[ i ] = shaper_blob_id;
uint32_t lut3d_blob_id = 0;
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut3d.data(), sizeof(uint16_t) * g_ColorMgmtLuts[i].lut3d.size(), &lut3d_blob_id) != 0) {
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut3d, sizeof(g_ColorMgmtLuts[i].lut3d), &lut3d_blob_id) != 0) {
drm_log.errorf_errno("Unable to create LUT3D property blob");
return false;
}

View file

@ -379,18 +379,28 @@ struct gamescope_color_mgmt_t
bool operator != (const gamescope_color_mgmt_t&) const = default;
};
static constexpr uint32_t nLutEdgeSize3d = 17;
static constexpr uint32_t nLutSize1d = 4096;
struct gamescope_color_mgmt_luts
{
std::vector<uint16_t> lut3d;
std::vector<uint16_t> lut1d;
bool bHasLut3D = false;
bool bHasLut1D = false;
uint16_t lut3d[nLutEdgeSize3d*nLutEdgeSize3d*nLutEdgeSize3d*4];
uint16_t lut1d[nLutSize1d*4];
std::shared_ptr<CVulkanTexture> vk_lut3d;
std::shared_ptr<CVulkanTexture> vk_lut1d;
bool HasLuts() const
{
return bHasLut3D && bHasLut1D;
}
void reset()
{
lut3d.clear();
lut1d.clear();
bHasLut1D = false;
bHasLut3D = false;
}
};

View file

@ -164,20 +164,19 @@ update_color_mgmt()
for ( uint32_t nInputEOTF = 0; nInputEOTF < EOTF_Count; nInputEOTF++ )
{
std::vector<uint16_t> lut3d;
uint32_t nLutEdgeSize3d = 17;
lut3d.resize( nLutEdgeSize3d*nLutEdgeSize3d*nLutEdgeSize3d*4 );
std::vector<uint16_t> lut1d;
uint32_t nLutSize1d = 4096;
lut1d.resize( nLutSize1d*4 );
if (!g_ColorMgmtLuts[nInputEOTF].vk_lut1d)
g_ColorMgmtLuts[nInputEOTF].vk_lut1d = vulkan_create_1d_lut(4096);
g_ColorMgmtLuts[nInputEOTF].vk_lut1d = vulkan_create_1d_lut(nLutSize1d);
if (!g_ColorMgmtLuts[nInputEOTF].vk_lut3d)
g_ColorMgmtLuts[nInputEOTF].vk_lut3d = vulkan_create_3d_lut(17, 17, 17);
g_ColorMgmtLuts[nInputEOTF].vk_lut3d = vulkan_create_3d_lut(nLutEdgeSize3d, nLutEdgeSize3d, nLutEdgeSize3d);
if ( g_ColorMgmtLutsOverride[nInputEOTF].HasLuts() )
{
memcpy(g_ColorMgmtLuts[nInputEOTF].lut1d, g_ColorMgmtLutsOverride[nInputEOTF].lut1d, sizeof(g_ColorMgmtLutsOverride[nInputEOTF].lut1d));
memcpy(g_ColorMgmtLuts[nInputEOTF].lut3d, g_ColorMgmtLutsOverride[nInputEOTF].lut3d, sizeof(g_ColorMgmtLutsOverride[nInputEOTF].lut3d));
}
else
{
displaycolorimetry_t inputColorimetry{};
colormapping_t colorMapping{};
@ -228,28 +227,15 @@ update_color_mgmt()
buildPQColorimetry( &inputColorimetry, &colorMapping, displayColorimetry );
}
calcColorTransform( &lut1d[0], nLutSize1d, &lut3d[0], nLutEdgeSize3d, inputColorimetry, inputEOTF,
calcColorTransform( g_ColorMgmtLuts[nInputEOTF].lut1d, nLutSize1d, g_ColorMgmtLuts[nInputEOTF].lut3d, nLutEdgeSize3d, inputColorimetry, inputEOTF,
outputEncodingColorimetry, g_ColorMgmt.pending.outputEncodingEOTF,
colorMapping, g_ColorMgmt.pending.nightmode, tonemapping, pLook, flGain );
if ( !g_ColorMgmtLutsOverride[nInputEOTF].lut3d.empty() && !g_ColorMgmtLutsOverride[nInputEOTF].lut1d.empty() )
{
g_ColorMgmtLuts[nInputEOTF].lut1d = g_ColorMgmtLutsOverride[nInputEOTF].lut1d;
g_ColorMgmtLuts[nInputEOTF].lut3d = g_ColorMgmtLutsOverride[nInputEOTF].lut3d;
}
else if ( !lut3d.empty() && !lut1d.empty() )
{
g_ColorMgmtLuts[nInputEOTF].lut3d = std::move(lut3d);
g_ColorMgmtLuts[nInputEOTF].lut1d = std::move(lut1d);
}
else
{
g_ColorMgmtLuts[nInputEOTF].reset();
}
if (!g_ColorMgmtLuts[nInputEOTF].lut3d.empty() && !g_ColorMgmtLuts[nInputEOTF].lut1d.empty())
vulkan_update_luts(g_ColorMgmtLuts[nInputEOTF].vk_lut1d, g_ColorMgmtLuts[nInputEOTF].vk_lut3d, g_ColorMgmtLuts[nInputEOTF].lut1d.data(), g_ColorMgmtLuts[nInputEOTF].lut3d.data());
g_ColorMgmtLuts[nInputEOTF].bHasLut1D = true;
g_ColorMgmtLuts[nInputEOTF].bHasLut3D = true;
vulkan_update_luts(g_ColorMgmtLuts[nInputEOTF].vk_lut1d, g_ColorMgmtLuts[nInputEOTF].vk_lut3d, g_ColorMgmtLuts[nInputEOTF].lut1d, g_ColorMgmtLuts[nInputEOTF].lut3d);
}
}
else
@ -378,8 +364,8 @@ bool set_color_mgmt_enabled( bool bEnabled )
bool set_color_3dlut_override(const char *path)
{
int nLutIndex = EOTF_Gamma22;
g_ColorMgmtLutsOverride[nLutIndex].lut3d.clear();
g_ColorMgmt.pending.externalDirtyCtr++;
g_ColorMgmtLutsOverride[nLutIndex].bHasLut3D = false;
FILE *f = fopen(path, "rb");
if (!f) {
@ -396,10 +382,8 @@ bool set_color_3dlut_override(const char *path)
return true;
}
auto data = std::vector<uint16_t>(elems);
fread(data.data(), elems, sizeof(uint16_t), f);
g_ColorMgmtLutsOverride[nLutIndex].lut3d = std::move(data);
fread(g_ColorMgmtLutsOverride[nLutIndex].lut3d, elems, sizeof(uint16_t), f);
g_ColorMgmtLutsOverride[nLutIndex].bHasLut3D = true;
return true;
}
@ -407,8 +391,8 @@ bool set_color_3dlut_override(const char *path)
bool set_color_shaperlut_override(const char *path)
{
int nLutIndex = EOTF_Gamma22;
g_ColorMgmtLutsOverride[nLutIndex].lut1d.clear();
g_ColorMgmt.pending.externalDirtyCtr++;
g_ColorMgmtLutsOverride[nLutIndex].bHasLut1D = false;
FILE *f = fopen(path, "rb");
if (!f) {
@ -425,10 +409,8 @@ bool set_color_shaperlut_override(const char *path)
return true;
}
auto data = std::vector<uint16_t>(elems);
fread(data.data(), elems, sizeof(uint16_t), f);
g_ColorMgmtLutsOverride[nLutIndex].lut1d = std::move(data);
fread(g_ColorMgmtLutsOverride[nLutIndex].lut1d, elems, sizeof(uint16_t), f);
g_ColorMgmtLutsOverride[nLutIndex].bHasLut1D = true;
return true;
}
@ -2360,11 +2342,12 @@ paint_all(bool async)
for (uint32_t i = 0; i < EOTF_Count; i++)
{
if (!g_ColorMgmtLuts[i].lut1d.empty())
if (g_ColorMgmtLuts[i].HasLuts())
{
frameInfo.shaperLut[i] = g_ColorMgmtLuts[i].vk_lut1d;
if (!g_ColorMgmtLuts[i].lut3d.empty())
frameInfo.lut3D[i] = g_ColorMgmtLuts[i].vk_lut3d;
}
}
if ( !BIsNested() && g_bOutputHDREnabled )
{