Optimize sRGB8 lookups by using lut.
authorMika Isojärvi <misojarvi@google.com>
Thu, 30 Apr 2015 22:15:36 +0000 (15:15 -0700)
committerMika Isojärvi <misojarvi@google.com>
Mon, 14 Sep 2015 21:49:25 +0000 (14:49 -0700)
Change-Id: I8e77ed3d6572130658b67f8b1dcccad68583d2e6

Android.mk
framework/common/tcuSRGB8Lut.inl [new file with mode: 0644]
framework/common/tcuTexture.cpp
framework/common/tcuTextureUtil.cpp
framework/common/tcuTextureUtil.hpp
modules/internal/CMakeLists.txt
modules/internal/ditSRGB8ConversionTest.cpp [new file with mode: 0644]
modules/internal/ditSRGB8ConversionTest.hpp [new file with mode: 0644]
modules/internal/ditTestPackage.cpp

index 68fe0bd..be05333 100644 (file)
@@ -659,6 +659,7 @@ LOCAL_SRC_FILES := \
        modules/glshared/glsUniformBlockCase.cpp \
        modules/glshared/glsVertexArrayTests.cpp \
        modules/internal/ditBuildInfoTests.cpp \
+       modules/internal/ditSRGB8ConversionTest.cpp \
        modules/internal/ditDelibsTests.cpp \
        modules/internal/ditFrameworkTests.cpp \
        modules/internal/ditImageCompareTests.cpp \
