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