Add new framebuffer fetch extension tests am: 2a609fb223
[platform/upstream/VK-GL-CTS.git] / modules / gles2 / functional / es2fTextureWrapTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.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 wrap mode tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es2fTextureWrapTests.hpp"
25 #include "glsTextureTestUtil.hpp"
26 #include "gluTexture.hpp"
27 #include "gluStrUtil.hpp"
28 #include "gluTextureUtil.hpp"
29 #include "gluPixelTransfer.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuTextureUtil.hpp"
32
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35
36 namespace deqp
37 {
38 namespace gles2
39 {
40 namespace Functional
41 {
42
43 using tcu::TestLog;
44 using std::vector;
45 using std::string;
46 using tcu::Sampler;
47 using namespace glu;
48 using namespace gls::TextureTestUtil;
49 using namespace glu::TextureTestUtil;
50
51 enum
52 {
53         VIEWPORT_WIDTH          = 256,
54         VIEWPORT_HEIGHT         = 256
55 };
56
57 class TextureWrapCase : public tcu::TestCase
58 {
59 public:
60                                                                 TextureWrapCase                 (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
61                                                                 TextureWrapCase                 (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames);
62                                                                 ~TextureWrapCase                (void);
63
64         void                                            init                                    (void);
65         void                                            deinit                                  (void);
66         IterateResult                           iterate                                 (void);
67
68 private:
69                                                                 TextureWrapCase                 (const TextureWrapCase& other);
70         TextureWrapCase&                        operator=                               (const TextureWrapCase& other);
71
72         glu::RenderContext&                     m_renderCtx;
73         const glu::ContextInfo&         m_renderCtxInfo;
74
75         deUint32                                        m_format;
76         deUint32                                        m_dataType;
77         deUint32                                        m_wrapS;
78         deUint32                                        m_wrapT;
79         deUint32                                        m_minFilter;
80         deUint32                                        m_magFilter;
81
82         int                                                     m_width;
83         int                                                     m_height;
84         std::vector<std::string>        m_filenames;
85
86         glu::Texture2D*                         m_texture;
87         TextureRenderer                         m_renderer;
88 };
89
90 TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
91         : TestCase                      (testCtx, name, description)
92         , m_renderCtx           (renderCtx)
93         , m_renderCtxInfo       (ctxInfo)
94         , m_format                      (format)
95         , m_dataType            (dataType)
96         , m_wrapS                       (wrapS)
97         , m_wrapT                       (wrapT)
98         , m_minFilter           (minFilter)
99         , m_magFilter           (magFilter)
100         , m_width                       (width)
101         , m_height                      (height)
102         , m_texture                     (DE_NULL)
103         , m_renderer            (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
104 {
105 }
106
107 TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames)
108         : TestCase                      (testCtx, name, description)
109         , m_renderCtx           (renderCtx)
110         , m_renderCtxInfo       (ctxInfo)
111         , m_format                      (GL_NONE)
112         , m_dataType            (GL_NONE)
113         , m_wrapS                       (wrapS)
114         , m_wrapT                       (wrapT)
115         , m_minFilter           (minFilter)
116         , m_magFilter           (magFilter)
117         , m_width                       (0)
118         , m_height                      (0)
119         , m_filenames           (filenames)
120         , m_texture                     (DE_NULL)
121         , m_renderer            (renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
122 {
123 }
124
125 TextureWrapCase::~TextureWrapCase (void)
126 {
127         deinit();
128 }
129
130 void TextureWrapCase::init (void)
131 {
132         if (!m_filenames.empty())
133         {
134                 DE_ASSERT(m_width == 0 && m_height == 0 && m_format == GL_NONE && m_dataType == GL_NONE);
135
136                 m_texture       = glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
137                 m_width         = m_texture->getRefTexture().getWidth();
138                 m_height        = m_texture->getRefTexture().getHeight();
139         }
140         else
141         {
142                 m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
143
144                 // Fill level 0.
145                 m_texture->getRefTexture().allocLevel(0);
146                 tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
147
148                 m_texture->upload();
149         }
150 }
151
152 void TextureWrapCase::deinit (void)
153 {
154         delete m_texture;
155         m_texture = DE_NULL;
156
157         m_renderer.clear();
158 }
159
160 TextureWrapCase::IterateResult TextureWrapCase::iterate (void)
161 {
162         const glw::Functions&   gl                                      = m_renderCtx.getFunctions();
163         TestLog&                                log                                     = m_testCtx.getLog();
164         RandomViewport                  viewport                        (m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()));
165         tcu::Surface                    renderedFrame           (viewport.width, viewport.height);
166         tcu::Surface                    referenceFrame          (viewport.width, viewport.height);
167         bool                                    isCompressedTex         = !m_filenames.empty();
168         ReferenceParams                 refParams                       (TEXTURETYPE_2D);
169         int                                             leftWidth                       = viewport.width / 2;
170         int                                             rightWidth                      = viewport.width - leftWidth;
171         vector<float>                   texCoord;
172         tcu::RGBA                               threshold                       = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold()
173                                                                                                 + (isCompressedTex ? tcu::RGBA(7,7,7,7) : tcu::RGBA(3,3,3,3));
174
175         // Bind to unit 0.
176         gl.activeTexture(GL_TEXTURE0);
177         gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
178
179         // Setup filtering and wrap modes.
180         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,              m_wrapS);
181         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,              m_wrapT);
182         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  m_minFilter);
183         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,  m_magFilter);
184
185         GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
186
187         // Parameters for reference images.
188         refParams.sampler       = mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
189         refParams.lodMode       = LODMODE_EXACT;
190
191         // Left: minification
192         {
193                 gl.viewport(viewport.x, viewport.y, leftWidth, viewport.height);
194
195                 computeQuadTexCoord2D(texCoord, tcu::Vec2(-1.5f, -3.0f), tcu::Vec2(1.5f, 2.5f));
196
197                 m_renderer.renderQuad(0, &texCoord[0], refParams);
198                 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
199
200                 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, viewport.height),
201                                           m_texture->getRefTexture(), &texCoord[0], refParams);
202         }
203
204         // Right: magnification
205         {
206                 gl.viewport(viewport.x+leftWidth, viewport.y, rightWidth, viewport.height);
207
208                 computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));
209
210                 m_renderer.renderQuad(0, &texCoord[0], refParams);
211                 glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
212
213                 sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, viewport.height),
214                                           m_texture->getRefTexture(), &texCoord[0], refParams);
215         }
216
217         // Compare and log.
218         bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
219
220         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS      : QP_TEST_RESULT_FAIL,
221                                                         isOk ? "Pass"                           : "Image comparison failed");
222
223         return STOP;
224 }
225
226 TextureWrapTests::TextureWrapTests (Context& context)
227         : TestCaseGroup(context, "wrap", "Wrap Mode Tests")
228 {
229 }
230
231 TextureWrapTests::~TextureWrapTests (void)
232 {
233 }
234
235 void TextureWrapTests::init (void)
236 {
237         static const struct
238         {
239                 const char*             name;
240                 deUint32                mode;
241         } wrapModes[] =
242         {
243                 { "clamp",              GL_CLAMP_TO_EDGE },
244                 { "repeat",             GL_REPEAT },
245                 { "mirror",             GL_MIRRORED_REPEAT }
246         };
247
248         static const struct
249         {
250                 const char*             name;
251                 deUint32                mode;
252         } filteringModes[] =
253         {
254                 { "nearest",    GL_NEAREST },
255                 { "linear",             GL_LINEAR }
256         };
257
258         static const struct
259         {
260                 const char*             name;
261                 int                             width;
262                 int                             height;
263         } sizes[] =
264         {
265                 { "pot",                64, 128 },
266                 { "npot",               63, 112 }
267         };
268
269         static const struct
270         {
271                 const char*             name;
272                 deUint32                format;
273                 deUint32                dataType;
274         } formats[] =
275         {
276                 { "rgba8888",   GL_RGBA,                        GL_UNSIGNED_BYTE },
277                 { "rgb888",             GL_RGB,                         GL_UNSIGNED_BYTE },
278                 { "rgba4444",   GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4 },
279                 { "l8",                 GL_LUMINANCE,           GL_UNSIGNED_BYTE },
280         };
281
282 #define FOR_EACH(ITERATOR, ARRAY, BODY) \
283         for (int (ITERATOR) = 0; (ITERATOR) < DE_LENGTH_OF_ARRAY(ARRAY); (ITERATOR)++)  \
284                 BODY
285
286         FOR_EACH(wrapS,         wrapModes,
287         FOR_EACH(wrapT,         wrapModes,
288         FOR_EACH(filter,        filteringModes,
289         FOR_EACH(size,          sizes,
290         FOR_EACH(format,        formats,
291                 {
292                         bool is_clamp_clamp             = (wrapModes[wrapS].mode == GL_CLAMP_TO_EDGE    && wrapModes[wrapT].mode == GL_CLAMP_TO_EDGE);
293                         bool is_repeat_mirror   = (wrapModes[wrapS].mode == GL_REPEAT                   && wrapModes[wrapT].mode == GL_MIRRORED_REPEAT);
294
295                         if (!is_clamp_clamp && !is_repeat_mirror && format != 0)
296                                 continue; // Use other format varants with clamp_clamp & repeat_mirror pair only.
297
298                         if (!is_clamp_clamp && (!deIsPowerOfTwo32(sizes[size].width) || !deIsPowerOfTwo32(sizes[size].height)))
299                                 continue; // Not supported as described in Spec section 3.8.2.
300
301                         string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + sizes[size].name + "_" + formats[format].name;
302                         addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
303                                                                                  formats[format].format, formats[format].dataType,
304                                                                                  wrapModes[wrapS].mode,
305                                                                                  wrapModes[wrapT].mode,
306                                                                                  filteringModes[filter].mode, filteringModes[filter].mode,
307                                                                                  sizes[size].width, sizes[size].height));
308
309                 })))));
310
311         // Power-of-two ETC1 texture
312         std::vector<std::string> potFilenames;
313         potFilenames.push_back("data/etc1/photo_helsinki_mip_0.pkm");
314
315         FOR_EACH(wrapS,         wrapModes,
316         FOR_EACH(wrapT,         wrapModes,
317         FOR_EACH(filter,        filteringModes,
318                 {
319                         string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_pot_etc1";
320                         addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
321                                                                                  wrapModes[wrapS].mode,
322                                                                                  wrapModes[wrapT].mode,
323                                                                                  filteringModes[filter].mode, filteringModes[filter].mode,
324                                                                                  potFilenames));
325
326                 })));
327
328         std::vector<std::string> npotFilenames;
329         npotFilenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
330
331         // NPOT ETC1 texture
332         for (int filter = 0; filter < DE_LENGTH_OF_ARRAY(filteringModes); filter++)
333         {
334                 string name = string("clamp_clamp_") + filteringModes[filter].name + "_npot_etc1";
335                 addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
336                                                                          GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
337                                                                          filteringModes[filter].mode, filteringModes[filter].mode,
338                                                                          npotFilenames));
339         }
340 }
341
342 } // Functional
343 } // gles2
344 } // deqp