Merge "Fix color change verification in dithering tests" into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / modules / gles3 / functional / es3fTextureSwizzleTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 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 Texture swizzle tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es3fTextureSwizzleTests.hpp"
25 #include "glsTextureTestUtil.hpp"
26 #include "gluPixelTransfer.hpp"
27 #include "gluTexture.hpp"
28 #include "gluRenderContext.hpp"
29 #include "tcuTextureUtil.hpp"
30 #include "tcuRenderTarget.hpp"
31 #include "deString.h"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41
42 using std::string;
43 using std::vector;
44 using tcu::TestLog;
45 using namespace deqp::gls;
46 using namespace deqp::gls::TextureTestUtil;
47
48 static int swizzle (const tcu::RGBA& c, deUint32 swz)
49 {
50         switch (swz)
51         {
52                 case GL_RED:    return c.getRed();
53                 case GL_GREEN:  return c.getGreen();
54                 case GL_BLUE:   return c.getBlue();
55                 case GL_ALPHA:  return c.getAlpha();
56                 case GL_ZERO:   return 0;
57                 case GL_ONE:    return (1<<8)-1;
58                 default:
59                         DE_ASSERT(false);
60                         return 0;
61         }
62 }
63
64 static void swizzle (tcu::Surface& surface, deUint32 swzR, deUint32 swzG, deUint32 swzB, deUint32 swzA)
65 {
66         for (int y = 0; y < surface.getHeight(); y++)
67         {
68                 for (int x = 0; x < surface.getWidth(); x++)
69                 {
70                         tcu::RGBA p = surface.getPixel(x, y);
71                         surface.setPixel(x, y, tcu::RGBA(swizzle(p, swzR), swizzle(p, swzG), swizzle(p, swzB), swizzle(p, swzA)));
72                 }
73         }
74 }
75
76 class Texture2DSwizzleCase : public TestCase
77 {
78 public:
79                                                         Texture2DSwizzleCase    (Context& context, const char* name, const char* description, deUint32 internalFormat, deUint32 format, deUint32 dataType, deUint32 swizzleR, deUint32 swizzleG, deUint32 swizzleB, deUint32 swizzleA);
80                                                         ~Texture2DSwizzleCase   (void);
81
82         void                                    init                                    (void);
83         void                                    deinit                                  (void);
84         IterateResult                   iterate                                 (void);
85
86 private:
87                                                         Texture2DSwizzleCase    (const Texture2DSwizzleCase& other);
88         Texture2DSwizzleCase&   operator=                               (const Texture2DSwizzleCase& other);
89
90         deUint32                                m_internalFormat;
91         deUint32                                m_format;
92         deUint32                                m_dataType;
93         deUint32                                m_swizzleR;
94         deUint32                                m_swizzleG;
95         deUint32                                m_swizzleB;
96         deUint32                                m_swizzleA;
97
98         glu::Texture2D*                 m_texture;
99         TextureRenderer                 m_renderer;
100 };
101
102 Texture2DSwizzleCase::Texture2DSwizzleCase (Context& context, const char* name, const char* description, deUint32 internalFormat, deUint32 format, deUint32 dataType, deUint32 swizzleR, deUint32 swizzleG, deUint32 swizzleB, deUint32 swizzleA)
103         : TestCase                      (context, name, description)
104         , m_internalFormat      (internalFormat)
105         , m_format                      (format)
106         , m_dataType            (dataType)
107         , m_swizzleR            (swizzleR)
108         , m_swizzleG            (swizzleG)
109         , m_swizzleB            (swizzleB)
110         , m_swizzleA            (swizzleA)
111         , m_texture                     (DE_NULL)
112         , m_renderer            (context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
113 {
114 }
115
116 Texture2DSwizzleCase::~Texture2DSwizzleCase (void)
117 {
118         deinit();
119 }
120
121 void Texture2DSwizzleCase::init (void)
122 {
123         int     width   = de::min(128, m_context.getRenderContext().getRenderTarget().getWidth());
124         int     height  = de::min(128, m_context.getRenderContext().getRenderTarget().getHeight());
125
126         m_texture = (m_internalFormat == m_format) ? new glu::Texture2D(m_context.getRenderContext(), m_format, m_dataType, width, height)
127                                                                                            : new glu::Texture2D(m_context.getRenderContext(), m_internalFormat, width, height);
128
129         tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
130
131         // Fill level 0.
132         m_texture->getRefTexture().allocLevel(0);
133         tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
134 }
135
136 void Texture2DSwizzleCase::deinit (void)
137 {
138         delete m_texture;
139         m_texture = DE_NULL;
140
141         m_renderer.clear();
142 }
143
144 Texture2DSwizzleCase::IterateResult Texture2DSwizzleCase::iterate (void)
145 {
146         const glw::Functions&   gl                                      = m_context.getRenderContext().getFunctions();
147         TestLog&                                log                                     = m_testCtx.getLog();
148         RandomViewport                  viewport                        (m_context.getRenderContext().getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
149         tcu::Surface                    renderedFrame           (viewport.width, viewport.height);
150         tcu::Surface                    referenceFrame          (viewport.width, viewport.height);
151         tcu::RGBA                               threshold                       = m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
152         vector<float>                   texCoord;
153         ReferenceParams                 renderParams            (TEXTURETYPE_2D);
154         tcu::TextureFormatInfo  spec                            = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
155
156         renderParams.samplerType        = getSamplerType(m_texture->getRefTexture().getFormat());
157         renderParams.sampler            = tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
158         renderParams.colorScale         = spec.lookupScale;
159         renderParams.colorBias          = spec.lookupBias;
160
161         computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
162
163         // Setup base viewport.
164         gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
165
166         // Upload texture data to GL.
167         m_texture->upload();
168
169         // Bind to unit 0.
170         gl.activeTexture(GL_TEXTURE0);
171         gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
172
173         // Setup nearest neighbor filtering and clamp-to-edge.
174         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,              GL_CLAMP_TO_EDGE);
175         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,              GL_CLAMP_TO_EDGE);
176         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  GL_NEAREST);
177         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  GL_NEAREST);
178
179         // Setup texture swizzle.
180         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,   m_swizzleR);
181         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,   m_swizzleG);
182         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,   m_swizzleB);
183         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,   m_swizzleA);
184
185         GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
186
187         // Draw.
188         m_renderer.renderQuad(0, &texCoord[0], renderParams);
189         glu::readPixels(m_context.getRenderContext(), viewport.x, viewport.y, renderedFrame.getAccess());
190
191         // Compute reference
192         {
193                 const tcu::PixelFormat pixelFormat = m_context.getRenderTarget().getPixelFormat();
194
195                 // Do initial rendering to RGBA8 in order to keep alpha
196                 sampleTexture(SurfaceAccess(referenceFrame, tcu::PixelFormat(8,8,8,8)), m_texture->getRefTexture(), &texCoord[0], renderParams);
197
198                 // Swizzle channels
199                 swizzle(referenceFrame, m_swizzleR, m_swizzleG, m_swizzleB, m_swizzleA);
200
201                 // Convert to destination format
202                 if (pixelFormat != tcu::PixelFormat(8,8,8,8))
203                 {
204                         for (int y = 0; y < referenceFrame.getHeight(); y++)
205                         {
206                                 for (int x = 0; x < referenceFrame.getWidth(); x++)
207                                 {
208                                         tcu::RGBA p = referenceFrame.getPixel(x, y);
209                                         referenceFrame.setPixel(x, y, pixelFormat.convertColor(p));
210                                 }
211                         }
212                 }
213         }
214
215         // Compare and log.
216         bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
217
218         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS      : QP_TEST_RESULT_FAIL,
219                                                         isOk ? "Pass"                           : "Image comparison failed");
220
221         return STOP;
222 }
223
224 TextureSwizzleTests::TextureSwizzleTests (Context& context)
225         : TestCaseGroup(context, "swizzle", "Texture Swizzle Tests")
226 {
227 }
228
229 TextureSwizzleTests::~TextureSwizzleTests (void)
230 {
231 }
232
233 void TextureSwizzleTests::init (void)
234 {
235         static const struct
236         {
237                 const char*             name;
238                 deUint32                internalFormat;
239                 deUint32                format;
240                 deUint32                dataType;
241         } formats[] =
242         {
243                 { "alpha",                              GL_ALPHA,                               GL_ALPHA,                       GL_UNSIGNED_BYTE },
244                 { "luminance",                  GL_LUMINANCE,                   GL_LUMINANCE,           GL_UNSIGNED_BYTE },
245                 { "luminance_alpha",    GL_LUMINANCE_ALPHA,             GL_LUMINANCE_ALPHA,     GL_UNSIGNED_BYTE },
246                 { "red",                                GL_R8,                                  GL_RED,                         GL_UNSIGNED_BYTE },
247                 { "rg",                                 GL_RG8,                                 GL_RG,                          GL_UNSIGNED_BYTE },
248                 { "rgb",                                GL_RGB8,                                GL_RGB,                         GL_UNSIGNED_BYTE },
249                 { "rgba",                               GL_RGBA8,                               GL_RGBA,                        GL_UNSIGNED_BYTE }
250         };
251
252         static const struct
253         {
254                 const char*             name;
255                 deUint32                channel;
256         } channels[] =
257         {
258                 { "r",  GL_TEXTURE_SWIZZLE_R },
259                 { "g",  GL_TEXTURE_SWIZZLE_G },
260                 { "b",  GL_TEXTURE_SWIZZLE_B },
261                 { "a",  GL_TEXTURE_SWIZZLE_A }
262         };
263
264         static const struct
265         {
266                 const char*             name;
267                 deUint32                swizzle;
268         } swizzles[] =
269         {
270                 { "red",                GL_RED          },
271                 { "green",              GL_GREEN        },
272                 { "blue",               GL_BLUE         },
273                 { "alpha",              GL_ALPHA        },
274                 { "zero",               GL_ZERO         },
275                 { "one",                GL_ONE          }
276         };
277
278         static const struct
279         {
280                 const char*             name;
281                 deUint32                swzR;
282                 deUint32                swzG;
283                 deUint32                swzB;
284                 deUint32                swzA;
285         } swizzleCases[] =
286         {
287                 { "all_red",                    GL_RED,         GL_RED,         GL_RED,         GL_RED          },
288                 { "all_green",                  GL_GREEN,       GL_GREEN,       GL_GREEN,       GL_GREEN        },
289                 { "all_blue",                   GL_BLUE,        GL_BLUE,        GL_BLUE,        GL_BLUE         },
290                 { "all_alpha",                  GL_ALPHA,       GL_ALPHA,       GL_ALPHA,       GL_ALPHA        },
291                 { "all_zero",                   GL_ZERO,        GL_ZERO,        GL_ZERO,        GL_ZERO         },
292                 { "all_one",                    GL_ONE,         GL_ONE,         GL_ONE,         GL_ONE          },
293                 { "bgra",                               GL_BLUE,        GL_GREEN,       GL_RED,         GL_ALPHA        },
294                 { "abgr",                               GL_ALPHA,       GL_BLUE,        GL_GREEN,       GL_RED          },
295                 { "one_one_red_green",  GL_ONE,         GL_ONE,         GL_RED,         GL_GREEN        }
296         };
297
298         static const deUint32 defaultSwizzles[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
299
300         // All swizzles applied to each channel.
301         tcu::TestCaseGroup* singleChannelGroup = new tcu::TestCaseGroup(m_testCtx, "single_channel", "Single-channel swizzle");
302         addChild(singleChannelGroup);
303         for (int chanNdx = 0; chanNdx < DE_LENGTH_OF_ARRAY(channels); chanNdx++)
304         {
305                 for (int swzNdx = 0; swzNdx < DE_LENGTH_OF_ARRAY(swizzles); swzNdx++)
306                 {
307                         if (swizzles[swzNdx].swizzle == defaultSwizzles[chanNdx])
308                                 continue; // No need to test default case.
309
310                         string          name    = string(channels[chanNdx].name) + "_" + swizzles[swzNdx].name;
311                         deUint32        swz             = swizzles[swzNdx].swizzle;
312                         deUint32        swzR    = (chanNdx == 0) ? swz : defaultSwizzles[0];
313                         deUint32        swzG    = (chanNdx == 1) ? swz : defaultSwizzles[1];
314                         deUint32        swzB    = (chanNdx == 2) ? swz : defaultSwizzles[2];
315                         deUint32        swzA    = (chanNdx == 3) ? swz : defaultSwizzles[3];
316
317                         singleChannelGroup->addChild(new Texture2DSwizzleCase(m_context, name.c_str(), "Single-channel swizzle", GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, swzR, swzG, swzB, swzA));
318                 }
319         }
320
321         // Swizzles for all formats.
322         tcu::TestCaseGroup* multiChannelGroup = new tcu::TestCaseGroup(m_testCtx, "multi_channel", "Multi-channel swizzle");
323         addChild(multiChannelGroup);
324         for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); fmtNdx++)
325         {
326                 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(swizzleCases); caseNdx++)
327                 {
328                         string          name            = string(formats[fmtNdx].name) + "_" + swizzleCases[caseNdx].name;
329                         deUint32        swzR            = swizzleCases[caseNdx].swzR;
330                         deUint32        swzG            = swizzleCases[caseNdx].swzG;
331                         deUint32        swzB            = swizzleCases[caseNdx].swzB;
332                         deUint32        swzA            = swizzleCases[caseNdx].swzA;
333                         deUint32        intFormat       = formats[fmtNdx].internalFormat;
334                         deUint32        format          = formats[fmtNdx].format;
335                         deUint32        dataType        = formats[fmtNdx].dataType;
336
337                         multiChannelGroup->addChild(new Texture2DSwizzleCase(m_context, name.c_str(), "Multi-channel swizzle", intFormat, format, dataType, swzR, swzG, swzB, swzA));
338                 }
339         }
340 }
341
342 } // Functional
343 } // gles3
344 } // deqp