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