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