Home | History | Annotate | Download | only in glshared
      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 
     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 
     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 
    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 
    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