1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program EGL 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 Rendering tests for different config and api combinations.
22*35238bceSAndroid Build Coastguard Worker * \todo [2013-03-19 pyry] GLES1 and VG support.
23*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
24*35238bceSAndroid Build Coastguard Worker
25*35238bceSAndroid Build Coastguard Worker #include "teglRenderTests.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "teglRenderCase.hpp"
27*35238bceSAndroid Build Coastguard Worker
28*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker #include "egluDefs.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "egluUtil.hpp"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker #include "eglwLibrary.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "eglwEnums.hpp"
39*35238bceSAndroid Build Coastguard Worker
40*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
44*35238bceSAndroid Build Coastguard Worker
45*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "deSemaphore.hpp"
48*35238bceSAndroid Build Coastguard Worker #include "deThread.hpp"
49*35238bceSAndroid Build Coastguard Worker #include "deString.h"
50*35238bceSAndroid Build Coastguard Worker
51*35238bceSAndroid Build Coastguard Worker #include "rrRenderer.hpp"
52*35238bceSAndroid Build Coastguard Worker #include "rrFragmentOperations.hpp"
53*35238bceSAndroid Build Coastguard Worker
54*35238bceSAndroid Build Coastguard Worker #include <algorithm>
55*35238bceSAndroid Build Coastguard Worker #include <iterator>
56*35238bceSAndroid Build Coastguard Worker #include <memory>
57*35238bceSAndroid Build Coastguard Worker #include <set>
58*35238bceSAndroid Build Coastguard Worker
59*35238bceSAndroid Build Coastguard Worker namespace deqp
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker namespace egl
62*35238bceSAndroid Build Coastguard Worker {
63*35238bceSAndroid Build Coastguard Worker
64*35238bceSAndroid Build Coastguard Worker using std::set;
65*35238bceSAndroid Build Coastguard Worker using std::string;
66*35238bceSAndroid Build Coastguard Worker using std::vector;
67*35238bceSAndroid Build Coastguard Worker
68*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
71*35238bceSAndroid Build Coastguard Worker
72*35238bceSAndroid Build Coastguard Worker using namespace glw;
73*35238bceSAndroid Build Coastguard Worker using namespace eglw;
74*35238bceSAndroid Build Coastguard Worker
75*35238bceSAndroid Build Coastguard Worker static const tcu::Vec4 CLEAR_COLOR = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
76*35238bceSAndroid Build Coastguard Worker static const float CLEAR_DEPTH = 1.0f;
77*35238bceSAndroid Build Coastguard Worker static const int CLEAR_STENCIL = 0;
78*35238bceSAndroid Build Coastguard Worker
79*35238bceSAndroid Build Coastguard Worker namespace
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker
82*35238bceSAndroid Build Coastguard Worker enum PrimitiveType
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker PRIMITIVETYPE_TRIANGLE = 0, //!< Triangles, requires 3 coordinates per primitive
85*35238bceSAndroid Build Coastguard Worker // PRIMITIVETYPE_POINT, //!< Points, requires 1 coordinate per primitive (w is used as size)
86*35238bceSAndroid Build Coastguard Worker // PRIMITIVETYPE_LINE, //!< Lines, requires 2 coordinates per primitive
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker PRIMITIVETYPE_LAST
89*35238bceSAndroid Build Coastguard Worker };
90*35238bceSAndroid Build Coastguard Worker
91*35238bceSAndroid Build Coastguard Worker enum BlendMode
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker BLENDMODE_NONE = 0, //!< No blending
94*35238bceSAndroid Build Coastguard Worker BLENDMODE_ADDITIVE, //!< Blending with ONE, ONE
95*35238bceSAndroid Build Coastguard Worker BLENDMODE_SRC_OVER, //!< Blending with SRC_ALPHA, ONE_MINUS_SRC_ALPHA
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker BLENDMODE_LAST
98*35238bceSAndroid Build Coastguard Worker };
99*35238bceSAndroid Build Coastguard Worker
100*35238bceSAndroid Build Coastguard Worker enum DepthMode
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker DEPTHMODE_NONE = 0, //!< No depth test or depth writes
103*35238bceSAndroid Build Coastguard Worker DEPTHMODE_LESS, //!< Depth test with less & depth write
104*35238bceSAndroid Build Coastguard Worker
105*35238bceSAndroid Build Coastguard Worker DEPTHMODE_LAST
106*35238bceSAndroid Build Coastguard Worker };
107*35238bceSAndroid Build Coastguard Worker
108*35238bceSAndroid Build Coastguard Worker enum StencilMode
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker STENCILMODE_NONE = 0, //!< No stencil test or write
111*35238bceSAndroid Build Coastguard Worker STENCILMODE_LEQUAL_INC, //!< Stencil test with LEQUAL, increment on pass
112*35238bceSAndroid Build Coastguard Worker
113*35238bceSAndroid Build Coastguard Worker STENCILMODE_LAST
114*35238bceSAndroid Build Coastguard Worker };
115*35238bceSAndroid Build Coastguard Worker
116*35238bceSAndroid Build Coastguard Worker struct DrawPrimitiveOp
117*35238bceSAndroid Build Coastguard Worker {
118*35238bceSAndroid Build Coastguard Worker PrimitiveType type;
119*35238bceSAndroid Build Coastguard Worker int count;
120*35238bceSAndroid Build Coastguard Worker vector<Vec4> positions;
121*35238bceSAndroid Build Coastguard Worker vector<Vec4> colors;
122*35238bceSAndroid Build Coastguard Worker BlendMode blend;
123*35238bceSAndroid Build Coastguard Worker DepthMode depth;
124*35238bceSAndroid Build Coastguard Worker StencilMode stencil;
125*35238bceSAndroid Build Coastguard Worker int stencilRef;
126*35238bceSAndroid Build Coastguard Worker };
127*35238bceSAndroid Build Coastguard Worker
isANarrowScreenSpaceTriangle(const tcu::Vec4 & p0,const tcu::Vec4 & p1,const tcu::Vec4 & p2)128*35238bceSAndroid Build Coastguard Worker static bool isANarrowScreenSpaceTriangle(const tcu::Vec4 &p0, const tcu::Vec4 &p1, const tcu::Vec4 &p2)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker // to clip space
131*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 csp0 = p0.swizzle(0, 1) / p0.w();
132*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 csp1 = p1.swizzle(0, 1) / p1.w();
133*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 csp2 = p2.swizzle(0, 1) / p2.w();
134*35238bceSAndroid Build Coastguard Worker
135*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 e01 = (csp1 - csp0);
136*35238bceSAndroid Build Coastguard Worker const tcu::Vec2 e02 = (csp2 - csp0);
137*35238bceSAndroid Build Coastguard Worker
138*35238bceSAndroid Build Coastguard Worker const float minimumVisibleArea = 0.4f; // must cover at least 10% of the surface
139*35238bceSAndroid Build Coastguard Worker const float visibleArea = de::abs(e01.x() * e02.y() - e02.x() * e01.y()) * 0.5f;
140*35238bceSAndroid Build Coastguard Worker
141*35238bceSAndroid Build Coastguard Worker return visibleArea < minimumVisibleArea;
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
randomizeDrawOp(de::Random & rnd,DrawPrimitiveOp & drawOp,const bool alphaZeroOrOne)144*35238bceSAndroid Build Coastguard Worker void randomizeDrawOp(de::Random &rnd, DrawPrimitiveOp &drawOp, const bool alphaZeroOrOne)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker const int minStencilRef = 0;
147*35238bceSAndroid Build Coastguard Worker const int maxStencilRef = 8;
148*35238bceSAndroid Build Coastguard Worker const int minPrimitives = 2;
149*35238bceSAndroid Build Coastguard Worker const int maxPrimitives = 4;
150*35238bceSAndroid Build Coastguard Worker
151*35238bceSAndroid Build Coastguard Worker const float maxTriOffset = 1.0f;
152*35238bceSAndroid Build Coastguard Worker const float minDepth = -1.0f; // \todo [pyry] Reference doesn't support Z clipping yet
153*35238bceSAndroid Build Coastguard Worker const float maxDepth = 1.0f;
154*35238bceSAndroid Build Coastguard Worker
155*35238bceSAndroid Build Coastguard Worker const float minRGB = 0.2f;
156*35238bceSAndroid Build Coastguard Worker const float maxRGB = 0.9f;
157*35238bceSAndroid Build Coastguard Worker const float minAlpha = 0.3f;
158*35238bceSAndroid Build Coastguard Worker const float maxAlpha = 1.0f;
159*35238bceSAndroid Build Coastguard Worker
160*35238bceSAndroid Build Coastguard Worker drawOp.type = (PrimitiveType)rnd.getInt(0, PRIMITIVETYPE_LAST - 1);
161*35238bceSAndroid Build Coastguard Worker drawOp.count = rnd.getInt(minPrimitives, maxPrimitives);
162*35238bceSAndroid Build Coastguard Worker drawOp.blend = (BlendMode)rnd.getInt(0, BLENDMODE_LAST - 1);
163*35238bceSAndroid Build Coastguard Worker drawOp.depth = (DepthMode)rnd.getInt(0, DEPTHMODE_LAST - 1);
164*35238bceSAndroid Build Coastguard Worker drawOp.stencil = (StencilMode)rnd.getInt(0, STENCILMODE_LAST - 1);
165*35238bceSAndroid Build Coastguard Worker drawOp.stencilRef = rnd.getInt(minStencilRef, maxStencilRef);
166*35238bceSAndroid Build Coastguard Worker
167*35238bceSAndroid Build Coastguard Worker if (drawOp.type == PRIMITIVETYPE_TRIANGLE)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker drawOp.positions.resize(drawOp.count * 3);
170*35238bceSAndroid Build Coastguard Worker drawOp.colors.resize(drawOp.count * 3);
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker for (int triNdx = 0; triNdx < drawOp.count; triNdx++)
173*35238bceSAndroid Build Coastguard Worker {
174*35238bceSAndroid Build Coastguard Worker const float cx = rnd.getFloat(-1.0f, 1.0f);
175*35238bceSAndroid Build Coastguard Worker const float cy = rnd.getFloat(-1.0f, 1.0f);
176*35238bceSAndroid Build Coastguard Worker const float flatAlpha = (rnd.getFloat(minAlpha, maxAlpha) > 0.5f) ? 1.0f : 0.0f;
177*35238bceSAndroid Build Coastguard Worker
178*35238bceSAndroid Build Coastguard Worker for (int coordNdx = 0; coordNdx < 3; coordNdx++)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker tcu::Vec4 &position = drawOp.positions[triNdx * 3 + coordNdx];
181*35238bceSAndroid Build Coastguard Worker tcu::Vec4 &color = drawOp.colors[triNdx * 3 + coordNdx];
182*35238bceSAndroid Build Coastguard Worker
183*35238bceSAndroid Build Coastguard Worker position.x() = cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
184*35238bceSAndroid Build Coastguard Worker position.y() = cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
185*35238bceSAndroid Build Coastguard Worker position.z() = rnd.getFloat(minDepth, maxDepth);
186*35238bceSAndroid Build Coastguard Worker position.w() = 1.0f;
187*35238bceSAndroid Build Coastguard Worker
188*35238bceSAndroid Build Coastguard Worker color.x() = rnd.getFloat(minRGB, maxRGB);
189*35238bceSAndroid Build Coastguard Worker color.y() = rnd.getFloat(minRGB, maxRGB);
190*35238bceSAndroid Build Coastguard Worker color.z() = rnd.getFloat(minRGB, maxRGB);
191*35238bceSAndroid Build Coastguard Worker color.w() = rnd.getFloat(minAlpha, maxAlpha);
192*35238bceSAndroid Build Coastguard Worker
193*35238bceSAndroid Build Coastguard Worker if (alphaZeroOrOne)
194*35238bceSAndroid Build Coastguard Worker {
195*35238bceSAndroid Build Coastguard Worker color.w() = flatAlpha;
196*35238bceSAndroid Build Coastguard Worker }
197*35238bceSAndroid Build Coastguard Worker }
198*35238bceSAndroid Build Coastguard Worker
199*35238bceSAndroid Build Coastguard Worker // avoid generating narrow triangles
200*35238bceSAndroid Build Coastguard Worker {
201*35238bceSAndroid Build Coastguard Worker const int maxAttempts = 100;
202*35238bceSAndroid Build Coastguard Worker int numAttempts = 0;
203*35238bceSAndroid Build Coastguard Worker tcu::Vec4 &p0 = drawOp.positions[triNdx * 3 + 0];
204*35238bceSAndroid Build Coastguard Worker tcu::Vec4 &p1 = drawOp.positions[triNdx * 3 + 1];
205*35238bceSAndroid Build Coastguard Worker tcu::Vec4 &p2 = drawOp.positions[triNdx * 3 + 2];
206*35238bceSAndroid Build Coastguard Worker
207*35238bceSAndroid Build Coastguard Worker while (isANarrowScreenSpaceTriangle(p0, p1, p2))
208*35238bceSAndroid Build Coastguard Worker {
209*35238bceSAndroid Build Coastguard Worker p1.x() = cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
210*35238bceSAndroid Build Coastguard Worker p1.y() = cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
211*35238bceSAndroid Build Coastguard Worker p1.z() = rnd.getFloat(minDepth, maxDepth);
212*35238bceSAndroid Build Coastguard Worker p1.w() = 1.0f;
213*35238bceSAndroid Build Coastguard Worker
214*35238bceSAndroid Build Coastguard Worker p2.x() = cx + rnd.getFloat(-maxTriOffset, maxTriOffset);
215*35238bceSAndroid Build Coastguard Worker p2.y() = cy + rnd.getFloat(-maxTriOffset, maxTriOffset);
216*35238bceSAndroid Build Coastguard Worker p2.z() = rnd.getFloat(minDepth, maxDepth);
217*35238bceSAndroid Build Coastguard Worker p2.w() = 1.0f;
218*35238bceSAndroid Build Coastguard Worker
219*35238bceSAndroid Build Coastguard Worker if (++numAttempts > maxAttempts)
220*35238bceSAndroid Build Coastguard Worker {
221*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
222*35238bceSAndroid Build Coastguard Worker break;
223*35238bceSAndroid Build Coastguard Worker }
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker }
226*35238bceSAndroid Build Coastguard Worker }
227*35238bceSAndroid Build Coastguard Worker }
228*35238bceSAndroid Build Coastguard Worker else
229*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker
232*35238bceSAndroid Build Coastguard Worker // Reference rendering code
233*35238bceSAndroid Build Coastguard Worker
234*35238bceSAndroid Build Coastguard Worker class ReferenceShader : public rr::VertexShader, public rr::FragmentShader
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker public:
237*35238bceSAndroid Build Coastguard Worker enum
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker VaryingLoc_Color = 0
240*35238bceSAndroid Build Coastguard Worker };
241*35238bceSAndroid Build Coastguard Worker
ReferenceShader()242*35238bceSAndroid Build Coastguard Worker ReferenceShader()
243*35238bceSAndroid Build Coastguard Worker : rr::VertexShader(2, 1) // color and pos in => color out
244*35238bceSAndroid Build Coastguard Worker , rr::FragmentShader(1, 1) // color in => color out
245*35238bceSAndroid Build Coastguard Worker {
246*35238bceSAndroid Build Coastguard Worker this->rr::VertexShader::m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
247*35238bceSAndroid Build Coastguard Worker this->rr::VertexShader::m_inputs[1].type = rr::GENERICVECTYPE_FLOAT;
248*35238bceSAndroid Build Coastguard Worker
249*35238bceSAndroid Build Coastguard Worker this->rr::VertexShader::m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
250*35238bceSAndroid Build Coastguard Worker this->rr::VertexShader::m_outputs[0].flatshade = false;
251*35238bceSAndroid Build Coastguard Worker
252*35238bceSAndroid Build Coastguard Worker this->rr::FragmentShader::m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
253*35238bceSAndroid Build Coastguard Worker this->rr::FragmentShader::m_inputs[0].flatshade = false;
254*35238bceSAndroid Build Coastguard Worker
255*35238bceSAndroid Build Coastguard Worker this->rr::FragmentShader::m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
256*35238bceSAndroid Build Coastguard Worker }
257*35238bceSAndroid Build Coastguard Worker
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const258*35238bceSAndroid Build Coastguard Worker void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker const int positionAttrLoc = 0;
263*35238bceSAndroid Build Coastguard Worker const int colorAttrLoc = 1;
264*35238bceSAndroid Build Coastguard Worker
265*35238bceSAndroid Build Coastguard Worker rr::VertexPacket &packet = *packets[packetNdx];
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker // Transform to position
268*35238bceSAndroid Build Coastguard Worker packet.position = rr::readVertexAttribFloat(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx);
269*35238bceSAndroid Build Coastguard Worker
270*35238bceSAndroid Build Coastguard Worker // Pass color to FS
271*35238bceSAndroid Build Coastguard Worker packet.outputs[VaryingLoc_Color] =
272*35238bceSAndroid Build Coastguard Worker rr::readVertexAttribFloat(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx);
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const276*35238bceSAndroid Build Coastguard Worker void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
277*35238bceSAndroid Build Coastguard Worker const rr::FragmentShadingContext &context) const
278*35238bceSAndroid Build Coastguard Worker {
279*35238bceSAndroid Build Coastguard Worker for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker rr::FragmentPacket &packet = packets[packetNdx];
282*35238bceSAndroid Build Coastguard Worker
283*35238bceSAndroid Build Coastguard Worker for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
284*35238bceSAndroid Build Coastguard Worker rr::writeFragmentOutput(context, packetNdx, fragNdx, 0,
285*35238bceSAndroid Build Coastguard Worker rr::readVarying<float>(packet, context, VaryingLoc_Color, fragNdx));
286*35238bceSAndroid Build Coastguard Worker }
287*35238bceSAndroid Build Coastguard Worker }
288*35238bceSAndroid Build Coastguard Worker };
289*35238bceSAndroid Build Coastguard Worker
toReferenceRenderState(rr::RenderState & state,const DrawPrimitiveOp & drawOp)290*35238bceSAndroid Build Coastguard Worker void toReferenceRenderState(rr::RenderState &state, const DrawPrimitiveOp &drawOp)
291*35238bceSAndroid Build Coastguard Worker {
292*35238bceSAndroid Build Coastguard Worker state.cullMode = rr::CULLMODE_NONE;
293*35238bceSAndroid Build Coastguard Worker
294*35238bceSAndroid Build Coastguard Worker if (drawOp.blend != BLENDMODE_NONE)
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker state.fragOps.blendMode = rr::BLENDMODE_STANDARD;
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker switch (drawOp.blend)
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker case BLENDMODE_ADDITIVE:
301*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.srcFunc = rr::BLENDFUNC_ONE;
302*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.dstFunc = rr::BLENDFUNC_ONE;
303*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.equation = rr::BLENDEQUATION_ADD;
304*35238bceSAndroid Build Coastguard Worker state.fragOps.blendAState = state.fragOps.blendRGBState;
305*35238bceSAndroid Build Coastguard Worker break;
306*35238bceSAndroid Build Coastguard Worker
307*35238bceSAndroid Build Coastguard Worker case BLENDMODE_SRC_OVER:
308*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.srcFunc = rr::BLENDFUNC_SRC_ALPHA;
309*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.dstFunc = rr::BLENDFUNC_ONE_MINUS_SRC_ALPHA;
310*35238bceSAndroid Build Coastguard Worker state.fragOps.blendRGBState.equation = rr::BLENDEQUATION_ADD;
311*35238bceSAndroid Build Coastguard Worker state.fragOps.blendAState = state.fragOps.blendRGBState;
312*35238bceSAndroid Build Coastguard Worker break;
313*35238bceSAndroid Build Coastguard Worker
314*35238bceSAndroid Build Coastguard Worker default:
315*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
316*35238bceSAndroid Build Coastguard Worker }
317*35238bceSAndroid Build Coastguard Worker }
318*35238bceSAndroid Build Coastguard Worker
319*35238bceSAndroid Build Coastguard Worker if (drawOp.depth != DEPTHMODE_NONE)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker state.fragOps.depthTestEnabled = true;
322*35238bceSAndroid Build Coastguard Worker
323*35238bceSAndroid Build Coastguard Worker DE_ASSERT(drawOp.depth == DEPTHMODE_LESS);
324*35238bceSAndroid Build Coastguard Worker state.fragOps.depthFunc = rr::TESTFUNC_LESS;
325*35238bceSAndroid Build Coastguard Worker }
326*35238bceSAndroid Build Coastguard Worker
327*35238bceSAndroid Build Coastguard Worker if (drawOp.stencil != STENCILMODE_NONE)
328*35238bceSAndroid Build Coastguard Worker {
329*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilTestEnabled = true;
330*35238bceSAndroid Build Coastguard Worker
331*35238bceSAndroid Build Coastguard Worker DE_ASSERT(drawOp.stencil == STENCILMODE_LEQUAL_INC);
332*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[0].func = rr::TESTFUNC_LEQUAL;
333*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[0].sFail = rr::STENCILOP_KEEP;
334*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[0].dpFail = rr::STENCILOP_INCR;
335*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[0].dpPass = rr::STENCILOP_INCR;
336*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[0].ref = drawOp.stencilRef;
337*35238bceSAndroid Build Coastguard Worker state.fragOps.stencilStates[1] = state.fragOps.stencilStates[0];
338*35238bceSAndroid Build Coastguard Worker }
339*35238bceSAndroid Build Coastguard Worker }
340*35238bceSAndroid Build Coastguard Worker
getColorFormat(const tcu::PixelFormat & colorBits)341*35238bceSAndroid Build Coastguard Worker tcu::TextureFormat getColorFormat(const tcu::PixelFormat &colorBits)
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker using tcu::TextureFormat;
344*35238bceSAndroid Build Coastguard Worker
345*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(colorBits.redBits, 0, 0xff) && de::inBounds(colorBits.greenBits, 0, 0xff) &&
346*35238bceSAndroid Build Coastguard Worker de::inBounds(colorBits.blueBits, 0, 0xff) && de::inBounds(colorBits.alphaBits, 0, 0xff));
347*35238bceSAndroid Build Coastguard Worker
348*35238bceSAndroid Build Coastguard Worker #define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
349*35238bceSAndroid Build Coastguard Worker
350*35238bceSAndroid Build Coastguard Worker // \note [pyry] This may not hold true on some implementations - best effort guess only.
351*35238bceSAndroid Build Coastguard Worker switch (PACK_FMT(colorBits.redBits, colorBits.greenBits, colorBits.blueBits, colorBits.alphaBits))
352*35238bceSAndroid Build Coastguard Worker {
353*35238bceSAndroid Build Coastguard Worker case PACK_FMT(8, 8, 8, 8):
354*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
355*35238bceSAndroid Build Coastguard Worker case PACK_FMT(8, 8, 8, 0):
356*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8);
357*35238bceSAndroid Build Coastguard Worker case PACK_FMT(4, 4, 4, 4):
358*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_4444);
359*35238bceSAndroid Build Coastguard Worker case PACK_FMT(5, 5, 5, 1):
360*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_SHORT_5551);
361*35238bceSAndroid Build Coastguard Worker case PACK_FMT(5, 6, 5, 0):
362*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_SHORT_565);
363*35238bceSAndroid Build Coastguard Worker case PACK_FMT(10, 10, 10, 2):
364*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT_1010102_REV);
365*35238bceSAndroid Build Coastguard Worker case PACK_FMT(10, 10, 10, 0):
366*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT_101010);
367*35238bceSAndroid Build Coastguard Worker // \note Defaults to RGBA8
368*35238bceSAndroid Build Coastguard Worker default:
369*35238bceSAndroid Build Coastguard Worker return TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8);
370*35238bceSAndroid Build Coastguard Worker }
371*35238bceSAndroid Build Coastguard Worker
372*35238bceSAndroid Build Coastguard Worker #undef PACK_FMT
373*35238bceSAndroid Build Coastguard Worker }
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker /*
376*35238bceSAndroid Build Coastguard Worker The getColorThreshold function is used to obtain a
377*35238bceSAndroid Build Coastguard Worker threshold usable for the fuzzyCompare function.
378*35238bceSAndroid Build Coastguard Worker
379*35238bceSAndroid Build Coastguard Worker For 8bit color depths a value of 0.02 should provide
380*35238bceSAndroid Build Coastguard Worker a good metric for rejecting images above this level.
381*35238bceSAndroid Build Coastguard Worker For other bit depths other thresholds should be selected.
382*35238bceSAndroid Build Coastguard Worker Ideally this function would take advantage of the
383*35238bceSAndroid Build Coastguard Worker getColorThreshold function provided by the PixelFormat class
384*35238bceSAndroid Build Coastguard Worker as this would also allow setting per channel thresholds.
385*35238bceSAndroid Build Coastguard Worker However using the PixelFormat provided function can result
386*35238bceSAndroid Build Coastguard Worker in too strict thresholds for 8bit bit depths (compared to
387*35238bceSAndroid Build Coastguard Worker the current default of 0.02) or too relaxed for lower bit
388*35238bceSAndroid Build Coastguard Worker depths if scaled proportionally to the 8bit default.
389*35238bceSAndroid Build Coastguard Worker */
390*35238bceSAndroid Build Coastguard Worker
getColorThreshold(const tcu::PixelFormat & colorBits)391*35238bceSAndroid Build Coastguard Worker float getColorThreshold(const tcu::PixelFormat &colorBits)
392*35238bceSAndroid Build Coastguard Worker {
393*35238bceSAndroid Build Coastguard Worker if ((colorBits.redBits > 0 && colorBits.redBits < 8) || (colorBits.greenBits > 0 && colorBits.greenBits < 8) ||
394*35238bceSAndroid Build Coastguard Worker (colorBits.blueBits > 0 && colorBits.blueBits < 8) || (colorBits.alphaBits > 0 && colorBits.alphaBits < 8))
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker return 0.05f;
397*35238bceSAndroid Build Coastguard Worker }
398*35238bceSAndroid Build Coastguard Worker else
399*35238bceSAndroid Build Coastguard Worker {
400*35238bceSAndroid Build Coastguard Worker return 0.02f;
401*35238bceSAndroid Build Coastguard Worker }
402*35238bceSAndroid Build Coastguard Worker }
403*35238bceSAndroid Build Coastguard Worker
getDepthFormat(const int depthBits)404*35238bceSAndroid Build Coastguard Worker tcu::TextureFormat getDepthFormat(const int depthBits)
405*35238bceSAndroid Build Coastguard Worker {
406*35238bceSAndroid Build Coastguard Worker switch (depthBits)
407*35238bceSAndroid Build Coastguard Worker {
408*35238bceSAndroid Build Coastguard Worker case 0:
409*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat();
410*35238bceSAndroid Build Coastguard Worker case 8:
411*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT8);
412*35238bceSAndroid Build Coastguard Worker case 16:
413*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
414*35238bceSAndroid Build Coastguard Worker case 24:
415*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT24);
416*35238bceSAndroid Build Coastguard Worker case 32:
417*35238bceSAndroid Build Coastguard Worker default:
418*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
419*35238bceSAndroid Build Coastguard Worker }
420*35238bceSAndroid Build Coastguard Worker }
421*35238bceSAndroid Build Coastguard Worker
getStencilFormat(int stencilBits)422*35238bceSAndroid Build Coastguard Worker tcu::TextureFormat getStencilFormat(int stencilBits)
423*35238bceSAndroid Build Coastguard Worker {
424*35238bceSAndroid Build Coastguard Worker switch (stencilBits)
425*35238bceSAndroid Build Coastguard Worker {
426*35238bceSAndroid Build Coastguard Worker case 0:
427*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat();
428*35238bceSAndroid Build Coastguard Worker case 8:
429*35238bceSAndroid Build Coastguard Worker default:
430*35238bceSAndroid Build Coastguard Worker return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker
renderReference(const tcu::PixelBufferAccess & dst,const vector<DrawPrimitiveOp> & drawOps,const tcu::PixelFormat & colorBits,const int depthBits,const int stencilBits,const int numSamples,const int subpixelBits)434*35238bceSAndroid Build Coastguard Worker void renderReference(const tcu::PixelBufferAccess &dst, const vector<DrawPrimitiveOp> &drawOps,
435*35238bceSAndroid Build Coastguard Worker const tcu::PixelFormat &colorBits, const int depthBits, const int stencilBits,
436*35238bceSAndroid Build Coastguard Worker const int numSamples, const int subpixelBits)
437*35238bceSAndroid Build Coastguard Worker {
438*35238bceSAndroid Build Coastguard Worker const int width = dst.getWidth();
439*35238bceSAndroid Build Coastguard Worker const int height = dst.getHeight();
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker tcu::TextureLevel colorBuffer;
442*35238bceSAndroid Build Coastguard Worker tcu::TextureLevel depthBuffer;
443*35238bceSAndroid Build Coastguard Worker tcu::TextureLevel stencilBuffer;
444*35238bceSAndroid Build Coastguard Worker
445*35238bceSAndroid Build Coastguard Worker rr::Renderer referenceRenderer;
446*35238bceSAndroid Build Coastguard Worker rr::VertexAttrib attributes[2];
447*35238bceSAndroid Build Coastguard Worker const ReferenceShader shader;
448*35238bceSAndroid Build Coastguard Worker
449*35238bceSAndroid Build Coastguard Worker attributes[0].type = rr::VERTEXATTRIBTYPE_FLOAT;
450*35238bceSAndroid Build Coastguard Worker attributes[0].size = 4;
451*35238bceSAndroid Build Coastguard Worker attributes[0].stride = 0;
452*35238bceSAndroid Build Coastguard Worker attributes[0].instanceDivisor = 0;
453*35238bceSAndroid Build Coastguard Worker
454*35238bceSAndroid Build Coastguard Worker attributes[1].type = rr::VERTEXATTRIBTYPE_FLOAT;
455*35238bceSAndroid Build Coastguard Worker attributes[1].size = 4;
456*35238bceSAndroid Build Coastguard Worker attributes[1].stride = 0;
457*35238bceSAndroid Build Coastguard Worker attributes[1].instanceDivisor = 0;
458*35238bceSAndroid Build Coastguard Worker
459*35238bceSAndroid Build Coastguard Worker // Initialize buffers.
460*35238bceSAndroid Build Coastguard Worker colorBuffer.setStorage(getColorFormat(colorBits), numSamples, width, height);
461*35238bceSAndroid Build Coastguard Worker rr::clearMultisampleColorBuffer(colorBuffer, CLEAR_COLOR, rr::WindowRectangle(0, 0, width, height));
462*35238bceSAndroid Build Coastguard Worker
463*35238bceSAndroid Build Coastguard Worker if (depthBits > 0)
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker depthBuffer.setStorage(getDepthFormat(depthBits), numSamples, width, height);
466*35238bceSAndroid Build Coastguard Worker rr::clearMultisampleDepthBuffer(depthBuffer, CLEAR_DEPTH, rr::WindowRectangle(0, 0, width, height));
467*35238bceSAndroid Build Coastguard Worker }
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker if (stencilBits > 0)
470*35238bceSAndroid Build Coastguard Worker {
471*35238bceSAndroid Build Coastguard Worker stencilBuffer.setStorage(getStencilFormat(stencilBits), numSamples, width, height);
472*35238bceSAndroid Build Coastguard Worker rr::clearMultisampleStencilBuffer(stencilBuffer, CLEAR_STENCIL, rr::WindowRectangle(0, 0, width, height));
473*35238bceSAndroid Build Coastguard Worker }
474*35238bceSAndroid Build Coastguard Worker
475*35238bceSAndroid Build Coastguard Worker const rr::RenderTarget renderTarget(
476*35238bceSAndroid Build Coastguard Worker rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess()),
477*35238bceSAndroid Build Coastguard Worker rr::MultisamplePixelBufferAccess::fromMultisampleAccess(depthBuffer.getAccess()),
478*35238bceSAndroid Build Coastguard Worker rr::MultisamplePixelBufferAccess::fromMultisampleAccess(stencilBuffer.getAccess()));
479*35238bceSAndroid Build Coastguard Worker
480*35238bceSAndroid Build Coastguard Worker for (vector<DrawPrimitiveOp>::const_iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); drawOp++)
481*35238bceSAndroid Build Coastguard Worker {
482*35238bceSAndroid Build Coastguard Worker // Translate state
483*35238bceSAndroid Build Coastguard Worker rr::RenderState renderState(
484*35238bceSAndroid Build Coastguard Worker (rr::ViewportState)(rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess())),
485*35238bceSAndroid Build Coastguard Worker subpixelBits);
486*35238bceSAndroid Build Coastguard Worker toReferenceRenderState(renderState, *drawOp);
487*35238bceSAndroid Build Coastguard Worker
488*35238bceSAndroid Build Coastguard Worker DE_ASSERT(drawOp->type == PRIMITIVETYPE_TRIANGLE);
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker attributes[0].pointer = &drawOp->positions[0];
491*35238bceSAndroid Build Coastguard Worker attributes[1].pointer = &drawOp->colors[0];
492*35238bceSAndroid Build Coastguard Worker
493*35238bceSAndroid Build Coastguard Worker referenceRenderer.draw(rr::DrawCommand(renderState, renderTarget,
494*35238bceSAndroid Build Coastguard Worker rr::Program(static_cast<const rr::VertexShader *>(&shader),
495*35238bceSAndroid Build Coastguard Worker static_cast<const rr::FragmentShader *>(&shader)),
496*35238bceSAndroid Build Coastguard Worker 2, attributes,
497*35238bceSAndroid Build Coastguard Worker rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, drawOp->count * 3, 0)));
498*35238bceSAndroid Build Coastguard Worker }
499*35238bceSAndroid Build Coastguard Worker
500*35238bceSAndroid Build Coastguard Worker rr::resolveMultisampleColorBuffer(dst,
501*35238bceSAndroid Build Coastguard Worker rr::MultisamplePixelBufferAccess::fromMultisampleAccess(colorBuffer.getAccess()));
502*35238bceSAndroid Build Coastguard Worker }
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker // API rendering code
505*35238bceSAndroid Build Coastguard Worker
506*35238bceSAndroid Build Coastguard Worker class Program
507*35238bceSAndroid Build Coastguard Worker {
508*35238bceSAndroid Build Coastguard Worker public:
Program(void)509*35238bceSAndroid Build Coastguard Worker Program(void)
510*35238bceSAndroid Build Coastguard Worker {
511*35238bceSAndroid Build Coastguard Worker }
~Program(void)512*35238bceSAndroid Build Coastguard Worker virtual ~Program(void)
513*35238bceSAndroid Build Coastguard Worker {
514*35238bceSAndroid Build Coastguard Worker }
515*35238bceSAndroid Build Coastguard Worker
516*35238bceSAndroid Build Coastguard Worker virtual void setup(void) const = DE_NULL;
517*35238bceSAndroid Build Coastguard Worker };
518*35238bceSAndroid Build Coastguard Worker
519*35238bceSAndroid Build Coastguard Worker typedef de::SharedPtr<Program> ProgramSp;
520*35238bceSAndroid Build Coastguard Worker
getProgramSourcesES2(void)521*35238bceSAndroid Build Coastguard Worker static glu::ProgramSources getProgramSourcesES2(void)
522*35238bceSAndroid Build Coastguard Worker {
523*35238bceSAndroid Build Coastguard Worker static const char *s_vertexSrc = "attribute highp vec4 a_position;\n"
524*35238bceSAndroid Build Coastguard Worker "attribute mediump vec4 a_color;\n"
525*35238bceSAndroid Build Coastguard Worker "varying mediump vec4 v_color;\n"
526*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
527*35238bceSAndroid Build Coastguard Worker "{\n"
528*35238bceSAndroid Build Coastguard Worker " gl_Position = a_position;\n"
529*35238bceSAndroid Build Coastguard Worker " v_color = a_color;\n"
530*35238bceSAndroid Build Coastguard Worker "}\n";
531*35238bceSAndroid Build Coastguard Worker
532*35238bceSAndroid Build Coastguard Worker static const char *s_fragmentSrc = "varying mediump vec4 v_color;\n"
533*35238bceSAndroid Build Coastguard Worker "void main (void)\n"
534*35238bceSAndroid Build Coastguard Worker "{\n"
535*35238bceSAndroid Build Coastguard Worker " gl_FragColor = v_color;\n"
536*35238bceSAndroid Build Coastguard Worker "}\n";
537*35238bceSAndroid Build Coastguard Worker
538*35238bceSAndroid Build Coastguard Worker return glu::ProgramSources() << glu::VertexSource(s_vertexSrc) << glu::FragmentSource(s_fragmentSrc);
539*35238bceSAndroid Build Coastguard Worker }
540*35238bceSAndroid Build Coastguard Worker
541*35238bceSAndroid Build Coastguard Worker class GLES2Program : public Program
542*35238bceSAndroid Build Coastguard Worker {
543*35238bceSAndroid Build Coastguard Worker public:
GLES2Program(const glw::Functions & gl)544*35238bceSAndroid Build Coastguard Worker GLES2Program(const glw::Functions &gl)
545*35238bceSAndroid Build Coastguard Worker : m_gl(gl)
546*35238bceSAndroid Build Coastguard Worker , m_program(gl, getProgramSourcesES2())
547*35238bceSAndroid Build Coastguard Worker , m_positionLoc(0)
548*35238bceSAndroid Build Coastguard Worker , m_colorLoc(0)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker
551*35238bceSAndroid Build Coastguard Worker m_positionLoc = m_gl.getAttribLocation(m_program.getProgram(), "a_position");
552*35238bceSAndroid Build Coastguard Worker m_colorLoc = m_gl.getAttribLocation(m_program.getProgram(), "a_color");
553*35238bceSAndroid Build Coastguard Worker }
554*35238bceSAndroid Build Coastguard Worker
~GLES2Program(void)555*35238bceSAndroid Build Coastguard Worker ~GLES2Program(void)
556*35238bceSAndroid Build Coastguard Worker {
557*35238bceSAndroid Build Coastguard Worker }
558*35238bceSAndroid Build Coastguard Worker
setup(void) const559*35238bceSAndroid Build Coastguard Worker void setup(void) const
560*35238bceSAndroid Build Coastguard Worker {
561*35238bceSAndroid Build Coastguard Worker m_gl.useProgram(m_program.getProgram());
562*35238bceSAndroid Build Coastguard Worker m_gl.enableVertexAttribArray(m_positionLoc);
563*35238bceSAndroid Build Coastguard Worker m_gl.enableVertexAttribArray(m_colorLoc);
564*35238bceSAndroid Build Coastguard Worker GLU_CHECK_GLW_MSG(m_gl, "Program setup failed");
565*35238bceSAndroid Build Coastguard Worker }
566*35238bceSAndroid Build Coastguard Worker
getPositionLoc(void) const567*35238bceSAndroid Build Coastguard Worker int getPositionLoc(void) const
568*35238bceSAndroid Build Coastguard Worker {
569*35238bceSAndroid Build Coastguard Worker return m_positionLoc;
570*35238bceSAndroid Build Coastguard Worker }
getColorLoc(void) const571*35238bceSAndroid Build Coastguard Worker int getColorLoc(void) const
572*35238bceSAndroid Build Coastguard Worker {
573*35238bceSAndroid Build Coastguard Worker return m_colorLoc;
574*35238bceSAndroid Build Coastguard Worker }
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker private:
577*35238bceSAndroid Build Coastguard Worker const glw::Functions &m_gl;
578*35238bceSAndroid Build Coastguard Worker glu::ShaderProgram m_program;
579*35238bceSAndroid Build Coastguard Worker int m_positionLoc;
580*35238bceSAndroid Build Coastguard Worker int m_colorLoc;
581*35238bceSAndroid Build Coastguard Worker };
582*35238bceSAndroid Build Coastguard Worker
clearGLES2(const glw::Functions & gl,const tcu::Vec4 & color,const float depth,const int stencil)583*35238bceSAndroid Build Coastguard Worker void clearGLES2(const glw::Functions &gl, const tcu::Vec4 &color, const float depth, const int stencil)
584*35238bceSAndroid Build Coastguard Worker {
585*35238bceSAndroid Build Coastguard Worker gl.clearColor(color.x(), color.y(), color.z(), color.w());
586*35238bceSAndroid Build Coastguard Worker gl.clearDepthf(depth);
587*35238bceSAndroid Build Coastguard Worker gl.clearStencil(stencil);
588*35238bceSAndroid Build Coastguard Worker gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
589*35238bceSAndroid Build Coastguard Worker }
590*35238bceSAndroid Build Coastguard Worker
drawGLES2(const glw::Functions & gl,const Program & program,const DrawPrimitiveOp & drawOp)591*35238bceSAndroid Build Coastguard Worker void drawGLES2(const glw::Functions &gl, const Program &program, const DrawPrimitiveOp &drawOp)
592*35238bceSAndroid Build Coastguard Worker {
593*35238bceSAndroid Build Coastguard Worker const GLES2Program &gles2Program = dynamic_cast<const GLES2Program &>(program);
594*35238bceSAndroid Build Coastguard Worker
595*35238bceSAndroid Build Coastguard Worker switch (drawOp.blend)
596*35238bceSAndroid Build Coastguard Worker {
597*35238bceSAndroid Build Coastguard Worker case BLENDMODE_NONE:
598*35238bceSAndroid Build Coastguard Worker gl.disable(GL_BLEND);
599*35238bceSAndroid Build Coastguard Worker break;
600*35238bceSAndroid Build Coastguard Worker
601*35238bceSAndroid Build Coastguard Worker case BLENDMODE_ADDITIVE:
602*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
603*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_ONE, GL_ONE);
604*35238bceSAndroid Build Coastguard Worker break;
605*35238bceSAndroid Build Coastguard Worker
606*35238bceSAndroid Build Coastguard Worker case BLENDMODE_SRC_OVER:
607*35238bceSAndroid Build Coastguard Worker gl.enable(GL_BLEND);
608*35238bceSAndroid Build Coastguard Worker gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
609*35238bceSAndroid Build Coastguard Worker break;
610*35238bceSAndroid Build Coastguard Worker
611*35238bceSAndroid Build Coastguard Worker default:
612*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
613*35238bceSAndroid Build Coastguard Worker }
614*35238bceSAndroid Build Coastguard Worker
615*35238bceSAndroid Build Coastguard Worker switch (drawOp.depth)
616*35238bceSAndroid Build Coastguard Worker {
617*35238bceSAndroid Build Coastguard Worker case DEPTHMODE_NONE:
618*35238bceSAndroid Build Coastguard Worker gl.disable(GL_DEPTH_TEST);
619*35238bceSAndroid Build Coastguard Worker break;
620*35238bceSAndroid Build Coastguard Worker
621*35238bceSAndroid Build Coastguard Worker case DEPTHMODE_LESS:
622*35238bceSAndroid Build Coastguard Worker gl.enable(GL_DEPTH_TEST);
623*35238bceSAndroid Build Coastguard Worker break;
624*35238bceSAndroid Build Coastguard Worker
625*35238bceSAndroid Build Coastguard Worker default:
626*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
627*35238bceSAndroid Build Coastguard Worker }
628*35238bceSAndroid Build Coastguard Worker
629*35238bceSAndroid Build Coastguard Worker switch (drawOp.stencil)
630*35238bceSAndroid Build Coastguard Worker {
631*35238bceSAndroid Build Coastguard Worker case STENCILMODE_NONE:
632*35238bceSAndroid Build Coastguard Worker gl.disable(GL_STENCIL_TEST);
633*35238bceSAndroid Build Coastguard Worker break;
634*35238bceSAndroid Build Coastguard Worker
635*35238bceSAndroid Build Coastguard Worker case STENCILMODE_LEQUAL_INC:
636*35238bceSAndroid Build Coastguard Worker gl.enable(GL_STENCIL_TEST);
637*35238bceSAndroid Build Coastguard Worker gl.stencilFunc(GL_LEQUAL, drawOp.stencilRef, ~0u);
638*35238bceSAndroid Build Coastguard Worker gl.stencilOp(GL_KEEP, GL_INCR, GL_INCR);
639*35238bceSAndroid Build Coastguard Worker break;
640*35238bceSAndroid Build Coastguard Worker
641*35238bceSAndroid Build Coastguard Worker default:
642*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
643*35238bceSAndroid Build Coastguard Worker }
644*35238bceSAndroid Build Coastguard Worker
645*35238bceSAndroid Build Coastguard Worker gl.disable(GL_DITHER);
646*35238bceSAndroid Build Coastguard Worker
647*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(gles2Program.getPositionLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.positions[0]);
648*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(gles2Program.getColorLoc(), 4, GL_FLOAT, GL_FALSE, 0, &drawOp.colors[0]);
649*35238bceSAndroid Build Coastguard Worker
650*35238bceSAndroid Build Coastguard Worker DE_ASSERT(drawOp.type == PRIMITIVETYPE_TRIANGLE);
651*35238bceSAndroid Build Coastguard Worker gl.drawArrays(GL_TRIANGLES, 0, drawOp.count * 3);
652*35238bceSAndroid Build Coastguard Worker }
653*35238bceSAndroid Build Coastguard Worker
readPixelsGLES2(const glw::Functions & gl,tcu::Surface & dst)654*35238bceSAndroid Build Coastguard Worker static void readPixelsGLES2(const glw::Functions &gl, tcu::Surface &dst)
655*35238bceSAndroid Build Coastguard Worker {
656*35238bceSAndroid Build Coastguard Worker gl.readPixels(0, 0, dst.getWidth(), dst.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
657*35238bceSAndroid Build Coastguard Worker }
658*35238bceSAndroid Build Coastguard Worker
createProgram(const glw::Functions & gl,EGLint api)659*35238bceSAndroid Build Coastguard Worker Program *createProgram(const glw::Functions &gl, EGLint api)
660*35238bceSAndroid Build Coastguard Worker {
661*35238bceSAndroid Build Coastguard Worker switch (api)
662*35238bceSAndroid Build Coastguard Worker {
663*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES2_BIT:
664*35238bceSAndroid Build Coastguard Worker return new GLES2Program(gl);
665*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES3_BIT_KHR:
666*35238bceSAndroid Build Coastguard Worker return new GLES2Program(gl);
667*35238bceSAndroid Build Coastguard Worker default:
668*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Unsupported API");
669*35238bceSAndroid Build Coastguard Worker }
670*35238bceSAndroid Build Coastguard Worker }
671*35238bceSAndroid Build Coastguard Worker
draw(const glw::Functions & gl,EGLint api,const Program & program,const DrawPrimitiveOp & drawOp)672*35238bceSAndroid Build Coastguard Worker void draw(const glw::Functions &gl, EGLint api, const Program &program, const DrawPrimitiveOp &drawOp)
673*35238bceSAndroid Build Coastguard Worker {
674*35238bceSAndroid Build Coastguard Worker switch (api)
675*35238bceSAndroid Build Coastguard Worker {
676*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES2_BIT:
677*35238bceSAndroid Build Coastguard Worker drawGLES2(gl, program, drawOp);
678*35238bceSAndroid Build Coastguard Worker break;
679*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES3_BIT_KHR:
680*35238bceSAndroid Build Coastguard Worker drawGLES2(gl, program, drawOp);
681*35238bceSAndroid Build Coastguard Worker break;
682*35238bceSAndroid Build Coastguard Worker default:
683*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Unsupported API");
684*35238bceSAndroid Build Coastguard Worker }
685*35238bceSAndroid Build Coastguard Worker }
686*35238bceSAndroid Build Coastguard Worker
clear(const glw::Functions & gl,EGLint api,const tcu::Vec4 & color,const float depth,const int stencil)687*35238bceSAndroid Build Coastguard Worker void clear(const glw::Functions &gl, EGLint api, const tcu::Vec4 &color, const float depth, const int stencil)
688*35238bceSAndroid Build Coastguard Worker {
689*35238bceSAndroid Build Coastguard Worker switch (api)
690*35238bceSAndroid Build Coastguard Worker {
691*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES2_BIT:
692*35238bceSAndroid Build Coastguard Worker clearGLES2(gl, color, depth, stencil);
693*35238bceSAndroid Build Coastguard Worker break;
694*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES3_BIT_KHR:
695*35238bceSAndroid Build Coastguard Worker clearGLES2(gl, color, depth, stencil);
696*35238bceSAndroid Build Coastguard Worker break;
697*35238bceSAndroid Build Coastguard Worker default:
698*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Unsupported API");
699*35238bceSAndroid Build Coastguard Worker }
700*35238bceSAndroid Build Coastguard Worker }
701*35238bceSAndroid Build Coastguard Worker
readPixels(const glw::Functions & gl,EGLint api,tcu::Surface & dst)702*35238bceSAndroid Build Coastguard Worker static void readPixels(const glw::Functions &gl, EGLint api, tcu::Surface &dst)
703*35238bceSAndroid Build Coastguard Worker {
704*35238bceSAndroid Build Coastguard Worker switch (api)
705*35238bceSAndroid Build Coastguard Worker {
706*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES2_BIT:
707*35238bceSAndroid Build Coastguard Worker readPixelsGLES2(gl, dst);
708*35238bceSAndroid Build Coastguard Worker break;
709*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES3_BIT_KHR:
710*35238bceSAndroid Build Coastguard Worker readPixelsGLES2(gl, dst);
711*35238bceSAndroid Build Coastguard Worker break;
712*35238bceSAndroid Build Coastguard Worker default:
713*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Unsupported API");
714*35238bceSAndroid Build Coastguard Worker }
715*35238bceSAndroid Build Coastguard Worker }
716*35238bceSAndroid Build Coastguard Worker
finish(const glw::Functions & gl,EGLint api)717*35238bceSAndroid Build Coastguard Worker static void finish(const glw::Functions &gl, EGLint api)
718*35238bceSAndroid Build Coastguard Worker {
719*35238bceSAndroid Build Coastguard Worker switch (api)
720*35238bceSAndroid Build Coastguard Worker {
721*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES2_BIT:
722*35238bceSAndroid Build Coastguard Worker case EGL_OPENGL_ES3_BIT_KHR:
723*35238bceSAndroid Build Coastguard Worker gl.finish();
724*35238bceSAndroid Build Coastguard Worker break;
725*35238bceSAndroid Build Coastguard Worker
726*35238bceSAndroid Build Coastguard Worker default:
727*35238bceSAndroid Build Coastguard Worker throw tcu::NotSupportedError("Unsupported API");
728*35238bceSAndroid Build Coastguard Worker }
729*35238bceSAndroid Build Coastguard Worker }
730*35238bceSAndroid Build Coastguard Worker
getPixelFormat(const Library & egl,EGLDisplay display,EGLConfig config)731*35238bceSAndroid Build Coastguard Worker tcu::PixelFormat getPixelFormat(const Library &egl, EGLDisplay display, EGLConfig config)
732*35238bceSAndroid Build Coastguard Worker {
733*35238bceSAndroid Build Coastguard Worker tcu::PixelFormat fmt;
734*35238bceSAndroid Build Coastguard Worker fmt.redBits = eglu::getConfigAttribInt(egl, display, config, EGL_RED_SIZE);
735*35238bceSAndroid Build Coastguard Worker fmt.greenBits = eglu::getConfigAttribInt(egl, display, config, EGL_GREEN_SIZE);
736*35238bceSAndroid Build Coastguard Worker fmt.blueBits = eglu::getConfigAttribInt(egl, display, config, EGL_BLUE_SIZE);
737*35238bceSAndroid Build Coastguard Worker fmt.alphaBits = eglu::getConfigAttribInt(egl, display, config, EGL_ALPHA_SIZE);
738*35238bceSAndroid Build Coastguard Worker return fmt;
739*35238bceSAndroid Build Coastguard Worker }
740*35238bceSAndroid Build Coastguard Worker
741*35238bceSAndroid Build Coastguard Worker } // namespace
742*35238bceSAndroid Build Coastguard Worker
743*35238bceSAndroid Build Coastguard Worker // SingleThreadRenderCase
744*35238bceSAndroid Build Coastguard Worker
745*35238bceSAndroid Build Coastguard Worker class SingleThreadRenderCase : public MultiContextRenderCase
746*35238bceSAndroid Build Coastguard Worker {
747*35238bceSAndroid Build Coastguard Worker public:
748*35238bceSAndroid Build Coastguard Worker SingleThreadRenderCase(EglTestContext &eglTestCtx, const char *name, const char *description, EGLint api,
749*35238bceSAndroid Build Coastguard Worker EGLint surfaceType, const eglu::FilterList &filters, int numContextsPerApi);
750*35238bceSAndroid Build Coastguard Worker
751*35238bceSAndroid Build Coastguard Worker void init(void);
752*35238bceSAndroid Build Coastguard Worker
753*35238bceSAndroid Build Coastguard Worker private:
754*35238bceSAndroid Build Coastguard Worker virtual void executeForContexts(EGLDisplay display, EGLSurface surface, const Config &config,
755*35238bceSAndroid Build Coastguard Worker const std::vector<std::pair<EGLint, EGLContext>> &contexts);
756*35238bceSAndroid Build Coastguard Worker
757*35238bceSAndroid Build Coastguard Worker glw::Functions m_gl;
758*35238bceSAndroid Build Coastguard Worker };
759*35238bceSAndroid Build Coastguard Worker
760*35238bceSAndroid Build Coastguard Worker // SingleThreadColorClearCase
761*35238bceSAndroid Build Coastguard Worker
SingleThreadRenderCase(EglTestContext & eglTestCtx,const char * name,const char * description,EGLint api,EGLint surfaceType,const eglu::FilterList & filters,int numContextsPerApi)762*35238bceSAndroid Build Coastguard Worker SingleThreadRenderCase::SingleThreadRenderCase(EglTestContext &eglTestCtx, const char *name, const char *description,
763*35238bceSAndroid Build Coastguard Worker EGLint api, EGLint surfaceType, const eglu::FilterList &filters,
764*35238bceSAndroid Build Coastguard Worker int numContextsPerApi)
765*35238bceSAndroid Build Coastguard Worker : MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
766*35238bceSAndroid Build Coastguard Worker {
767*35238bceSAndroid Build Coastguard Worker }
768*35238bceSAndroid Build Coastguard Worker
init(void)769*35238bceSAndroid Build Coastguard Worker void SingleThreadRenderCase::init(void)
770*35238bceSAndroid Build Coastguard Worker {
771*35238bceSAndroid Build Coastguard Worker MultiContextRenderCase::init();
772*35238bceSAndroid Build Coastguard Worker m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0));
773*35238bceSAndroid Build Coastguard Worker }
774*35238bceSAndroid Build Coastguard Worker
executeForContexts(EGLDisplay display,EGLSurface surface,const Config & config,const std::vector<std::pair<EGLint,EGLContext>> & contexts)775*35238bceSAndroid Build Coastguard Worker void SingleThreadRenderCase::executeForContexts(EGLDisplay display, EGLSurface surface, const Config &config,
776*35238bceSAndroid Build Coastguard Worker const std::vector<std::pair<EGLint, EGLContext>> &contexts)
777*35238bceSAndroid Build Coastguard Worker {
778*35238bceSAndroid Build Coastguard Worker const Library &egl = m_eglTestCtx.getLibrary();
779*35238bceSAndroid Build Coastguard Worker const int width = eglu::querySurfaceInt(egl, display, surface, EGL_WIDTH);
780*35238bceSAndroid Build Coastguard Worker const int height = eglu::querySurfaceInt(egl, display, surface, EGL_HEIGHT);
781*35238bceSAndroid Build Coastguard Worker const int numContexts = (int)contexts.size();
782*35238bceSAndroid Build Coastguard Worker const int drawsPerCtx = 2;
783*35238bceSAndroid Build Coastguard Worker const int numIters = 2;
784*35238bceSAndroid Build Coastguard Worker const tcu::PixelFormat pixelFmt = getPixelFormat(egl, display, config.config);
785*35238bceSAndroid Build Coastguard Worker const float threshold = getColorThreshold(pixelFmt);
786*35238bceSAndroid Build Coastguard Worker
787*35238bceSAndroid Build Coastguard Worker const int depthBits = eglu::getConfigAttribInt(egl, display, config.config, EGL_DEPTH_SIZE);
788*35238bceSAndroid Build Coastguard Worker const int stencilBits = eglu::getConfigAttribInt(egl, display, config.config, EGL_STENCIL_SIZE);
789*35238bceSAndroid Build Coastguard Worker const int numSamples = eglu::getConfigAttribInt(egl, display, config.config, EGL_SAMPLES);
790*35238bceSAndroid Build Coastguard Worker
791*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
792*35238bceSAndroid Build Coastguard Worker
793*35238bceSAndroid Build Coastguard Worker tcu::Surface refFrame(width, height);
794*35238bceSAndroid Build Coastguard Worker tcu::Surface frame(width, height);
795*35238bceSAndroid Build Coastguard Worker
796*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()) ^ deInt32Hash(numContexts));
797*35238bceSAndroid Build Coastguard Worker vector<ProgramSp> programs(contexts.size());
798*35238bceSAndroid Build Coastguard Worker vector<DrawPrimitiveOp> drawOps;
799*35238bceSAndroid Build Coastguard Worker
800*35238bceSAndroid Build Coastguard Worker // Log basic information about config.
801*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_RED_SIZE = " << pixelFmt.redBits << TestLog::EndMessage;
802*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_GREEN_SIZE = " << pixelFmt.greenBits << TestLog::EndMessage;
803*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_BLUE_SIZE = " << pixelFmt.blueBits << TestLog::EndMessage;
804*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_ALPHA_SIZE = " << pixelFmt.alphaBits << TestLog::EndMessage;
805*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_DEPTH_SIZE = " << depthBits << TestLog::EndMessage;
806*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_STENCIL_SIZE = " << stencilBits << TestLog::EndMessage;
807*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_SAMPLES = " << numSamples << TestLog::EndMessage;
808*35238bceSAndroid Build Coastguard Worker
809*35238bceSAndroid Build Coastguard Worker // Generate draw ops.
810*35238bceSAndroid Build Coastguard Worker drawOps.resize(numContexts * drawsPerCtx * numIters);
811*35238bceSAndroid Build Coastguard Worker for (vector<DrawPrimitiveOp>::iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); ++drawOp)
812*35238bceSAndroid Build Coastguard Worker {
813*35238bceSAndroid Build Coastguard Worker // The randomized draws force us to use the fuzzyCompare algorithm to check for possible rasterization differences between
814*35238bceSAndroid Build Coastguard Worker // our rasterizer and the one used by the implementation. However, fuzzyCompare only takes a single float as the error
815*35238bceSAndroid Build Coastguard Worker // threshold. As per the comments in the code, that threshold doesn't have a direct equivalent to a difference in color
816*35238bceSAndroid Build Coastguard Worker // values. Instead, it's related to an accumulated quadratic error. Also according to these comments, this works well for
817*35238bceSAndroid Build Coastguard Worker // rgba8 (the only case it was originally designed for), and it can also be made to work for other formats in which all
818*35238bceSAndroid Build Coastguard Worker // used channels have a roughly similar number of bits.
819*35238bceSAndroid Build Coastguard Worker //
820*35238bceSAndroid Build Coastguard Worker // However, in some of these tests we will run this code using formats such as rgb10a2, in which the alpha can only have
821*35238bceSAndroid Build Coastguard Worker // values of 0, 0.33, 0.66 and 1.0 while other channels have much more precission. Any small difference in the rounding
822*35238bceSAndroid Build Coastguard Worker // applied by CTS and the implementation could result in wildly different alpha values that make using the single floating
823*35238bceSAndroid Build Coastguard Worker // point threshold risky, because we can't separate the alpha errors from the rgb errors. If we increase the threshold to
824*35238bceSAndroid Build Coastguard Worker // a point which is acceptable for alpha errors, the kind of errors we allow in the colors would be huge.
825*35238bceSAndroid Build Coastguard Worker //
826*35238bceSAndroid Build Coastguard Worker // For this reason, with 2 bits for alpha we restrict ourselves to alpha values of 1.0 and 0.0, as if alphabits was 1.
827*35238bceSAndroid Build Coastguard Worker randomizeDrawOp(rnd, *drawOp, (pixelFmt.alphaBits <= 2));
828*35238bceSAndroid Build Coastguard Worker }
829*35238bceSAndroid Build Coastguard Worker
830*35238bceSAndroid Build Coastguard Worker // Create and setup programs per context
831*35238bceSAndroid Build Coastguard Worker for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
832*35238bceSAndroid Build Coastguard Worker {
833*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[ctxNdx].first;
834*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[ctxNdx].second;
835*35238bceSAndroid Build Coastguard Worker
836*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
837*35238bceSAndroid Build Coastguard Worker
838*35238bceSAndroid Build Coastguard Worker programs[ctxNdx] = ProgramSp(createProgram(m_gl, api));
839*35238bceSAndroid Build Coastguard Worker programs[ctxNdx]->setup();
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker
842*35238bceSAndroid Build Coastguard Worker // Clear to black using first context.
843*35238bceSAndroid Build Coastguard Worker {
844*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[0].first;
845*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[0].second;
846*35238bceSAndroid Build Coastguard Worker
847*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
848*35238bceSAndroid Build Coastguard Worker
849*35238bceSAndroid Build Coastguard Worker clear(m_gl, api, CLEAR_COLOR, CLEAR_DEPTH, CLEAR_STENCIL);
850*35238bceSAndroid Build Coastguard Worker finish(m_gl, api);
851*35238bceSAndroid Build Coastguard Worker }
852*35238bceSAndroid Build Coastguard Worker
853*35238bceSAndroid Build Coastguard Worker // Render.
854*35238bceSAndroid Build Coastguard Worker for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
855*35238bceSAndroid Build Coastguard Worker {
856*35238bceSAndroid Build Coastguard Worker for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
857*35238bceSAndroid Build Coastguard Worker {
858*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[ctxNdx].first;
859*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[ctxNdx].second;
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
862*35238bceSAndroid Build Coastguard Worker
863*35238bceSAndroid Build Coastguard Worker for (int drawNdx = 0; drawNdx < drawsPerCtx; drawNdx++)
864*35238bceSAndroid Build Coastguard Worker {
865*35238bceSAndroid Build Coastguard Worker const DrawPrimitiveOp &drawOp =
866*35238bceSAndroid Build Coastguard Worker drawOps[iterNdx * numContexts * drawsPerCtx + ctxNdx * drawsPerCtx + drawNdx];
867*35238bceSAndroid Build Coastguard Worker draw(m_gl, api, *programs[ctxNdx], drawOp);
868*35238bceSAndroid Build Coastguard Worker }
869*35238bceSAndroid Build Coastguard Worker
870*35238bceSAndroid Build Coastguard Worker finish(m_gl, api);
871*35238bceSAndroid Build Coastguard Worker }
872*35238bceSAndroid Build Coastguard Worker }
873*35238bceSAndroid Build Coastguard Worker
874*35238bceSAndroid Build Coastguard Worker // Read pixels using first context. \todo [pyry] Randomize?
875*35238bceSAndroid Build Coastguard Worker {
876*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[0].first;
877*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[0].second;
878*35238bceSAndroid Build Coastguard Worker
879*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
880*35238bceSAndroid Build Coastguard Worker
881*35238bceSAndroid Build Coastguard Worker readPixels(m_gl, api, frame);
882*35238bceSAndroid Build Coastguard Worker }
883*35238bceSAndroid Build Coastguard Worker
884*35238bceSAndroid Build Coastguard Worker int subpixelBits = 0;
885*35238bceSAndroid Build Coastguard Worker m_gl.getIntegerv(GL_SUBPIXEL_BITS, &subpixelBits);
886*35238bceSAndroid Build Coastguard Worker
887*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
888*35238bceSAndroid Build Coastguard Worker
889*35238bceSAndroid Build Coastguard Worker // Render reference.
890*35238bceSAndroid Build Coastguard Worker // \note Reference image is always generated using single-sampling.
891*35238bceSAndroid Build Coastguard Worker renderReference(refFrame.getAccess(), drawOps, pixelFmt, depthBits, stencilBits, 1, subpixelBits);
892*35238bceSAndroid Build Coastguard Worker
893*35238bceSAndroid Build Coastguard Worker // Compare images
894*35238bceSAndroid Build Coastguard Worker {
895*35238bceSAndroid Build Coastguard Worker bool imagesOk = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame,
896*35238bceSAndroid Build Coastguard Worker threshold, tcu::COMPARE_LOG_RESULT);
897*35238bceSAndroid Build Coastguard Worker
898*35238bceSAndroid Build Coastguard Worker if (!imagesOk)
899*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
900*35238bceSAndroid Build Coastguard Worker }
901*35238bceSAndroid Build Coastguard Worker }
902*35238bceSAndroid Build Coastguard Worker
903*35238bceSAndroid Build Coastguard Worker // MultiThreadRenderCase
904*35238bceSAndroid Build Coastguard Worker
905*35238bceSAndroid Build Coastguard Worker class MultiThreadRenderCase : public MultiContextRenderCase
906*35238bceSAndroid Build Coastguard Worker {
907*35238bceSAndroid Build Coastguard Worker public:
908*35238bceSAndroid Build Coastguard Worker MultiThreadRenderCase(EglTestContext &eglTestCtx, const char *name, const char *description, EGLint api,
909*35238bceSAndroid Build Coastguard Worker EGLint surfaceType, const eglu::FilterList &filters, int numContextsPerApi);
910*35238bceSAndroid Build Coastguard Worker
911*35238bceSAndroid Build Coastguard Worker void init(void);
912*35238bceSAndroid Build Coastguard Worker
913*35238bceSAndroid Build Coastguard Worker private:
914*35238bceSAndroid Build Coastguard Worker virtual void executeForContexts(EGLDisplay display, EGLSurface surface, const Config &config,
915*35238bceSAndroid Build Coastguard Worker const std::vector<std::pair<EGLint, EGLContext>> &contexts);
916*35238bceSAndroid Build Coastguard Worker
917*35238bceSAndroid Build Coastguard Worker glw::Functions m_gl;
918*35238bceSAndroid Build Coastguard Worker };
919*35238bceSAndroid Build Coastguard Worker
920*35238bceSAndroid Build Coastguard Worker class RenderTestThread;
921*35238bceSAndroid Build Coastguard Worker
922*35238bceSAndroid Build Coastguard Worker typedef de::SharedPtr<RenderTestThread> RenderTestThreadSp;
923*35238bceSAndroid Build Coastguard Worker typedef de::SharedPtr<de::Semaphore> SemaphoreSp;
924*35238bceSAndroid Build Coastguard Worker
925*35238bceSAndroid Build Coastguard Worker struct DrawOpPacket
926*35238bceSAndroid Build Coastguard Worker {
DrawOpPacketdeqp::egl::DrawOpPacket927*35238bceSAndroid Build Coastguard Worker DrawOpPacket(void) : drawOps(DE_NULL), numOps(0)
928*35238bceSAndroid Build Coastguard Worker {
929*35238bceSAndroid Build Coastguard Worker }
930*35238bceSAndroid Build Coastguard Worker
931*35238bceSAndroid Build Coastguard Worker const DrawPrimitiveOp *drawOps;
932*35238bceSAndroid Build Coastguard Worker int numOps;
933*35238bceSAndroid Build Coastguard Worker SemaphoreSp wait;
934*35238bceSAndroid Build Coastguard Worker SemaphoreSp signal;
935*35238bceSAndroid Build Coastguard Worker };
936*35238bceSAndroid Build Coastguard Worker
937*35238bceSAndroid Build Coastguard Worker class RenderTestThread : public de::Thread
938*35238bceSAndroid Build Coastguard Worker {
939*35238bceSAndroid Build Coastguard Worker public:
RenderTestThread(const Library & egl,EGLDisplay display,EGLSurface surface,EGLContext context,EGLint api,const glw::Functions & gl,const Program & program,const std::vector<DrawOpPacket> & packets)940*35238bceSAndroid Build Coastguard Worker RenderTestThread(const Library &egl, EGLDisplay display, EGLSurface surface, EGLContext context, EGLint api,
941*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl, const Program &program, const std::vector<DrawOpPacket> &packets)
942*35238bceSAndroid Build Coastguard Worker : m_egl(egl)
943*35238bceSAndroid Build Coastguard Worker , m_display(display)
944*35238bceSAndroid Build Coastguard Worker , m_surface(surface)
945*35238bceSAndroid Build Coastguard Worker , m_context(context)
946*35238bceSAndroid Build Coastguard Worker , m_api(api)
947*35238bceSAndroid Build Coastguard Worker , m_gl(gl)
948*35238bceSAndroid Build Coastguard Worker , m_program(program)
949*35238bceSAndroid Build Coastguard Worker , m_packets(packets)
950*35238bceSAndroid Build Coastguard Worker {
951*35238bceSAndroid Build Coastguard Worker }
952*35238bceSAndroid Build Coastguard Worker
run(void)953*35238bceSAndroid Build Coastguard Worker void run(void)
954*35238bceSAndroid Build Coastguard Worker {
955*35238bceSAndroid Build Coastguard Worker for (std::vector<DrawOpPacket>::const_iterator packetIter = m_packets.begin(); packetIter != m_packets.end();
956*35238bceSAndroid Build Coastguard Worker packetIter++)
957*35238bceSAndroid Build Coastguard Worker {
958*35238bceSAndroid Build Coastguard Worker // Wait until it is our turn.
959*35238bceSAndroid Build Coastguard Worker packetIter->wait->decrement();
960*35238bceSAndroid Build Coastguard Worker
961*35238bceSAndroid Build Coastguard Worker // Acquire context.
962*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, m_surface, m_surface, m_context));
963*35238bceSAndroid Build Coastguard Worker
964*35238bceSAndroid Build Coastguard Worker // Execute rendering.
965*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < packetIter->numOps; ndx++)
966*35238bceSAndroid Build Coastguard Worker draw(m_gl, m_api, m_program, packetIter->drawOps[ndx]);
967*35238bceSAndroid Build Coastguard Worker
968*35238bceSAndroid Build Coastguard Worker finish(m_gl, m_api);
969*35238bceSAndroid Build Coastguard Worker
970*35238bceSAndroid Build Coastguard Worker // Release context.
971*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
972*35238bceSAndroid Build Coastguard Worker
973*35238bceSAndroid Build Coastguard Worker // Signal completion.
974*35238bceSAndroid Build Coastguard Worker packetIter->signal->increment();
975*35238bceSAndroid Build Coastguard Worker }
976*35238bceSAndroid Build Coastguard Worker m_egl.releaseThread();
977*35238bceSAndroid Build Coastguard Worker }
978*35238bceSAndroid Build Coastguard Worker
979*35238bceSAndroid Build Coastguard Worker private:
980*35238bceSAndroid Build Coastguard Worker const Library &m_egl;
981*35238bceSAndroid Build Coastguard Worker EGLDisplay m_display;
982*35238bceSAndroid Build Coastguard Worker EGLSurface m_surface;
983*35238bceSAndroid Build Coastguard Worker EGLContext m_context;
984*35238bceSAndroid Build Coastguard Worker EGLint m_api;
985*35238bceSAndroid Build Coastguard Worker const glw::Functions &m_gl;
986*35238bceSAndroid Build Coastguard Worker const Program &m_program;
987*35238bceSAndroid Build Coastguard Worker const std::vector<DrawOpPacket> &m_packets;
988*35238bceSAndroid Build Coastguard Worker };
989*35238bceSAndroid Build Coastguard Worker
MultiThreadRenderCase(EglTestContext & eglTestCtx,const char * name,const char * description,EGLint api,EGLint surfaceType,const eglu::FilterList & filters,int numContextsPerApi)990*35238bceSAndroid Build Coastguard Worker MultiThreadRenderCase::MultiThreadRenderCase(EglTestContext &eglTestCtx, const char *name, const char *description,
991*35238bceSAndroid Build Coastguard Worker EGLint api, EGLint surfaceType, const eglu::FilterList &filters,
992*35238bceSAndroid Build Coastguard Worker int numContextsPerApi)
993*35238bceSAndroid Build Coastguard Worker : MultiContextRenderCase(eglTestCtx, name, description, api, surfaceType, filters, numContextsPerApi)
994*35238bceSAndroid Build Coastguard Worker {
995*35238bceSAndroid Build Coastguard Worker }
996*35238bceSAndroid Build Coastguard Worker
init(void)997*35238bceSAndroid Build Coastguard Worker void MultiThreadRenderCase::init(void)
998*35238bceSAndroid Build Coastguard Worker {
999*35238bceSAndroid Build Coastguard Worker MultiContextRenderCase::init();
1000*35238bceSAndroid Build Coastguard Worker m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0));
1001*35238bceSAndroid Build Coastguard Worker }
1002*35238bceSAndroid Build Coastguard Worker
executeForContexts(EGLDisplay display,EGLSurface surface,const Config & config,const std::vector<std::pair<EGLint,EGLContext>> & contexts)1003*35238bceSAndroid Build Coastguard Worker void MultiThreadRenderCase::executeForContexts(EGLDisplay display, EGLSurface surface, const Config &config,
1004*35238bceSAndroid Build Coastguard Worker const std::vector<std::pair<EGLint, EGLContext>> &contexts)
1005*35238bceSAndroid Build Coastguard Worker {
1006*35238bceSAndroid Build Coastguard Worker const Library &egl = m_eglTestCtx.getLibrary();
1007*35238bceSAndroid Build Coastguard Worker const int width = eglu::querySurfaceInt(egl, display, surface, EGL_WIDTH);
1008*35238bceSAndroid Build Coastguard Worker const int height = eglu::querySurfaceInt(egl, display, surface, EGL_HEIGHT);
1009*35238bceSAndroid Build Coastguard Worker const int numContexts = (int)contexts.size();
1010*35238bceSAndroid Build Coastguard Worker const int opsPerPacket = 2;
1011*35238bceSAndroid Build Coastguard Worker const int packetsPerThread = 2;
1012*35238bceSAndroid Build Coastguard Worker const int numThreads = numContexts;
1013*35238bceSAndroid Build Coastguard Worker const int numPackets = numThreads * packetsPerThread;
1014*35238bceSAndroid Build Coastguard Worker const tcu::PixelFormat pixelFmt = getPixelFormat(egl, display, config.config);
1015*35238bceSAndroid Build Coastguard Worker const float threshold = getColorThreshold(pixelFmt);
1016*35238bceSAndroid Build Coastguard Worker
1017*35238bceSAndroid Build Coastguard Worker const int depthBits = eglu::getConfigAttribInt(egl, display, config.config, EGL_DEPTH_SIZE);
1018*35238bceSAndroid Build Coastguard Worker const int stencilBits = eglu::getConfigAttribInt(egl, display, config.config, EGL_STENCIL_SIZE);
1019*35238bceSAndroid Build Coastguard Worker const int numSamples = eglu::getConfigAttribInt(egl, display, config.config, EGL_SAMPLES);
1020*35238bceSAndroid Build Coastguard Worker
1021*35238bceSAndroid Build Coastguard Worker TestLog &log = m_testCtx.getLog();
1022*35238bceSAndroid Build Coastguard Worker
1023*35238bceSAndroid Build Coastguard Worker tcu::Surface refFrame(width, height);
1024*35238bceSAndroid Build Coastguard Worker tcu::Surface frame(width, height);
1025*35238bceSAndroid Build Coastguard Worker
1026*35238bceSAndroid Build Coastguard Worker de::Random rnd(deStringHash(getName()) ^ deInt32Hash(numContexts));
1027*35238bceSAndroid Build Coastguard Worker
1028*35238bceSAndroid Build Coastguard Worker // Resources that need cleanup
1029*35238bceSAndroid Build Coastguard Worker vector<ProgramSp> programs(numContexts);
1030*35238bceSAndroid Build Coastguard Worker vector<SemaphoreSp> semaphores(numPackets + 1);
1031*35238bceSAndroid Build Coastguard Worker vector<DrawPrimitiveOp> drawOps(numPackets * opsPerPacket);
1032*35238bceSAndroid Build Coastguard Worker vector<vector<DrawOpPacket>> packets(numThreads);
1033*35238bceSAndroid Build Coastguard Worker vector<RenderTestThreadSp> threads(numThreads);
1034*35238bceSAndroid Build Coastguard Worker
1035*35238bceSAndroid Build Coastguard Worker // Log basic information about config.
1036*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_RED_SIZE = " << pixelFmt.redBits << TestLog::EndMessage;
1037*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_GREEN_SIZE = " << pixelFmt.greenBits << TestLog::EndMessage;
1038*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_BLUE_SIZE = " << pixelFmt.blueBits << TestLog::EndMessage;
1039*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_ALPHA_SIZE = " << pixelFmt.alphaBits << TestLog::EndMessage;
1040*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_DEPTH_SIZE = " << depthBits << TestLog::EndMessage;
1041*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_STENCIL_SIZE = " << stencilBits << TestLog::EndMessage;
1042*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << "EGL_SAMPLES = " << numSamples << TestLog::EndMessage;
1043*35238bceSAndroid Build Coastguard Worker
1044*35238bceSAndroid Build Coastguard Worker // Initialize semaphores.
1045*35238bceSAndroid Build Coastguard Worker for (vector<SemaphoreSp>::iterator sem = semaphores.begin(); sem != semaphores.end(); ++sem)
1046*35238bceSAndroid Build Coastguard Worker *sem = SemaphoreSp(new de::Semaphore(0));
1047*35238bceSAndroid Build Coastguard Worker
1048*35238bceSAndroid Build Coastguard Worker // Create draw ops.
1049*35238bceSAndroid Build Coastguard Worker for (vector<DrawPrimitiveOp>::iterator drawOp = drawOps.begin(); drawOp != drawOps.end(); ++drawOp)
1050*35238bceSAndroid Build Coastguard Worker {
1051*35238bceSAndroid Build Coastguard Worker // The randomized draws force us to use the fuzzyCompare algorithm to check for possible rasterization differences between
1052*35238bceSAndroid Build Coastguard Worker // our rasterizer and the one used by the implementation. However, fuzzyCompare only takes a single float as the error
1053*35238bceSAndroid Build Coastguard Worker // threshold. As per the comments in the code, that threshold doesn't have a direct equivalent to a difference in color
1054*35238bceSAndroid Build Coastguard Worker // values. Instead, it's related to an accumulated quadratic error. Also according to these comments, this works well for
1055*35238bceSAndroid Build Coastguard Worker // rgba8 (the only case it was originally designed for), and it can also be made to work for other formats in which all
1056*35238bceSAndroid Build Coastguard Worker // used channels have a roughly similar number of bits.
1057*35238bceSAndroid Build Coastguard Worker //
1058*35238bceSAndroid Build Coastguard Worker // However, in some of these tests we will run this code using formats such as rgb10a2, in which the alpha can only have
1059*35238bceSAndroid Build Coastguard Worker // values of 0, 0.33, 0.66 and 1.0 while other channels have much more precission. Any small difference in the rounding
1060*35238bceSAndroid Build Coastguard Worker // applied by CTS and the implementation could result in wildly different alpha values that make using the single floating
1061*35238bceSAndroid Build Coastguard Worker // point threshold risky, because we can't separate the alpha errors from the rgb errors. If we increase the threshold to
1062*35238bceSAndroid Build Coastguard Worker // a point which is acceptable for alpha errors, the kind of errors we allow in the colors would be huge.
1063*35238bceSAndroid Build Coastguard Worker //
1064*35238bceSAndroid Build Coastguard Worker // For this reason, with 2 bits for alpha we restrict ourselves to alpha values of 1.0 and 0.0, as if alphabits was 1.
1065*35238bceSAndroid Build Coastguard Worker randomizeDrawOp(rnd, *drawOp, (pixelFmt.alphaBits <= 2));
1066*35238bceSAndroid Build Coastguard Worker }
1067*35238bceSAndroid Build Coastguard Worker
1068*35238bceSAndroid Build Coastguard Worker // Create packets.
1069*35238bceSAndroid Build Coastguard Worker for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
1070*35238bceSAndroid Build Coastguard Worker {
1071*35238bceSAndroid Build Coastguard Worker packets[threadNdx].resize(packetsPerThread);
1072*35238bceSAndroid Build Coastguard Worker
1073*35238bceSAndroid Build Coastguard Worker for (int packetNdx = 0; packetNdx < packetsPerThread; packetNdx++)
1074*35238bceSAndroid Build Coastguard Worker {
1075*35238bceSAndroid Build Coastguard Worker DrawOpPacket &packet = packets[threadNdx][packetNdx];
1076*35238bceSAndroid Build Coastguard Worker
1077*35238bceSAndroid Build Coastguard Worker // Threads take turns with packets.
1078*35238bceSAndroid Build Coastguard Worker packet.wait = semaphores[packetNdx * numThreads + threadNdx];
1079*35238bceSAndroid Build Coastguard Worker packet.signal = semaphores[packetNdx * numThreads + threadNdx + 1];
1080*35238bceSAndroid Build Coastguard Worker packet.numOps = opsPerPacket;
1081*35238bceSAndroid Build Coastguard Worker packet.drawOps = &drawOps[(packetNdx * numThreads + threadNdx) * opsPerPacket];
1082*35238bceSAndroid Build Coastguard Worker }
1083*35238bceSAndroid Build Coastguard Worker }
1084*35238bceSAndroid Build Coastguard Worker
1085*35238bceSAndroid Build Coastguard Worker // Create and setup programs per context
1086*35238bceSAndroid Build Coastguard Worker for (int ctxNdx = 0; ctxNdx < numContexts; ctxNdx++)
1087*35238bceSAndroid Build Coastguard Worker {
1088*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[ctxNdx].first;
1089*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[ctxNdx].second;
1090*35238bceSAndroid Build Coastguard Worker
1091*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
1092*35238bceSAndroid Build Coastguard Worker
1093*35238bceSAndroid Build Coastguard Worker programs[ctxNdx] = ProgramSp(createProgram(m_gl, api));
1094*35238bceSAndroid Build Coastguard Worker programs[ctxNdx]->setup();
1095*35238bceSAndroid Build Coastguard Worker
1096*35238bceSAndroid Build Coastguard Worker // Release context
1097*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1098*35238bceSAndroid Build Coastguard Worker }
1099*35238bceSAndroid Build Coastguard Worker
1100*35238bceSAndroid Build Coastguard Worker // Clear to black using first context.
1101*35238bceSAndroid Build Coastguard Worker {
1102*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[0].first;
1103*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[0].second;
1104*35238bceSAndroid Build Coastguard Worker
1105*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
1106*35238bceSAndroid Build Coastguard Worker
1107*35238bceSAndroid Build Coastguard Worker clear(m_gl, api, CLEAR_COLOR, CLEAR_DEPTH, CLEAR_STENCIL);
1108*35238bceSAndroid Build Coastguard Worker finish(m_gl, api);
1109*35238bceSAndroid Build Coastguard Worker
1110*35238bceSAndroid Build Coastguard Worker // Release context
1111*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1112*35238bceSAndroid Build Coastguard Worker }
1113*35238bceSAndroid Build Coastguard Worker
1114*35238bceSAndroid Build Coastguard Worker // Create and launch threads (actual rendering starts once first semaphore is signaled).
1115*35238bceSAndroid Build Coastguard Worker for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
1116*35238bceSAndroid Build Coastguard Worker {
1117*35238bceSAndroid Build Coastguard Worker threads[threadNdx] = RenderTestThreadSp(new RenderTestThread(egl, display, surface, contexts[threadNdx].second,
1118*35238bceSAndroid Build Coastguard Worker contexts[threadNdx].first, m_gl,
1119*35238bceSAndroid Build Coastguard Worker *programs[threadNdx], packets[threadNdx]));
1120*35238bceSAndroid Build Coastguard Worker threads[threadNdx]->start();
1121*35238bceSAndroid Build Coastguard Worker }
1122*35238bceSAndroid Build Coastguard Worker
1123*35238bceSAndroid Build Coastguard Worker // Signal start and wait until complete.
1124*35238bceSAndroid Build Coastguard Worker semaphores.front()->increment();
1125*35238bceSAndroid Build Coastguard Worker semaphores.back()->decrement();
1126*35238bceSAndroid Build Coastguard Worker
1127*35238bceSAndroid Build Coastguard Worker // Read pixels using first context. \todo [pyry] Randomize?
1128*35238bceSAndroid Build Coastguard Worker {
1129*35238bceSAndroid Build Coastguard Worker EGLint api = contexts[0].first;
1130*35238bceSAndroid Build Coastguard Worker EGLContext context = contexts[0].second;
1131*35238bceSAndroid Build Coastguard Worker
1132*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, surface, surface, context));
1133*35238bceSAndroid Build Coastguard Worker
1134*35238bceSAndroid Build Coastguard Worker readPixels(m_gl, api, frame);
1135*35238bceSAndroid Build Coastguard Worker }
1136*35238bceSAndroid Build Coastguard Worker
1137*35238bceSAndroid Build Coastguard Worker int subpixelBits = 0;
1138*35238bceSAndroid Build Coastguard Worker m_gl.getIntegerv(GL_SUBPIXEL_BITS, &subpixelBits);
1139*35238bceSAndroid Build Coastguard Worker
1140*35238bceSAndroid Build Coastguard Worker EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1141*35238bceSAndroid Build Coastguard Worker
1142*35238bceSAndroid Build Coastguard Worker // Join threads.
1143*35238bceSAndroid Build Coastguard Worker for (int threadNdx = 0; threadNdx < numThreads; threadNdx++)
1144*35238bceSAndroid Build Coastguard Worker threads[threadNdx]->join();
1145*35238bceSAndroid Build Coastguard Worker
1146*35238bceSAndroid Build Coastguard Worker // Render reference.
1147*35238bceSAndroid Build Coastguard Worker renderReference(refFrame.getAccess(), drawOps, pixelFmt, depthBits, stencilBits, 1, subpixelBits);
1148*35238bceSAndroid Build Coastguard Worker
1149*35238bceSAndroid Build Coastguard Worker // Compare images
1150*35238bceSAndroid Build Coastguard Worker {
1151*35238bceSAndroid Build Coastguard Worker bool imagesOk = tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, frame,
1152*35238bceSAndroid Build Coastguard Worker threshold, tcu::COMPARE_LOG_RESULT);
1153*35238bceSAndroid Build Coastguard Worker
1154*35238bceSAndroid Build Coastguard Worker if (!imagesOk)
1155*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
1156*35238bceSAndroid Build Coastguard Worker }
1157*35238bceSAndroid Build Coastguard Worker }
1158*35238bceSAndroid Build Coastguard Worker
RenderTests(EglTestContext & eglTestCtx)1159*35238bceSAndroid Build Coastguard Worker RenderTests::RenderTests(EglTestContext &eglTestCtx)
1160*35238bceSAndroid Build Coastguard Worker : TestCaseGroup(eglTestCtx, "render", "Basic rendering with different client APIs")
1161*35238bceSAndroid Build Coastguard Worker {
1162*35238bceSAndroid Build Coastguard Worker }
1163*35238bceSAndroid Build Coastguard Worker
~RenderTests(void)1164*35238bceSAndroid Build Coastguard Worker RenderTests::~RenderTests(void)
1165*35238bceSAndroid Build Coastguard Worker {
1166*35238bceSAndroid Build Coastguard Worker }
1167*35238bceSAndroid Build Coastguard Worker
1168*35238bceSAndroid Build Coastguard Worker struct RenderGroupSpec
1169*35238bceSAndroid Build Coastguard Worker {
1170*35238bceSAndroid Build Coastguard Worker const char *name;
1171*35238bceSAndroid Build Coastguard Worker const char *desc;
1172*35238bceSAndroid Build Coastguard Worker EGLint apiBits;
1173*35238bceSAndroid Build Coastguard Worker eglu::ConfigFilter baseFilter;
1174*35238bceSAndroid Build Coastguard Worker int numContextsPerApi;
1175*35238bceSAndroid Build Coastguard Worker };
1176*35238bceSAndroid Build Coastguard Worker
1177*35238bceSAndroid Build Coastguard Worker template <uint32_t Bits>
renderable(const eglu::CandidateConfig & c)1178*35238bceSAndroid Build Coastguard Worker static bool renderable(const eglu::CandidateConfig &c)
1179*35238bceSAndroid Build Coastguard Worker {
1180*35238bceSAndroid Build Coastguard Worker return (c.renderableType() & Bits) == Bits;
1181*35238bceSAndroid Build Coastguard Worker }
1182*35238bceSAndroid Build Coastguard Worker
1183*35238bceSAndroid Build Coastguard Worker template <class RenderClass>
createRenderGroups(EglTestContext & eglTestCtx,tcu::TestCaseGroup * group,const RenderGroupSpec * first,const RenderGroupSpec * last)1184*35238bceSAndroid Build Coastguard Worker static void createRenderGroups(EglTestContext &eglTestCtx, tcu::TestCaseGroup *group, const RenderGroupSpec *first,
1185*35238bceSAndroid Build Coastguard Worker const RenderGroupSpec *last)
1186*35238bceSAndroid Build Coastguard Worker {
1187*35238bceSAndroid Build Coastguard Worker for (const RenderGroupSpec *groupIter = first; groupIter != last; groupIter++)
1188*35238bceSAndroid Build Coastguard Worker {
1189*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *configGroup =
1190*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(eglTestCtx.getTestContext(), groupIter->name, groupIter->desc);
1191*35238bceSAndroid Build Coastguard Worker group->addChild(configGroup);
1192*35238bceSAndroid Build Coastguard Worker
1193*35238bceSAndroid Build Coastguard Worker vector<RenderFilterList> filterLists;
1194*35238bceSAndroid Build Coastguard Worker eglu::FilterList baseFilters;
1195*35238bceSAndroid Build Coastguard Worker baseFilters << groupIter->baseFilter;
1196*35238bceSAndroid Build Coastguard Worker getDefaultRenderFilterLists(filterLists, baseFilters);
1197*35238bceSAndroid Build Coastguard Worker
1198*35238bceSAndroid Build Coastguard Worker for (vector<RenderFilterList>::const_iterator listIter = filterLists.begin(); listIter != filterLists.end();
1199*35238bceSAndroid Build Coastguard Worker listIter++)
1200*35238bceSAndroid Build Coastguard Worker configGroup->addChild(new RenderClass(eglTestCtx, listIter->getName(), "", groupIter->apiBits,
1201*35238bceSAndroid Build Coastguard Worker listIter->getSurfaceTypeMask(), *listIter,
1202*35238bceSAndroid Build Coastguard Worker groupIter->numContextsPerApi));
1203*35238bceSAndroid Build Coastguard Worker }
1204*35238bceSAndroid Build Coastguard Worker }
1205*35238bceSAndroid Build Coastguard Worker
init(void)1206*35238bceSAndroid Build Coastguard Worker void RenderTests::init(void)
1207*35238bceSAndroid Build Coastguard Worker {
1208*35238bceSAndroid Build Coastguard Worker static const RenderGroupSpec singleContextCases[] = {
1209*35238bceSAndroid Build Coastguard Worker {"gles2", "Primitive rendering using GLES2", EGL_OPENGL_ES2_BIT, renderable<EGL_OPENGL_ES2_BIT>, 1},
1210*35238bceSAndroid Build Coastguard Worker {"gles3", "Primitive rendering using GLES3", EGL_OPENGL_ES3_BIT, renderable<EGL_OPENGL_ES3_BIT>, 1},
1211*35238bceSAndroid Build Coastguard Worker };
1212*35238bceSAndroid Build Coastguard Worker
1213*35238bceSAndroid Build Coastguard Worker static const RenderGroupSpec multiContextCases[] = {
1214*35238bceSAndroid Build Coastguard Worker {"gles2", "Primitive rendering using multiple GLES2 contexts to shared surface", EGL_OPENGL_ES2_BIT,
1215*35238bceSAndroid Build Coastguard Worker renderable<EGL_OPENGL_ES2_BIT>, 3},
1216*35238bceSAndroid Build Coastguard Worker {"gles3", "Primitive rendering using multiple GLES3 contexts to shared surface", EGL_OPENGL_ES3_BIT,
1217*35238bceSAndroid Build Coastguard Worker renderable<EGL_OPENGL_ES3_BIT>, 3},
1218*35238bceSAndroid Build Coastguard Worker {"gles2_gles3", "Primitive rendering using multiple APIs to shared surface",
1219*35238bceSAndroid Build Coastguard Worker EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT, renderable<EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT>, 1},
1220*35238bceSAndroid Build Coastguard Worker };
1221*35238bceSAndroid Build Coastguard Worker
1222*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *singleContextGroup =
1223*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "single_context", "Single-context rendering");
1224*35238bceSAndroid Build Coastguard Worker addChild(singleContextGroup);
1225*35238bceSAndroid Build Coastguard Worker createRenderGroups<SingleThreadRenderCase>(m_eglTestCtx, singleContextGroup, &singleContextCases[0],
1226*35238bceSAndroid Build Coastguard Worker &singleContextCases[DE_LENGTH_OF_ARRAY(singleContextCases)]);
1227*35238bceSAndroid Build Coastguard Worker
1228*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *multiContextGroup =
1229*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "multi_context", "Multi-context rendering with shared surface");
1230*35238bceSAndroid Build Coastguard Worker addChild(multiContextGroup);
1231*35238bceSAndroid Build Coastguard Worker createRenderGroups<SingleThreadRenderCase>(m_eglTestCtx, multiContextGroup, &multiContextCases[0],
1232*35238bceSAndroid Build Coastguard Worker &multiContextCases[DE_LENGTH_OF_ARRAY(multiContextCases)]);
1233*35238bceSAndroid Build Coastguard Worker
1234*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *multiThreadGroup =
1235*35238bceSAndroid Build Coastguard Worker new tcu::TestCaseGroup(m_testCtx, "multi_thread", "Multi-thread rendering with shared surface");
1236*35238bceSAndroid Build Coastguard Worker addChild(multiThreadGroup);
1237*35238bceSAndroid Build Coastguard Worker createRenderGroups<MultiThreadRenderCase>(m_eglTestCtx, multiThreadGroup, &multiContextCases[0],
1238*35238bceSAndroid Build Coastguard Worker &multiContextCases[DE_LENGTH_OF_ARRAY(multiContextCases)]);
1239*35238bceSAndroid Build Coastguard Worker }
1240*35238bceSAndroid Build Coastguard Worker
1241*35238bceSAndroid Build Coastguard Worker } // namespace egl
1242*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1243