xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fBlendTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.0 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 Blend tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fBlendTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsFragmentOpUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuRenderTarget.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "rrFragmentOperations.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "sglrReferenceUtils.hpp"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker #include "glw.h"
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker #include <string>
40*35238bceSAndroid Build Coastguard Worker #include <vector>
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker namespace deqp
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker using gls::FragmentOpUtil::IntegerQuad;
46*35238bceSAndroid Build Coastguard Worker using gls::FragmentOpUtil::Quad;
47*35238bceSAndroid Build Coastguard Worker using gls::FragmentOpUtil::QuadRenderer;
48*35238bceSAndroid Build Coastguard Worker using gls::FragmentOpUtil::ReferenceQuadRenderer;
49*35238bceSAndroid Build Coastguard Worker using glu::getBlendEquationName;
50*35238bceSAndroid Build Coastguard Worker using glu::getBlendFactorName;
51*35238bceSAndroid Build Coastguard Worker using std::string;
52*35238bceSAndroid Build Coastguard Worker using std::vector;
53*35238bceSAndroid Build Coastguard Worker using tcu::Surface;
54*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
55*35238bceSAndroid Build Coastguard Worker using tcu::TextureFormat;
56*35238bceSAndroid Build Coastguard Worker using tcu::TextureLevel;
57*35238bceSAndroid Build Coastguard Worker using tcu::UVec4;
58*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
59*35238bceSAndroid Build Coastguard Worker 
60*35238bceSAndroid Build Coastguard Worker namespace gles2
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker namespace Functional
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker static const int MAX_VIEWPORT_WIDTH  = 64;
66*35238bceSAndroid Build Coastguard Worker static const int MAX_VIEWPORT_HEIGHT = 64;
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker struct BlendParams
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker     GLenum equationRGB;
71*35238bceSAndroid Build Coastguard Worker     GLenum srcFuncRGB;
72*35238bceSAndroid Build Coastguard Worker     GLenum dstFuncRGB;
73*35238bceSAndroid Build Coastguard Worker     GLenum equationAlpha;
74*35238bceSAndroid Build Coastguard Worker     GLenum srcFuncAlpha;
75*35238bceSAndroid Build Coastguard Worker     GLenum dstFuncAlpha;
76*35238bceSAndroid Build Coastguard Worker     Vec4 blendColor;
77*35238bceSAndroid Build Coastguard Worker 
BlendParamsdeqp::gles2::Functional::BlendParams78*35238bceSAndroid Build Coastguard Worker     BlendParams(GLenum equationRGB_, GLenum srcFuncRGB_, GLenum dstFuncRGB_, GLenum equationAlpha_,
79*35238bceSAndroid Build Coastguard Worker                 GLenum srcFuncAlpha_, GLenum dstFuncAlpha_, Vec4 blendColor_)
80*35238bceSAndroid Build Coastguard Worker         : equationRGB(equationRGB_)
81*35238bceSAndroid Build Coastguard Worker         , srcFuncRGB(srcFuncRGB_)
82*35238bceSAndroid Build Coastguard Worker         , dstFuncRGB(dstFuncRGB_)
83*35238bceSAndroid Build Coastguard Worker         , equationAlpha(equationAlpha_)
84*35238bceSAndroid Build Coastguard Worker         , srcFuncAlpha(srcFuncAlpha_)
85*35238bceSAndroid Build Coastguard Worker         , dstFuncAlpha(dstFuncAlpha_)
86*35238bceSAndroid Build Coastguard Worker         , blendColor(blendColor_)
87*35238bceSAndroid Build Coastguard Worker     {
88*35238bceSAndroid Build Coastguard Worker     }
89*35238bceSAndroid Build Coastguard Worker };
90*35238bceSAndroid Build Coastguard Worker 
91*35238bceSAndroid Build Coastguard Worker class BlendCase : public TestCase
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker public:
94*35238bceSAndroid Build Coastguard Worker     BlendCase(Context &context, const char *name, const char *desc, const vector<BlendParams> &paramSets);
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker     ~BlendCase(void);
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker     void init(void);
99*35238bceSAndroid Build Coastguard Worker     void deinit(void);
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
102*35238bceSAndroid Build Coastguard Worker 
103*35238bceSAndroid Build Coastguard Worker private:
104*35238bceSAndroid Build Coastguard Worker     BlendCase(const BlendCase &other);
105*35238bceSAndroid Build Coastguard Worker     BlendCase &operator=(const BlendCase &other);
106*35238bceSAndroid Build Coastguard Worker 
107*35238bceSAndroid Build Coastguard Worker     vector<BlendParams> m_paramSets;
108*35238bceSAndroid Build Coastguard Worker     int m_curParamSetNdx;
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     QuadRenderer *m_renderer;
111*35238bceSAndroid Build Coastguard Worker     ReferenceQuadRenderer *m_referenceRenderer;
112*35238bceSAndroid Build Coastguard Worker     TextureLevel *m_refColorBuffer;
113*35238bceSAndroid Build Coastguard Worker     Quad m_firstQuad;
114*35238bceSAndroid Build Coastguard Worker     Quad m_secondQuad;
115*35238bceSAndroid Build Coastguard Worker     IntegerQuad m_firstQuadInt;
116*35238bceSAndroid Build Coastguard Worker     IntegerQuad m_secondQuadInt;
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     int m_viewportW;
119*35238bceSAndroid Build Coastguard Worker     int m_viewportH;
120*35238bceSAndroid Build Coastguard Worker };
121*35238bceSAndroid Build Coastguard Worker 
BlendCase(Context & context,const char * name,const char * desc,const vector<BlendParams> & paramSets)122*35238bceSAndroid Build Coastguard Worker BlendCase::BlendCase(Context &context, const char *name, const char *desc, const vector<BlendParams> &paramSets)
123*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
124*35238bceSAndroid Build Coastguard Worker     , m_paramSets(paramSets)
125*35238bceSAndroid Build Coastguard Worker     , m_curParamSetNdx(0)
126*35238bceSAndroid Build Coastguard Worker     , m_renderer(DE_NULL)
127*35238bceSAndroid Build Coastguard Worker     , m_referenceRenderer(DE_NULL)
128*35238bceSAndroid Build Coastguard Worker     , m_refColorBuffer(DE_NULL)
129*35238bceSAndroid Build Coastguard Worker     , m_viewportW(0)
130*35238bceSAndroid Build Coastguard Worker     , m_viewportH(0)
131*35238bceSAndroid Build Coastguard Worker {
132*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_paramSets.empty());
133*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < (int)m_paramSets.size(); i++)
134*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_paramSets[i].dstFuncRGB != GL_SRC_ALPHA_SATURATE &&
135*35238bceSAndroid Build Coastguard Worker                   m_paramSets[i].dstFuncAlpha != GL_SRC_ALPHA_SATURATE);
136*35238bceSAndroid Build Coastguard Worker }
137*35238bceSAndroid Build Coastguard Worker 
init(void)138*35238bceSAndroid Build Coastguard Worker void BlendCase::init(void)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker     bool useRGB = m_context.getRenderTarget().getPixelFormat().alphaBits == 0;
141*35238bceSAndroid Build Coastguard Worker 
142*35238bceSAndroid Build Coastguard Worker     static const Vec4 baseGradientColors[4] = {Vec4(0.0f, 0.5f, 1.0f, 0.5f), Vec4(0.5f, 0.0f, 0.5f, 1.0f),
143*35238bceSAndroid Build Coastguard Worker                                                Vec4(0.5f, 1.0f, 0.5f, 0.0f), Vec4(1.0f, 0.5f, 0.0f, 0.5f)};
144*35238bceSAndroid Build Coastguard Worker 
145*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_firstQuad.color) == DE_LENGTH_OF_ARRAY(m_firstQuadInt.color));
146*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_firstQuad.color); i++)
147*35238bceSAndroid Build Coastguard Worker     {
148*35238bceSAndroid Build Coastguard Worker         m_firstQuad.color[i]    = (baseGradientColors[i] - 0.5f) * 0.2f + 0.5f;
149*35238bceSAndroid Build Coastguard Worker         m_firstQuadInt.color[i] = m_firstQuad.color[i];
150*35238bceSAndroid Build Coastguard Worker 
151*35238bceSAndroid Build Coastguard Worker         m_secondQuad.color[i]    = (Vec4(1.0f) - baseGradientColors[i] - 0.5f) * 1.0f + 0.5f;
152*35238bceSAndroid Build Coastguard Worker         m_secondQuadInt.color[i] = m_secondQuad.color[i];
153*35238bceSAndroid Build Coastguard Worker     }
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker     m_viewportW = de::min<int>(m_context.getRenderTarget().getWidth(), MAX_VIEWPORT_WIDTH);
156*35238bceSAndroid Build Coastguard Worker     m_viewportH = de::min<int>(m_context.getRenderTarget().getHeight(), MAX_VIEWPORT_HEIGHT);
157*35238bceSAndroid Build Coastguard Worker 
158*35238bceSAndroid Build Coastguard Worker     m_firstQuadInt.posA  = tcu::IVec2(0, 0);
159*35238bceSAndroid Build Coastguard Worker     m_secondQuadInt.posA = tcu::IVec2(0, 0);
160*35238bceSAndroid Build Coastguard Worker     m_firstQuadInt.posB  = tcu::IVec2(m_viewportW - 1, m_viewportH - 1);
161*35238bceSAndroid Build Coastguard Worker     m_secondQuadInt.posB = tcu::IVec2(m_viewportW - 1, m_viewportH - 1);
162*35238bceSAndroid Build Coastguard Worker 
163*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_renderer);
164*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_referenceRenderer);
165*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_refColorBuffer);
166*35238bceSAndroid Build Coastguard Worker 
167*35238bceSAndroid Build Coastguard Worker     m_renderer          = new QuadRenderer(m_context.getRenderContext(), glu::GLSL_VERSION_100_ES);
168*35238bceSAndroid Build Coastguard Worker     m_referenceRenderer = new ReferenceQuadRenderer;
169*35238bceSAndroid Build Coastguard Worker     m_refColorBuffer =
170*35238bceSAndroid Build Coastguard Worker         new TextureLevel(TextureFormat(useRGB ? TextureFormat::RGB : TextureFormat::RGBA, TextureFormat::UNORM_INT8),
171*35238bceSAndroid Build Coastguard Worker                          m_viewportW, m_viewportH);
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker     m_curParamSetNdx = 0;
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker 
~BlendCase(void)176*35238bceSAndroid Build Coastguard Worker BlendCase::~BlendCase(void)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker     delete m_renderer;
179*35238bceSAndroid Build Coastguard Worker     delete m_referenceRenderer;
180*35238bceSAndroid Build Coastguard Worker     delete m_refColorBuffer;
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker 
deinit(void)183*35238bceSAndroid Build Coastguard Worker void BlendCase::deinit(void)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker     delete m_renderer;
186*35238bceSAndroid Build Coastguard Worker     delete m_referenceRenderer;
187*35238bceSAndroid Build Coastguard Worker     delete m_refColorBuffer;
188*35238bceSAndroid Build Coastguard Worker 
189*35238bceSAndroid Build Coastguard Worker     m_renderer          = DE_NULL;
190*35238bceSAndroid Build Coastguard Worker     m_referenceRenderer = DE_NULL;
191*35238bceSAndroid Build Coastguard Worker     m_refColorBuffer    = DE_NULL;
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker 
iterate(void)194*35238bceSAndroid Build Coastguard Worker BlendCase::IterateResult BlendCase::iterate(void)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()) ^ deInt32Hash(m_curParamSetNdx));
197*35238bceSAndroid Build Coastguard Worker     int viewportX = rnd.getInt(0, m_context.getRenderTarget().getWidth() - m_viewportW);
198*35238bceSAndroid Build Coastguard Worker     int viewportY = rnd.getInt(0, m_context.getRenderTarget().getHeight() - m_viewportH);
199*35238bceSAndroid Build Coastguard Worker     tcu::Surface renderedImg(m_viewportW, m_viewportH);
200*35238bceSAndroid Build Coastguard Worker     tcu::Surface referenceImg(m_viewportH, m_viewportH);
201*35238bceSAndroid Build Coastguard Worker     TestLog &log(m_testCtx.getLog());
202*35238bceSAndroid Build Coastguard Worker     const BlendParams &paramSet = m_paramSets[m_curParamSetNdx];
203*35238bceSAndroid Build Coastguard Worker     rr::FragmentOperationState referenceState;
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker     // Log the blend parameters.
206*35238bceSAndroid Build Coastguard Worker 
207*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "RGB equation = " << getBlendEquationName(paramSet.equationRGB) << TestLog::EndMessage;
208*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "RGB src func = " << getBlendFactorName(paramSet.srcFuncRGB) << TestLog::EndMessage;
209*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "RGB dst func = " << getBlendFactorName(paramSet.dstFuncRGB) << TestLog::EndMessage;
210*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Alpha equation = " << getBlendEquationName(paramSet.equationAlpha)
211*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
212*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Alpha src func = " << getBlendFactorName(paramSet.srcFuncAlpha) << TestLog::EndMessage;
213*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Alpha dst func = " << getBlendFactorName(paramSet.dstFuncAlpha) << TestLog::EndMessage;
214*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Blend color = (" << paramSet.blendColor.x() << ", " << paramSet.blendColor.y() << ", "
215*35238bceSAndroid Build Coastguard Worker         << paramSet.blendColor.z() << ", " << paramSet.blendColor.w() << ")" << TestLog::EndMessage;
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker     // Set GL state.
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendEquationSeparate(paramSet.equationRGB, paramSet.equationAlpha));
220*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(
221*35238bceSAndroid Build Coastguard Worker         glBlendFuncSeparate(paramSet.srcFuncRGB, paramSet.dstFuncRGB, paramSet.srcFuncAlpha, paramSet.dstFuncAlpha));
222*35238bceSAndroid Build Coastguard Worker     GLU_CHECK_CALL(glBlendColor(paramSet.blendColor.x(), paramSet.blendColor.y(), paramSet.blendColor.z(),
223*35238bceSAndroid Build Coastguard Worker                                 paramSet.blendColor.w()));
224*35238bceSAndroid Build Coastguard Worker 
225*35238bceSAndroid Build Coastguard Worker     // Set reference state.
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker     referenceState.blendRGBState.equation = sglr::rr_util::mapGLBlendEquation(paramSet.equationRGB);
228*35238bceSAndroid Build Coastguard Worker     referenceState.blendRGBState.srcFunc  = sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncRGB);
229*35238bceSAndroid Build Coastguard Worker     referenceState.blendRGBState.dstFunc  = sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncRGB);
230*35238bceSAndroid Build Coastguard Worker     referenceState.blendAState.equation   = sglr::rr_util::mapGLBlendEquation(paramSet.equationAlpha);
231*35238bceSAndroid Build Coastguard Worker     referenceState.blendAState.srcFunc    = sglr::rr_util::mapGLBlendFunc(paramSet.srcFuncAlpha);
232*35238bceSAndroid Build Coastguard Worker     referenceState.blendAState.dstFunc    = sglr::rr_util::mapGLBlendFunc(paramSet.dstFuncAlpha);
233*35238bceSAndroid Build Coastguard Worker     referenceState.blendColor             = paramSet.blendColor;
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker     // Render with GL.
236*35238bceSAndroid Build Coastguard Worker 
237*35238bceSAndroid Build Coastguard Worker     glDisable(GL_BLEND);
238*35238bceSAndroid Build Coastguard Worker     glViewport(viewportX, viewportY, m_viewportW, m_viewportH);
239*35238bceSAndroid Build Coastguard Worker     m_renderer->render(m_firstQuad);
240*35238bceSAndroid Build Coastguard Worker     glEnable(GL_BLEND);
241*35238bceSAndroid Build Coastguard Worker     m_renderer->render(m_secondQuad);
242*35238bceSAndroid Build Coastguard Worker     glFlush();
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker     // Render reference.
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker     const tcu::PixelBufferAccess nullAccess = tcu::PixelBufferAccess();
247*35238bceSAndroid Build Coastguard Worker 
248*35238bceSAndroid Build Coastguard Worker     referenceState.blendMode = rr::BLENDMODE_NONE;
249*35238bceSAndroid Build Coastguard Worker     m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()),
250*35238bceSAndroid Build Coastguard Worker                                 nullAccess /* no depth */, nullAccess /* no stencil */, m_firstQuadInt, referenceState);
251*35238bceSAndroid Build Coastguard Worker     referenceState.blendMode = rr::BLENDMODE_STANDARD;
252*35238bceSAndroid Build Coastguard Worker     m_referenceRenderer->render(gls::FragmentOpUtil::getMultisampleAccess(m_refColorBuffer->getAccess()),
253*35238bceSAndroid Build Coastguard Worker                                 nullAccess /* no depth */, nullAccess /* no stencil */, m_secondQuadInt,
254*35238bceSAndroid Build Coastguard Worker                                 referenceState);
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker     // Expand reference color buffer to RGBA8
257*35238bceSAndroid Build Coastguard Worker     copy(referenceImg.getAccess(), m_refColorBuffer->getAccess());
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker     // Read GL image.
260*35238bceSAndroid Build Coastguard Worker 
261*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, renderedImg.getAccess());
262*35238bceSAndroid Build Coastguard Worker 
263*35238bceSAndroid Build Coastguard Worker     // Compare images.
264*35238bceSAndroid Build Coastguard Worker 
265*35238bceSAndroid Build Coastguard Worker     UVec4 compareThreshold =
266*35238bceSAndroid Build Coastguard Worker         m_context.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().asUint() * UVec4(5) / UVec4(2) +
267*35238bceSAndroid Build Coastguard Worker         UVec4(
268*35238bceSAndroid Build Coastguard Worker             3); // \note Non-scientific ad hoc formula. Need big threshold when few color bits; blending brings extra inaccuracy.
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker     bool comparePass = tcu::intThresholdCompare(m_testCtx.getLog(), "CompareResult", "Image Comparison Result",
271*35238bceSAndroid Build Coastguard Worker                                                 referenceImg.getAccess(), renderedImg.getAccess(), compareThreshold,
272*35238bceSAndroid Build Coastguard Worker                                                 tcu::COMPARE_LOG_RESULT);
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker     // Fail now if images don't match.
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker     if (!comparePass)
277*35238bceSAndroid Build Coastguard Worker     {
278*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Image compare failed");
279*35238bceSAndroid Build Coastguard Worker         return STOP;
280*35238bceSAndroid Build Coastguard Worker     }
281*35238bceSAndroid Build Coastguard Worker 
282*35238bceSAndroid Build Coastguard Worker     // Continue if param sets still remain in m_paramSets; otherwise stop.
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker     m_curParamSetNdx++;
285*35238bceSAndroid Build Coastguard Worker 
286*35238bceSAndroid Build Coastguard Worker     if (m_curParamSetNdx < (int)m_paramSets.size())
287*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
288*35238bceSAndroid Build Coastguard Worker     else
289*35238bceSAndroid Build Coastguard Worker     {
290*35238bceSAndroid Build Coastguard Worker         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Passed");
291*35238bceSAndroid Build Coastguard Worker         return STOP;
292*35238bceSAndroid Build Coastguard Worker     }
293*35238bceSAndroid Build Coastguard Worker }
294*35238bceSAndroid Build Coastguard Worker 
BlendTests(Context & context)295*35238bceSAndroid Build Coastguard Worker BlendTests::BlendTests(Context &context) : TestCaseGroup(context, "blend", "Blend tests")
296*35238bceSAndroid Build Coastguard Worker {
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker 
~BlendTests(void)299*35238bceSAndroid Build Coastguard Worker BlendTests::~BlendTests(void)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker }
302*35238bceSAndroid Build Coastguard Worker 
init(void)303*35238bceSAndroid Build Coastguard Worker void BlendTests::init(void)
304*35238bceSAndroid Build Coastguard Worker {
305*35238bceSAndroid Build Coastguard Worker     struct EnumGL
306*35238bceSAndroid Build Coastguard Worker     {
307*35238bceSAndroid Build Coastguard Worker         GLenum glValue;
308*35238bceSAndroid Build Coastguard Worker         const char *nameStr;
309*35238bceSAndroid Build Coastguard Worker     };
310*35238bceSAndroid Build Coastguard Worker 
311*35238bceSAndroid Build Coastguard Worker     static const EnumGL blendEquations[] = {
312*35238bceSAndroid Build Coastguard Worker         {GL_FUNC_ADD, "add"}, {GL_FUNC_SUBTRACT, "subtract"}, {GL_FUNC_REVERSE_SUBTRACT, "reverse_subtract"}};
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker     static const EnumGL blendFunctions[] = {{GL_ZERO, "zero"},
315*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE, "one"},
316*35238bceSAndroid Build Coastguard Worker                                             {GL_SRC_COLOR, "src_color"},
317*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_SRC_COLOR, "one_minus_src_color"},
318*35238bceSAndroid Build Coastguard Worker                                             {GL_DST_COLOR, "dst_color"},
319*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_DST_COLOR, "one_minus_dst_color"},
320*35238bceSAndroid Build Coastguard Worker                                             {GL_SRC_ALPHA, "src_alpha"},
321*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_SRC_ALPHA, "one_minus_src_alpha"},
322*35238bceSAndroid Build Coastguard Worker                                             {GL_DST_ALPHA, "dst_alpha"},
323*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_DST_ALPHA, "one_minus_dst_alpha"},
324*35238bceSAndroid Build Coastguard Worker                                             {GL_CONSTANT_COLOR, "constant_color"},
325*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_CONSTANT_COLOR, "one_minus_constant_color"},
326*35238bceSAndroid Build Coastguard Worker                                             {GL_CONSTANT_ALPHA, "constant_alpha"},
327*35238bceSAndroid Build Coastguard Worker                                             {GL_ONE_MINUS_CONSTANT_ALPHA, "one_minus_constant_alpha"},
328*35238bceSAndroid Build Coastguard Worker                                             {GL_SRC_ALPHA_SATURATE, "src_alpha_saturate"}};
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker     const Vec4 defaultBlendColor(0.2f, 0.4f, 0.6f, 0.8f);
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker     // Test all blend equation, src blend function, dst blend function combinations. RGB and alpha modes are the same.
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker     {
335*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *group =
336*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, "equation_src_func_dst_func", "Combinations of Blend Equations and Functions");
337*35238bceSAndroid Build Coastguard Worker         addChild(group);
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker         for (int equationNdx = 0; equationNdx < DE_LENGTH_OF_ARRAY(blendEquations); equationNdx++)
340*35238bceSAndroid Build Coastguard Worker             for (int srcFuncNdx = 0; srcFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions); srcFuncNdx++)
341*35238bceSAndroid Build Coastguard Worker                 for (int dstFuncNdx = 0; dstFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions); dstFuncNdx++)
342*35238bceSAndroid Build Coastguard Worker                 {
343*35238bceSAndroid Build Coastguard Worker                     const EnumGL &eq  = blendEquations[equationNdx];
344*35238bceSAndroid Build Coastguard Worker                     const EnumGL &src = blendFunctions[srcFuncNdx];
345*35238bceSAndroid Build Coastguard Worker                     const EnumGL &dst = blendFunctions[dstFuncNdx];
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker                     if (dst.glValue == GL_SRC_ALPHA_SATURATE) // SRC_ALPHA_SATURATE is only valid for src func.
348*35238bceSAndroid Build Coastguard Worker                         continue;
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker                     string name        = string("") + eq.nameStr + "_" + src.nameStr + "_" + dst.nameStr;
351*35238bceSAndroid Build Coastguard Worker                     string description = string("") + "Equations " + getBlendEquationName(eq.glValue) + ", src funcs " +
352*35238bceSAndroid Build Coastguard Worker                                          getBlendFactorName(src.glValue) + ", dst funcs " +
353*35238bceSAndroid Build Coastguard Worker                                          getBlendFactorName(dst.glValue);
354*35238bceSAndroid Build Coastguard Worker 
355*35238bceSAndroid Build Coastguard Worker                     vector<BlendParams> paramSets;
356*35238bceSAndroid Build Coastguard Worker                     paramSets.push_back(BlendParams(eq.glValue, src.glValue, dst.glValue, eq.glValue, src.glValue,
357*35238bceSAndroid Build Coastguard Worker                                                     dst.glValue, defaultBlendColor));
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker                     group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets));
360*35238bceSAndroid Build Coastguard Worker                 }
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     // Test all RGB src, alpha src and RGB dst, alpha dst combinations. Equations are ADD.
364*35238bceSAndroid Build Coastguard Worker     // \note For all RGB src, alpha src combinations, also test a couple of different RGBA dst functions, and vice versa.
365*35238bceSAndroid Build Coastguard Worker 
366*35238bceSAndroid Build Coastguard Worker     {
367*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *mainGroup =
368*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, "rgb_func_alpha_func", "Combinations of RGB and Alpha Functions");
369*35238bceSAndroid Build Coastguard Worker         addChild(mainGroup);
370*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *srcGroup = new TestCaseGroup(m_context, "src", "Source functions");
371*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *dstGroup = new TestCaseGroup(m_context, "dst", "Destination functions");
372*35238bceSAndroid Build Coastguard Worker         mainGroup->addChild(srcGroup);
373*35238bceSAndroid Build Coastguard Worker         mainGroup->addChild(dstGroup);
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker         for (int isDstI = 0; isDstI <= 1; isDstI++)
376*35238bceSAndroid Build Coastguard Worker             for (int rgbFuncNdx = 0; rgbFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions); rgbFuncNdx++)
377*35238bceSAndroid Build Coastguard Worker                 for (int alphaFuncNdx = 0; alphaFuncNdx < DE_LENGTH_OF_ARRAY(blendFunctions); alphaFuncNdx++)
378*35238bceSAndroid Build Coastguard Worker                 {
379*35238bceSAndroid Build Coastguard Worker                     bool isSrc              = isDstI == 0;
380*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *curGroup = isSrc ? srcGroup : dstGroup;
381*35238bceSAndroid Build Coastguard Worker                     const EnumGL &funcRGB   = blendFunctions[rgbFuncNdx];
382*35238bceSAndroid Build Coastguard Worker                     const EnumGL &funcAlpha = blendFunctions[alphaFuncNdx];
383*35238bceSAndroid Build Coastguard Worker                     const char *dstOrSrcStr = isSrc ? "src" : "dst";
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker                     if (!isSrc &&
386*35238bceSAndroid Build Coastguard Worker                         (funcRGB.glValue == GL_SRC_ALPHA_SATURATE ||
387*35238bceSAndroid Build Coastguard Worker                          funcAlpha.glValue == GL_SRC_ALPHA_SATURATE)) // SRC_ALPHA_SATURATE is only valid for src func.
388*35238bceSAndroid Build Coastguard Worker                         continue;
389*35238bceSAndroid Build Coastguard Worker 
390*35238bceSAndroid Build Coastguard Worker                     string name        = string("") + funcRGB.nameStr + "_" + funcAlpha.nameStr;
391*35238bceSAndroid Build Coastguard Worker                     string description = string("") + "RGB " + dstOrSrcStr + " func " +
392*35238bceSAndroid Build Coastguard Worker                                          getBlendFactorName(funcRGB.glValue) + ", alpha " + dstOrSrcStr + " func " +
393*35238bceSAndroid Build Coastguard Worker                                          getBlendFactorName(funcAlpha.glValue);
394*35238bceSAndroid Build Coastguard Worker 
395*35238bceSAndroid Build Coastguard Worker                     // First, make param sets as if this was a src case.
396*35238bceSAndroid Build Coastguard Worker 
397*35238bceSAndroid Build Coastguard Worker                     vector<BlendParams> paramSets;
398*35238bceSAndroid Build Coastguard Worker                     paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ONE, GL_FUNC_ADD,
399*35238bceSAndroid Build Coastguard Worker                                                     funcAlpha.glValue, GL_ONE, defaultBlendColor));
400*35238bceSAndroid Build Coastguard Worker                     paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_ZERO, GL_FUNC_ADD,
401*35238bceSAndroid Build Coastguard Worker                                                     funcAlpha.glValue, GL_ZERO, defaultBlendColor));
402*35238bceSAndroid Build Coastguard Worker                     paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_SRC_COLOR, GL_FUNC_ADD,
403*35238bceSAndroid Build Coastguard Worker                                                     funcAlpha.glValue, GL_SRC_COLOR, defaultBlendColor));
404*35238bceSAndroid Build Coastguard Worker                     paramSets.push_back(BlendParams(GL_FUNC_ADD, funcRGB.glValue, GL_DST_COLOR, GL_FUNC_ADD,
405*35238bceSAndroid Build Coastguard Worker                                                     funcAlpha.glValue, GL_DST_COLOR, defaultBlendColor));
406*35238bceSAndroid Build Coastguard Worker 
407*35238bceSAndroid Build Coastguard Worker                     // Swap src and dst params if this is a dst case.
408*35238bceSAndroid Build Coastguard Worker 
409*35238bceSAndroid Build Coastguard Worker                     if (!isSrc)
410*35238bceSAndroid Build Coastguard Worker                     {
411*35238bceSAndroid Build Coastguard Worker                         for (int i = 0; i < (int)paramSets.size(); i++)
412*35238bceSAndroid Build Coastguard Worker                         {
413*35238bceSAndroid Build Coastguard Worker                             std::swap(paramSets[i].srcFuncRGB, paramSets[i].dstFuncRGB);
414*35238bceSAndroid Build Coastguard Worker                             std::swap(paramSets[i].srcFuncAlpha, paramSets[i].dstFuncAlpha);
415*35238bceSAndroid Build Coastguard Worker                         }
416*35238bceSAndroid Build Coastguard Worker                     }
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker                     curGroup->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets));
419*35238bceSAndroid Build Coastguard Worker                 }
420*35238bceSAndroid Build Coastguard Worker     }
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker     // Test all RGB and alpha equation combinations. Src and dst funcs are ONE for both.
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker     {
425*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *group = new TestCaseGroup(m_context, "rgb_equation_alpha_equation",
426*35238bceSAndroid Build Coastguard Worker                                                  "Combinations of RGB and Alpha Equation Combinations");
427*35238bceSAndroid Build Coastguard Worker         addChild(group);
428*35238bceSAndroid Build Coastguard Worker 
429*35238bceSAndroid Build Coastguard Worker         for (int equationRGBNdx = 0; equationRGBNdx < DE_LENGTH_OF_ARRAY(blendEquations); equationRGBNdx++)
430*35238bceSAndroid Build Coastguard Worker             for (int equationAlphaNdx = 0; equationAlphaNdx < DE_LENGTH_OF_ARRAY(blendEquations); equationAlphaNdx++)
431*35238bceSAndroid Build Coastguard Worker             {
432*35238bceSAndroid Build Coastguard Worker                 const EnumGL &eqRGB   = blendEquations[equationRGBNdx];
433*35238bceSAndroid Build Coastguard Worker                 const EnumGL &eqAlpha = blendEquations[equationAlphaNdx];
434*35238bceSAndroid Build Coastguard Worker 
435*35238bceSAndroid Build Coastguard Worker                 string name        = string("") + eqRGB.nameStr + "_" + eqAlpha.nameStr;
436*35238bceSAndroid Build Coastguard Worker                 string description = string("") + "RGB equation " + getBlendEquationName(eqRGB.glValue) +
437*35238bceSAndroid Build Coastguard Worker                                      ", alpha equation " + getBlendEquationName(eqAlpha.glValue);
438*35238bceSAndroid Build Coastguard Worker 
439*35238bceSAndroid Build Coastguard Worker                 vector<BlendParams> paramSets;
440*35238bceSAndroid Build Coastguard Worker                 paramSets.push_back(
441*35238bceSAndroid Build Coastguard Worker                     BlendParams(eqRGB.glValue, GL_ONE, GL_ONE, eqAlpha.glValue, GL_ONE, GL_ONE, defaultBlendColor));
442*35238bceSAndroid Build Coastguard Worker 
443*35238bceSAndroid Build Coastguard Worker                 group->addChild(new BlendCase(m_context, name.c_str(), description.c_str(), paramSets));
444*35238bceSAndroid Build Coastguard Worker             }
445*35238bceSAndroid Build Coastguard Worker     }
446*35238bceSAndroid Build Coastguard Worker }
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker } // namespace Functional
449*35238bceSAndroid Build Coastguard Worker } // namespace gles2
450*35238bceSAndroid Build Coastguard Worker } // namespace deqp
451