xref: /aosp_15_r20/external/deqp/modules/glshared/glsInteractionTestUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 std::vector;
41 using tcu::IVec2;
42 using tcu::Vec4;
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,
55                               int targetHeight)
56 {
57     // Constants governing randomization.
58     const float scissorTestProbability = 0.2f;
59     const float stencilTestProbability = 0.4f;
60     const float depthTestProbability   = 0.6f;
61     const float blendProbability       = 0.4f;
62     const float ditherProbability      = 0.5f;
63 
64     const float depthWriteProbability = 0.7f;
65     const float colorWriteProbability = 0.7f;
66 
67     const int minStencilVal = -3;
68     const int maxStencilVal = 260;
69 
70     const int maxScissorOutOfBounds = 10;
71     const float minScissorSize      = 0.7f;
72 
73     static const uint32_t compareFuncs[] = {GL_NEVER, GL_ALWAYS, GL_LESS,    GL_LEQUAL,
74                                             GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL};
75 
76     static const uint32_t stencilOps[] = {GL_KEEP, GL_ZERO,   GL_REPLACE,   GL_INCR,
77                                           GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP};
78 
79     static const uint32_t blendEquations[] = {GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX};
80 
81     static const uint32_t blendFuncs[] = {GL_ZERO,
82                                           GL_ONE,
83                                           GL_SRC_COLOR,
84                                           GL_ONE_MINUS_SRC_COLOR,
85                                           GL_DST_COLOR,
86                                           GL_ONE_MINUS_DST_COLOR,
87                                           GL_SRC_ALPHA,
88                                           GL_ONE_MINUS_SRC_ALPHA,
89                                           GL_DST_ALPHA,
90                                           GL_ONE_MINUS_DST_ALPHA,
91                                           GL_CONSTANT_COLOR,
92                                           GL_ONE_MINUS_CONSTANT_COLOR,
93                                           GL_CONSTANT_ALPHA,
94                                           GL_ONE_MINUS_CONSTANT_ALPHA,
95                                           GL_SRC_ALPHA_SATURATE};
96 
97     static const uint32_t blendEquationsES2[] = {GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT};
98 
99     static const uint32_t blendFuncsDstES2[] = {GL_ZERO,           GL_ONE,
100                                                 GL_SRC_COLOR,      GL_ONE_MINUS_SRC_COLOR,
101                                                 GL_DST_COLOR,      GL_ONE_MINUS_DST_COLOR,
102                                                 GL_SRC_ALPHA,      GL_ONE_MINUS_SRC_ALPHA,
103                                                 GL_DST_ALPHA,      GL_ONE_MINUS_DST_ALPHA,
104                                                 GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
105                                                 GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA};
106 
107     state.scissorTestEnabled = rnd.getFloat() < scissorTestProbability;
108     state.stencilTestEnabled = rnd.getFloat() < stencilTestProbability;
109     state.depthTestEnabled   = rnd.getFloat() < depthTestProbability;
110     state.blendEnabled       = rnd.getFloat() < blendProbability;
111     state.ditherEnabled      = rnd.getFloat() < ditherProbability;
112 
113     if (state.scissorTestEnabled)
114     {
115         int minScissorW = deCeilFloatToInt32(minScissorSize * (float)targetWidth);
116         int minScissorH = deCeilFloatToInt32(minScissorSize * (float)targetHeight);
117         int maxScissorW = targetWidth + 2 * maxScissorOutOfBounds;
118         int maxScissorH = targetHeight + 2 * maxScissorOutOfBounds;
119 
120         int scissorW = rnd.getInt(minScissorW, maxScissorW);
121         int scissorH = rnd.getInt(minScissorH, maxScissorH);
122         int scissorX = rnd.getInt(-maxScissorOutOfBounds, targetWidth + maxScissorOutOfBounds - scissorW);
123         int scissorY = rnd.getInt(-maxScissorOutOfBounds, targetHeight + maxScissorOutOfBounds - scissorH);
124 
125         state.scissorRectangle = rr::WindowRectangle(scissorX, scissorY, scissorW, scissorH);
126     }
127 
128     if (state.stencilTestEnabled)
129     {
130         for (int ndx = 0; ndx < 2; ndx++)
131         {
132             state.stencil[ndx].function =
133                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
134             state.stencil[ndx].reference   = rnd.getInt(minStencilVal, maxStencilVal);
135             state.stencil[ndx].compareMask = rnd.getUint32();
136             state.stencil[ndx].stencilFailOp =
137                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
138             state.stencil[ndx].depthFailOp = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
139             state.stencil[ndx].depthPassOp = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(stencilOps), DE_ARRAY_END(stencilOps));
140             state.stencil[ndx].writeMask   = rnd.getUint32();
141         }
142     }
143 
144     if (state.depthTestEnabled)
145     {
146         state.depthFunc      = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(compareFuncs), DE_ARRAY_END(compareFuncs));
147         state.depthWriteMask = rnd.getFloat() < depthWriteProbability;
148     }
149 
150     if (state.blendEnabled)
151     {
152         if (apiType == glu::ApiType::es(2, 0))
153         {
154             state.blendRGBState.equation =
155                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendEquationsES2), DE_ARRAY_END(blendEquationsES2));
156             state.blendRGBState.srcFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
157             state.blendRGBState.dstFunc =
158                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncsDstES2), DE_ARRAY_END(blendFuncsDstES2));
159 
160             state.blendAState.equation =
161                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendEquationsES2), DE_ARRAY_END(blendEquationsES2));
162             state.blendAState.srcFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
163             state.blendAState.dstFunc =
164                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncsDstES2), DE_ARRAY_END(blendFuncsDstES2));
165         }
166         else
167         {
168             state.blendRGBState.equation =
169                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendEquations), DE_ARRAY_END(blendEquations));
170             state.blendRGBState.srcFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
171             state.blendRGBState.dstFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
172 
173             state.blendAState.equation =
174                 rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendEquations), DE_ARRAY_END(blendEquations));
175             state.blendAState.srcFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
176             state.blendAState.dstFunc = rnd.choose<uint32_t>(DE_ARRAY_BEGIN(blendFuncs), DE_ARRAY_END(blendFuncs));
177         }
178 
179         state.blendColor = getRandomColor(rnd);
180     }
181 
182     for (int ndx = 0; ndx < 4; ndx++)
183         state.colorMask[ndx] = rnd.getFloat() < colorWriteProbability;
184 }
185 
computeRandomQuad(de::Random & rnd,gls::FragmentOpUtil::IntegerQuad & quad,int targetWidth,int targetHeight)186 void computeRandomQuad(de::Random &rnd, gls::FragmentOpUtil::IntegerQuad &quad, int targetWidth, int targetHeight)
187 {
188     // \note In viewport coordinates.
189     // \todo [2012-12-18 pyry] Out-of-bounds values.
190     // \note Not using depth 1.0 since clearing with 1.0 and rendering with 1.0 may not be same value.
191     static const float depthValues[] = {0.0f, 0.2f, 0.4f, 0.5f, 0.51f, 0.6f, 0.8f, 0.95f};
192 
193     const int maxOutOfBounds = 0;
194     const float minSize      = 0.5f;
195 
196     int minW = deCeilFloatToInt32(minSize * (float)targetWidth);
197     int minH = deCeilFloatToInt32(minSize * (float)targetHeight);
198     int maxW = targetWidth + 2 * maxOutOfBounds;
199     int maxH = targetHeight + 2 * maxOutOfBounds;
200 
201     int width  = rnd.getInt(minW, maxW);
202     int height = rnd.getInt(minH, maxH);
203     int x      = rnd.getInt(-maxOutOfBounds, targetWidth + maxOutOfBounds - width);
204     int y      = rnd.getInt(-maxOutOfBounds, targetHeight + maxOutOfBounds - height);
205 
206     bool flipX = rnd.getBool();
207     bool flipY = rnd.getBool();
208 
209     float depth = rnd.choose<float>(DE_ARRAY_BEGIN(depthValues), DE_ARRAY_END(depthValues));
210 
211     quad.posA = IVec2(flipX ? (x + width - 1) : x, flipY ? (y + height - 1) : y);
212     quad.posB = IVec2(flipX ? x : (x + width - 1), flipY ? y : (y + height - 1));
213 
214     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(quad.color); ndx++)
215         quad.color[ndx] = getRandomColor(rnd);
216 
217     std::fill(DE_ARRAY_BEGIN(quad.depth), DE_ARRAY_END(quad.depth), depth);
218 }
219 
computeRandomRenderCommands(de::Random & rnd,glu::ApiType apiType,int numCommands,int targetW,int targetH,vector<RenderCommand> & dst)220 void computeRandomRenderCommands(de::Random &rnd, glu::ApiType apiType, int numCommands, int targetW, int targetH,
221                                  vector<RenderCommand> &dst)
222 {
223     DE_ASSERT(dst.empty());
224 
225     dst.resize(numCommands);
226     for (vector<RenderCommand>::iterator cmd = dst.begin(); cmd != dst.end(); cmd++)
227     {
228         computeRandomRenderState(rnd, cmd->state, apiType, targetW, targetH);
229         computeRandomQuad(rnd, cmd->quad, targetW, targetH);
230     }
231 }
232 
233 } // namespace InteractionTestUtil
234 } // namespace gls
235 } // namespace deqp
236