You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
7.6 KiB
242 lines
7.6 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.1 Module
|
|
* -------------------------------------------------
|
|
*
|
|
* Copyright 2018 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 Built-in function tests for uniform constants.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es31fShaderUniformIntegerFunctionTests.hpp"
|
|
#include "glsShaderExecUtil.hpp"
|
|
#include "glwFunctions.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include <iostream>
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles31
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using std::vector;
|
|
using std::string;
|
|
using tcu::TestLog;
|
|
using namespace gls::ShaderExecUtil;
|
|
|
|
class UniformIntegerFunctionCase : public TestCase
|
|
{
|
|
public:
|
|
UniformIntegerFunctionCase (Context& context, const char* description, int inputValue, glu::Precision precision, glu::ShaderType shaderType);
|
|
~UniformIntegerFunctionCase (void);
|
|
|
|
void init (void);
|
|
void deinit (void);
|
|
IterateResult iterate (void);
|
|
virtual const char* getFunctionName() = 0;
|
|
virtual int computeExpectedResult(deInt32 value) = 0;
|
|
|
|
protected:
|
|
UniformIntegerFunctionCase (const UniformIntegerFunctionCase& other);
|
|
UniformIntegerFunctionCase& operator= (const UniformIntegerFunctionCase& other);
|
|
|
|
private:
|
|
ShaderSpec m_spec;
|
|
glu::ShaderType m_shaderType;
|
|
int m_input;
|
|
int m_value;
|
|
ShaderExecutor* m_executor;
|
|
};
|
|
|
|
static std::string getCaseName (glu::Precision precision, glu::ShaderType shaderType);
|
|
|
|
UniformIntegerFunctionCase::UniformIntegerFunctionCase(Context& context, const char* description, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
|
|
: TestCase(context, getCaseName(precision, shaderType).c_str(), description)
|
|
, m_shaderType(shaderType)
|
|
, m_input(inputValue)
|
|
, m_value(0)
|
|
, m_executor(DE_NULL)
|
|
{
|
|
m_spec.version = glu::GLSL_VERSION_310_ES;
|
|
|
|
std::ostringstream oss;
|
|
glu::VarType varType(glu::TYPE_INT, precision);
|
|
oss << "uniform " << glu::declare(varType, "value", 0) << ";\n";
|
|
m_spec.globalDeclarations = oss.str();
|
|
m_spec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_INT, glu::PRECISION_LOWP)));
|
|
m_spec.outputs.push_back(Symbol("comparison", glu::VarType(glu::TYPE_BOOL, glu::PRECISION_LAST)));
|
|
}
|
|
|
|
UniformIntegerFunctionCase::~UniformIntegerFunctionCase(void)
|
|
{
|
|
UniformIntegerFunctionCase::deinit();
|
|
}
|
|
|
|
void UniformIntegerFunctionCase::deinit(void)
|
|
{
|
|
delete m_executor;
|
|
m_executor = DE_NULL;
|
|
}
|
|
|
|
void UniformIntegerFunctionCase::init(void)
|
|
{
|
|
std::ostringstream oss;
|
|
oss <<
|
|
"result = " << getFunctionName() << "(value);\n"
|
|
"comparison = (" << getFunctionName() << "(value) == " << computeExpectedResult(m_input) << ");\n";
|
|
m_spec.source = oss.str();
|
|
|
|
DE_ASSERT(!m_executor);
|
|
m_executor = createExecutor(m_context.getRenderContext(), m_shaderType, m_spec);
|
|
m_testCtx.getLog() << m_executor;
|
|
|
|
if (!m_executor->isOk())
|
|
throw tcu::TestError("Compile failed");
|
|
|
|
m_value = m_context.getRenderContext().getFunctions().getUniformLocation(m_executor->getProgram(), "value");
|
|
}
|
|
|
|
tcu::TestNode::IterateResult UniformIntegerFunctionCase::iterate(void)
|
|
{
|
|
deInt32 result;
|
|
deBool comparison;
|
|
vector<void*> outputPointers (2);
|
|
|
|
outputPointers[0]= &result;
|
|
outputPointers[1] = &comparison;
|
|
|
|
m_executor->useProgram();
|
|
m_context.getRenderContext().getFunctions().uniform1i(m_value, m_input);
|
|
m_executor->execute(1, DE_NULL, &outputPointers[0]);
|
|
|
|
int expectedResult = computeExpectedResult(m_input);
|
|
if (result != expectedResult) {
|
|
m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed for " << getFunctionName() << "(" << m_input << ") == " << expectedResult << TestLog::EndMessage;
|
|
m_testCtx.getLog() << TestLog::Message << "input: " << m_input << TestLog::EndMessage;
|
|
m_testCtx.getLog() << TestLog::Message << "result: " << result << TestLog::EndMessage;
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
|
|
return STOP;
|
|
} else if (!comparison) {
|
|
m_testCtx.getLog() << TestLog::Message << "ERROR: result is as expected, but not when use in condition statement (" << getFunctionName() << "(" << m_input << ") == " << expectedResult << ") == true" << TestLog::EndMessage;
|
|
m_testCtx.getLog() << TestLog::Message << "input:" << m_input << TestLog::EndMessage;
|
|
m_testCtx.getLog() << TestLog::Message << "result: " << result << TestLog::EndMessage;
|
|
m_testCtx.getLog() << TestLog::Message << "comparison: " << comparison << TestLog::EndMessage;
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed");
|
|
return STOP;
|
|
}
|
|
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
|
|
return STOP;
|
|
}
|
|
|
|
static std::string getCaseName (glu::Precision precision, glu::ShaderType shaderType)
|
|
{
|
|
return string(getPrecisionName(precision)) + getShaderTypePostfix(shaderType);
|
|
}
|
|
|
|
static int findMSB (deInt32 value)
|
|
{
|
|
if (value > 0)
|
|
return 31 - deClz32((deUint32)value);
|
|
else if (value < 0)
|
|
return 31 - deClz32(~(deUint32)value);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
class FindMSBEdgeCase : public UniformIntegerFunctionCase {
|
|
public:
|
|
FindMSBEdgeCase(Context& context, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
|
|
: UniformIntegerFunctionCase(context, "findMSB", inputValue, precision, shaderType)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
const char* getFunctionName() {
|
|
return "findMSB";
|
|
}
|
|
|
|
int computeExpectedResult(deInt32 input) {
|
|
return findMSB(input);
|
|
}
|
|
};
|
|
|
|
static int findLSB (deUint32 value)
|
|
{
|
|
for (int i = 0; i < 32; i++)
|
|
{
|
|
if (value & (1u<<i))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
class FindLSBEdgeCase : public UniformIntegerFunctionCase {
|
|
public:
|
|
FindLSBEdgeCase(Context& context, int inputValue, glu::Precision precision, glu::ShaderType shaderType)
|
|
: UniformIntegerFunctionCase(context, "findLSB", inputValue, precision, shaderType)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
const char* getFunctionName() {
|
|
return "findLSB";
|
|
}
|
|
|
|
int computeExpectedResult(deInt32 input) {
|
|
return findLSB(input);
|
|
}
|
|
};
|
|
|
|
|
|
template<class TestClass>
|
|
static void addFunctionCases (TestCaseGroup* parent, const char* functionName, int input)
|
|
{
|
|
tcu::TestCaseGroup* group = new tcu::TestCaseGroup(parent->getTestContext(), functionName, functionName);
|
|
parent->addChild(group);
|
|
for (int prec = glu::PRECISION_LOWP; prec <= glu::PRECISION_HIGHP; prec++)
|
|
{
|
|
for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; shaderTypeNdx++)
|
|
{
|
|
if (executorSupported(glu::ShaderType(shaderTypeNdx)))
|
|
{
|
|
group->addChild(new TestClass(parent->getContext(), input, glu::Precision(prec), glu::ShaderType(shaderTypeNdx)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ShaderUniformIntegerFunctionTests::ShaderUniformIntegerFunctionTests(Context& context)
|
|
: TestCaseGroup(context, "uniform", "Function on uniform")
|
|
{
|
|
}
|
|
|
|
ShaderUniformIntegerFunctionTests::~ShaderUniformIntegerFunctionTests()
|
|
{
|
|
}
|
|
void ShaderUniformIntegerFunctionTests::init()
|
|
{
|
|
addFunctionCases<FindMSBEdgeCase>(this, "findMSBZero", 0);
|
|
addFunctionCases<FindMSBEdgeCase>(this, "findMSBMinusOne", -1);
|
|
addFunctionCases<FindLSBEdgeCase>(this, "findLSBZero", 0);
|
|
addFunctionCases<FindLSBEdgeCase>(this, "findLSBMinusOne", -1);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|