diff --git a/framework/common/tcuSRGB8Lut.inl b/framework/common/tcuSRGB8Lut.inl
new file mode 100644 (file)
index 0000000..f38a499
--- /dev/null
@@ -0,0 +1,257 @@
+       // Generated on x86_64 linux
+       0x0u,
+       0x399f22b4u,
+       0x3a1f22b4u,
+       0x3a6eb40eu,
+       0x3a9f22b4u,
+       0x3ac6eb61u,
+       0x3aeeb40eu,
+       0x3b0b3e5du,
+       0x3b1f22b4u,
+       0x3b33070bu,
+       0x3b46eb61u,
+       0x3b5b518du,
+       0x3b70f18du,
+       0x3b83e1c6u,
+       0x3b8fe616u,
+       0x3b9c87fdu,
+       0x3ba9c9b6u,
+       0x3bb7ad6fu,
+       0x3bc63549u,
+       0x3bd56361u,
+       0x3be539c1u,
+       0x3bf5ba70u,
+       0x3c0373b5u,
+       0x3c0c6152u,
+       0x3c15a703u,
+       0x3c1f45beu,
+       0x3c293e6bu,
+       0x3c3391f7u,
+       0x3c3e4149u,
+       0x3c494d43u,
+       0x3c54b6c7u,
+       0x3c607eb1u,
+       0x3c6ca5dfu,
+       0x3c792d22u,
+       0x3c830aa8u,
+       0x3c89af9eu,
+       0x3c9085dbu,
+       0x3c978dc5u,
+       0x3c9ec7c2u,
+       0x3ca63434u,
+       0x3cadd37du,
+       0x3cb5a601u,
+       0x3cbdac20u,
+       0x3cc5e639u,
+       0x3cce54abu,
+       0x3cd6f7d5u,
+       0x3cdfd010u,
+       0x3ce8ddb9u,
+       0x3cf2212cu,
+       0x3cfb9ac1u,
+       0x3d02a569u,
+       0x3d0798dcu,
+       0x3d0ca7e6u,
+       0x3d11d2afu,
+       0x3d171963u,
+       0x3d1c7c2eu,
+       0x3d21fb3cu,
+       0x3d2796b2u,
+       0x3d2d4ebbu,
+       0x3d332380u,
+       0x3d39152bu,
+       0x3d3f23e3u,
+       0x3d454fd0u,
+       0x3d4b991cu,
+       0x3d51ffeeu,
+       0x3d58846au,
+       0x3d5f26b7u,
+       0x3d65e6feu,
+       0x3d6cc564u,
+       0x3d73c210u,
+       0x3d7add29u,
+       0x3d810b67u,
+       0x3d84b795u,
+       0x3d887330u,
+       0x3d8c3e4au,
+       0x3d9018f6u,
+       0x3d940345u,
+       0x3d97fd4au,
+       0x3d9c0716u,
+       0x3da020bbu,
+       0x3da44a4bu,
+       0x3da883d6u,
+       0x3daccd70u,
+       0x3db12728u,
+       0x3db59112u,
+       0x3dba0b3au,
+       0x3dbe95b5u,
+       0x3dc33092u,
+       0x3dc7dbe2u,
+       0x3dcc97b6u,
+       0x3dd1641fu,
+       0x3dd6412cu,
+       0x3ddb2eefu,
+       0x3de02d77u,
+       0x3de53cd5u,
+       0x3dea5d19u,
+       0x3def8e52u,
+       0x3df4d091u,
+       0x3dfa23e8u,
+       0x3dff8861u,
+       0x3e027f07u,
+       0x3e054280u,
+       0x3e080ea3u,
+       0x3e0ae378u,
+       0x3e0dc105u,
+       0x3e10a754u,
+       0x3e13966bu,
+       0x3e168e52u,
+       0x3e198f10u,
+       0x3e1c98adu,
+       0x3e1fab30u,
+       0x3e22c6a3u,
+       0x3e25eb09u,
+       0x3e29186cu,
+       0x3e2c4ed0u,
+       0x3e2f8e42u,
+       0x3e32d6c4u,
+       0x3e362861u,
+       0x3e39831eu,
+       0x3e3ce702u,
+       0x3e405416u,
+       0x3e43ca5eu,
+       0x3e4749e4u,
+       0x3e4ad2aeu,
+       0x3e4e64c2u,
+       0x3e520027u,
+       0x3e55a4e6u,
+       0x3e595303u,
+       0x3e5d0a8au,
+       0x3e60cb7cu,
+       0x3e6495e0u,
+       0x3e6869bfu,
+       0x3e6c4720u,
+       0x3e702e0cu,
+       0x3e741e84u,
+       0x3e781890u,
+       0x3e7c1c38u,
+       0x3e8014c2u,
+       0x3e82203bu,
+       0x3e84308du,
+       0x3e8645bau,
+       0x3e885fc5u,
+       0x3e8a7eb2u,
+       0x3e8ca283u,
+       0x3e8ecb3cu,
+       0x3e90f8e1u,
+       0x3e932b74u,
+       0x3e9562f8u,
+       0x3e979f71u,
+       0x3e99e0e2u,
+       0x3e9c274eu,
+       0x3e9e72b8u,
+       0x3ea0c322u,
+       0x3ea31892u,
+       0x3ea57308u,
+       0x3ea7d28au,
+       0x3eaa3718u,
+       0x3eaca0b7u,
+       0x3eaf0f69u,
+       0x3eb18332u,
+       0x3eb3fc18u,
+       0x3eb67a18u,
+       0x3eb8fd37u,
+       0x3ebb8579u,
+       0x3ebe12e0u,
+       0x3ec0a571u,
+       0x3ec33d2du,
+       0x3ec5da17u,
+       0x3ec87c33u,
+       0x3ecb2383u,
+       0x3ecdd00bu,
+       0x3ed081ccu,
+       0x3ed338ccu,
+       0x3ed5f50au,
+       0x3ed8b68du,
+       0x3edb7d54u,
+       0x3ede4965u,
+       0x3ee11ac1u,
+       0x3ee3f16bu,
+       0x3ee6cd67u,
+       0x3ee9aeb6u,
+       0x3eec955du,
+       0x3eef815du,
+       0x3ef272bau,
+       0x3ef56976u,
+       0x3ef86594u,
+       0x3efb6717u,
+       0x3efe6e02u,
+       0x3f00bd2du,
+       0x3f02460eu,
+       0x3f03d1a7u,
+       0x3f055ff9u,
+       0x3f06f106u,
+       0x3f0884cfu,
+       0x3f0a1b56u,
+       0x3f0bb49bu,
+       0x3f0d50a0u,
+       0x3f0eef67u,
+       0x3f1090f1u,
+       0x3f12353eu,
+       0x3f13dc51u,
+       0x3f15862bu,
+       0x3f1732cdu,
+       0x3f18e239u,
+       0x3f1a946fu,
+       0x3f1c4972u,
+       0x3f1e0141u,
+       0x3f1fbbe0u,
+       0x3f21794eu,
+       0x3f23398eu,
+       0x3f24fca0u,
+       0x3f26c286u,
+       0x3f288b42u,
+       0x3f2a56d3u,
+       0x3f2c253du,
+       0x3f2df680u,
+       0x3f2fca9fu,
+       0x3f31a197u,
+       0x3f337b6cu,
+       0x3f355820u,
+       0x3f3737b2u,
+       0x3f391a26u,
+       0x3f3aff7cu,
+       0x3f3ce7b4u,
+       0x3f3ed2d2u,
+       0x3f40c0d4u,
+       0x3f42b1beu,
+       0x3f44a590u,
+       0x3f469c4bu,
+       0x3f4895f0u,
+       0x3f4a9282u,
+       0x3f4c9201u,
+       0x3f4e946eu,
+       0x3f5099cau,
+       0x3f52a218u,
+       0x3f54ad57u,
+       0x3f56bb8au,
+       0x3f58ccb0u,
+       0x3f5ae0cdu,
+       0x3f5cf7e0u,
+       0x3f5f11ecu,
+       0x3f612eeeu,
+       0x3f634eefu,
+       0x3f6571eau,
+       0x3f6797e3u,
+       0x3f69c0d6u,
+       0x3f6beccdu,
+       0x3f6e1bc0u,
+       0x3f704db8u,
+       0x3f7282afu,
+       0x3f74baaeu,
+       0x3f76f5aeu,
+       0x3f7933b8u,
+       0x3f7b74c6u,
+       0x3f7db8e0u,
+       0x3f800000u
index 43c7616..a41d9c6 100644 (file)
@@ -1187,8 +1187,21 @@ static bool isFixedPointDepthTextureFormat (const tcu::TextureFormat& format)
 // Texel lookup with color conversion.
 static inline Vec4 lookup (const ConstPixelBufferAccess& access, int i, int j, int k)
 {
-       Vec4 p = access.getPixel(i, j, k);
-       return isSRGB(access.getFormat()) ? sRGBToLinear(p) : p;
+       const TextureFormat&    format  = access.getFormat();
+
+       if (isSRGB(format))
+       {
+               if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGB)
+                               return sRGB8ToLinear(access.getPixelUint(i, j, k));
+               else if (format.type == TextureFormat::UNORM_INT8 && format.order == TextureFormat::sRGBA)
+                               return sRGBA8ToLinear(access.getPixelUint(i, j, k));
+               else
+                       return sRGBToLinear(access.getPixel(i, j, k));
+       }
+       else
+       {
+               return access.getPixel(i, j, k);
+       }
 }
 
 // Border texel lookup with color conversion.
