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.
250 lines
7.2 KiB
250 lines
7.2 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 2.0 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 gl_FragData[] tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es2fShaderFragDataTests.hpp"
|
|
|
|
#include "glsShaderLibrary.hpp"
|
|
|
|
#include "gluRenderContext.hpp"
|
|
#include "gluShaderProgram.hpp"
|
|
#include "gluDrawUtil.hpp"
|
|
#include "gluPixelTransfer.hpp"
|
|
#include "gluObjectWrapper.hpp"
|
|
|
|
#include "tcuRenderTarget.hpp"
|
|
#include "tcuStringTemplate.hpp"
|
|
#include "tcuTestLog.hpp"
|
|
#include "tcuSurface.hpp"
|
|
|
|
#include "glwFunctions.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles2
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using std::string;
|
|
using tcu::TestLog;
|
|
|
|
namespace
|
|
{
|
|
|
|
enum IndexExprType
|
|
{
|
|
INDEX_EXPR_STATIC = 0,
|
|
INDEX_EXPR_UNIFORM,
|
|
INDEX_EXPR_DYNAMIC,
|
|
|
|
INDEX_EXPR_TYPE_LAST
|
|
};
|
|
|
|
static bool compareSingleColor (tcu::TestLog& log, const tcu::Surface& surface, tcu::RGBA expectedColor, tcu::RGBA threshold)
|
|
{
|
|
const int maxPrints = 10;
|
|
int numFailedPixels = 0;
|
|
|
|
log << TestLog::Message << "Expecting " << expectedColor << " with threshold " << threshold << TestLog::EndMessage;
|
|
|
|
for (int y = 0; y < surface.getHeight(); y++)
|
|
{
|
|
for (int x = 0; x < surface.getWidth(); x++)
|
|
{
|
|
const tcu::RGBA resultColor = surface.getPixel(x, y);
|
|
const bool isOk = compareThreshold(resultColor, expectedColor, threshold);
|
|
|
|
if (!isOk)
|
|
{
|
|
if (numFailedPixels < maxPrints)
|
|
log << TestLog::Message << "ERROR: Got " << resultColor << " at (" << x << ", " << y << ")!" << TestLog::EndMessage;
|
|
else if (numFailedPixels == maxPrints)
|
|
log << TestLog::Message << "..." << TestLog::EndMessage;
|
|
|
|
numFailedPixels += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numFailedPixels > 0)
|
|
{
|
|
log << TestLog::Message << "Found " << numFailedPixels << " invalid pixels, comparison FAILED!" << TestLog::EndMessage;
|
|
log << TestLog::Image("ResultImage", "Result Image", surface);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
log << TestLog::Message << "Image comparison passed." << TestLog::EndMessage;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
class FragDataIndexingCase : public TestCase
|
|
{
|
|
public:
|
|
FragDataIndexingCase (Context& context, const char* name, const char* description, IndexExprType indexExprType)
|
|
: TestCase (context, name, description)
|
|
, m_indexExprType (indexExprType)
|
|
{
|
|
}
|
|
|
|
static glu::ProgramSources genSources (const IndexExprType indexExprType)
|
|
{
|
|
const char* const fragIndexExpr = indexExprType == INDEX_EXPR_STATIC ? "0" :
|
|
indexExprType == INDEX_EXPR_UNIFORM ? "u_index" :
|
|
indexExprType == INDEX_EXPR_DYNAMIC ? "int(v_index)" : DE_NULL;
|
|
glu::ProgramSources sources;
|
|
|
|
DE_ASSERT(fragIndexExpr);
|
|
|
|
sources << glu::VertexSource(
|
|
"attribute highp vec4 a_position;\n"
|
|
"attribute highp float a_index;\n"
|
|
"attribute highp vec4 a_color;\n"
|
|
"varying mediump float v_index;\n"
|
|
"varying mediump vec4 v_color;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = a_position;\n"
|
|
" v_color = a_color;\n"
|
|
" v_index = a_index;\n"
|
|
"}\n");
|
|
|
|
sources << glu::FragmentSource(string(
|
|
"varying mediump vec4 v_color;\n"
|
|
"varying mediump float v_index;\n"
|
|
"uniform mediump int u_index;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_FragData[") + fragIndexExpr + "] = v_color;\n"
|
|
"}\n");
|
|
|
|
return sources;
|
|
}
|
|
|
|
IterateResult iterate (void)
|
|
{
|
|
const glu::RenderContext& renderCtx = m_context.getRenderContext();
|
|
const glw::Functions& gl = renderCtx.getFunctions();
|
|
const glu::ShaderProgram program (renderCtx, genSources(m_indexExprType));
|
|
const int viewportW = de::min(renderCtx.getRenderTarget().getWidth(), 128);
|
|
const int viewportH = de::min(renderCtx.getRenderTarget().getHeight(), 128);
|
|
|
|
const float positions[] =
|
|
{
|
|
-1.0f, -1.0f,
|
|
+1.0f, -1.0f,
|
|
-1.0f, +1.0f,
|
|
+1.0f, +1.0f
|
|
};
|
|
const float colors[] =
|
|
{
|
|
0.0f, 1.0f, 0.0f, 1.0f,
|
|
0.0f, 1.0f, 0.0f, 1.0f,
|
|
0.0f, 1.0f, 0.0f, 1.0f,
|
|
0.0f, 1.0f, 0.0f, 1.0f
|
|
};
|
|
const float indexValues[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
|
|
|
|
const glu::VertexArrayBinding vertexArrays[] =
|
|
{
|
|
glu::va::Float("a_position", 2, 4, 0, &positions[0]),
|
|
glu::va::Float("a_color", 4, 4, 0, &colors[0]),
|
|
glu::va::Float("a_index", 1, 4, 0, &indexValues[0])
|
|
};
|
|
|
|
m_testCtx.getLog() << program;
|
|
|
|
if (!program.isOk())
|
|
{
|
|
if (m_indexExprType == INDEX_EXPR_STATIC)
|
|
TCU_FAIL("Compile failed");
|
|
else
|
|
throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");
|
|
}
|
|
|
|
gl.clearColor (1.0f, 0.0f, 0.0f, 1.0f);
|
|
gl.clear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
|
|
|
gl.viewport (0, 0, viewportW, viewportH);
|
|
gl.useProgram (program.getProgram());
|
|
gl.uniform1i (gl.getUniformLocation(program.getProgram(), "u_index"), 0);
|
|
|
|
glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
|
|
glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
|
|
|
|
{
|
|
tcu::Surface result (viewportW, viewportH);
|
|
const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
|
|
bool isOk;
|
|
|
|
glu::readPixels(renderCtx, 0, 0, result.getAccess());
|
|
GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
|
|
|
|
isOk = compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold);
|
|
|
|
m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
|
|
isOk ? "Pass" : "Image comparison failed");
|
|
}
|
|
|
|
return STOP;
|
|
}
|
|
|
|
private:
|
|
const IndexExprType m_indexExprType;
|
|
};
|
|
|
|
} // anonymous
|
|
|
|
ShaderFragDataTests::ShaderFragDataTests (Context& context)
|
|
: TestCaseGroup(context, "fragdata", "gl_FragData[] Tests")
|
|
{
|
|
}
|
|
|
|
ShaderFragDataTests::~ShaderFragDataTests (void)
|
|
{
|
|
}
|
|
|
|
void ShaderFragDataTests::init (void)
|
|
{
|
|
addChild(new FragDataIndexingCase(m_context, "valid_static_index", "Valid gl_FragData[] assignment using static index", INDEX_EXPR_STATIC));
|
|
addChild(new FragDataIndexingCase(m_context, "valid_uniform_index", "Valid gl_FragData[] assignment using uniform index", INDEX_EXPR_UNIFORM));
|
|
addChild(new FragDataIndexingCase(m_context, "valid_dynamic_index", "Valid gl_FragData[] assignment using dynamic index", INDEX_EXPR_DYNAMIC));
|
|
|
|
// Negative cases.
|
|
{
|
|
gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
|
|
std::vector<tcu::TestNode*> negativeCases = library.loadShaderFile("shaders/fragdata.test");
|
|
|
|
for (std::vector<tcu::TestNode*>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++)
|
|
addChild(*i);
|
|
}
|
|
}
|
|
|
|
} // Functional
|
|
} // gles2
|
|
} // deqp
|