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 Base class for FBO tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es3fFboTestCase.hpp" 25#include "es3fFboTestUtil.hpp" 26#include "tcuTestLog.hpp" 27#include "tcuImageCompare.hpp" 28#include "tcuRenderTarget.hpp" 29#include "sglrGLContext.hpp" 30#include "sglrReferenceContext.hpp" 31#include "gluStrUtil.hpp" 32#include "gluContextInfo.hpp" 33#include "deRandom.hpp" 34#include "glwEnums.hpp" 35#include "glwFunctions.hpp" 36 37#include <algorithm> 38 39namespace deqp 40{ 41namespace gles3 42{ 43namespace Functional 44{ 45 46using tcu::TestLog; 47using std::string; 48 49FboTestCase::FboTestCase (Context& context, const char* name, const char* description, bool useScreenSizedViewport) 50 : TestCase (context, name, description) 51 , m_viewportWidth (useScreenSizedViewport ? context.getRenderTarget().getWidth() : 128) 52 , m_viewportHeight (useScreenSizedViewport ? context.getRenderTarget().getHeight() : 128) 53{ 54} 55 56FboTestCase::~FboTestCase (void) 57{ 58} 59 60FboTestCase::IterateResult FboTestCase::iterate (void) 61{ 62 glu::RenderContext& renderCtx = TestCase::m_context.getRenderContext(); 63 const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); 64 TestLog& log = m_testCtx.getLog(); 65 66 // Viewport. 67 de::Random rnd (deStringHash(getName())); 68 int width = deMin32(renderTarget.getWidth(), m_viewportWidth); 69 int height = deMin32(renderTarget.getHeight(), m_viewportHeight); 70 int x = rnd.getInt(0, renderTarget.getWidth() - width); 71 int y = rnd.getInt(0, renderTarget.getHeight() - height); 72 73 // Surface format and storage is choosen by render(). 74 tcu::Surface reference; 75 tcu::Surface result; 76 77 // Call preCheck() that can throw exception if some requirement is not met. 78 preCheck(); 79 80 // Render using GLES3. 81 try 82 { 83 sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height)); 84 setContext(&context); 85 render(result); 86 87 // Check error. 88 deUint32 err = glGetError(); 89 if (err != GL_NO_ERROR) 90 throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), DE_NULL, __FILE__, __LINE__); 91 92 setContext(DE_NULL); 93 } 94 catch (const FboTestUtil::FboIncompleteException& e) 95 { 96 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED) 97 { 98 log << e; 99 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); 100 return STOP; 101 } 102 else 103 throw; 104 } 105 106 // Render reference. 107 { 108 sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height); 109 sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer()); 110 111 setContext(&context); 112 render(reference); 113 setContext(DE_NULL); 114 } 115 116 bool isOk = compare(reference, result); 117 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 118 isOk ? "Pass" : "Image comparison failed"); 119 return STOP; 120} 121 122bool FboTestCase::compare (const tcu::Surface& reference, const tcu::Surface& result) 123{ 124 return tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, 0.05f, tcu::COMPARE_LOG_RESULT); 125} 126 127void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias) 128{ 129 FboTestUtil::readPixels(*getCurrentContext(), dst, x, y, width, height, format, scale, bias); 130} 131 132void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height) 133{ 134 getCurrentContext()->readPixels(dst, x, y, width, height); 135} 136 137void FboTestCase::checkFramebufferStatus (deUint32 target) 138{ 139 deUint32 status = glCheckFramebufferStatus(target); 140 if (status != GL_FRAMEBUFFER_COMPLETE) 141 throw FboTestUtil::FboIncompleteException(status, __FILE__, __LINE__); 142} 143 144void FboTestCase::checkError (void) 145{ 146 deUint32 err = glGetError(); 147 if (err != GL_NO_ERROR) 148 throw glu::Error((int)err, (string("Got ") + glu::getErrorStr(err).toString()).c_str(), DE_NULL, __FILE__, __LINE__); 149} 150 151static bool isRequiredFormat (deUint32 format) 152{ 153 switch (format) 154 { 155 // Color-renderable formats 156 case GL_RGBA32I: 157 case GL_RGBA32UI: 158 case GL_RGBA16I: 159 case GL_RGBA16UI: 160 case GL_RGBA8: 161 case GL_RGBA8I: 162 case GL_RGBA8UI: 163 case GL_SRGB8_ALPHA8: 164 case GL_RGB10_A2: 165 case GL_RGB10_A2UI: 166 case GL_RGBA4: 167 case GL_RGB5_A1: 168 case GL_RGB8: 169 case GL_RGB565: 170 case GL_RG32I: 171 case GL_RG32UI: 172 case GL_RG16I: 173 case GL_RG16UI: 174 case GL_RG8: 175 case GL_RG8I: 176 case GL_RG8UI: 177 case GL_R32I: 178 case GL_R32UI: 179 case GL_R16I: 180 case GL_R16UI: 181 case GL_R8: 182 case GL_R8I: 183 case GL_R8UI: 184 return true; 185 186 // Depth formats 187 case GL_DEPTH_COMPONENT32F: 188 case GL_DEPTH_COMPONENT24: 189 case GL_DEPTH_COMPONENT16: 190 return true; 191 192 // Depth+stencil formats 193 case GL_DEPTH32F_STENCIL8: 194 case GL_DEPTH24_STENCIL8: 195 return true; 196 197 // Stencil formats 198 case GL_STENCIL_INDEX8: 199 return true; 200 201 default: 202 return false; 203 } 204} 205 206static std::vector<std::string> getEnablingExtensions (deUint32 format) 207{ 208 std::vector<std::string> out; 209 210 DE_ASSERT(!isRequiredFormat(format)); 211 212 switch (format) 213 { 214 case GL_RGB16F: 215 out.push_back("GL_EXT_color_buffer_half_float"); 216 break; 217 218 case GL_RGBA16F: 219 case GL_RG16F: 220 case GL_R16F: 221 out.push_back("GL_EXT_color_buffer_half_float"); 222 223 case GL_RGBA32F: 224 case GL_RGB32F: 225 case GL_R11F_G11F_B10F: 226 case GL_RG32F: 227 case GL_R32F: 228 out.push_back("GL_EXT_color_buffer_float"); 229 230 default: 231 break; 232 } 233 234 return out; 235} 236 237static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts) 238{ 239 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++) 240 { 241 const std::string& extension = *iter; 242 243 if (context.getContextInfo().isExtensionSupported(extension.c_str())) 244 return true; 245 } 246 247 return false; 248} 249 250void FboTestCase::checkFormatSupport (deUint32 sizedFormat) 251{ 252 const bool isCoreFormat = isRequiredFormat(sizedFormat); 253 const std::vector<std::string> requiredExts = (!isCoreFormat) ? getEnablingExtensions(sizedFormat) : std::vector<std::string>(); 254 255 // Check that we don't try to use invalid formats. 256 DE_ASSERT(isCoreFormat || !requiredExts.empty()); 257 258 if (!requiredExts.empty() && !isAnyExtensionSupported(m_context, requiredExts)) 259 throw tcu::NotSupportedError("Format not supported"); 260} 261 262static int getMinimumSampleCount (deUint32 format) 263{ 264 switch (format) 265 { 266 // Core formats 267 case GL_RGBA32I: 268 case GL_RGBA32UI: 269 case GL_RGBA16I: 270 case GL_RGBA16UI: 271 case GL_RGBA8: 272 case GL_RGBA8I: 273 case GL_RGBA8UI: 274 case GL_SRGB8_ALPHA8: 275 case GL_RGB10_A2: 276 case GL_RGB10_A2UI: 277 case GL_RGBA4: 278 case GL_RGB5_A1: 279 case GL_RGB8: 280 case GL_RGB565: 281 case GL_RG32I: 282 case GL_RG32UI: 283 case GL_RG16I: 284 case GL_RG16UI: 285 case GL_RG8: 286 case GL_RG8I: 287 case GL_RG8UI: 288 case GL_R32I: 289 case GL_R32UI: 290 case GL_R16I: 291 case GL_R16UI: 292 case GL_R8: 293 case GL_R8I: 294 case GL_R8UI: 295 case GL_DEPTH_COMPONENT32F: 296 case GL_DEPTH_COMPONENT24: 297 case GL_DEPTH_COMPONENT16: 298 case GL_DEPTH32F_STENCIL8: 299 case GL_DEPTH24_STENCIL8: 300 case GL_STENCIL_INDEX8: 301 return 4; 302 303 // GL_EXT_color_buffer_float 304 case GL_R11F_G11F_B10F: 305 case GL_RG16F: 306 case GL_R16F: 307 return 4; 308 309 case GL_RGBA32F: 310 case GL_RGBA16F: 311 case GL_RG32F: 312 case GL_R32F: 313 return 0; 314 315 // GL_EXT_color_buffer_half_float 316 case GL_RGB16F: 317 return 0; 318 319 default: 320 DE_ASSERT(!"Unknown format"); 321 return 0; 322 } 323} 324 325static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format) 326{ 327 int numSampleCounts = 0; 328 std::vector<int> sampleCounts; 329 330 gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts); 331 332 if (numSampleCounts > 0) 333 { 334 sampleCounts.resize(numSampleCounts); 335 gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]); 336 } 337 338 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format"); 339 340 return sampleCounts; 341} 342 343void FboTestCase::checkSampleCount (deUint32 sizedFormat, int numSamples) 344{ 345 const int minSampleCount = getMinimumSampleCount(sizedFormat); 346 347 if (numSamples > minSampleCount) 348 { 349 // Exceeds spec-mandated minimum - need to check. 350 const std::vector<int> supportedSampleCounts = querySampleCounts(m_context.getRenderContext().getFunctions(), sizedFormat); 351 352 if (std::find(supportedSampleCounts.begin(), supportedSampleCounts.end(), numSamples) == supportedSampleCounts.end()) 353 throw tcu::NotSupportedError("Sample count not supported"); 354 } 355} 356 357void FboTestCase::clearColorBuffer (const tcu::TextureFormat& format, const tcu::Vec4& value) 358{ 359 FboTestUtil::clearColorBuffer(*getCurrentContext(), format, value); 360} 361 362} // Functional 363} // gles3 364} // deqp 365