index f11778e..5ac30de 100644 (file)
@@ -40,6 +40,19 @@ static inline float sRGBChannelToLinear (float cs)
                return deFloatPow((cs + 0.055f) / 1.055f, 2.4f);
 }
 
+static const deUint32 s_srgb8Lut[256] =
+{
+#include "tcuSRGB8Lut.inl"
+};
+
+static inline float sRGB8ChannelToLinear (deUint32 cs)
+{
+       DE_ASSERT(cs < 256);
+
+       // \note This triggers UB, but in practice it doesn't cause any problems
+       return ((const float*)s_srgb8Lut)[cs];
+}
+
 static inline float linearChannelToSRGB (float cl)
 {
        if (cl <= 0.0f)
@@ -61,6 +74,22 @@ Vec4 sRGBToLinear (const Vec4& cs)
                                cs[3]);
 }
 
+Vec4 sRGB8ToLinear (const UVec4& cs)
+{
+       return Vec4(sRGB8ChannelToLinear(cs[0]),
+                               sRGB8ChannelToLinear(cs[1]),
+                               sRGB8ChannelToLinear(cs[2]),
+                               1.0f);
+}
+
+Vec4 sRGBA8ToLinear (const UVec4& cs)
+{
+       return Vec4(sRGB8ChannelToLinear(cs[0]),
+                               sRGB8ChannelToLinear(cs[1]),
+                               sRGB8ChannelToLinear(cs[2]),
+                               (float)cs[3] / 255.0f);
+}
+
 //! Convert from linear to sRGB colorspace
 Vec4 linearToSRGB (const Vec4& cl)
 {
index b31f2d0..056a930 100644 (file)
@@ -45,6 +45,8 @@ bool                                  hasDepthComponent                       (TextureFormat::ChannelOrder order);
 
 // sRGB - linear conversion.
 Vec4                                   sRGBToLinear                            (const Vec4& cs);
+Vec4                                   sRGB8ToLinear                           (const UVec4& cs);
+Vec4                                   sRGBA8ToLinear                          (const UVec4& cs);
 Vec4                                   linearToSRGB                            (const Vec4& cl);
 bool                                   isSRGB                                          (TextureFormat format);
 
index d14a271..a8f7983 100644 (file)
@@ -19,6 +19,8 @@ set(DE_INTERNAL_TESTS_SRCS
        ditTestPackage.hpp
        ditSeedBuilderTests.hpp
        ditSeedBuilderTests.cpp
+       ditSRGB8ConversionTest.hpp
+       ditSRGB8ConversionTest.cpp
        )
 
 set(DE_INTERNAL_TESTS_LIBS
diff --git a/modules/internal/ditSRGB8ConversionTest.cpp b/modules/internal/ditSRGB8ConversionTest.cpp
new file mode 100644 (file)
index 0000000..5092e73
--- /dev/null
@@ -0,0 +1,104 @@
+/*-------------------------------------------------------------------------
+ * drawElements Internal Test Module
+ * ---------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief 8-bit sRGB conversion test.
+ *//*--------------------------------------------------------------------*/
+
+#include "ditSRGB8ConversionTest.hpp"
+
+#include "tcuFloat.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuVectorUtil.hpp"
+
+namespace dit
+{
+namespace
+{
+
+deUint32 calculateDiscreteFloatDistance (float a, float b)
+{
+       const deUint32          au              = tcu::Float32(a).bits();
+       const deUint32          bu              = tcu::Float32(b).bits();
+
+       const bool                      asign   = (au & (0x1u << 31u)) != 0u;
+       const bool                      bsign   = (bu & (0x1u << 31u)) != 0u;
+
+       const deUint32          avalue  = (au & ((0x1u << 31u) - 1u));
+       const deUint32          bvalue  = (bu & ((0x1u << 31u) - 1u));
+
+       if (asign != bsign)
+               return avalue + bvalue + 1u;
+       else if (avalue < bvalue)
+               return bvalue - avalue;
+       else
+               return avalue - bvalue;
+}
+
+const tcu::UVec4 calculateDiscreteFloatDistance (const tcu::Vec4& ref, const tcu::Vec4& res)
+{
+       return tcu::UVec4(calculateDiscreteFloatDistance(ref[0], res[0]), calculateDiscreteFloatDistance(ref[1], res[1]), calculateDiscreteFloatDistance(ref[2], res[2]), calculateDiscreteFloatDistance(ref[3], res[3]));
+}
+
+class SRGB8ConversionTest : public tcu::TestCase
+{
+public:
+       SRGB8ConversionTest (tcu::TestContext& context)
+               : tcu::TestCase (context, "srgb8", "SRGB8 conversion test")
+       {
+       }
+
+       IterateResult iterate (void)
+       {
+               bool                    isOk    = true;
+               tcu::TestLog&   log             = m_testCtx.getLog();
+
+               for (int i = 0; i < 256; i++)
+               {
+                       const tcu::UVec4        src                                     (i);
+                       const tcu::Vec4         res                                     (tcu::sRGBA8ToLinear(src));
+                       const tcu::Vec4         ref                                     (tcu::sRGBToLinear(src.cast<float>() / tcu::Vec4(255.0f)));
+                       const tcu::Vec4         diff                            (res - ref);
+                       const tcu::UVec4        discreteFloatDiff       (calculateDiscreteFloatDistance(ref, res));
+
+                       if (tcu::anyNotEqual(res, ref))
+                               log << tcu::TestLog::Message << i << ", Res: " << res << ", Ref: " << ref << ", Diff: " << diff << ", Discrete float diff: " << discreteFloatDiff << tcu::TestLog::EndMessage;
+
+                       if (tcu::boolAny(tcu::greaterThan(discreteFloatDiff, tcu::UVec4(1u))))
+                               isOk = false;
+               }
+
+               if (isOk)
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               else
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got ulp diffs greater than one.");
+
+               return STOP;
+       }
+};
+
+} // anonymous
+
+tcu::TestCase* createSRGB8ConversionTest (tcu::TestContext& context)
+{
+       return new SRGB8ConversionTest(context);
+}
+
+} // dit
diff --git a/modules/internal/ditSRGB8ConversionTest.hpp b/modules/internal/ditSRGB8ConversionTest.hpp
new file mode 100644 (file)
index 0000000..536babb
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _DITSRGB8CONVERSIONTEST_HPP
+#define _DITSRGB8CONVERSIONTEST_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Internal Test Module
+ * ---------------------------------
+ *
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief 8-bit sRGB conversion test.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace dit
+{
+
+tcu::TestCase* createSRGB8ConversionTest (tcu::TestContext& context);
+
+} // dit
+
+#endif // _DITSRGB8CONVERSIONTEST_HPP
index a290c70..607a7d1 100644 (file)
 #include "ditImageCompareTests.hpp"
 #include "ditTestLogTests.hpp"
 #include "ditSeedBuilderTests.hpp"
+#include "ditSRGB8ConversionTest.hpp"
 
 namespace dit
 {
+namespace
+{
+
+class TextureTests : public tcu::TestCaseGroup
+{
+public:
+       TextureTests (tcu::TestContext& testCtx)
+               : tcu::TestCaseGroup(testCtx, "texture", "Tests for tcu::Texture and utils.")
+       {
+       }
+
+       void init (void)
+       {
+               addChild(createSRGB8ConversionTest(m_testCtx));
+       }
+};
 
 class DeqpTests : public tcu::TestCaseGroup
 {
@@ -46,10 +63,13 @@ public:
                addChild(new TestLogTests               (m_testCtx));
                addChild(new ImageIOTests               (m_testCtx));
                addChild(new ImageCompareTests  (m_testCtx));
+               addChild(new TextureTests               (m_testCtx));
                addChild(createSeedBuilderTests (m_testCtx));
        }
 };
 
+} // anonymous
+
 class TestCaseExecutor : public tcu::TestCaseExecutor
 {
 public: