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 FBO depthbuffer tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es3fFboDepthbufferTests.hpp" 25#include "es3fFboTestCase.hpp" 26#include "es3fFboTestUtil.hpp" 27#include "gluTextureUtil.hpp" 28#include "tcuTextureUtil.hpp" 29#include "sglrContextUtil.hpp" 30#include "glwEnums.hpp" 31 32namespace deqp 33{ 34namespace gles3 35{ 36namespace Functional 37{ 38 39using std::string; 40using tcu::Vec2; 41using tcu::Vec3; 42using tcu::Vec4; 43using tcu::IVec2; 44using tcu::IVec3; 45using tcu::IVec4; 46using tcu::UVec4; 47using namespace FboTestUtil; 48 49class BasicFboDepthCase : public FboTestCase 50{ 51public: 52 BasicFboDepthCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height) 53 : FboTestCase (context, name, desc) 54 , m_format (format) 55 , m_width (width) 56 , m_height (height) 57 { 58 } 59 60protected: 61 void preCheck (void) 62 { 63 checkFormatSupport(m_format); 64 } 65 66 void render (tcu::Surface& dst) 67 { 68 const deUint32 colorFormat = GL_RGBA8; 69 deUint32 fbo = 0; 70 deUint32 colorRbo = 0; 71 deUint32 depthRbo = 0; 72 GradientShader gradShader (glu::TYPE_FLOAT_VEC4); 73 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 74 deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); 75 deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); 76 float clearDepth = 1.0f; 77 78 // Setup shaders 79 gradShader.setGradient(*getCurrentContext(), gradShaderID, tcu::Vec4(0.0f), tcu::Vec4(1.0f)); 80 texShader.setUniforms (*getCurrentContext(), texShaderID); 81 82 // Setup FBO 83 84 glGenFramebuffers(1, &fbo); 85 glGenRenderbuffers(1, &colorRbo); 86 glGenRenderbuffers(1, &depthRbo); 87 88 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo); 89 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height); 90 91 glBindRenderbuffer(GL_RENDERBUFFER, depthRbo); 92 glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_width, m_height); 93 94 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 95 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 96 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRbo); 97 checkError(); 98 checkFramebufferStatus(GL_FRAMEBUFFER); 99 100 glViewport(0, 0, m_width, m_height); 101 102 // Clear depth to 1 103 glClearBufferfv(GL_DEPTH, 0, &clearDepth); 104 105 // Render gradient with depth = [-1..1] 106 glEnable(GL_DEPTH_TEST); 107 sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 108 109 // Render grid pattern with depth = 0 110 { 111 const deUint32 format = GL_RGBA; 112 const deUint32 dataType = GL_UNSIGNED_BYTE; 113 const int texW = 128; 114 const int texH = 128; 115 deUint32 gridTex = 0; 116 tcu::TextureLevel data (glu::mapGLTransferFormat(format, dataType), texW, texH, 1); 117 118 tcu::fillWithGrid(data.getAccess(), 8, Vec4(0.2f, 0.7f, 0.1f, 1.0f), Vec4(0.7f, 0.1f, 0.5f, 0.8f)); 119 120 glGenTextures(1, &gridTex); 121 glBindTexture(GL_TEXTURE_2D, gridTex); 122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 126 glTexImage2D(GL_TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr()); 127 128 sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 129 } 130 131 // Read results. 132 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f)); 133 } 134 135private: 136 deUint32 m_format; 137 int m_width; 138 int m_height; 139}; 140 141class DepthWriteClampCase : public FboTestCase 142{ 143public: 144 DepthWriteClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height) 145 : FboTestCase (context, name, desc) 146 , m_format (format) 147 , m_width (width) 148 , m_height (height) 149 { 150 } 151 152protected: 153 void preCheck (void) 154 { 155 checkFormatSupport(m_format); 156 } 157 158 void render (tcu::Surface& dst) 159 { 160 const deUint32 colorFormat = GL_RGBA8; 161 deUint32 fbo = 0; 162 deUint32 colorRbo = 0; 163 deUint32 depthTexture = 0; 164 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format)); 165 166 DepthGradientShader depthGradShader (glu::TYPE_FLOAT_VEC4); 167 const deUint32 depthGradShaderID = getCurrentContext()->createProgram(&depthGradShader); 168 const float clearDepth = 1.0f; 169 const tcu::Vec4 red (1.0, 0.0, 0.0, 1.0); 170 const tcu::Vec4 green (0.0, 1.0, 0.0, 1.0); 171 172 // Setup FBO 173 174 glGenFramebuffers(1, &fbo); 175 glGenRenderbuffers(1, &colorRbo); 176 glGenTextures(1, &depthTexture); 177 178 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo); 179 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height); 180 181 glBindTexture(GL_TEXTURE_2D, depthTexture); 182 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL); 183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 185 186 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 187 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 188 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0); 189 checkError(); 190 checkFramebufferStatus(GL_FRAMEBUFFER); 191 192 glViewport(0, 0, m_width, m_height); 193 194 // Clear depth to 1 195 glClearBufferfv(GL_DEPTH, 0, &clearDepth); 196 197 // Test that invalid values are not written to the depth buffer 198 199 // Render green quad, depth gradient = [-1..2] 200 glEnable(GL_DEPTH_TEST); 201 glDepthFunc(GL_ALWAYS); 202 203 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green); 204 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 205 glDepthMask(GL_FALSE); 206 207 // Test if any fragment has greater depth than 1; there should be none 208 glDepthFunc(GL_LESS); // (1 < depth) ? 209 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 1.0f, 1.0f, red); 210 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 211 212 // Test if any fragment has smaller depth than 0; there should be none 213 glDepthFunc(GL_GREATER); // (0 > depth) ? 214 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, 0.0f, 0.0f, red); 215 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 216 217 // Read results. 218 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f)); 219 } 220 221private: 222 const deUint32 m_format; 223 const int m_width; 224 const int m_height; 225}; 226 227class DepthTestClampCase : public FboTestCase 228{ 229public: 230 DepthTestClampCase (Context& context, const char* name, const char* desc, deUint32 format, int width, int height) 231 : FboTestCase (context, name, desc) 232 , m_format (format) 233 , m_width (width) 234 , m_height (height) 235 { 236 } 237 238protected: 239 void preCheck (void) 240 { 241 checkFormatSupport(m_format); 242 } 243 244 void render (tcu::Surface& dst) 245 { 246 const deUint32 colorFormat = GL_RGBA8; 247 deUint32 fbo = 0; 248 deUint32 colorRbo = 0; 249 deUint32 depthTexture = 0; 250 glu::TransferFormat transferFmt = glu::getTransferFormat(glu::mapGLInternalFormat(m_format)); 251 252 DepthGradientShader depthGradShader (glu::TYPE_FLOAT_VEC4); 253 const deUint32 depthGradShaderID = getCurrentContext()->createProgram(&depthGradShader); 254 const float clearDepth = 1.0f; 255 const tcu::Vec4 yellow (1.0, 1.0, 0.0, 1.0); 256 const tcu::Vec4 green (0.0, 1.0, 0.0, 1.0); 257 258 // Setup FBO 259 260 glGenFramebuffers(1, &fbo); 261 glGenRenderbuffers(1, &colorRbo); 262 glGenTextures(1, &depthTexture); 263 264 glBindRenderbuffer(GL_RENDERBUFFER, colorRbo); 265 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_width, m_height); 266 267 glBindTexture(GL_TEXTURE_2D, depthTexture); 268 glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL); 269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 271 272 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 273 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); 274 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0); 275 checkError(); 276 checkFramebufferStatus(GL_FRAMEBUFFER); 277 278 glViewport(0, 0, m_width, m_height); 279 280 // Clear depth to 1 281 glClearBufferfv(GL_DEPTH, 0, &clearDepth); 282 283 // Test values used in depth test are clamped 284 285 // Render green quad, depth gradient = [-1..2] 286 glEnable(GL_DEPTH_TEST); 287 glDepthFunc(GL_ALWAYS); 288 289 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -1.0f, 2.0f, green); 290 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 291 292 // Render yellow quad, depth gradient = [-0.5..3]. Gradients have equal values only outside [0, 1] range due to clamping 293 glDepthFunc(GL_EQUAL); 294 depthGradShader.setUniforms(*getCurrentContext(), depthGradShaderID, -0.5f, 3.0f, yellow); 295 sglr::drawQuad(*getCurrentContext(), depthGradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 296 297 // Read results. 298 readPixels(dst, 0, 0, m_width, m_height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f)); 299 } 300 301private: 302 const deUint32 m_format; 303 const int m_width; 304 const int m_height; 305}; 306 307FboDepthTests::FboDepthTests (Context& context) 308 : TestCaseGroup(context, "depth", "Depth tests") 309{ 310} 311 312FboDepthTests::~FboDepthTests (void) 313{ 314} 315 316void FboDepthTests::init (void) 317{ 318 static const deUint32 depthFormats[] = 319 { 320 GL_DEPTH_COMPONENT32F, 321 GL_DEPTH_COMPONENT24, 322 GL_DEPTH_COMPONENT16, 323 GL_DEPTH32F_STENCIL8, 324 GL_DEPTH24_STENCIL8 325 }; 326 327 // .basic 328 { 329 tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic depth tests"); 330 addChild(basicGroup); 331 332 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++) 333 basicGroup->addChild(new BasicFboDepthCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127)); 334 } 335 336 // .depth_write_clamp 337 { 338 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_write_clamp", "Depth write clamping tests"); 339 addChild(depthClampGroup); 340 341 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++) 342 depthClampGroup->addChild(new DepthWriteClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127)); 343 } 344 345 // .depth_test_clamp 346 { 347 tcu::TestCaseGroup* depthClampGroup = new tcu::TestCaseGroup(m_testCtx, "depth_test_clamp", "Depth test value clamping tests"); 348 addChild(depthClampGroup); 349 350 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthFormats); fmtNdx++) 351 depthClampGroup->addChild(new DepthTestClampCase(m_context, getFormatName(depthFormats[fmtNdx]), "", depthFormats[fmtNdx], 119, 127)); 352 } 353} 354 355} // Functional 356} // gles3 357} // deqp 358