1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module
3e5c31af7Sopenharmony_ci * -----------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Interaction test utilities.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "glsInteractionTestUtil.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "tcuVector.hpp"
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ci#include "deRandom.hpp"
29e5c31af7Sopenharmony_ci#include "deMath.h"
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_cinamespace deqp
34e5c31af7Sopenharmony_ci{
35e5c31af7Sopenharmony_cinamespace gls
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cinamespace InteractionTestUtil
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ciusing tcu::Vec4;
41e5c31af7Sopenharmony_ciusing tcu::IVec2;
42e5c31af7Sopenharmony_ciusing std::vector;
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_cistatic Vec4 getRandomColor (de::Random& rnd)
45e5c31af7Sopenharmony_ci{
46e5c31af7Sopenharmony_ci	static const float components[] = { 0.0f, 0.2f, 0.4f, 0.5f, 0.6f, 0.8f, 1.0f };
47e5c31af7Sopenharmony_ci	float r = rnd.choose<float>(DE_ARRAY_BEGIN(components), DE_ARRAY_END(components));
48e5c31af7Sopenharmony_ci	float g = rnd.choose<float>(DE_ARRAY_BEGIN(components), DE_ARRAY_END(components));
49e5c31af7Sopenharmony_ci	float b = rnd.choose<float>(DE_ARRAY_BEGIN(components), DE_ARRAY_END(components));
50e5c31af7Sopenharmony_ci	float a = rnd.choose<float>(DE_ARRAY_BEGIN(components), DE_ARRAY_END(components));
51e5c31af7Sopenharmony_ci	return Vec4(r, g, b, a);
52e5c31af7Sopenharmony_ci}
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_civoid computeRandomRenderState (de::Random& rnd, RenderState& state, glu::ApiType apiType, int targetWidth, int targetHeight)
55e5c31af7Sopenharmony_ci{
56e5c31af7Sopenharmony_ci	// Constants governing randomization.
57e5c31af7Sopenharmony_ci	const float		scissorTestProbability		= 0.2f;
58e5c31af7Sopenharmony_ci	const float		stencilTestProbability		= 0.4f;
59e5c31af7Sopenharmony_ci	const float		depthTestProbability		= 0.6f;
60e5c31af7Sopenharmony_ci	const float		blendProbability			= 0.4f;
61e5c31af7Sopenharmony_ci	const float		ditherProbability			= 0.5f;
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_ci	const float		depthWriteProbability		= 0.7f;
64e5c31af7Sopenharmony_ci	const float		colorWriteProbability		= 0.7f;
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ci	const int		minStencilVal				= -3;
67e5c31af7Sopenharmony_ci	const int		maxStencilVal				= 260;
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ci	const int		maxScissorOutOfBounds		= 10;
70e5c31af7Sopenharmony_ci	const float		minScissorSize				= 0.7f;
71e5c31af7Sopenharmony_ci
72e5c31af7Sopenharmony_ci	static const deUint32 compareFuncs[] =
73e5c31af7Sopenharmony_ci	{
74e5c31af7Sopenharmony_ci		GL_NEVER,
75e5c31af7Sopenharmony_ci		GL_ALWAYS,
76e5c31af7Sopenharmony_ci		GL_LESS,
77e5c31af7Sopenharmony_ci		GL_LEQUAL,
78e5c31af7Sopenharmony_ci		GL_EQUAL,
79e5c31af7Sopenharmony_ci		GL_GEQUAL,
80e5c31af7Sopenharmony_ci		GL_GREATER,
81e5c31af7Sopenharmony_ci		GL_NOTEQUAL
82e5c31af7Sopenharmony_ci	};
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci	static const deUint32 stencilOps[] =
85e5c31af7Sopenharmony_ci	{
86e5c31af7Sopenharmony_ci		GL_KEEP,
87e5c31af7Sopenharmony_ci		GL_ZERO,
88e5c31af7Sopenharmony_ci		GL_REPLACE,
89e5c31af7Sopenharmony_ci		GL_INCR,
90e5c31af7Sopenharmony_ci		GL_DECR,
91e5c31af7Sopenharmony_ci		GL_INVERT,
92e5c31af7Sopenharmony_ci		GL_INCR_WRAP,
93e5c31af7Sopenharmony_ci		GL_DECR_WRAP
94e5c31af7Sopenharmony_ci	};
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci	static const deUint32 blendEquations[] =
97e5c31af7Sopenharmony_ci	{
98e5c31af7Sopenharmony_ci		GL_FUNC_ADD,
99e5c31af7Sopenharmony_ci		GL_FUNC_SUBTRACT,
100e5c31af7Sopenharmony_ci		GL_FUNC_REVERSE_SUBTRACT,
101e5c31af7Sopenharmony_ci		GL_MIN,
102e5c31af7Sopenharmony_ci		GL_MAX
103e5c31af7Sopenharmony_ci	};
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_ci	static const deUint32 blendFuncs[] =
106e5c31af7Sopenharmony_ci	{
107e5c31af7Sopenharmony_ci		GL_ZERO,
108e5c31af7Sopenharmony_ci		GL_ONE,
109e5c31af7Sopenharmony_ci		GL_SRC_COLOR,
110e5c31af7Sopenharmony_ci		GL_ONE_MINUS_SRC_COLOR,
111e5c31af7Sopenharmony_ci		GL_DST_COLOR,
112e5c31af7Sopenharmony_ci		GL_ONE_MINUS_DST_COLOR,
113e5c31af7Sopenharmony_ci		GL_SRC_ALPHA,
114e5c31af7Sopenharmony_ci		GL_ONE_MINUS_SRC_ALPHA,
115e5c31af7Sopenharmony_ci		GL_DST_ALPHA,
116e5c31af7Sopenharmony_ci		GL_ONE_MINUS_DST_ALPHA,
117e5c31af7Sopenharmony_ci		GL_CONSTANT_COLOR,
118e5c31af7Sopenharmony_ci		GL_ONE_MINUS_CONSTANT_COLOR,
119e5c31af7Sopenharmony_ci		GL_CONSTANT_ALPHA,
120e5c31af7Sopenharmony_ci		GL_ONE_MINUS_CONSTANT_ALPHA,
121e5c31af7Sopenharmony_ci		GL_SRC_ALPHA_SATURATE
122e5c31af7Sopenharmony_ci	};
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	static const deUint32 blendEquationsES2[] =
125e5c31af7Sopenharmony_ci	{
126e5c31af7Sopenharmony_ci		GL_FUNC_ADD,
127e5c31af7Sopenharmony_ci		GL_FUNC_SUBTRACT,
128e5c31af7Sopenharmony_ci		GL_FUNC_REVERSE_SUBTRACT
129e5c31af7Sopenharmony_ci	};
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_ci	static const deUint32 blendFuncsDstES2[] =
132e5c31af7Sopenharmony_ci	{
133e5c31af7Sopenharmony_ci		GL_ZERO,
134e5c31af7Sopenharmony_ci		GL_ONE,
135e5c31af7Sopenharmony_ci		GL_SRC_COLOR,
136e5c31af7Sopenharmony_ci		GL_ONE_MINUS_SRC_COLOR,
137e5c31af7Sopenharmony_ci		GL_DST_COLOR,
138e5c31af7Sopenharmony_ci		GL_ONE_MINUS_DST_COLOR,
139e5c31af7Sopenharmony_ci		GL_SRC_ALPHA,
140e5c31af7Sopenharmony_ci		GL_ONE_MINUS_SRC_ALPHA,
141e5c31af7Sopenharmony_ci		GL_DST_ALPHA,
142e5c31af7Sopenharmony_ci		GL_ONE_MINUS_DST_ALPHA,
143e5c31af7Sopenharmony_ci		GL_CONSTANT_COLOR,
144e5c31af7Sopenharmony_ci		GL_ONE_MINUS_CONSTANT_COLOR,
145e5c31af7Sopenharmony_ci		GL_CONSTANT_ALPHA,
146e5c31af7Sopenharmony_ci		GL_ONE_MINUS_CONSTANT_ALPHA
147e5c31af7Sopenharmony_ci	};
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_ci	state.scissorTestEnabled	= rnd.getFloat() < scissorTestProbability;
150e5c31af7Sopenharmony_ci	state.stencilTestEnabled	= rnd.getFloat() < stencilTestProbability;
151e5c31af7Sopenharmony_ci	state.depthTestEnabled		= rnd.getFloat() < depthTestProbability;
152e5c31af7Sopenharmony_ci	state.blendEnabled			= rnd.getFloat() < blendProbability;
153e5c31af7Sopenharmony_ci	state.ditherEnabled			= rnd.getFloat() < ditherProbability;
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_ci	if (state.scissorTestEnabled)
156e5c31af7Sopenharmony_ci	{
157e5c31af7Sopenharmony_ci		int minScissorW		= deCeilFloatToInt32(minScissorSize * (float)targetWidth);
158e5c31af7Sopenharmony_ci		int minScissorH		= deCeilFloatToInt32(minScissorSize * (float)targetHeight);
159e5c31af7Sopenharmony_ci		int maxScissorW		= targetWidth + 2*maxScissorOutOfBounds;
160e5c31af7Sopenharmony_ci		int maxScissorH		= targetHeight + 2*maxScissorOutOfBounds;
161e5c31af7Sopenharmony_ci
162e5c31af7Sopenharmony_ci		int scissorW		= rnd.getInt(minScissorW, maxScissorW);
163e5c31af7Sopenharmony_ci		int	scissorH		= rnd.getInt(minScissorH, maxScissorH);
164e5c31af7Sopenharmony_ci		int scissorX		= rnd.getInt(-maxScissorOutOfBounds, targetWidth+maxScissorOutOfBounds-scissorW);
165e5c31af7Sopenharmony_ci		int scissorY		= rnd.getInt(-maxScissorOutOfBounds, targetHeight+maxScissorOutOfBounds-scissorH);
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci		state.scissorRectangle = rr::WindowRectangle(scissorX, scissorY, scissorW, scissorH);
168e5c31af7Sopenharmony_ci	}
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ci	if (state.stencilTestEnabled)
171e5c31af7Sopenharmony_ci	{
172e5c31af7Sopenharmony_ci		for (int ndx = 0; ndx < 2; ndx++)
173e5c31af7Sopenharmony_ci		{
174e5c31af7Sopenharmony_ci			state.stencil[ndx].function			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
175e5c31af7Sopenharmony_ci			state.stencil[ndx].reference		= rnd.getInt(minStencilVal, maxStencilVal);
176e5c31af7Sopenharmony_ci			state.stencil[ndx].compareMask		= rnd.getUint32();
177e5c31af7Sopenharmony_ci			state.stencil[ndx].stencilFailOp	= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
178e5c31af7Sopenharmony_ci			state.stencil[ndx].depthFailOp		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
179e5c31af7Sopenharmony_ci			state.stencil[ndx].depthPassOp		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
180e5c31af7Sopenharmony_ci			state.stencil[ndx].writeMask		= rnd.getUint32();
181e5c31af7Sopenharmony_ci		}
182e5c31af7Sopenharmony_ci	}
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	if (state.depthTestEnabled)
185e5c31af7Sopenharmony_ci	{
186e5c31af7Sopenharmony_ci		state.depthFunc			= rnd.choose<deUint32>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
187e5c31af7Sopenharmony_ci		state.depthWriteMask	= rnd.getFloat() < depthWriteProbability;
188e5c31af7Sopenharmony_ci	}
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci	if (state.blendEnabled)
191e5c31af7Sopenharmony_ci	{
192e5c31af7Sopenharmony_ci		if (apiType == glu::ApiType::es(2,0))
193e5c31af7Sopenharmony_ci		{
194e5c31af7Sopenharmony_ci			state.blendRGBState.equation	= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendEquationsES2), DE_ARRAY_END(blendEquationsES2));
195e5c31af7Sopenharmony_ci			state.blendRGBState.srcFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
196e5c31af7Sopenharmony_ci			state.blendRGBState.dstFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncsDstES2), DE_ARRAY_END(blendFuncsDstES2));
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci			state.blendAState.equation		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendEquationsES2), DE_ARRAY_END(blendEquationsES2));
199e5c31af7Sopenharmony_ci			state.blendAState.srcFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
200e5c31af7Sopenharmony_ci			state.blendAState.dstFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncsDstES2), DE_ARRAY_END(blendFuncsDstES2));
201e5c31af7Sopenharmony_ci		}
202e5c31af7Sopenharmony_ci		else
203e5c31af7Sopenharmony_ci		{
204e5c31af7Sopenharmony_ci			state.blendRGBState.equation	= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendEquations), DE_ARRAY_END(blendEquations));
205e5c31af7Sopenharmony_ci			state.blendRGBState.srcFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
206e5c31af7Sopenharmony_ci			state.blendRGBState.dstFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_ci			state.blendAState.equation		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendEquations), DE_ARRAY_END(blendEquations));
209e5c31af7Sopenharmony_ci			state.blendAState.srcFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
210e5c31af7Sopenharmony_ci			state.blendAState.dstFunc		= rnd.choose<deUint32>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
211e5c31af7Sopenharmony_ci		}
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci		state.blendColor				= getRandomColor(rnd);
214e5c31af7Sopenharmony_ci	}
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < 4; ndx++)
217e5c31af7Sopenharmony_ci		state.colorMask[ndx] = rnd.getFloat() < colorWriteProbability;
218e5c31af7Sopenharmony_ci}
219e5c31af7Sopenharmony_ci
220e5c31af7Sopenharmony_civoid computeRandomQuad (de::Random& rnd, gls::FragmentOpUtil::IntegerQuad& quad, int targetWidth, int targetHeight)
221e5c31af7Sopenharmony_ci{
222e5c31af7Sopenharmony_ci	// \note In viewport coordinates.
223e5c31af7Sopenharmony_ci	// \todo [2012-12-18 pyry] Out-of-bounds values.
224e5c31af7Sopenharmony_ci	// \note Not using depth 1.0 since clearing with 1.0 and rendering with 1.0 may not be same value.
225e5c31af7Sopenharmony_ci	static const float depthValues[] = { 0.0f, 0.2f, 0.4f, 0.5f, 0.51f, 0.6f, 0.8f, 0.95f };
226e5c31af7Sopenharmony_ci
227e5c31af7Sopenharmony_ci	const int		maxOutOfBounds		= 0;
228e5c31af7Sopenharmony_ci	const float		minSize				= 0.5f;
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci	int minW		= deCeilFloatToInt32(minSize * (float)targetWidth);
231e5c31af7Sopenharmony_ci	int minH		= deCeilFloatToInt32(minSize * (float)targetHeight);
232e5c31af7Sopenharmony_ci	int maxW		= targetWidth + 2*maxOutOfBounds;
233e5c31af7Sopenharmony_ci	int maxH		= targetHeight + 2*maxOutOfBounds;
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci	int width		= rnd.getInt(minW, maxW);
236e5c31af7Sopenharmony_ci	int	height		= rnd.getInt(minH, maxH);
237e5c31af7Sopenharmony_ci	int x			= rnd.getInt(-maxOutOfBounds, targetWidth+maxOutOfBounds-width);
238e5c31af7Sopenharmony_ci	int y			= rnd.getInt(-maxOutOfBounds, targetHeight+maxOutOfBounds-height);
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci	bool flipX		= rnd.getBool();
241e5c31af7Sopenharmony_ci	bool flipY		= rnd.getBool();
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_ci	float depth		= rnd.choose<float>(DE_ARRAY_BEGIN(depthValues), DE_ARRAY_END(depthValues));
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_ci	quad.posA	= IVec2(flipX ? (x+width-1) : x, flipY ? (y+height-1) : y);
246e5c31af7Sopenharmony_ci	quad.posB	= IVec2(flipX ? x : (x+width-1), flipY ? y : (y+height-1));
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(quad.color); ndx++)
249e5c31af7Sopenharmony_ci		quad.color[ndx] = getRandomColor(rnd);
250e5c31af7Sopenharmony_ci
251e5c31af7Sopenharmony_ci	std::fill(DE_ARRAY_BEGIN(quad.depth), DE_ARRAY_END(quad.depth), depth);
252e5c31af7Sopenharmony_ci}
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_civoid computeRandomRenderCommands (de::Random& rnd, glu::ApiType apiType, int numCommands, int targetW, int targetH, vector<RenderCommand>& dst)
255e5c31af7Sopenharmony_ci{
256e5c31af7Sopenharmony_ci	DE_ASSERT(dst.empty());
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	dst.resize(numCommands);
259e5c31af7Sopenharmony_ci	for (vector<RenderCommand>::iterator cmd = dst.begin(); cmd != dst.end(); cmd++)
260e5c31af7Sopenharmony_ci	{
261e5c31af7Sopenharmony_ci		computeRandomRenderState(rnd, cmd->state, apiType, targetW, targetH);
262e5c31af7Sopenharmony_ci		computeRandomQuad(rnd, cmd->quad, targetW, targetH);
263e5c31af7Sopenharmony_ci	}
264e5c31af7Sopenharmony_ci}
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci} // InteractionTestUtil
267e5c31af7Sopenharmony_ci} // gls
268e5c31af7Sopenharmony_ci} // deqp
269