From 12d5a304b5e0f593ac2390bdc3113ac1add23cbf Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Tue, 15 Feb 2022 16:47:58 -0600 Subject: [PATCH] Improved performance of UNORM_SRGB pixel retrieval by switching to a pre-computed lookup table Signed-off-by: Chris Galvan --- .../RPI/Code/Source/RPI.Public/RPIUtils.cpp | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/RPIUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/RPIUtils.cpp index 5683a3effa..b2d1663857 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/RPIUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/RPIUtils.cpp @@ -15,6 +15,7 @@ #include #include +#include #include namespace AZ @@ -106,6 +107,30 @@ namespace AZ return ((value - origMin) / (origMax - origMin)) * (scaledMax - scaledMin) + scaledMin; } + // Pre-compute a lookup table for converting SRGB gamma to linear + // by specifying the AZ::u8 so we don't have to do the computation + // when retrieving pixels + using ConversionLookupTable = AZStd::array; + ConversionLookupTable CreateSrgbGammaToLinearLookupTable() + { + ConversionLookupTable lookupTable; + + for (size_t i = 0; i < lookupTable.array_size; ++i) + { + float srgbValue = i / static_cast(std::numeric_limits::max()); + lookupTable[i] = AZ::Color::ConvertSrgbGammaToLinear(srgbValue); + } + + return lookupTable; + } + + static ConversionLookupTable s_SrgbGammaToLinearLookupTable = CreateSrgbGammaToLinearLookupTable(); + + float ConvertSrgbGammaToLinearUint(AZ::u8 x) + { + return s_SrgbGammaToLinearLookupTable[x]; + } + float RetrieveFloatValue(const AZ::u8* mem, size_t index, AZ::RHI::Format format) { switch (format) @@ -123,8 +148,9 @@ namespace AZ case AZ::RHI::Format::R8G8B8A8_UNORM_SRGB: case AZ::RHI::Format::A8B8G8R8_UNORM_SRGB: { - float srgbValue = mem[index] / static_cast(std::numeric_limits::max()); - return AZ::Color::ConvertSrgbGammaToLinear(srgbValue); + // Use a variant of ConvertSrgbGammaToLinear that takes an AZ::u8 + // and a lookup table instead of a float for better performance + return ConvertSrgbGammaToLinearUint(mem[index]); } case AZ::RHI::Format::R8_SNORM: case AZ::RHI::Format::R8G8_SNORM: