summaryrefslogtreecommitdiff
path: root/modules/egl/teglChooseConfigReference.cpp
diff options
context:
space:
mode:
authorJarkko Poyry <jpoyry@google.com>2014-09-02 11:48:52 +0300
committerJarkko Poyry <jpoyry@google.com>2014-09-10 18:04:33 +0300
commit3c827367444ee418f129b2c238299f49d3264554 (patch)
tree62dd09feabba812bdff287366e9593b99007152c /modules/egl/teglChooseConfigReference.cpp
parent49238d46b847a2099e64118ff22aef9563c8b81f (diff)
downloadVK-GL-CTS-3c827367444ee418f129b2c238299f49d3264554.tar.gz
VK-GL-CTS-3c827367444ee418f129b2c238299f49d3264554.tar.bz2
VK-GL-CTS-3c827367444ee418f129b2c238299f49d3264554.zip
Import dEQP.
Import drawElements Quality Program from an internal repository. Bug: 17388917 Change-Id: Ic109fe4a57e31b2a816113d90fbdf51a43e7abeb
Diffstat (limited to 'modules/egl/teglChooseConfigReference.cpp')
-rw-r--r--modules/egl/teglChooseConfigReference.cpp392
1 files changed, 392 insertions, 0 deletions
diff --git a/modules/egl/teglChooseConfigReference.cpp b/modules/egl/teglChooseConfigReference.cpp
new file mode 100644
index 000000000..10f253008
--- /dev/null
+++ b/modules/egl/teglChooseConfigReference.cpp
@@ -0,0 +1,392 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * Copyright 2014 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 Choose config reference implementation.
+ *//*--------------------------------------------------------------------*/
+
+#include "teglChooseConfigReference.hpp"
+
+#include <algorithm>
+#include <vector>
+#include <map>
+
+namespace deqp
+{
+namespace egl
+{
+
+using eglu::ConfigInfo;
+
+enum Criteria
+{
+ CRITERIA_AT_LEAST = 0,
+ CRITERIA_EXACT,
+ CRITERIA_MASK,
+ CRITERIA_SPECIAL,
+
+ CRITERIA_LAST
+};
+
+enum SortOrder
+{
+ SORTORDER_NONE = 0,
+ SORTORDER_SMALLER,
+ SORTORDER_SPECIAL,
+
+ SORTORDER_LAST
+};
+
+struct AttribRule
+{
+ EGLenum name;
+ EGLint value;
+ Criteria criteria;
+ SortOrder sortOrder;
+
+ AttribRule (void)
+ : name (EGL_NONE)
+ , value (EGL_NONE)
+ , criteria (CRITERIA_LAST)
+ , sortOrder (SORTORDER_LAST)
+ {
+ }
+
+ AttribRule (EGLenum name_, EGLint value_, Criteria criteria_, SortOrder sortOrder_)
+ : name (name_)
+ , value (value_)
+ , criteria (criteria_)
+ , sortOrder (sortOrder_)
+ {
+ }
+};
+
+class SurfaceConfig
+{
+private:
+ static int getCaveatRank (EGLenum caveat)
+ {
+ switch (caveat)
+ {
+ case EGL_NONE: return 0;
+ case EGL_SLOW_CONFIG: return 1;
+ case EGL_NON_CONFORMANT_CONFIG: return 2;
+ default: DE_ASSERT(DE_FALSE); return 3;
+ }
+ }
+
+ static int getColorBufferTypeRank (EGLenum type)
+ {
+ switch (type)
+ {
+ case EGL_RGB_BUFFER: return 0;
+ case EGL_LUMINANCE_BUFFER: return 1;
+ default: DE_ASSERT(DE_FALSE); return 2;
+ }
+ }
+
+ typedef bool (*CompareFunc) (const SurfaceConfig& a, const SurfaceConfig& b);
+
+ static bool compareCaveat (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ return getCaveatRank((EGLenum)a.m_info.configCaveat) < getCaveatRank((EGLenum)b.m_info.configCaveat);
+ }
+
+ static bool compareColorBufferType (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ return getColorBufferTypeRank((EGLenum)a.m_info.colorBufferType) < getColorBufferTypeRank((EGLenum)b.m_info.colorBufferType);
+ }
+
+ static bool compareColorBufferBits (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ DE_ASSERT(a.m_info.colorBufferType == b.m_info.colorBufferType);
+ switch (a.m_info.colorBufferType)
+ {
+ case EGL_RGB_BUFFER:
+ return (a.m_info.redSize + a.m_info.greenSize + a.m_info.blueSize + a.m_info.alphaSize)
+ > (b.m_info.redSize + b.m_info.greenSize + b.m_info.blueSize + b.m_info.alphaSize);
+
+ case EGL_LUMINANCE_BUFFER:
+ return (a.m_info.luminanceSize + a.m_info.alphaSize) > (b.m_info.luminanceSize + b.m_info.alphaSize);
+
+ default:
+ DE_ASSERT(DE_FALSE);
+ return true;
+ }
+ }
+
+ template <EGLenum Attribute>
+ static bool compareAttributeSmaller (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ return a.getAttribute(Attribute) < b.getAttribute(Attribute);
+ }
+public:
+ SurfaceConfig (EGLConfig config, ConfigInfo &info)
+ : m_config(config)
+ , m_info(info)
+ {
+ }
+
+ EGLConfig getEglConfig (void) const
+ {
+ return m_config;
+ }
+
+ EGLint getAttribute (const EGLenum attribute) const
+ {
+ return m_info.getAttribute(attribute);
+ }
+
+ friend bool operator== (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ for (std::map<EGLenum, AttribRule>::const_iterator iter = SurfaceConfig::defaultRules.begin(); iter != SurfaceConfig::defaultRules.end(); iter++)
+ {
+ const EGLenum attribute = iter->first;
+
+ if (a.getAttribute(attribute) != b.getAttribute(attribute)) return false;
+ }
+ return true;
+ }
+
+ bool compareTo (const SurfaceConfig& b, bool skipColorBufferBits=false) const
+ {
+ static const SurfaceConfig::CompareFunc compareFuncs[] =
+ {
+ SurfaceConfig::compareCaveat,
+ SurfaceConfig::compareColorBufferType,
+ SurfaceConfig::compareColorBufferBits,
+ SurfaceConfig::compareAttributeSmaller<EGL_BUFFER_SIZE>,
+ SurfaceConfig::compareAttributeSmaller<EGL_SAMPLE_BUFFERS>,
+ SurfaceConfig::compareAttributeSmaller<EGL_SAMPLES>,
+ SurfaceConfig::compareAttributeSmaller<EGL_DEPTH_SIZE>,
+ SurfaceConfig::compareAttributeSmaller<EGL_STENCIL_SIZE>,
+ SurfaceConfig::compareAttributeSmaller<EGL_ALPHA_MASK_SIZE>,
+ SurfaceConfig::compareAttributeSmaller<EGL_CONFIG_ID>
+ };
+
+ if (*this == b)
+ return false; // std::sort() can compare object to itself.
+
+ for (int ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(compareFuncs); ndx++)
+ {
+ if (skipColorBufferBits && (compareFuncs[ndx] == SurfaceConfig::compareColorBufferBits))
+ continue;
+
+ if (compareFuncs[ndx](*this, b))
+ return true;
+ else if (compareFuncs[ndx](b, *this))
+ return false;
+ }
+
+ TCU_FAIL("Unable to compare configs - duplicate ID?");
+ }
+
+ static const std::map<EGLenum, AttribRule> defaultRules;
+
+ static std::map<EGLenum, AttribRule> initAttribRules (void)
+ {
+ // \todo [2011-03-24 pyry] From EGL 1.4 spec - check that this is valid for other versions as well
+ std::map<EGLenum, AttribRule> rules;
+
+ // Attribute Default Selection Criteria Sort Order Sort Priority
+ rules[EGL_BUFFER_SIZE] = AttribRule(EGL_BUFFER_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 4
+ rules[EGL_RED_SIZE] = AttribRule(EGL_RED_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); // 3
+ rules[EGL_GREEN_SIZE] = AttribRule(EGL_GREEN_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); // 3
+ rules[EGL_BLUE_SIZE] = AttribRule(EGL_BLUE_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); // 3
+ rules[EGL_LUMINANCE_SIZE] = AttribRule(EGL_LUMINANCE_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); // 3
+ rules[EGL_ALPHA_SIZE] = AttribRule(EGL_ALPHA_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SPECIAL); // 3
+ rules[EGL_ALPHA_MASK_SIZE] = AttribRule(EGL_ALPHA_MASK_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 9
+ rules[EGL_BIND_TO_TEXTURE_RGB] = AttribRule(EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_BIND_TO_TEXTURE_RGBA] = AttribRule(EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_COLOR_BUFFER_TYPE] = AttribRule(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, CRITERIA_EXACT, SORTORDER_NONE); // 2
+ rules[EGL_CONFIG_CAVEAT] = AttribRule(EGL_CONFIG_CAVEAT, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SPECIAL); // 1
+ rules[EGL_CONFIG_ID] = AttribRule(EGL_CONFIG_ID, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SMALLER); // 11
+ rules[EGL_CONFORMANT] = AttribRule(EGL_CONFORMANT, 0, CRITERIA_MASK, SORTORDER_NONE);
+ rules[EGL_DEPTH_SIZE] = AttribRule(EGL_DEPTH_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 7
+ rules[EGL_LEVEL] = AttribRule(EGL_LEVEL, 0, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_MATCH_NATIVE_PIXMAP] = AttribRule(EGL_MATCH_NATIVE_PIXMAP, EGL_NONE, CRITERIA_SPECIAL, SORTORDER_NONE);
+ rules[EGL_MAX_SWAP_INTERVAL] = AttribRule(EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_MIN_SWAP_INTERVAL] = AttribRule(EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_NATIVE_RENDERABLE] = AttribRule(EGL_NATIVE_RENDERABLE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_NATIVE_VISUAL_TYPE] = AttribRule(EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_SPECIAL); // 10
+ rules[EGL_RENDERABLE_TYPE] = AttribRule(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, CRITERIA_MASK, SORTORDER_NONE);
+ rules[EGL_SAMPLE_BUFFERS] = AttribRule(EGL_SAMPLE_BUFFERS, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 5
+ rules[EGL_SAMPLES] = AttribRule(EGL_SAMPLES, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 6
+ rules[EGL_STENCIL_SIZE] = AttribRule(EGL_STENCIL_SIZE, 0, CRITERIA_AT_LEAST, SORTORDER_SMALLER); // 8
+ rules[EGL_SURFACE_TYPE] = AttribRule(EGL_SURFACE_TYPE, EGL_WINDOW_BIT, CRITERIA_MASK, SORTORDER_NONE);
+ rules[EGL_TRANSPARENT_TYPE] = AttribRule(EGL_TRANSPARENT_TYPE, EGL_NONE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_TRANSPARENT_RED_VALUE] = AttribRule(EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_TRANSPARENT_GREEN_VALUE] = AttribRule(EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+ rules[EGL_TRANSPARENT_BLUE_VALUE] = AttribRule(EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE, CRITERIA_EXACT, SORTORDER_NONE);
+
+ return rules;
+ }
+private:
+ EGLConfig m_config;
+ ConfigInfo m_info;
+};
+
+const std::map<EGLenum, AttribRule> SurfaceConfig::defaultRules = SurfaceConfig::initAttribRules();
+
+class CompareConfigs
+{
+public:
+ CompareConfigs (bool skipColorBufferBits)
+ : m_skipColorBufferBits(skipColorBufferBits)
+ {
+ }
+
+ bool operator() (const SurfaceConfig& a, const SurfaceConfig& b)
+ {
+ return a.compareTo(b, m_skipColorBufferBits);
+ }
+
+private:
+ bool m_skipColorBufferBits;
+};
+
+class ConfigFilter
+{
+private:
+ std::map<EGLenum, AttribRule> m_rules;
+public:
+ ConfigFilter ()
+ : m_rules(SurfaceConfig::defaultRules)
+ {
+ }
+
+ void setValue (EGLenum name, EGLint value)
+ {
+ DE_ASSERT(SurfaceConfig::defaultRules.find(name) != SurfaceConfig::defaultRules.end());
+ m_rules[name].value = value;
+ }
+
+ void setValues (std::vector<std::pair<EGLenum, EGLint> > values)
+ {
+ for (size_t ndx = 0; ndx < values.size(); ndx++)
+ {
+ const EGLenum name = values[ndx].first;
+ const EGLint value = values[ndx].second;
+
+ setValue(name, value);
+ }
+ }
+
+ AttribRule getAttribute (EGLenum name)
+ {
+ DE_ASSERT(SurfaceConfig::defaultRules.find(name) != SurfaceConfig::defaultRules.end());
+ return m_rules[name];
+ }
+
+ bool isMatch (const SurfaceConfig& config)
+ {
+ bool result = true;
+ for (std::map<EGLenum, AttribRule>::const_iterator iter = m_rules.begin(); iter != m_rules.end(); iter++)
+ {
+ const AttribRule rule = iter->second;
+
+ if (rule.value == EGL_DONT_CARE)
+ continue;
+ else if (rule.name == EGL_MATCH_NATIVE_PIXMAP)
+ TCU_CHECK(rule.value == EGL_NONE); // Not supported
+ else if (rule.name == EGL_TRANSPARENT_RED_VALUE || rule.name == EGL_TRANSPARENT_GREEN_VALUE || rule.name == EGL_TRANSPARENT_BLUE_VALUE)
+ continue;
+ else
+ {
+ const EGLint cfgValue = config.getAttribute(rule.name);
+
+ switch (rule.criteria)
+ {
+ case CRITERIA_EXACT: result = rule.value == cfgValue; break;
+ case CRITERIA_AT_LEAST: result = rule.value <= cfgValue; break;
+ case CRITERIA_MASK: result = (rule.value & cfgValue) == rule.value; break;
+ default: TCU_FAIL("Unknown criteria");
+ }
+ }
+
+ if (result == false) return false;
+ }
+
+ return true;
+ }
+
+ bool isColorBitsUnspecified (void)
+ {
+ const EGLenum bitAttribs[] = { EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_LUMINANCE_SIZE };
+
+ for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bitAttribs); ndx++)
+ {
+ const EGLenum attrib = bitAttribs[ndx];
+ const EGLint value = getAttribute(attrib).value;
+
+ if (value != 0 && value != EGL_DONT_CARE) return false;
+ }
+
+ return true;
+ }
+
+ std::vector<SurfaceConfig> filter (const std::vector<SurfaceConfig>& configs)
+ {
+ std::vector<SurfaceConfig> out;
+
+ for (std::vector<SurfaceConfig>::const_iterator iter = configs.begin(); iter != configs.end(); iter++)
+ {
+ if (isMatch(*iter)) out.push_back(*iter);
+ }
+
+ return out;
+ }
+};
+
+void chooseConfigReference (const tcu::egl::Display& display, std::vector<EGLConfig>& dst, const std::vector<std::pair<EGLenum, EGLint> >& attributes)
+{
+ // Get all configs
+ std::vector<EGLConfig> eglConfigs;
+ display.getConfigs(eglConfigs);
+
+ // Config infos
+ std::vector<ConfigInfo> configInfos;
+ configInfos.resize(eglConfigs.size());
+ for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
+ display.describeConfig(eglConfigs[ndx], configInfos[ndx]);
+
+ TCU_CHECK_EGL_MSG("Config query failed");
+
+ // Pair configs with info
+ std::vector<SurfaceConfig> configs;
+ for (size_t ndx = 0; ndx < eglConfigs.size(); ndx++)
+ configs.push_back(SurfaceConfig(eglConfigs[ndx], configInfos[ndx]));
+
+ // Filter configs
+ ConfigFilter configFilter;
+ configFilter.setValues(attributes);
+
+ std::vector<SurfaceConfig> filteredConfigs = configFilter.filter(configs);
+
+ // Sort configs
+ std::sort(filteredConfigs.begin(), filteredConfigs.end(), CompareConfigs(configFilter.isColorBitsUnspecified()));
+
+ // Write to dst list
+ dst.resize(filteredConfigs.size());
+ for (size_t ndx = 0; ndx < filteredConfigs.size(); ndx++)
+ dst[ndx] = filteredConfigs[ndx].getEglConfig();
+}
+
+} // egl
+} // deqp