xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fShaderFragDataTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.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 GLSL ES 1.0 gl_FragData[] tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3fShaderFragDataTests.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 gles3
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 
isExtensionSupported(const glu::RenderContext & renderCtx,const std::string & extension)64*35238bceSAndroid Build Coastguard Worker static bool isExtensionSupported(const glu::RenderContext &renderCtx, const std::string &extension)
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl = renderCtx.getFunctions();
67*35238bceSAndroid Build Coastguard Worker     int numExts              = 0;
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker     gl.getIntegerv(GL_NUM_EXTENSIONS, &numExts);
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < numExts; ndx++)
72*35238bceSAndroid Build Coastguard Worker     {
73*35238bceSAndroid Build Coastguard Worker         const char *curExt = (const char *)gl.getStringi(GL_EXTENSIONS, ndx);
74*35238bceSAndroid Build Coastguard Worker 
75*35238bceSAndroid Build Coastguard Worker         if (extension == curExt)
76*35238bceSAndroid Build Coastguard Worker             return true;
77*35238bceSAndroid Build Coastguard Worker     }
78*35238bceSAndroid Build Coastguard Worker 
79*35238bceSAndroid Build Coastguard Worker     return false;
80*35238bceSAndroid Build Coastguard Worker }
81*35238bceSAndroid Build Coastguard Worker 
compareSingleColor(tcu::TestLog & log,const tcu::Surface & surface,tcu::RGBA expectedColor,tcu::RGBA threshold)82*35238bceSAndroid Build Coastguard Worker static bool compareSingleColor(tcu::TestLog &log, const tcu::Surface &surface, tcu::RGBA expectedColor,
83*35238bceSAndroid Build Coastguard Worker                                tcu::RGBA threshold)
84*35238bceSAndroid Build Coastguard Worker {
85*35238bceSAndroid Build Coastguard Worker     const int maxPrints = 10;
86*35238bceSAndroid Build Coastguard Worker     int numFailedPixels = 0;
87*35238bceSAndroid Build Coastguard Worker 
88*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Expecting " << expectedColor << " with threshold " << threshold << TestLog::EndMessage;
89*35238bceSAndroid Build Coastguard Worker 
90*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < surface.getHeight(); y++)
91*35238bceSAndroid Build Coastguard Worker     {
92*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < surface.getWidth(); x++)
93*35238bceSAndroid Build Coastguard Worker         {
94*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA resultColor = surface.getPixel(x, y);
95*35238bceSAndroid Build Coastguard Worker             const bool isOk             = compareThreshold(resultColor, expectedColor, threshold);
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker             if (!isOk)
98*35238bceSAndroid Build Coastguard Worker             {
99*35238bceSAndroid Build Coastguard Worker                 if (numFailedPixels < maxPrints)
100*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "ERROR: Got " << resultColor << " at (" << x << ", " << y << ")!"
101*35238bceSAndroid Build Coastguard Worker                         << TestLog::EndMessage;
102*35238bceSAndroid Build Coastguard Worker                 else if (numFailedPixels == maxPrints)
103*35238bceSAndroid Build Coastguard Worker                     log << TestLog::Message << "..." << TestLog::EndMessage;
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker                 numFailedPixels += 1;
106*35238bceSAndroid Build Coastguard Worker             }
107*35238bceSAndroid Build Coastguard Worker         }
108*35238bceSAndroid Build Coastguard Worker     }
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
111*35238bceSAndroid Build Coastguard Worker     {
112*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Found " << numFailedPixels << " invalid pixels, comparison FAILED!"
113*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
114*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("ResultImage", "Result Image", surface);
115*35238bceSAndroid Build Coastguard Worker         return false;
116*35238bceSAndroid Build Coastguard Worker     }
117*35238bceSAndroid Build Coastguard Worker     else
118*35238bceSAndroid Build Coastguard Worker     {
119*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Image comparison passed." << TestLog::EndMessage;
120*35238bceSAndroid Build Coastguard Worker         return true;
121*35238bceSAndroid Build Coastguard Worker     }
122*35238bceSAndroid Build Coastguard Worker }
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker class FragDataIndexingCase : public TestCase
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker public:
FragDataIndexingCase(Context & context,const char * name,const char * description,IndexExprType indexExprType)127*35238bceSAndroid Build Coastguard Worker     FragDataIndexingCase(Context &context, const char *name, const char *description, IndexExprType indexExprType)
128*35238bceSAndroid Build Coastguard Worker         : TestCase(context, name, description)
129*35238bceSAndroid Build Coastguard Worker         , m_indexExprType(indexExprType)
130*35238bceSAndroid Build Coastguard Worker     {
131*35238bceSAndroid Build Coastguard Worker     }
132*35238bceSAndroid Build Coastguard Worker 
genSources(const IndexExprType indexExprType)133*35238bceSAndroid Build Coastguard Worker     static glu::ProgramSources genSources(const IndexExprType indexExprType)
134*35238bceSAndroid Build Coastguard Worker     {
135*35238bceSAndroid Build Coastguard Worker         const char *const fragIndexExpr = indexExprType == INDEX_EXPR_STATIC  ? "0" :
136*35238bceSAndroid Build Coastguard Worker                                           indexExprType == INDEX_EXPR_UNIFORM ? "u_index" :
137*35238bceSAndroid Build Coastguard Worker                                           indexExprType == INDEX_EXPR_DYNAMIC ? "int(v_index)" :
138*35238bceSAndroid Build Coastguard Worker                                                                                 DE_NULL;
139*35238bceSAndroid Build Coastguard Worker         glu::ProgramSources sources;
140*35238bceSAndroid Build Coastguard Worker 
141*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(fragIndexExpr);
142*35238bceSAndroid Build Coastguard Worker 
143*35238bceSAndroid Build Coastguard Worker         sources << glu::VertexSource("attribute highp vec4 a_position;\n"
144*35238bceSAndroid Build Coastguard Worker                                      "attribute highp float a_index;\n"
145*35238bceSAndroid Build Coastguard Worker                                      "attribute highp vec4 a_color;\n"
146*35238bceSAndroid Build Coastguard Worker                                      "varying mediump float v_index;\n"
147*35238bceSAndroid Build Coastguard Worker                                      "varying mediump vec4 v_color;\n"
148*35238bceSAndroid Build Coastguard Worker                                      "void main (void)\n"
149*35238bceSAndroid Build Coastguard Worker                                      "{\n"
150*35238bceSAndroid Build Coastguard Worker                                      "    gl_Position = a_position;\n"
151*35238bceSAndroid Build Coastguard Worker                                      "    v_color = a_color;\n"
152*35238bceSAndroid Build Coastguard Worker                                      "    v_index = a_index;\n"
153*35238bceSAndroid Build Coastguard Worker                                      "}\n");
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker         sources << glu::FragmentSource(string("varying mediump vec4 v_color;\n"
156*35238bceSAndroid Build Coastguard Worker                                               "varying mediump float v_index;\n"
157*35238bceSAndroid Build Coastguard Worker                                               "uniform mediump int u_index;\n"
158*35238bceSAndroid Build Coastguard Worker                                               "void main (void)\n"
159*35238bceSAndroid Build Coastguard Worker                                               "{\n"
160*35238bceSAndroid Build Coastguard Worker                                               "    gl_FragData[") +
161*35238bceSAndroid Build Coastguard Worker                                        fragIndexExpr +
162*35238bceSAndroid Build Coastguard Worker                                        "] = v_color;\n"
163*35238bceSAndroid Build Coastguard Worker                                        "}\n");
164*35238bceSAndroid Build Coastguard Worker 
165*35238bceSAndroid Build Coastguard Worker         return sources;
166*35238bceSAndroid Build Coastguard Worker     }
167*35238bceSAndroid Build Coastguard Worker 
iterate(void)168*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
169*35238bceSAndroid Build Coastguard Worker     {
170*35238bceSAndroid Build Coastguard Worker         const glu::RenderContext &renderCtx = m_context.getRenderContext();
171*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl            = renderCtx.getFunctions();
172*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(renderCtx, genSources(m_indexExprType));
173*35238bceSAndroid Build Coastguard Worker         const int viewportW = de::min(renderCtx.getRenderTarget().getWidth(), 128);
174*35238bceSAndroid Build Coastguard Worker         const int viewportH = de::min(renderCtx.getRenderTarget().getHeight(), 128);
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker         const float positions[]   = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
177*35238bceSAndroid Build Coastguard Worker         const float colors[]      = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
178*35238bceSAndroid Build Coastguard Worker                                      0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
179*35238bceSAndroid Build Coastguard Worker         const float indexValues[] = {0.0f, 0.0f, 0.0f, 0.0f};
180*35238bceSAndroid Build Coastguard Worker         const uint8_t indices[]   = {0, 1, 2, 2, 1, 3};
181*35238bceSAndroid Build Coastguard Worker 
182*35238bceSAndroid Build Coastguard Worker         const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
183*35238bceSAndroid Build Coastguard Worker                                                         glu::va::Float("a_color", 4, 4, 0, &colors[0]),
184*35238bceSAndroid Build Coastguard Worker                                                         glu::va::Float("a_index", 1, 4, 0, &indexValues[0])};
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
189*35238bceSAndroid Build Coastguard Worker         {
190*35238bceSAndroid Build Coastguard Worker             if (m_indexExprType == INDEX_EXPR_STATIC)
191*35238bceSAndroid Build Coastguard Worker                 TCU_FAIL("Compile failed");
192*35238bceSAndroid Build Coastguard Worker             else
193*35238bceSAndroid Build Coastguard Worker                 throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");
194*35238bceSAndroid Build Coastguard Worker         }
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker         gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
197*35238bceSAndroid Build Coastguard Worker         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
198*35238bceSAndroid Build Coastguard Worker 
199*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, viewportW, viewportH);
200*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
201*35238bceSAndroid Build Coastguard Worker         gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_index"), 0);
202*35238bceSAndroid Build Coastguard Worker 
203*35238bceSAndroid Build Coastguard Worker         glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
204*35238bceSAndroid Build Coastguard Worker                   glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
205*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker         {
208*35238bceSAndroid Build Coastguard Worker             tcu::Surface result(viewportW, viewportH);
209*35238bceSAndroid Build Coastguard Worker             const tcu::RGBA threshold =
210*35238bceSAndroid Build Coastguard Worker                 renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
211*35238bceSAndroid Build Coastguard Worker             bool isOk;
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker             glu::readPixels(renderCtx, 0, 0, result.getAccess());
214*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker             isOk = compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold);
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
219*35238bceSAndroid Build Coastguard Worker                                     isOk ? "Pass" : "Image comparison failed");
220*35238bceSAndroid Build Coastguard Worker         }
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker         return STOP;
223*35238bceSAndroid Build Coastguard Worker     }
224*35238bceSAndroid Build Coastguard Worker 
225*35238bceSAndroid Build Coastguard Worker private:
226*35238bceSAndroid Build Coastguard Worker     const IndexExprType m_indexExprType;
227*35238bceSAndroid Build Coastguard Worker };
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker class FragDataDrawBuffersCase : public TestCase
230*35238bceSAndroid Build Coastguard Worker {
231*35238bceSAndroid Build Coastguard Worker public:
FragDataDrawBuffersCase(Context & context)232*35238bceSAndroid Build Coastguard Worker     FragDataDrawBuffersCase(Context &context)
233*35238bceSAndroid Build Coastguard Worker         : TestCase(context, "draw_buffers", "gl_FragData[] and glDrawBuffers() interaction")
234*35238bceSAndroid Build Coastguard Worker     {
235*35238bceSAndroid Build Coastguard Worker     }
236*35238bceSAndroid Build Coastguard Worker 
iterate(void)237*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
238*35238bceSAndroid Build Coastguard Worker     {
239*35238bceSAndroid Build Coastguard Worker         const glu::RenderContext &renderCtx = m_context.getRenderContext();
240*35238bceSAndroid Build Coastguard Worker 
241*35238bceSAndroid Build Coastguard Worker         int num_test_attachment = 2;
242*35238bceSAndroid Build Coastguard Worker         if (!isExtensionSupported(renderCtx, "GL_EXT_draw_buffers") &&
243*35238bceSAndroid Build Coastguard Worker             !isExtensionSupported(renderCtx, "GL_NV_draw_buffers"))
244*35238bceSAndroid Build Coastguard Worker             num_test_attachment = 1;
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker         std::string extensionString;
247*35238bceSAndroid Build Coastguard Worker         if (isExtensionSupported(renderCtx, "GL_EXT_draw_buffers"))
248*35238bceSAndroid Build Coastguard Worker             extensionString = "#extension GL_EXT_draw_buffers : require\n";
249*35238bceSAndroid Build Coastguard Worker         else if (isExtensionSupported(renderCtx, "GL_NV_draw_buffers"))
250*35238bceSAndroid Build Coastguard Worker             extensionString = "#extension GL_NV_draw_buffers : require\n";
251*35238bceSAndroid Build Coastguard Worker 
252*35238bceSAndroid Build Coastguard Worker         const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
253*35238bceSAndroid Build Coastguard Worker                                                         << glu::VertexSource("attribute highp vec4 a_position;\n"
254*35238bceSAndroid Build Coastguard Worker                                                                              "attribute highp vec4 a_color;\n"
255*35238bceSAndroid Build Coastguard Worker                                                                              "varying mediump vec4 v_color;\n"
256*35238bceSAndroid Build Coastguard Worker                                                                              "void main (void)\n"
257*35238bceSAndroid Build Coastguard Worker                                                                              "{\n"
258*35238bceSAndroid Build Coastguard Worker                                                                              "    gl_Position = a_position;\n"
259*35238bceSAndroid Build Coastguard Worker                                                                              "    v_color = a_color;\n"
260*35238bceSAndroid Build Coastguard Worker                                                                              "}\n")
261*35238bceSAndroid Build Coastguard Worker                                                         << glu::FragmentSource(extensionString +
262*35238bceSAndroid Build Coastguard Worker                                                                                "varying mediump vec4 v_color;\n"
263*35238bceSAndroid Build Coastguard Worker                                                                                "uniform mediump int u_index;\n"
264*35238bceSAndroid Build Coastguard Worker                                                                                "void main (void)\n"
265*35238bceSAndroid Build Coastguard Worker                                                                                "{\n"
266*35238bceSAndroid Build Coastguard Worker                                                                                "    gl_FragData[u_index] = v_color;\n"
267*35238bceSAndroid Build Coastguard Worker                                                                                "}\n"));
268*35238bceSAndroid Build Coastguard Worker         const glw::Functions &gl = renderCtx.getFunctions();
269*35238bceSAndroid Build Coastguard Worker         const int width          = 128;
270*35238bceSAndroid Build Coastguard Worker         const int height         = 128;
271*35238bceSAndroid Build Coastguard Worker         const int indexLoc       = program.isOk() ? gl.getUniformLocation(program.getProgram(), "u_index") : -1;
272*35238bceSAndroid Build Coastguard Worker         const glu::Framebuffer fbo(renderCtx);
273*35238bceSAndroid Build Coastguard Worker         const glu::Renderbuffer colorBuf0(renderCtx);
274*35238bceSAndroid Build Coastguard Worker         const glu::Renderbuffer colorBuf1(renderCtx);
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker         const float positions[] = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
277*35238bceSAndroid Build Coastguard Worker         const float colors[]    = {0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
278*35238bceSAndroid Build Coastguard Worker                                    0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};
279*35238bceSAndroid Build Coastguard Worker         const uint8_t indices[] = {0, 1, 2, 2, 1, 3};
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker         const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
282*35238bceSAndroid Build Coastguard Worker                                                         glu::va::Float("a_color", 4, 4, 0, &colors[0])};
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << program;
285*35238bceSAndroid Build Coastguard Worker 
286*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
287*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Dynamic indexing of gl_FragData[] not supported");
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
290*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < num_test_attachment; ndx++)
291*35238bceSAndroid Build Coastguard Worker         {
292*35238bceSAndroid Build Coastguard Worker             const uint32_t rbo = ndx == 0 ? *colorBuf0 : *colorBuf1;
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker             gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
295*35238bceSAndroid Build Coastguard Worker             gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
296*35238bceSAndroid Build Coastguard Worker             gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + ndx, GL_RENDERBUFFER, rbo);
297*35238bceSAndroid Build Coastguard Worker         }
298*35238bceSAndroid Build Coastguard Worker         TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker         {
301*35238bceSAndroid Build Coastguard Worker             const uint32_t drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
302*35238bceSAndroid Build Coastguard Worker             gl.drawBuffers(DE_LENGTH_OF_ARRAY(drawBuffers), &drawBuffers[0]);
303*35238bceSAndroid Build Coastguard Worker         }
304*35238bceSAndroid Build Coastguard Worker 
305*35238bceSAndroid Build Coastguard Worker         gl.viewport(0, 0, width, height);
306*35238bceSAndroid Build Coastguard Worker         gl.useProgram(program.getProgram());
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed");
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker         bool allOk = true;
311*35238bceSAndroid Build Coastguard Worker         const tcu::RGBA threshold =
312*35238bceSAndroid Build Coastguard Worker             renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1, 1, 1, 1);
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < num_test_attachment; ndx++)
315*35238bceSAndroid Build Coastguard Worker         {
316*35238bceSAndroid Build Coastguard Worker             gl.clearBufferfv(GL_COLOR, 0, tcu::RGBA::red().toVec().getPtr());
317*35238bceSAndroid Build Coastguard Worker             gl.clearBufferfv(GL_COLOR, 1, tcu::RGBA::red().toVec().getPtr());
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << "Drawing to attachments " << ndx << TestLog::EndMessage;
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker             gl.uniform1i(indexLoc, ndx);
322*35238bceSAndroid Build Coastguard Worker             glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
323*35238bceSAndroid Build Coastguard Worker                       glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
324*35238bceSAndroid Build Coastguard Worker 
325*35238bceSAndroid Build Coastguard Worker             GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
326*35238bceSAndroid Build Coastguard Worker 
327*35238bceSAndroid Build Coastguard Worker             {
328*35238bceSAndroid Build Coastguard Worker                 tcu::Surface result(width, height);
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << TestLog::Message << "Verifying attachment " << ndx << "..."
331*35238bceSAndroid Build Coastguard Worker                                    << TestLog::EndMessage;
332*35238bceSAndroid Build Coastguard Worker 
333*35238bceSAndroid Build Coastguard Worker                 gl.readBuffer(GL_COLOR_ATTACHMENT0 + ndx);
334*35238bceSAndroid Build Coastguard Worker                 glu::readPixels(renderCtx, 0, 0, result.getAccess());
335*35238bceSAndroid Build Coastguard Worker                 GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker                 if (!compareSingleColor(m_testCtx.getLog(), result, tcu::RGBA::green(), threshold))
338*35238bceSAndroid Build Coastguard Worker                     allOk = false;
339*35238bceSAndroid Build Coastguard Worker             }
340*35238bceSAndroid Build Coastguard Worker         }
341*35238bceSAndroid Build Coastguard Worker 
342*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(allOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
343*35238bceSAndroid Build Coastguard Worker                                 allOk ? "Pass" : "Image comparison failed");
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker         return STOP;
346*35238bceSAndroid Build Coastguard Worker     }
347*35238bceSAndroid Build Coastguard Worker };
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker } // namespace
350*35238bceSAndroid Build Coastguard Worker 
ShaderFragDataTests(Context & context)351*35238bceSAndroid Build Coastguard Worker ShaderFragDataTests::ShaderFragDataTests(Context &context) : TestCaseGroup(context, "fragdata", "gl_FragData[] Tests")
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker }
354*35238bceSAndroid Build Coastguard Worker 
~ShaderFragDataTests(void)355*35238bceSAndroid Build Coastguard Worker ShaderFragDataTests::~ShaderFragDataTests(void)
356*35238bceSAndroid Build Coastguard Worker {
357*35238bceSAndroid Build Coastguard Worker }
358*35238bceSAndroid Build Coastguard Worker 
init(void)359*35238bceSAndroid Build Coastguard Worker void ShaderFragDataTests::init(void)
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker     addChild(new FragDataIndexingCase(m_context, "valid_static_index",
362*35238bceSAndroid Build Coastguard Worker                                       "Valid gl_FragData[] assignment using static index", INDEX_EXPR_STATIC));
363*35238bceSAndroid Build Coastguard Worker     addChild(new FragDataIndexingCase(m_context, "valid_uniform_index",
364*35238bceSAndroid Build Coastguard Worker                                       "Valid gl_FragData[] assignment using uniform index", INDEX_EXPR_UNIFORM));
365*35238bceSAndroid Build Coastguard Worker     addChild(new FragDataIndexingCase(m_context, "valid_dynamic_index",
366*35238bceSAndroid Build Coastguard Worker                                       "Valid gl_FragData[] assignment using dynamic index", INDEX_EXPR_DYNAMIC));
367*35238bceSAndroid Build Coastguard Worker     addChild(new FragDataDrawBuffersCase(m_context));
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker     // Negative cases.
370*35238bceSAndroid Build Coastguard Worker     {
371*35238bceSAndroid Build Coastguard Worker         gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
372*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::TestNode *> negativeCases = library.loadShaderFile("shaders/fragdata.test");
373*35238bceSAndroid Build Coastguard Worker 
374*35238bceSAndroid Build Coastguard Worker         for (std::vector<tcu::TestNode *>::iterator i = negativeCases.begin(); i != negativeCases.end(); i++)
375*35238bceSAndroid Build Coastguard Worker             addChild(*i);
376*35238bceSAndroid Build Coastguard Worker     }
377*35238bceSAndroid Build Coastguard Worker }
378*35238bceSAndroid Build Coastguard Worker 
379*35238bceSAndroid Build Coastguard Worker } // namespace Functional
380*35238bceSAndroid Build Coastguard Worker } // namespace gles3
381*35238bceSAndroid Build Coastguard Worker } // namespace deqp
382