1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES 2.0 Module
3*35238bceSAndroid Build Coastguard Worker * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief gl_FragData[] tests.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "es2fShaderFragDataTests.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "glsShaderLibrary.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
38*35238bceSAndroid Build Coastguard Worker
39*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker namespace deqp
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker namespace gles2
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace Functional
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker using std::string;
50*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
51*35238bceSAndroid Build Coastguard Worker
52*35238bceSAndroid Build Coastguard Worker namespace
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker
55*35238bceSAndroid Build Coastguard Worker enum IndexExprType
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker INDEX_EXPR_STATIC = 0,
58*35238bceSAndroid Build Coastguard Worker INDEX_EXPR_UNIFORM,
59*35238bceSAndroid Build Coastguard Worker INDEX_EXPR_DYNAMIC,
60*35238bceSAndroid Build Coastguard Worker
61*35238bceSAndroid Build Coastguard Worker INDEX_EXPR_TYPE_LAST
62*35238bceSAndroid Build Coastguard Worker };
63*35238bceSAndroid Build Coastguard Worker
compareSingleColor(tcu::TestLog & log,const tcu::Surface & surface,tcu::RGBA expectedColor,tcu::RGBA threshold)64*35238bceSAndroid Build Coastguard Worker static bool compareSingleColor(tcu::TestLog &log, const tcu::Surface &surface, tcu::RGBA expectedColor,
65*35238bceSAndroid Build Coastguard Worker tcu::RGBA threshold)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker const int maxPrints = 10;
68*35238bceSAndroid Build Coastguard Worker int numFailedPixels = 0;
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Expecting " << expectedColor << " with threshold " << threshold << TestLog::EndMessage;
71*35238bceSAndroid Build Coastguard Worker
72*35238bceSAndroid Build Coastguard Worker for (int y = 0; y < surface.getHeight(); y++)
73*35238bceSAndroid Build Coastguard Worker {
74*35238bceSAndroid Build Coastguard Worker for (int x = 0; x < surface.getWidth(); x++)
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker const tcu::RGBA resultColor = surface.getPixel(x, y);
77*35238bceSAndroid Build Coastguard Worker const bool isOk = compareThreshold(resultColor, expectedColor, threshold);
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker if (!isOk)
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker if (numFailedPixels < maxPrints)
82*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "ERROR: Got " << resultColor << " at (" << x << ", " << y << ")!"
83*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
84*35238bceSAndroid Build Coastguard Worker else if (numFailedPixels == maxPrints)
85*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "..." << TestLog::EndMessage;
86*35238bceSAndroid Build Coastguard Worker
87*35238bceSAndroid Build Coastguard Worker numFailedPixels += 1;
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker
92*35238bceSAndroid Build Coastguard Worker if (numFailedPixels > 0)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Found " << numFailedPixels << " invalid pixels, comparison FAILED!"
95*35238bceSAndroid Build Coastguard Worker << TestLog::EndMessage;
96*35238bceSAndroid Build Coastguard Worker log << TestLog::Image("ResultImage", "Result Image", surface);
97*35238bceSAndroid Build Coastguard Worker return false;
98*35238bceSAndroid Build Coastguard Worker }
99*35238bceSAndroid Build Coastguard Worker else
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "Image comparison passed." << TestLog::EndMessage;
102*35238bceSAndroid Build Coastguard Worker return true;
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker }
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker class FragDataIndexingCase : public TestCase
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker public:
FragDataIndexingCase(Context & context,const char * name,const char * description,IndexExprType indexExprType)109*35238bceSAndroid Build Coastguard Worker FragDataIndexingCase(Context &context, const char *name, const char *description, IndexExprType indexExprType)
110*35238bceSAndroid Build Coastguard Worker : TestCase(context, name, description)
111*35238bceSAndroid Build Coastguard Worker , m_indexExprType(indexExprType)
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker
genSources(const IndexExprType indexExprType)115*35238bceSAndroid Build Coastguard Worker static glu::ProgramSources genSources(const IndexExprType indexExprType)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker const char *const fragIndexExpr = indexExprType == INDEX_EXPR_STATIC ? "0" :
118*35238bceSAndroid Build Coastguard Worker indexExprType == INDEX_EXPR_UNIFORM ? "u_index" :
119*35238bceSAndroid Build Coastguard Worker indexExprType == INDEX_EXPR_DYNAMIC ? "int(v_index)" :
120*35238bceSAndroid Build Coastguard Worker DE_NULL;
121*35238bceSAndroid Build Coastguard Worker glu::ProgramSources sources;
122*35238bceSAndroid Build Coastguard Worker
123*35238bceSAndroid Build Coastguard Worker DE_ASSERT(fragIndexExpr);
124*35238bceSAndroid Build Coastguard Worker
125*35238bceSAndroid Build Coastguard Worker sources << glu::VertexSource("attribute highp vec4 a_position;\n"
126*35238bceSAndroid Build Coastguard Worker "attribute highp float a_index;\n"
127*35238bceSAndroid Build Coastguard Worker "attribute highp vec4 a_color;\n"
128*35238bceSAndroid Build Coastguard Worker "varying mediump float v_index;\n"
129*35238bceSAndroid Build Coastguard Worker "varying mediump vec4 v_color;\n"
130*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
131*35238bceSAndroid Build Coastguard Worker "{\n"
132*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
133*35238bceSAndroid Build Coastguard Worker " v_color = a_color;\n"
134*35238bceSAndroid Build Coastguard Worker " v_index = a_index;\n"
135*35238bceSAndroid Build Coastguard Worker "}\n");
136*35238bceSAndroid Build Coastguard Worker
137*35238bceSAndroid Build Coastguard Worker sources << glu::FragmentSource(string("varying mediump vec4 v_color;\n"
138*35238bceSAndroid Build Coastguard Worker "varying mediump float v_index;\n"
139*35238bceSAndroid Build Coastguard Worker "uniform mediump int u_index;\n"
140*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
141*35238bceSAndroid Build Coastguard Worker "{\n"
142*35238bceSAndroid Build Coastguard Worker " gl_FragData[") +
143*35238bceSAndroid Build Coastguard Worker fragIndexExpr +
144*35238bceSAndroid Build Coastguard Worker "] = v_color;\n"
145*35238bceSAndroid Build Coastguard Worker "}\n");
146*35238bceSAndroid Build Coastguard Worker
147*35238bceSAndroid Build Coastguard Worker return sources;
148*35238bceSAndroid Build Coastguard Worker }
149*35238bceSAndroid Build Coastguard Worker
iterate(void)150*35238bceSAndroid Build Coastguard Worker IterateResult iterate(void)
151*35238bceSAndroid Build Coastguard Worker {
152*35238bceSAndroid Build Coastguard Worker const glu::RenderContext &renderCtx = m_context.getRenderContext();
153*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = renderCtx.getFunctions();
154*35238bceSAndroid Build Coastguard Worker const glu::ShaderProgram program(renderCtx, genSources(m_indexExprType));
155*35238bceSAndroid Build Coastguard Worker const int viewportW = de::min(renderCtx.getRenderTarget().getWidth(), 128);
156*35238bceSAndroid Build Coastguard Worker const int viewportH = de::min(renderCtx.getRenderTarget().getHeight(), 128);
157*35238bceSAndroid Build Coastguard Worker
158*35238bceSAndroid Build Coastguard Worker const float positions[] = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
159*35238bceSAndroid Build Coastguard Worker const float colors[] = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
160*35238bceSAndroid Build Coastguard Worker 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
161*35238bceSAndroid Build Coastguard Worker const float indexValues[] = {0.0f, 0.0f, 0.0f, 0.0f};
162*35238bceSAndroid Build Coastguard Worker const uint8_t indices[] = {0, 1, 2, 2, 1, 3};
163*35238bceSAndroid Build Coastguard Worker
164*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
165*35238bceSAndroid Build Coastguard Worker glu::va::Float("a_color", 4, 4, 0, &colors[0]),
166*35238bceSAndroid Build Coastguard Worker glu::va::Float("a_index", 1, 4, 0, &indexValues[0])};
167*35238bceSAndroid Build Coastguard Worker
168*35238bceSAndroid Build Coastguard Worker m_testCtx.getLog() << program;
169*35238bceSAndroid Build Coastguard Worker
170*35238bceSAndroid Build Coastguard Worker if (!program.isOk())
171*35238bceSAndroid Build Coastguard Worker {
172*35238bceSAndroid Build Coastguard Worker if (m_indexExprType == INDEX_EXPR_STATIC)
173*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Compile failed");
174*35238bceSAndroid Build Coastguard Worker else
175*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker
178*35238bceSAndroid Build Coastguard Worker gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
179*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
180*35238bceSAndroid Build Coastguard Worker
181*35238bceSAndroid Build Coastguard Worker gl.viewport(0, 0, viewportW, viewportH);
182*35238bceSAndroid Build Coastguard Worker gl.useProgram(program.getProgram());
183*35238bceSAndroid Build Coastguard Worker gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_index"), 0);
184*35238bceSAndroid Build Coastguard Worker
185*35238bceSAndroid Build Coastguard Worker glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
186*35238bceSAndroid Build Coastguard Worker glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
187*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
188*35238bceSAndroid Build Coastguard Worker
189*35238bceSAndroid Build Coastguard Worker {
190*35238bceSAndroid Build Coastguard Worker tcu::Surface result(viewportW, viewportH);
191*35238bceSAndroid Build Coastguard Worker const tcu::RGBA threshold =
192*35238bceSAndroid Build Coastguard Worker renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
193*35238bceSAndroid Build Coastguard Worker bool isOk;
194*35238bceSAndroid Build Coastguard Worker
195*35238bceSAndroid Build Coastguard Worker glu::readPixels(renderCtx, 0, 0, result.getAccess());
196*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
197*35238bceSAndroid Build Coastguard Worker
198*35238bceSAndroid Build Coastguard Worker isOk = compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold);
199*35238bceSAndroid Build Coastguard Worker
200*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
201*35238bceSAndroid Build Coastguard Worker isOk ? "Pass" : "Image comparison failed");
202*35238bceSAndroid Build Coastguard Worker }
203*35238bceSAndroid Build Coastguard Worker
204*35238bceSAndroid Build Coastguard Worker return STOP;
205*35238bceSAndroid Build Coastguard Worker }
206*35238bceSAndroid Build Coastguard Worker
207*35238bceSAndroid Build Coastguard Worker private:
208*35238bceSAndroid Build Coastguard Worker const IndexExprType m_indexExprType;
209*35238bceSAndroid Build Coastguard Worker };
210*35238bceSAndroid Build Coastguard Worker
211*35238bceSAndroid Build Coastguard Worker } // namespace
212*35238bceSAndroid Build Coastguard Worker
ShaderFragDataTests(Context & context)213*35238bceSAndroid Build Coastguard Worker ShaderFragDataTests::ShaderFragDataTests(Context &context) : TestCaseGroup(context, "fragdata", "gl_FragData[] Tests")
214*35238bceSAndroid Build Coastguard Worker {
215*35238bceSAndroid Build Coastguard Worker }
216*35238bceSAndroid Build Coastguard Worker
~ShaderFragDataTests(void)217*35238bceSAndroid Build Coastguard Worker ShaderFragDataTests::~ShaderFragDataTests(void)
218*35238bceSAndroid Build Coastguard Worker {
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker
init(void)221*35238bceSAndroid Build Coastguard Worker void ShaderFragDataTests::init(void)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker addChild(new FragDataIndexingCase(m_context, "valid_static_index",
224*35238bceSAndroid Build Coastguard Worker "Valid gl_FragData[] assignment using static index", INDEX_EXPR_STATIC));
225*35238bceSAndroid Build Coastguard Worker addChild(new FragDataIndexingCase(m_context, "valid_uniform_index",
226*35238bceSAndroid Build Coastguard Worker "Valid gl_FragData[] assignment using uniform index", INDEX_EXPR_UNIFORM));
227*35238bceSAndroid Build Coastguard Worker addChild(new FragDataIndexingCase(m_context, "valid_dynamic_index",
228*35238bceSAndroid Build Coastguard Worker "Valid gl_FragData[] assignment using dynamic index", INDEX_EXPR_DYNAMIC));
229*35238bceSAndroid Build Coastguard Worker
230*35238bceSAndroid Build Coastguard Worker // Negative cases.
231*35238bceSAndroid Build Coastguard Worker {
232*35238bceSAndroid Build Coastguard Worker gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
233*35238bceSAndroid Build Coastguard Worker std::vector<tcu::TestNode *> negativeCases = library.loadShaderFile("shaders/fragdata.test");
234*35238bceSAndroid Build Coastguard Worker
235*35238bceSAndroid Build Coastguard Worker for (std::vector<tcu::TestNode *>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++)
236*35238bceSAndroid Build Coastguard Worker addChild(*i);
237*35238bceSAndroid Build Coastguard Worker }
238*35238bceSAndroid Build Coastguard Worker }
239*35238bceSAndroid Build Coastguard Worker
240*35238bceSAndroid Build Coastguard Worker } // namespace Functional
241*35238bceSAndroid Build Coastguard Worker } // namespace gles2
242*35238bceSAndroid Build Coastguard Worker } // namespace deqp
243