1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL (ES) 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 Shader - render state interaction case.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "glsFragOpInteractionCase.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "glsRandomShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "glsFragmentOpUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "glsInteractionTestUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker
30*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
32*35238bceSAndroid Build Coastguard Worker
33*35238bceSAndroid Build Coastguard Worker #include "rsgShader.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "rsgProgramGenerator.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker #include "sglrContext.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "sglrReferenceContext.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "sglrGLContext.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "sglrContextUtil.hpp"
41*35238bceSAndroid Build Coastguard Worker
42*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
44*35238bceSAndroid Build Coastguard Worker
45*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "deString.h"
47*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
50*35238bceSAndroid Build Coastguard Worker
51*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker namespace deqp
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker namespace gls
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker
58*35238bceSAndroid Build Coastguard Worker using std::string;
59*35238bceSAndroid Build Coastguard Worker using std::vector;
60*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
61*35238bceSAndroid Build Coastguard Worker using tcu::IVec4;
62*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
63*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
64*35238bceSAndroid Build Coastguard Worker
65*35238bceSAndroid Build Coastguard Worker using gls::InteractionTestUtil::RenderState;
66*35238bceSAndroid Build Coastguard Worker using gls::InteractionTestUtil::StencilState;
67*35238bceSAndroid Build Coastguard Worker
68*35238bceSAndroid Build Coastguard Worker enum
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker NUM_ITERATIONS = 5,
71*35238bceSAndroid Build Coastguard Worker NUM_COMMANDS_PER_ITERATION = 5,
72*35238bceSAndroid Build Coastguard Worker VIEWPORT_WIDTH = 64,
73*35238bceSAndroid Build Coastguard Worker VIEWPORT_HEIGHT = 64
74*35238bceSAndroid Build Coastguard Worker };
75*35238bceSAndroid Build Coastguard Worker
76*35238bceSAndroid Build Coastguard Worker namespace
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker
computeVertexLayout(const vector<rsg::ShaderInput * > & attributes,int numVertices,vector<glu::VertexArrayBinding> * layout,int * stride)79*35238bceSAndroid Build Coastguard Worker static void computeVertexLayout(const vector<rsg::ShaderInput *> &attributes, int numVertices,
80*35238bceSAndroid Build Coastguard Worker vector<glu::VertexArrayBinding> *layout, int *stride)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker DE_ASSERT(layout->empty());
83*35238bceSAndroid Build Coastguard Worker
84*35238bceSAndroid Build Coastguard Worker int curOffset = 0;
85*35238bceSAndroid Build Coastguard Worker
86*35238bceSAndroid Build Coastguard Worker for (vector<rsg::ShaderInput *>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker const rsg::ShaderInput *attrib = *iter;
89*35238bceSAndroid Build Coastguard Worker const rsg::Variable *var = attrib->getVariable();
90*35238bceSAndroid Build Coastguard Worker const rsg::VariableType &type = var->getType();
91*35238bceSAndroid Build Coastguard Worker const int numComps = type.getNumElements();
92*35238bceSAndroid Build Coastguard Worker
93*35238bceSAndroid Build Coastguard Worker TCU_CHECK_INTERNAL(type.getBaseType() == rsg::VariableType::TYPE_FLOAT &&
94*35238bceSAndroid Build Coastguard Worker de::inRange(type.getNumElements(), 1, 4));
95*35238bceSAndroid Build Coastguard Worker
96*35238bceSAndroid Build Coastguard Worker layout->push_back(glu::va::Float(var->getName(), numComps, numVertices, 0 /* computed later */,
97*35238bceSAndroid Build Coastguard Worker (const float *)(uintptr_t)curOffset));
98*35238bceSAndroid Build Coastguard Worker
99*35238bceSAndroid Build Coastguard Worker curOffset += numComps * (int)sizeof(float);
100*35238bceSAndroid Build Coastguard Worker }
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker for (vector<glu::VertexArrayBinding>::iterator vaIter = layout->begin(); vaIter != layout->end(); ++vaIter)
103*35238bceSAndroid Build Coastguard Worker vaIter->pointer.stride = curOffset;
104*35238bceSAndroid Build Coastguard Worker
105*35238bceSAndroid Build Coastguard Worker *stride = curOffset;
106*35238bceSAndroid Build Coastguard Worker }
107*35238bceSAndroid Build Coastguard Worker
108*35238bceSAndroid Build Coastguard Worker class VertexDataStorage
109*35238bceSAndroid Build Coastguard Worker {
110*35238bceSAndroid Build Coastguard Worker public:
111*35238bceSAndroid Build Coastguard Worker VertexDataStorage(const vector<rsg::ShaderInput *> &attributes, int numVertices);
112*35238bceSAndroid Build Coastguard Worker
getDataSize(void) const113*35238bceSAndroid Build Coastguard Worker int getDataSize(void) const
114*35238bceSAndroid Build Coastguard Worker {
115*35238bceSAndroid Build Coastguard Worker return (int)m_data.size();
116*35238bceSAndroid Build Coastguard Worker }
getBasePtr(void)117*35238bceSAndroid Build Coastguard Worker void *getBasePtr(void)
118*35238bceSAndroid Build Coastguard Worker {
119*35238bceSAndroid Build Coastguard Worker return m_data.empty() ? DE_NULL : &m_data[0];
120*35238bceSAndroid Build Coastguard Worker }
getBasePtr(void) const121*35238bceSAndroid Build Coastguard Worker const void *getBasePtr(void) const
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker return m_data.empty() ? DE_NULL : &m_data[0];
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker
getLayout(void) const126*35238bceSAndroid Build Coastguard Worker const std::vector<glu::VertexArrayBinding> &getLayout(void) const
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker return m_layout;
129*35238bceSAndroid Build Coastguard Worker }
130*35238bceSAndroid Build Coastguard Worker
getNumEntries(void) const131*35238bceSAndroid Build Coastguard Worker int getNumEntries(void) const
132*35238bceSAndroid Build Coastguard Worker {
133*35238bceSAndroid Build Coastguard Worker return (int)m_layout.size();
134*35238bceSAndroid Build Coastguard Worker }
getLayoutEntry(int ndx) const135*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding &getLayoutEntry(int ndx) const
136*35238bceSAndroid Build Coastguard Worker {
137*35238bceSAndroid Build Coastguard Worker return m_layout[ndx];
138*35238bceSAndroid Build Coastguard Worker }
139*35238bceSAndroid Build Coastguard Worker
140*35238bceSAndroid Build Coastguard Worker private:
141*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> m_data;
142*35238bceSAndroid Build Coastguard Worker std::vector<glu::VertexArrayBinding> m_layout;
143*35238bceSAndroid Build Coastguard Worker };
144*35238bceSAndroid Build Coastguard Worker
VertexDataStorage(const vector<rsg::ShaderInput * > & attributes,int numVertices)145*35238bceSAndroid Build Coastguard Worker VertexDataStorage::VertexDataStorage(const vector<rsg::ShaderInput *> &attributes, int numVertices)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker int stride = 0;
148*35238bceSAndroid Build Coastguard Worker computeVertexLayout(attributes, numVertices, &m_layout, &stride);
149*35238bceSAndroid Build Coastguard Worker m_data.resize(stride * numVertices);
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker
getEntryWithPointer(const VertexDataStorage & data,int ndx)152*35238bceSAndroid Build Coastguard Worker static inline glu::VertexArrayBinding getEntryWithPointer(const VertexDataStorage &data, int ndx)
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding &entry = data.getLayoutEntry(ndx);
155*35238bceSAndroid Build Coastguard Worker return glu::VertexArrayBinding(
156*35238bceSAndroid Build Coastguard Worker entry.binding,
157*35238bceSAndroid Build Coastguard Worker glu::VertexArrayPointer(entry.pointer.componentType, entry.pointer.convert, entry.pointer.numComponents,
158*35238bceSAndroid Build Coastguard Worker entry.pointer.numElements, entry.pointer.stride,
159*35238bceSAndroid Build Coastguard Worker (const void *)((uintptr_t)entry.pointer.data + (uintptr_t)data.getBasePtr())));
160*35238bceSAndroid Build Coastguard Worker }
161*35238bceSAndroid Build Coastguard Worker
162*35238bceSAndroid Build Coastguard Worker template <int Size>
setVertex(const glu::VertexArrayPointer & pointer,int vertexNdx,const tcu::Vector<float,Size> & value)163*35238bceSAndroid Build Coastguard Worker static void setVertex(const glu::VertexArrayPointer &pointer, int vertexNdx, const tcu::Vector<float, Size> &value)
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker // \todo [2013-12-14 pyry] Implement other modes.
166*35238bceSAndroid Build Coastguard Worker DE_ASSERT(pointer.componentType == glu::VTX_COMP_FLOAT && pointer.convert == glu::VTX_COMP_CONVERT_NONE);
167*35238bceSAndroid Build Coastguard Worker DE_ASSERT(pointer.numComponents == Size);
168*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inBounds(vertexNdx, 0, pointer.numElements));
169*35238bceSAndroid Build Coastguard Worker
170*35238bceSAndroid Build Coastguard Worker float *dst = (float *)((uint8_t *)pointer.data + pointer.stride * vertexNdx);
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ndx++)
173*35238bceSAndroid Build Coastguard Worker dst[ndx] = value[ndx];
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker
176*35238bceSAndroid Build Coastguard Worker template <int Size>
interpolateRange(const rsg::ConstValueRangeAccess & range,const tcu::Vector<float,Size> & t)177*35238bceSAndroid Build Coastguard Worker static tcu::Vector<float, Size> interpolateRange(const rsg::ConstValueRangeAccess &range,
178*35238bceSAndroid Build Coastguard Worker const tcu::Vector<float, Size> &t)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker tcu::Vector<float, Size> result;
181*35238bceSAndroid Build Coastguard Worker
182*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < Size; ndx++)
183*35238bceSAndroid Build Coastguard Worker result[ndx] = range.getMin().component(ndx).asFloat() * (1.0f - t[ndx]) +
184*35238bceSAndroid Build Coastguard Worker range.getMax().component(ndx).asFloat() * t[ndx];
185*35238bceSAndroid Build Coastguard Worker
186*35238bceSAndroid Build Coastguard Worker return result;
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker
189*35238bceSAndroid Build Coastguard Worker struct Quad
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker tcu::IVec2 posA;
192*35238bceSAndroid Build Coastguard Worker tcu::IVec2 posB;
193*35238bceSAndroid Build Coastguard Worker };
194*35238bceSAndroid Build Coastguard Worker
195*35238bceSAndroid Build Coastguard Worker struct RenderCommand
196*35238bceSAndroid Build Coastguard Worker {
197*35238bceSAndroid Build Coastguard Worker Quad quad;
198*35238bceSAndroid Build Coastguard Worker float depth;
199*35238bceSAndroid Build Coastguard Worker RenderState state;
200*35238bceSAndroid Build Coastguard Worker
RenderCommanddeqp::gls::__anon7fa661730211::RenderCommand201*35238bceSAndroid Build Coastguard Worker RenderCommand(void) : depth(0.0f)
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker };
205*35238bceSAndroid Build Coastguard Worker
getRandomQuad(de::Random & rnd,int targetW,int targetH)206*35238bceSAndroid Build Coastguard Worker static Quad getRandomQuad(de::Random &rnd, int targetW, int targetH)
207*35238bceSAndroid Build Coastguard Worker {
208*35238bceSAndroid Build Coastguard Worker // \note In viewport coordinates.
209*35238bceSAndroid Build Coastguard Worker // \todo [2012-12-18 pyry] Out-of-bounds values.
210*35238bceSAndroid Build Coastguard Worker const int maxOutOfBounds = 0;
211*35238bceSAndroid Build Coastguard Worker const float minSize = 0.5f;
212*35238bceSAndroid Build Coastguard Worker
213*35238bceSAndroid Build Coastguard Worker const int minW = deCeilFloatToInt32(minSize * (float)targetW);
214*35238bceSAndroid Build Coastguard Worker const int minH = deCeilFloatToInt32(minSize * (float)targetH);
215*35238bceSAndroid Build Coastguard Worker const int maxW = targetW + 2 * maxOutOfBounds;
216*35238bceSAndroid Build Coastguard Worker const int maxH = targetH + 2 * maxOutOfBounds;
217*35238bceSAndroid Build Coastguard Worker
218*35238bceSAndroid Build Coastguard Worker const int width = rnd.getInt(minW, maxW);
219*35238bceSAndroid Build Coastguard Worker const int height = rnd.getInt(minH, maxH);
220*35238bceSAndroid Build Coastguard Worker const int x = rnd.getInt(-maxOutOfBounds, targetW + maxOutOfBounds - width);
221*35238bceSAndroid Build Coastguard Worker const int y = rnd.getInt(-maxOutOfBounds, targetH + maxOutOfBounds - height);
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker const bool flipX = rnd.getBool();
224*35238bceSAndroid Build Coastguard Worker const bool flipY = rnd.getBool();
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker Quad quad;
227*35238bceSAndroid Build Coastguard Worker
228*35238bceSAndroid Build Coastguard Worker quad.posA = tcu::IVec2(flipX ? (x + width - 1) : x, flipY ? (y + height - 1) : y);
229*35238bceSAndroid Build Coastguard Worker quad.posB = tcu::IVec2(flipX ? x : (x + width - 1), flipY ? y : (y + height - 1));
230*35238bceSAndroid Build Coastguard Worker
231*35238bceSAndroid Build Coastguard Worker return quad;
232*35238bceSAndroid Build Coastguard Worker }
233*35238bceSAndroid Build Coastguard Worker
getRandomDepth(de::Random & rnd)234*35238bceSAndroid Build Coastguard Worker static float getRandomDepth(de::Random &rnd)
235*35238bceSAndroid Build Coastguard Worker {
236*35238bceSAndroid Build Coastguard Worker // \note Not using depth 1.0 since clearing with 1.0 and rendering with 1.0 may not be same value.
237*35238bceSAndroid Build Coastguard Worker static const float depthValues[] = {0.0f, 0.2f, 0.4f, 0.5f, 0.51f, 0.6f, 0.8f, 0.95f};
238*35238bceSAndroid Build Coastguard Worker return rnd.choose<float>(DE_ARRAY_BEGIN(depthValues), DE_ARRAY_END(depthValues));
239*35238bceSAndroid Build Coastguard Worker }
240*35238bceSAndroid Build Coastguard Worker
computeRandomRenderCommand(de::Random & rnd,RenderCommand & command,glu::ApiType apiType,int targetW,int targetH)241*35238bceSAndroid Build Coastguard Worker static void computeRandomRenderCommand(de::Random &rnd, RenderCommand &command, glu::ApiType apiType, int targetW,
242*35238bceSAndroid Build Coastguard Worker int targetH)
243*35238bceSAndroid Build Coastguard Worker {
244*35238bceSAndroid Build Coastguard Worker command.quad = getRandomQuad(rnd, targetW, targetH);
245*35238bceSAndroid Build Coastguard Worker command.depth = getRandomDepth(rnd);
246*35238bceSAndroid Build Coastguard Worker gls::InteractionTestUtil::computeRandomRenderState(rnd, command.state, apiType, targetW, targetH);
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker
setRenderState(sglr::Context & ctx,const RenderState & state)249*35238bceSAndroid Build Coastguard Worker static void setRenderState(sglr::Context &ctx, const RenderState &state)
250*35238bceSAndroid Build Coastguard Worker {
251*35238bceSAndroid Build Coastguard Worker if (state.scissorTestEnabled)
252*35238bceSAndroid Build Coastguard Worker {
253*35238bceSAndroid Build Coastguard Worker ctx.enable(GL_SCISSOR_TEST);
254*35238bceSAndroid Build Coastguard Worker ctx.scissor(state.scissorRectangle.left, state.scissorRectangle.bottom, state.scissorRectangle.width,
255*35238bceSAndroid Build Coastguard Worker state.scissorRectangle.height);
256*35238bceSAndroid Build Coastguard Worker }
257*35238bceSAndroid Build Coastguard Worker else
258*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_SCISSOR_TEST);
259*35238bceSAndroid Build Coastguard Worker
260*35238bceSAndroid Build Coastguard Worker if (state.stencilTestEnabled)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker ctx.enable(GL_STENCIL_TEST);
263*35238bceSAndroid Build Coastguard Worker
264*35238bceSAndroid Build Coastguard Worker for (int face = 0; face < rr::FACETYPE_LAST; face++)
265*35238bceSAndroid Build Coastguard Worker {
266*35238bceSAndroid Build Coastguard Worker uint32_t glFace = face == rr::FACETYPE_BACK ? GL_BACK : GL_FRONT;
267*35238bceSAndroid Build Coastguard Worker const StencilState &sParams = state.stencil[face];
268*35238bceSAndroid Build Coastguard Worker
269*35238bceSAndroid Build Coastguard Worker ctx.stencilFuncSeparate(glFace, sParams.function, sParams.reference, sParams.compareMask);
270*35238bceSAndroid Build Coastguard Worker ctx.stencilOpSeparate(glFace, sParams.stencilFailOp, sParams.depthFailOp, sParams.depthPassOp);
271*35238bceSAndroid Build Coastguard Worker ctx.stencilMaskSeparate(glFace, sParams.writeMask);
272*35238bceSAndroid Build Coastguard Worker }
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker else
275*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_STENCIL_TEST);
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker if (state.depthTestEnabled)
278*35238bceSAndroid Build Coastguard Worker {
279*35238bceSAndroid Build Coastguard Worker ctx.enable(GL_DEPTH_TEST);
280*35238bceSAndroid Build Coastguard Worker ctx.depthFunc(state.depthFunc);
281*35238bceSAndroid Build Coastguard Worker ctx.depthMask(state.depthWriteMask ? GL_TRUE : GL_FALSE);
282*35238bceSAndroid Build Coastguard Worker }
283*35238bceSAndroid Build Coastguard Worker else
284*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_DEPTH_TEST);
285*35238bceSAndroid Build Coastguard Worker
286*35238bceSAndroid Build Coastguard Worker if (state.blendEnabled)
287*35238bceSAndroid Build Coastguard Worker {
288*35238bceSAndroid Build Coastguard Worker ctx.enable(GL_BLEND);
289*35238bceSAndroid Build Coastguard Worker ctx.blendEquationSeparate(state.blendRGBState.equation, state.blendAState.equation);
290*35238bceSAndroid Build Coastguard Worker ctx.blendFuncSeparate(state.blendRGBState.srcFunc, state.blendRGBState.dstFunc, state.blendAState.srcFunc,
291*35238bceSAndroid Build Coastguard Worker state.blendAState.dstFunc);
292*35238bceSAndroid Build Coastguard Worker ctx.blendColor(state.blendColor.x(), state.blendColor.y(), state.blendColor.z(), state.blendColor.w());
293*35238bceSAndroid Build Coastguard Worker }
294*35238bceSAndroid Build Coastguard Worker else
295*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_BLEND);
296*35238bceSAndroid Build Coastguard Worker
297*35238bceSAndroid Build Coastguard Worker if (state.ditherEnabled)
298*35238bceSAndroid Build Coastguard Worker ctx.enable(GL_DITHER);
299*35238bceSAndroid Build Coastguard Worker else
300*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_DITHER);
301*35238bceSAndroid Build Coastguard Worker
302*35238bceSAndroid Build Coastguard Worker ctx.colorMask(state.colorMask[0] ? GL_TRUE : GL_FALSE, state.colorMask[1] ? GL_TRUE : GL_FALSE,
303*35238bceSAndroid Build Coastguard Worker state.colorMask[2] ? GL_TRUE : GL_FALSE, state.colorMask[3] ? GL_TRUE : GL_FALSE);
304*35238bceSAndroid Build Coastguard Worker }
305*35238bceSAndroid Build Coastguard Worker
renderQuad(sglr::Context & ctx,const glu::VertexArrayPointer & posPtr,const Quad & quad,const float depth)306*35238bceSAndroid Build Coastguard Worker static void renderQuad(sglr::Context &ctx, const glu::VertexArrayPointer &posPtr, const Quad &quad, const float depth)
307*35238bceSAndroid Build Coastguard Worker {
308*35238bceSAndroid Build Coastguard Worker const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker const bool flipX = quad.posB.x() < quad.posA.x();
311*35238bceSAndroid Build Coastguard Worker const bool flipY = quad.posB.y() < quad.posA.y();
312*35238bceSAndroid Build Coastguard Worker const int viewportX = de::min(quad.posA.x(), quad.posB.x());
313*35238bceSAndroid Build Coastguard Worker const int viewportY = de::min(quad.posA.y(), quad.posB.y());
314*35238bceSAndroid Build Coastguard Worker const int viewportW = de::abs(quad.posA.x() - quad.posB.x()) + 1;
315*35238bceSAndroid Build Coastguard Worker const int viewportH = de::abs(quad.posA.y() - quad.posB.y()) + 1;
316*35238bceSAndroid Build Coastguard Worker
317*35238bceSAndroid Build Coastguard Worker const Vec2 pA(flipX ? 1.0f : -1.0f, flipY ? 1.0f : -1.0f);
318*35238bceSAndroid Build Coastguard Worker const Vec2 pB(flipX ? -1.0f : 1.0f, flipY ? -1.0f : 1.0f);
319*35238bceSAndroid Build Coastguard Worker
320*35238bceSAndroid Build Coastguard Worker setVertex(posPtr, 0, Vec4(pA.x(), pA.y(), depth, 1.0f));
321*35238bceSAndroid Build Coastguard Worker setVertex(posPtr, 1, Vec4(pB.x(), pA.y(), depth, 1.0f));
322*35238bceSAndroid Build Coastguard Worker setVertex(posPtr, 2, Vec4(pA.x(), pB.y(), depth, 1.0f));
323*35238bceSAndroid Build Coastguard Worker setVertex(posPtr, 3, Vec4(pB.x(), pB.y(), depth, 1.0f));
324*35238bceSAndroid Build Coastguard Worker
325*35238bceSAndroid Build Coastguard Worker ctx.viewport(viewportX, viewportY, viewportW, viewportH);
326*35238bceSAndroid Build Coastguard Worker ctx.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_SHORT, &indices[0]);
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker
render(sglr::Context & ctx,const glu::VertexArrayPointer & posPtr,const RenderCommand & cmd)329*35238bceSAndroid Build Coastguard Worker static void render(sglr::Context &ctx, const glu::VertexArrayPointer &posPtr, const RenderCommand &cmd)
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker setRenderState(ctx, cmd.state);
332*35238bceSAndroid Build Coastguard Worker renderQuad(ctx, posPtr, cmd.quad, cmd.depth);
333*35238bceSAndroid Build Coastguard Worker }
334*35238bceSAndroid Build Coastguard Worker
setupAttributes(sglr::Context & ctx,const VertexDataStorage & vertexData,uint32_t program)335*35238bceSAndroid Build Coastguard Worker static void setupAttributes(sglr::Context &ctx, const VertexDataStorage &vertexData, uint32_t program)
336*35238bceSAndroid Build Coastguard Worker {
337*35238bceSAndroid Build Coastguard Worker for (int attribNdx = 0; attribNdx < vertexData.getNumEntries(); ++attribNdx)
338*35238bceSAndroid Build Coastguard Worker {
339*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding bindingPtr = getEntryWithPointer(vertexData, attribNdx);
340*35238bceSAndroid Build Coastguard Worker const int attribLoc = bindingPtr.binding.type == glu::BindingPoint::BPTYPE_NAME ?
341*35238bceSAndroid Build Coastguard Worker ctx.getAttribLocation(program, bindingPtr.binding.name.c_str()) :
342*35238bceSAndroid Build Coastguard Worker bindingPtr.binding.location;
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker DE_ASSERT(bindingPtr.pointer.componentType == glu::VTX_COMP_FLOAT);
345*35238bceSAndroid Build Coastguard Worker
346*35238bceSAndroid Build Coastguard Worker if (attribLoc >= 0)
347*35238bceSAndroid Build Coastguard Worker {
348*35238bceSAndroid Build Coastguard Worker ctx.enableVertexAttribArray(attribLoc);
349*35238bceSAndroid Build Coastguard Worker ctx.vertexAttribPointer(attribLoc, bindingPtr.pointer.numComponents, GL_FLOAT, GL_FALSE,
350*35238bceSAndroid Build Coastguard Worker bindingPtr.pointer.stride, bindingPtr.pointer.data);
351*35238bceSAndroid Build Coastguard Worker }
352*35238bceSAndroid Build Coastguard Worker }
353*35238bceSAndroid Build Coastguard Worker }
354*35238bceSAndroid Build Coastguard Worker
setUniformValue(sglr::Context & ctx,int location,rsg::ConstValueAccess value)355*35238bceSAndroid Build Coastguard Worker void setUniformValue(sglr::Context &ctx, int location, rsg::ConstValueAccess value)
356*35238bceSAndroid Build Coastguard Worker {
357*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(float));
358*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(sizeof(rsg::Scalar) == sizeof(int));
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker switch (value.getType().getBaseType())
361*35238bceSAndroid Build Coastguard Worker {
362*35238bceSAndroid Build Coastguard Worker case rsg::VariableType::TYPE_FLOAT:
363*35238bceSAndroid Build Coastguard Worker switch (value.getType().getNumElements())
364*35238bceSAndroid Build Coastguard Worker {
365*35238bceSAndroid Build Coastguard Worker case 1:
366*35238bceSAndroid Build Coastguard Worker ctx.uniform1fv(location, 1, (float *)value.value().getValuePtr());
367*35238bceSAndroid Build Coastguard Worker break;
368*35238bceSAndroid Build Coastguard Worker case 2:
369*35238bceSAndroid Build Coastguard Worker ctx.uniform2fv(location, 1, (float *)value.value().getValuePtr());
370*35238bceSAndroid Build Coastguard Worker break;
371*35238bceSAndroid Build Coastguard Worker case 3:
372*35238bceSAndroid Build Coastguard Worker ctx.uniform3fv(location, 1, (float *)value.value().getValuePtr());
373*35238bceSAndroid Build Coastguard Worker break;
374*35238bceSAndroid Build Coastguard Worker case 4:
375*35238bceSAndroid Build Coastguard Worker ctx.uniform4fv(location, 1, (float *)value.value().getValuePtr());
376*35238bceSAndroid Build Coastguard Worker break;
377*35238bceSAndroid Build Coastguard Worker default:
378*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Unsupported type");
379*35238bceSAndroid Build Coastguard Worker }
380*35238bceSAndroid Build Coastguard Worker break;
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker case rsg::VariableType::TYPE_INT:
383*35238bceSAndroid Build Coastguard Worker case rsg::VariableType::TYPE_BOOL:
384*35238bceSAndroid Build Coastguard Worker case rsg::VariableType::TYPE_SAMPLER_2D:
385*35238bceSAndroid Build Coastguard Worker case rsg::VariableType::TYPE_SAMPLER_CUBE:
386*35238bceSAndroid Build Coastguard Worker switch (value.getType().getNumElements())
387*35238bceSAndroid Build Coastguard Worker {
388*35238bceSAndroid Build Coastguard Worker case 1:
389*35238bceSAndroid Build Coastguard Worker ctx.uniform1iv(location, 1, (int *)value.value().getValuePtr());
390*35238bceSAndroid Build Coastguard Worker break;
391*35238bceSAndroid Build Coastguard Worker case 2:
392*35238bceSAndroid Build Coastguard Worker ctx.uniform2iv(location, 1, (int *)value.value().getValuePtr());
393*35238bceSAndroid Build Coastguard Worker break;
394*35238bceSAndroid Build Coastguard Worker case 3:
395*35238bceSAndroid Build Coastguard Worker ctx.uniform3iv(location, 1, (int *)value.value().getValuePtr());
396*35238bceSAndroid Build Coastguard Worker break;
397*35238bceSAndroid Build Coastguard Worker case 4:
398*35238bceSAndroid Build Coastguard Worker ctx.uniform4iv(location, 1, (int *)value.value().getValuePtr());
399*35238bceSAndroid Build Coastguard Worker break;
400*35238bceSAndroid Build Coastguard Worker default:
401*35238bceSAndroid Build Coastguard Worker TCU_FAIL("Unsupported type");
402*35238bceSAndroid Build Coastguard Worker }
403*35238bceSAndroid Build Coastguard Worker break;
404*35238bceSAndroid Build Coastguard Worker
405*35238bceSAndroid Build Coastguard Worker default:
406*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError("Unsupported type", "", __FILE__, __LINE__);
407*35238bceSAndroid Build Coastguard Worker }
408*35238bceSAndroid Build Coastguard Worker }
409*35238bceSAndroid Build Coastguard Worker
findShaderInputIndex(const vector<rsg::ShaderInput * > & vars,const char * name)410*35238bceSAndroid Build Coastguard Worker static int findShaderInputIndex(const vector<rsg::ShaderInput *> &vars, const char *name)
411*35238bceSAndroid Build Coastguard Worker {
412*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)vars.size(); ++ndx)
413*35238bceSAndroid Build Coastguard Worker {
414*35238bceSAndroid Build Coastguard Worker if (deStringEqual(vars[ndx]->getVariable()->getName(), name))
415*35238bceSAndroid Build Coastguard Worker return ndx;
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError(string(name) + " not found in shader inputs");
419*35238bceSAndroid Build Coastguard Worker }
420*35238bceSAndroid Build Coastguard Worker
getWellBehavingChannelColor(float v,int numBits)421*35238bceSAndroid Build Coastguard Worker static float getWellBehavingChannelColor(float v, int numBits)
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker DE_ASSERT(de::inRange(numBits, 0, 32));
424*35238bceSAndroid Build Coastguard Worker
425*35238bceSAndroid Build Coastguard Worker // clear color may not be accurately representable in the target format. If the clear color is
426*35238bceSAndroid Build Coastguard Worker // on a representable value mapping range border, it could be rounded differently by the GL and in
427*35238bceSAndroid Build Coastguard Worker // SGLR adding an unexpected error source. However, selecting an accurately representable background
428*35238bceSAndroid Build Coastguard Worker // color would effectively disable dithering. To allow dithering and to prevent undefined rounding
429*35238bceSAndroid Build Coastguard Worker // direction from affecting results, round accurate color to target color format with 8 sub-units
430*35238bceSAndroid Build Coastguard Worker // (3 bits). If the selected sub-unit value is 3 or 4 (bordering 0.5), replace it with 2 and 5,
431*35238bceSAndroid Build Coastguard Worker // respectively.
432*35238bceSAndroid Build Coastguard Worker
433*35238bceSAndroid Build Coastguard Worker if (numBits == 0 || v <= 0.0f || v >= 1.0f)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker // already accurately representable
436*35238bceSAndroid Build Coastguard Worker return v;
437*35238bceSAndroid Build Coastguard Worker }
438*35238bceSAndroid Build Coastguard Worker else
439*35238bceSAndroid Build Coastguard Worker {
440*35238bceSAndroid Build Coastguard Worker const uint64_t numSubBits = 3;
441*35238bceSAndroid Build Coastguard Worker const uint64_t subUnitBorderLo = (1u << (numSubBits - 1u)) - 1u;
442*35238bceSAndroid Build Coastguard Worker const uint64_t subUnitBorderHi = 1u << (numSubBits - 1u);
443*35238bceSAndroid Build Coastguard Worker const uint64_t maxFixedValue = (1u << (numBits + numSubBits)) - 1u;
444*35238bceSAndroid Build Coastguard Worker const uint64_t fixedValue = deRoundFloatToInt64(v * (float)maxFixedValue);
445*35238bceSAndroid Build Coastguard Worker
446*35238bceSAndroid Build Coastguard Worker const uint64_t units = fixedValue >> numSubBits;
447*35238bceSAndroid Build Coastguard Worker const uint64_t subUnits = fixedValue & ((1u << numSubBits) - 1u);
448*35238bceSAndroid Build Coastguard Worker
449*35238bceSAndroid Build Coastguard Worker const uint64_t tweakedSubUnits = (subUnits == subUnitBorderLo) ? (subUnitBorderLo - 1) :
450*35238bceSAndroid Build Coastguard Worker (subUnits == subUnitBorderHi) ? (subUnitBorderHi + 1) :
451*35238bceSAndroid Build Coastguard Worker (subUnits);
452*35238bceSAndroid Build Coastguard Worker const uint64_t tweakedValue = (units << numSubBits) | (tweakedSubUnits);
453*35238bceSAndroid Build Coastguard Worker
454*35238bceSAndroid Build Coastguard Worker return float(tweakedValue) / float(maxFixedValue);
455*35238bceSAndroid Build Coastguard Worker }
456*35238bceSAndroid Build Coastguard Worker }
457*35238bceSAndroid Build Coastguard Worker
getWellBehavingColor(const tcu::Vec4 & accurateColor,const tcu::PixelFormat & format)458*35238bceSAndroid Build Coastguard Worker static tcu::Vec4 getWellBehavingColor(const tcu::Vec4 &accurateColor, const tcu::PixelFormat &format)
459*35238bceSAndroid Build Coastguard Worker {
460*35238bceSAndroid Build Coastguard Worker return tcu::Vec4(getWellBehavingChannelColor(accurateColor[0], format.redBits),
461*35238bceSAndroid Build Coastguard Worker getWellBehavingChannelColor(accurateColor[1], format.greenBits),
462*35238bceSAndroid Build Coastguard Worker getWellBehavingChannelColor(accurateColor[2], format.blueBits),
463*35238bceSAndroid Build Coastguard Worker getWellBehavingChannelColor(accurateColor[3], format.alphaBits));
464*35238bceSAndroid Build Coastguard Worker }
465*35238bceSAndroid Build Coastguard Worker
466*35238bceSAndroid Build Coastguard Worker } // namespace
467*35238bceSAndroid Build Coastguard Worker
468*35238bceSAndroid Build Coastguard Worker struct FragOpInteractionCase::ReferenceContext
469*35238bceSAndroid Build Coastguard Worker {
470*35238bceSAndroid Build Coastguard Worker const sglr::ReferenceContextLimits limits;
471*35238bceSAndroid Build Coastguard Worker sglr::ReferenceContextBuffers buffers;
472*35238bceSAndroid Build Coastguard Worker sglr::ReferenceContext context;
473*35238bceSAndroid Build Coastguard Worker
ReferenceContextdeqp::gls::FragOpInteractionCase::ReferenceContext474*35238bceSAndroid Build Coastguard Worker ReferenceContext(glu::RenderContext &renderCtx, int width, int height)
475*35238bceSAndroid Build Coastguard Worker : limits(renderCtx)
476*35238bceSAndroid Build Coastguard Worker , buffers(renderCtx.getRenderTarget().getPixelFormat(), renderCtx.getRenderTarget().getDepthBits(),
477*35238bceSAndroid Build Coastguard Worker renderCtx.getRenderTarget().getStencilBits(), width, height)
478*35238bceSAndroid Build Coastguard Worker , context(limits, buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer())
479*35238bceSAndroid Build Coastguard Worker {
480*35238bceSAndroid Build Coastguard Worker }
481*35238bceSAndroid Build Coastguard Worker };
482*35238bceSAndroid Build Coastguard Worker
FragOpInteractionCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const glu::ContextInfo & ctxInfo,const char * name,const rsg::ProgramParameters & params)483*35238bceSAndroid Build Coastguard Worker FragOpInteractionCase::FragOpInteractionCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx,
484*35238bceSAndroid Build Coastguard Worker const glu::ContextInfo &ctxInfo, const char *name,
485*35238bceSAndroid Build Coastguard Worker const rsg::ProgramParameters ¶ms)
486*35238bceSAndroid Build Coastguard Worker : TestCase(testCtx, name, "")
487*35238bceSAndroid Build Coastguard Worker , m_renderCtx(renderCtx)
488*35238bceSAndroid Build Coastguard Worker , m_ctxInfo(ctxInfo)
489*35238bceSAndroid Build Coastguard Worker , m_params(params)
490*35238bceSAndroid Build Coastguard Worker , m_vertexShader(rsg::Shader::TYPE_VERTEX)
491*35238bceSAndroid Build Coastguard Worker , m_fragmentShader(rsg::Shader::TYPE_FRAGMENT)
492*35238bceSAndroid Build Coastguard Worker , m_program(DE_NULL)
493*35238bceSAndroid Build Coastguard Worker , m_glCtx(DE_NULL)
494*35238bceSAndroid Build Coastguard Worker , m_referenceCtx(DE_NULL)
495*35238bceSAndroid Build Coastguard Worker , m_glProgram(0)
496*35238bceSAndroid Build Coastguard Worker , m_refProgram(0)
497*35238bceSAndroid Build Coastguard Worker , m_iterNdx(0)
498*35238bceSAndroid Build Coastguard Worker {
499*35238bceSAndroid Build Coastguard Worker }
500*35238bceSAndroid Build Coastguard Worker
~FragOpInteractionCase(void)501*35238bceSAndroid Build Coastguard Worker FragOpInteractionCase::~FragOpInteractionCase(void)
502*35238bceSAndroid Build Coastguard Worker {
503*35238bceSAndroid Build Coastguard Worker FragOpInteractionCase::deinit();
504*35238bceSAndroid Build Coastguard Worker }
505*35238bceSAndroid Build Coastguard Worker
init(void)506*35238bceSAndroid Build Coastguard Worker void FragOpInteractionCase::init(void)
507*35238bceSAndroid Build Coastguard Worker {
508*35238bceSAndroid Build Coastguard Worker de::Random rnd(m_params.seed ^ 0x232faac);
509*35238bceSAndroid Build Coastguard Worker const int viewportW = de::min<int>(m_renderCtx.getRenderTarget().getWidth(), VIEWPORT_WIDTH);
510*35238bceSAndroid Build Coastguard Worker const int viewportH = de::min<int>(m_renderCtx.getRenderTarget().getHeight(), VIEWPORT_HEIGHT);
511*35238bceSAndroid Build Coastguard Worker const int viewportX = rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportW);
512*35238bceSAndroid Build Coastguard Worker const int viewportY = rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportH);
513*35238bceSAndroid Build Coastguard Worker
514*35238bceSAndroid Build Coastguard Worker rsg::ProgramGenerator generator;
515*35238bceSAndroid Build Coastguard Worker
516*35238bceSAndroid Build Coastguard Worker generator.generate(m_params, m_vertexShader, m_fragmentShader);
517*35238bceSAndroid Build Coastguard Worker rsg::computeUnifiedUniforms(m_vertexShader, m_fragmentShader, m_unifiedUniforms);
518*35238bceSAndroid Build Coastguard Worker
519*35238bceSAndroid Build Coastguard Worker try
520*35238bceSAndroid Build Coastguard Worker {
521*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_program);
522*35238bceSAndroid Build Coastguard Worker m_program = new gls::RandomShaderProgram(m_vertexShader, m_fragmentShader, (int)m_unifiedUniforms.size(),
523*35238bceSAndroid Build Coastguard Worker m_unifiedUniforms.empty() ? DE_NULL : &m_unifiedUniforms[0]);
524*35238bceSAndroid Build Coastguard Worker
525*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_referenceCtx);
526*35238bceSAndroid Build Coastguard Worker m_referenceCtx = new ReferenceContext(m_renderCtx, viewportW, viewportH);
527*35238bceSAndroid Build Coastguard Worker
528*35238bceSAndroid Build Coastguard Worker DE_ASSERT(!m_glCtx);
529*35238bceSAndroid Build Coastguard Worker m_glCtx = new sglr::GLContext(m_renderCtx, m_testCtx.getLog(),
530*35238bceSAndroid Build Coastguard Worker sglr::GLCONTEXT_LOG_CALLS | sglr::GLCONTEXT_LOG_PROGRAMS,
531*35238bceSAndroid Build Coastguard Worker IVec4(viewportX, viewportY, viewportW, viewportH));
532*35238bceSAndroid Build Coastguard Worker
533*35238bceSAndroid Build Coastguard Worker m_refProgram = m_referenceCtx->context.createProgram(m_program);
534*35238bceSAndroid Build Coastguard Worker m_glProgram = m_glCtx->createProgram(m_program);
535*35238bceSAndroid Build Coastguard Worker
536*35238bceSAndroid Build Coastguard Worker m_viewportSize = tcu::IVec2(viewportW, viewportH);
537*35238bceSAndroid Build Coastguard Worker m_iterNdx = 0;
538*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
539*35238bceSAndroid Build Coastguard Worker }
540*35238bceSAndroid Build Coastguard Worker catch (...)
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker // Save some memory by cleaning up stuff.
543*35238bceSAndroid Build Coastguard Worker FragOpInteractionCase::deinit();
544*35238bceSAndroid Build Coastguard Worker throw;
545*35238bceSAndroid Build Coastguard Worker }
546*35238bceSAndroid Build Coastguard Worker }
547*35238bceSAndroid Build Coastguard Worker
deinit(void)548*35238bceSAndroid Build Coastguard Worker void FragOpInteractionCase::deinit(void)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker delete m_referenceCtx;
551*35238bceSAndroid Build Coastguard Worker m_referenceCtx = DE_NULL;
552*35238bceSAndroid Build Coastguard Worker
553*35238bceSAndroid Build Coastguard Worker delete m_glCtx;
554*35238bceSAndroid Build Coastguard Worker m_glCtx = DE_NULL;
555*35238bceSAndroid Build Coastguard Worker
556*35238bceSAndroid Build Coastguard Worker delete m_program;
557*35238bceSAndroid Build Coastguard Worker m_program = DE_NULL;
558*35238bceSAndroid Build Coastguard Worker }
559*35238bceSAndroid Build Coastguard Worker
iterate(void)560*35238bceSAndroid Build Coastguard Worker FragOpInteractionCase::IterateResult FragOpInteractionCase::iterate(void)
561*35238bceSAndroid Build Coastguard Worker {
562*35238bceSAndroid Build Coastguard Worker de::Random rnd(m_params.seed ^ deInt32Hash(m_iterNdx));
563*35238bceSAndroid Build Coastguard Worker const tcu::ScopedLogSection section(m_testCtx.getLog(), string("Iter") + de::toString(m_iterNdx),
564*35238bceSAndroid Build Coastguard Worker string("Iteration ") + de::toString(m_iterNdx));
565*35238bceSAndroid Build Coastguard Worker
566*35238bceSAndroid Build Coastguard Worker const int positionNdx = findShaderInputIndex(m_vertexShader.getInputs(), "dEQP_Position");
567*35238bceSAndroid Build Coastguard Worker
568*35238bceSAndroid Build Coastguard Worker const int numVertices = 4;
569*35238bceSAndroid Build Coastguard Worker VertexDataStorage vertexData(m_vertexShader.getInputs(), numVertices);
570*35238bceSAndroid Build Coastguard Worker std::vector<rsg::VariableValue> uniformValues;
571*35238bceSAndroid Build Coastguard Worker std::vector<RenderCommand> renderCmds(NUM_COMMANDS_PER_ITERATION);
572*35238bceSAndroid Build Coastguard Worker
573*35238bceSAndroid Build Coastguard Worker tcu::Surface rendered(m_viewportSize.x(), m_viewportSize.y());
574*35238bceSAndroid Build Coastguard Worker tcu::Surface reference(m_viewportSize.x(), m_viewportSize.y());
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 vtxInterpFactors[] = {tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.5f, 0.5f),
577*35238bceSAndroid Build Coastguard Worker tcu::Vec4(0.0f, 1.0f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f)};
578*35238bceSAndroid Build Coastguard Worker
579*35238bceSAndroid Build Coastguard Worker rsg::computeUniformValues(rnd, uniformValues, m_unifiedUniforms);
580*35238bceSAndroid Build Coastguard Worker
581*35238bceSAndroid Build Coastguard Worker for (int attribNdx = 0; attribNdx < (int)m_vertexShader.getInputs().size(); ++attribNdx)
582*35238bceSAndroid Build Coastguard Worker {
583*35238bceSAndroid Build Coastguard Worker if (attribNdx == positionNdx)
584*35238bceSAndroid Build Coastguard Worker continue;
585*35238bceSAndroid Build Coastguard Worker
586*35238bceSAndroid Build Coastguard Worker const rsg::ShaderInput *shaderIn = m_vertexShader.getInputs()[attribNdx];
587*35238bceSAndroid Build Coastguard Worker const rsg::VariableType &varType = shaderIn->getVariable()->getType();
588*35238bceSAndroid Build Coastguard Worker const rsg::ConstValueRangeAccess valueRange = shaderIn->getValueRange();
589*35238bceSAndroid Build Coastguard Worker const int numComponents = varType.getNumElements();
590*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayBinding layoutEntry = getEntryWithPointer(vertexData, attribNdx);
591*35238bceSAndroid Build Coastguard Worker
592*35238bceSAndroid Build Coastguard Worker DE_ASSERT(varType.getBaseType() == rsg::VariableType::TYPE_FLOAT);
593*35238bceSAndroid Build Coastguard Worker
594*35238bceSAndroid Build Coastguard Worker for (int vtxNdx = 0; vtxNdx < 4; vtxNdx++)
595*35238bceSAndroid Build Coastguard Worker {
596*35238bceSAndroid Build Coastguard Worker const int fNdx = (attribNdx + vtxNdx + m_iterNdx) % DE_LENGTH_OF_ARRAY(vtxInterpFactors);
597*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 &f = vtxInterpFactors[fNdx];
598*35238bceSAndroid Build Coastguard Worker
599*35238bceSAndroid Build Coastguard Worker switch (numComponents)
600*35238bceSAndroid Build Coastguard Worker {
601*35238bceSAndroid Build Coastguard Worker case 1:
602*35238bceSAndroid Build Coastguard Worker setVertex(layoutEntry.pointer, vtxNdx, interpolateRange(valueRange, f.toWidth<1>()));
603*35238bceSAndroid Build Coastguard Worker break;
604*35238bceSAndroid Build Coastguard Worker case 2:
605*35238bceSAndroid Build Coastguard Worker setVertex(layoutEntry.pointer, vtxNdx, interpolateRange(valueRange, f.toWidth<2>()));
606*35238bceSAndroid Build Coastguard Worker break;
607*35238bceSAndroid Build Coastguard Worker case 3:
608*35238bceSAndroid Build Coastguard Worker setVertex(layoutEntry.pointer, vtxNdx, interpolateRange(valueRange, f.toWidth<3>()));
609*35238bceSAndroid Build Coastguard Worker break;
610*35238bceSAndroid Build Coastguard Worker case 4:
611*35238bceSAndroid Build Coastguard Worker setVertex(layoutEntry.pointer, vtxNdx, interpolateRange(valueRange, f.toWidth<4>()));
612*35238bceSAndroid Build Coastguard Worker break;
613*35238bceSAndroid Build Coastguard Worker default:
614*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
615*35238bceSAndroid Build Coastguard Worker }
616*35238bceSAndroid Build Coastguard Worker }
617*35238bceSAndroid Build Coastguard Worker }
618*35238bceSAndroid Build Coastguard Worker
619*35238bceSAndroid Build Coastguard Worker for (vector<RenderCommand>::iterator cmdIter = renderCmds.begin(); cmdIter != renderCmds.end(); ++cmdIter)
620*35238bceSAndroid Build Coastguard Worker computeRandomRenderCommand(rnd, *cmdIter, m_renderCtx.getType().getAPI(), m_viewportSize.x(),
621*35238bceSAndroid Build Coastguard Worker m_viewportSize.y());
622*35238bceSAndroid Build Coastguard Worker
623*35238bceSAndroid Build Coastguard Worker // Workaround for inaccurate barycentric/depth computation in current reference renderer:
624*35238bceSAndroid Build Coastguard Worker // Small bias is added to the draw call depths, in increasing order, to avoid accuracy issues in depth comparison.
625*35238bceSAndroid Build Coastguard Worker for (int cmdNdx = 0; cmdNdx < (int)renderCmds.size(); cmdNdx++)
626*35238bceSAndroid Build Coastguard Worker renderCmds[cmdNdx].depth += 0.0231725f * float(cmdNdx);
627*35238bceSAndroid Build Coastguard Worker
628*35238bceSAndroid Build Coastguard Worker {
629*35238bceSAndroid Build Coastguard Worker const glu::VertexArrayPointer posPtr = getEntryWithPointer(vertexData, positionNdx).pointer;
630*35238bceSAndroid Build Coastguard Worker
631*35238bceSAndroid Build Coastguard Worker sglr::Context *const contexts[] = {m_glCtx, &m_referenceCtx->context};
632*35238bceSAndroid Build Coastguard Worker const uint32_t programs[] = {m_glProgram, m_refProgram};
633*35238bceSAndroid Build Coastguard Worker tcu::PixelBufferAccess readDst[] = {rendered.getAccess(), reference.getAccess()};
634*35238bceSAndroid Build Coastguard Worker
635*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 accurateClearColor = tcu::Vec4(0.0f, 0.25f, 0.5f, 1.0f);
636*35238bceSAndroid Build Coastguard Worker const tcu::Vec4 clearColor =
637*35238bceSAndroid Build Coastguard Worker getWellBehavingColor(accurateClearColor, m_renderCtx.getRenderTarget().getPixelFormat());
638*35238bceSAndroid Build Coastguard Worker
639*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(contexts); ndx++)
640*35238bceSAndroid Build Coastguard Worker {
641*35238bceSAndroid Build Coastguard Worker sglr::Context &ctx = *contexts[ndx];
642*35238bceSAndroid Build Coastguard Worker const uint32_t program = programs[ndx];
643*35238bceSAndroid Build Coastguard Worker
644*35238bceSAndroid Build Coastguard Worker setupAttributes(ctx, vertexData, program);
645*35238bceSAndroid Build Coastguard Worker
646*35238bceSAndroid Build Coastguard Worker ctx.disable(GL_SCISSOR_TEST);
647*35238bceSAndroid Build Coastguard Worker ctx.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
648*35238bceSAndroid Build Coastguard Worker ctx.depthMask(GL_TRUE);
649*35238bceSAndroid Build Coastguard Worker ctx.stencilMask(~0u);
650*35238bceSAndroid Build Coastguard Worker ctx.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
651*35238bceSAndroid Build Coastguard Worker ctx.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
652*35238bceSAndroid Build Coastguard Worker
653*35238bceSAndroid Build Coastguard Worker ctx.useProgram(program);
654*35238bceSAndroid Build Coastguard Worker
655*35238bceSAndroid Build Coastguard Worker for (vector<rsg::VariableValue>::const_iterator uniformIter = uniformValues.begin();
656*35238bceSAndroid Build Coastguard Worker uniformIter != uniformValues.end(); ++uniformIter)
657*35238bceSAndroid Build Coastguard Worker setUniformValue(ctx, ctx.getUniformLocation(program, uniformIter->getVariable()->getName()),
658*35238bceSAndroid Build Coastguard Worker uniformIter->getValue());
659*35238bceSAndroid Build Coastguard Worker
660*35238bceSAndroid Build Coastguard Worker for (vector<RenderCommand>::const_iterator cmdIter = renderCmds.begin(); cmdIter != renderCmds.end();
661*35238bceSAndroid Build Coastguard Worker ++cmdIter)
662*35238bceSAndroid Build Coastguard Worker render(ctx, posPtr, *cmdIter);
663*35238bceSAndroid Build Coastguard Worker
664*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(ctx.getError(), "Rendering failed");
665*35238bceSAndroid Build Coastguard Worker
666*35238bceSAndroid Build Coastguard Worker ctx.readPixels(0, 0, m_viewportSize.x(), m_viewportSize.y(), GL_RGBA, GL_UNSIGNED_BYTE,
667*35238bceSAndroid Build Coastguard Worker readDst[ndx].getDataPtr());
668*35238bceSAndroid Build Coastguard Worker }
669*35238bceSAndroid Build Coastguard Worker }
670*35238bceSAndroid Build Coastguard Worker
671*35238bceSAndroid Build Coastguard Worker {
672*35238bceSAndroid Build Coastguard Worker const tcu::RGBA threshold =
673*35238bceSAndroid Build Coastguard Worker m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(3, 3, 3, 3);
674*35238bceSAndroid Build Coastguard Worker const bool compareOk =
675*35238bceSAndroid Build Coastguard Worker tcu::bilinearCompare(m_testCtx.getLog(), "CompareResult", "Image comparison result", reference.getAccess(),
676*35238bceSAndroid Build Coastguard Worker rendered.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
677*35238bceSAndroid Build Coastguard Worker
678*35238bceSAndroid Build Coastguard Worker if (!compareOk)
679*35238bceSAndroid Build Coastguard Worker {
680*35238bceSAndroid Build Coastguard Worker m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
681*35238bceSAndroid Build Coastguard Worker return STOP;
682*35238bceSAndroid Build Coastguard Worker }
683*35238bceSAndroid Build Coastguard Worker }
684*35238bceSAndroid Build Coastguard Worker
685*35238bceSAndroid Build Coastguard Worker m_iterNdx += 1;
686*35238bceSAndroid Build Coastguard Worker return (m_iterNdx < NUM_ITERATIONS) ? CONTINUE : STOP;
687*35238bceSAndroid Build Coastguard Worker }
688*35238bceSAndroid Build Coastguard Worker
689*35238bceSAndroid Build Coastguard Worker } // namespace gls
690*35238bceSAndroid Build Coastguard Worker } // namespace deqp
691