Path: blob/main_old/src/tests/gl_tests/DepthStencilFormatsTest.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "test_utils/ANGLETest.h"7#include "test_utils/gl_raii.h"89#include "common/mathutil.h"10#include "platform/FeaturesD3D.h"1112using namespace angle;1314struct ReadbackTestParam15{16GLuint attachment;17GLuint format;18GLuint type;19void *data;20int depthBits;21int stencilBits;22};2324class DepthStencilFormatsTestBase : public ANGLETest25{26protected:27DepthStencilFormatsTestBase()28{29setWindowWidth(128);30setWindowHeight(128);31setConfigRedBits(8);32setConfigGreenBits(8);33setConfigBlueBits(8);34setConfigAlphaBits(8);35}3637bool checkTexImageFormatSupport(GLenum format, GLenum type)38{39EXPECT_GL_NO_ERROR();4041GLuint tex = 0;42glGenTextures(1, &tex);43glBindTexture(GL_TEXTURE_2D, tex);44glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);45glDeleteTextures(1, &tex);4647return (glGetError() == GL_NO_ERROR);48}4950bool checkTexStorageFormatSupport(GLenum internalFormat)51{52EXPECT_GL_NO_ERROR();5354GLuint tex = 0;55glGenTextures(1, &tex);56glBindTexture(GL_TEXTURE_2D, tex);57glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);58glDeleteTextures(1, &tex);5960return (glGetError() == GL_NO_ERROR);61}6263bool checkRenderbufferFormatSupport(GLenum internalFormat)64{65EXPECT_GL_NO_ERROR();6667GLuint rb = 0;68glGenRenderbuffers(1, &rb);69glBindRenderbuffer(GL_RENDERBUFFER, rb);70glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);71glDeleteRenderbuffers(1, &rb);7273return (glGetError() == GL_NO_ERROR);74}7576void verifyDepthRenderBuffer(GLenum internalFormat)77{78GLTexture tex;79glBindTexture(GL_TEXTURE_2D, tex);80glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);81ASSERT_GL_NO_ERROR();8283GLRenderbuffer rbDepth;84glBindRenderbuffer(GL_RENDERBUFFER, rbDepth);85glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);86ASSERT_GL_NO_ERROR();8788GLFramebuffer fbo;89glBindFramebuffer(GL_FRAMEBUFFER, fbo);90glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);91glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbDepth);9293EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);94ASSERT_GL_NO_ERROR();9596ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());97glEnable(GL_DEPTH_TEST);98glDepthFunc(GL_GEQUAL);99glClearDepthf(0.99f);100glClearColor(0, 0, 0, 1);101glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);102103// Pass Depth Test and draw red104float depthValue = 1.0f;105drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);106EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);107108ASSERT_GL_NO_ERROR();109110ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());111112// Fail Depth Test and color buffer is unchanged113depthValue = 0.98f;114drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);115EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);116117ASSERT_GL_NO_ERROR();118119ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());120glClearDepthf(0.0f);121glClear(GL_DEPTH_BUFFER_BIT);122123// Pass Depth Test and draw blue124depthValue = 0.01f;125drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);126EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);127128glDisable(GL_DEPTH_TEST);129ASSERT_GL_NO_ERROR();130}131132void testSetUp() override133{134constexpr char kVS[] = R"(precision highp float;135attribute vec4 position;136varying vec2 texcoord;137138void main()139{140gl_Position = position;141texcoord = (position.xy * 0.5) + 0.5;142})";143144constexpr char kFS[] = R"(precision highp float;145uniform sampler2D tex;146varying vec2 texcoord;147148void main()149{150gl_FragColor = texture2D(tex, texcoord);151})";152153mProgram = CompileProgram(kVS, kFS);154if (mProgram == 0)155{156FAIL() << "shader compilation failed.";157}158159mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");160EXPECT_NE(-1, mTextureUniformLocation);161162glGenTextures(1, &mTexture);163ASSERT_GL_NO_ERROR();164}165166void testTearDown() override167{168glDeleteProgram(mProgram);169glDeleteTextures(1, &mTexture);170}171172bool hasReadDepthSupport() const { return IsGLExtensionEnabled("GL_NV_read_depth"); }173174bool hasReadStencilSupport() const { return IsGLExtensionEnabled("GL_NV_read_stencil"); }175176bool hasFloatDepthSupport() const { return IsGLExtensionEnabled("GL_NV_depth_buffer_float2"); }177178void depthStencilReadbackCase(const ReadbackTestParam &type);179180GLuint mProgram;181GLuint mTexture;182GLint mTextureUniformLocation;183};184185class DepthStencilFormatsTest : public DepthStencilFormatsTestBase186{};187188class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase189{};190191TEST_P(DepthStencilFormatsTest, DepthTexture)192{193bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_ANGLE_depth_texture") ||194IsGLExtensionEnabled("GL_OES_depth_texture"));195196EXPECT_EQ(shouldHaveTextureSupport,197checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));198EXPECT_EQ(shouldHaveTextureSupport,199checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));200201if (IsGLExtensionEnabled("GL_EXT_texture_storage"))202{203EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));204EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));205}206}207208TEST_P(DepthStencilFormatsTest, PackedDepthStencil)209{210// Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.211// Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not212// present.213214bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil");215EXPECT_EQ(shouldHaveRenderbufferSupport,216checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));217218bool shouldHaveTextureSupport = ((IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||219IsGLExtensionEnabled("GL_OES_depth_texture_cube_map")) &&220IsGLExtensionEnabled("GL_OES_depth_texture")) ||221IsGLExtensionEnabled("GL_ANGLE_depth_texture");222EXPECT_EQ(shouldHaveTextureSupport,223checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));224225if (IsGLExtensionEnabled("GL_EXT_texture_storage"))226{227bool shouldHaveTexStorageSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||228IsGLExtensionEnabled("GL_ANGLE_depth_texture");229EXPECT_EQ(shouldHaveTexStorageSupport,230checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));231}232}233234void DepthStencilFormatsTestBase::depthStencilReadbackCase(const ReadbackTestParam &type)235{236ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));237238const bool hasFloatDepth = (type.type == GL_FLOAT);239ANGLE_SKIP_TEST_IF(hasFloatDepth && !hasFloatDepthSupport());240241const bool hasStencil = (type.format != GL_DEPTH_COMPONENT);242243const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;244245const int res = 2;246const int destRes = 4;247248GLTexture tex;249glBindTexture(GL_TEXTURE_2D, tex);250glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);251glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);252glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);253glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);254255// test level > 0256glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);257EXPECT_GL_NO_ERROR();258259// test with data260glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);261EXPECT_GL_NO_ERROR();262263// test real thing264glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type, nullptr);265EXPECT_GL_NO_ERROR();266267// test texSubImage2D268glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);269EXPECT_GL_NO_ERROR();270271GLuint fbo = 0;272glGenFramebuffers(1, &fbo);273glBindFramebuffer(GL_FRAMEBUFFER, fbo);274if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)275{276glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);277EXPECT_GL_NO_ERROR();278glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);279EXPECT_GL_NO_ERROR();280}281else282{283glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);284EXPECT_GL_NO_ERROR();285}286287// Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24288// UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for289// UNSIGNED_INT_24_8_WEBGL.290291GLint depthBits = 0;292glGetIntegerv(GL_DEPTH_BITS, &depthBits);293EXPECT_GE(depthBits, type.depthBits);294295GLint stencilBits = 0;296glGetIntegerv(GL_STENCIL_BITS, &stencilBits);297EXPECT_GE(stencilBits, type.stencilBits);298299// TODO: remove this check if the spec is updated to require these combinations to work.300if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)301{302// try adding a color buffer.303GLuint colorTex = 0;304glGenTextures(1, &colorTex);305glBindTexture(GL_TEXTURE_2D, colorTex);306glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);307glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);308glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);309glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);310glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);311glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);312EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));313}314315EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));316317// use the default texture to render with while we return to the depth texture.318glBindTexture(GL_TEXTURE_2D, 0);319320/* Setup 2x2 depth texture:321* 1 0.6 0.8322* |323* 0 0.2 0.4324* 0---1325*/326GLbitfield clearBits = GL_DEPTH_BUFFER_BIT;327if (hasStencil)328{329clearBits |= GL_STENCIL_BUFFER_BIT;330}331332const GLfloat d00 = 0.2;333const GLfloat d01 = 0.4;334const GLfloat d10 = 0.6;335const GLfloat d11 = 0.8;336glEnable(GL_SCISSOR_TEST);337glScissor(0, 0, 1, 1);338glClearDepthf(d00);339glClearStencil(1);340glClear(clearBits);341glScissor(1, 0, 1, 1);342glClearDepthf(d10);343glClearStencil(2);344glClear(clearBits);345glScissor(0, 1, 1, 1);346glClearDepthf(d01);347glClearStencil(3);348glClear(clearBits);349glScissor(1, 1, 1, 1);350glClearDepthf(d11);351glClearStencil(4);352glClear(clearBits);353glDisable(GL_SCISSOR_TEST);354355GLubyte actualPixels[destRes * destRes * 8];356glReadPixels(0, 0, destRes, destRes, GL_DEPTH_COMPONENT,357hasFloatDepth ? GL_FLOAT : GL_UNSIGNED_SHORT, actualPixels);358// NV_read_depth and NV_read_stencil do not support packed depth/stencil359if (hasReadDepthSupport() && type.format != GL_DEPTH_STENCIL)360{361EXPECT_GL_NO_ERROR();362if (hasFloatDepth)363{364constexpr float kEpsilon = 0.002f;365const float *pixels = reinterpret_cast<const float *>(actualPixels);366ASSERT_NEAR(pixels[0], d00, kEpsilon);367ASSERT_NEAR(pixels[0 + destRes], d01, kEpsilon);368ASSERT_NEAR(pixels[1], d10, kEpsilon);369ASSERT_NEAR(pixels[1 + destRes], d11, kEpsilon);370}371else372{373auto scale = [](float f) {374return static_cast<uint16_t>(375static_cast<float>(std::numeric_limits<uint16_t>::max()) * f);376};377378constexpr unsigned short kEpsilon = 2;379const unsigned short *pixels = reinterpret_cast<const unsigned short *>(actualPixels);380ASSERT_NEAR(pixels[0], scale(d00), kEpsilon);381ASSERT_NEAR(pixels[0 + destRes], scale(d01), kEpsilon);382ASSERT_NEAR(pixels[1], scale(d10), kEpsilon);383ASSERT_NEAR(pixels[1 + destRes], scale(d11), kEpsilon);384}385}386else387{388EXPECT_GL_ERROR(GL_INVALID_OPERATION);389}390if (hasStencil)391{392glReadPixels(0, 0, destRes, destRes, GL_STENCIL_INDEX_OES, GL_UNSIGNED_BYTE, actualPixels);393if (hasReadStencilSupport())394{395EXPECT_GL_NO_ERROR();396ASSERT_TRUE((actualPixels[0] == 1) && (actualPixels[1] == 2) &&397(actualPixels[0 + destRes] == 3) && (actualPixels[1 + destRes] = 4));398}399else400{401EXPECT_GL_ERROR(GL_INVALID_OPERATION);402}403}404}405406// This test will initialize a depth texture, clear it and read it back, if possible407TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UShort)408{409GLuint fakeData[10] = {0};410ReadbackTestParam type = {411GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0};412depthStencilReadbackCase(type);413}414415// This test will initialize a depth texture, clear it and read it back, if possible416TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UInt)417{418// http://anglebug.com/5269419ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());420421GLuint fakeData[10] = {0};422ReadbackTestParam type = {423GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0};424depthStencilReadbackCase(type);425}426427// This test will initialize a depth texture, clear it and read it back, if possible428TEST_P(DepthStencilFormatsTest, DepthStencilReadback_Float)429{430// http://anglebug.com/5269431ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());432433GLuint fakeData[10] = {0};434ReadbackTestParam type = {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_FLOAT, fakeData, 32, 0};435depthStencilReadbackCase(type);436}437438// This test will initialize a depth texture, clear it and read it back, if possible439TEST_P(DepthStencilFormatsTest, DepthStencilReadback_DepthStencil)440{441GLuint fakeData[10] = {0};442ReadbackTestParam type = {443GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8};444depthStencilReadbackCase(type);445}446447// This test will initialize a depth texture and then render with it and verify448// pixel correctness.449// This is modeled after webgl-depth-texture.html450TEST_P(DepthStencilFormatsTest, DepthTextureRender)451{452constexpr char kVS[] = R"(attribute vec4 a_position;453void main()454{455gl_Position = a_position;456})";457458constexpr char kFS[] = R"(precision mediump float;459uniform sampler2D u_texture;460uniform vec2 u_resolution;461void main()462{463vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));464gl_FragColor = texture2D(u_texture, texcoord);465})";466467ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture") &&468!IsGLExtensionEnabled("GL_ANGLE_depth_texture"));469470bool depthTextureCubeSupport = IsGLExtensionEnabled("GL_OES_depth_texture_cube_map");471472// http://anglebug.com/3454473ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsD3D9());474475const int res = 2;476const int destRes = 4;477GLint resolution;478479ANGLE_GL_PROGRAM(program, kVS, kFS);480481glUseProgram(program);482resolution = glGetUniformLocation(program, "u_resolution");483ASSERT_NE(-1, resolution);484glUniform2f(resolution, static_cast<float>(destRes), static_cast<float>(destRes));485486GLuint buffer;487glGenBuffers(1, &buffer);488glBindBuffer(GL_ARRAY_BUFFER, buffer);489float verts[] = {4901, 1, 1, -1, 1, 0, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 0,491};492glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);493glEnableVertexAttribArray(0);494glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);495496// OpenGL ES does not have a FLIPY PixelStore attribute497// glPixelStorei(GL_UNPACK_FLIP)498499struct TypeInfo500{501GLuint attachment;502GLuint format;503GLuint type;504void *data;505int depthBits;506int stencilBits;507};508509GLuint fakeData[10] = {0};510511std::vector<TypeInfo> types = {512{GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0},513{GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0},514{GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8},515};516517for (const TypeInfo &type : types)518{519GLTexture cubeTex;520glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);521ASSERT_GL_NO_ERROR();522523std::vector<GLuint> targets{GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,524GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,525GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};526527for (const GLuint target : targets)528{529glTexImage2D(target, 0, type.format, 1, 1, 0, type.format, type.type, nullptr);530if (depthTextureCubeSupport)531{532ASSERT_GL_NO_ERROR();533}534else535{536EXPECT_GL_ERROR(GL_INVALID_OPERATION);537}538}539540std::vector<GLuint> filterModes = {GL_LINEAR, GL_NEAREST};541542const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;543544for (const GLuint filterMode : filterModes)545{546GLTexture tex;547glBindTexture(GL_TEXTURE_2D, tex);548glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);549glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);550glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);551glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);552553// test level > 0554glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);555if (IsGLExtensionEnabled("GL_OES_depth_texture"))556{557EXPECT_GL_NO_ERROR();558}559else560{561EXPECT_GL_ERROR(GL_INVALID_OPERATION);562}563564// test with data565glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);566if (IsGLExtensionEnabled("GL_OES_depth_texture"))567{568EXPECT_GL_NO_ERROR();569}570else571{572EXPECT_GL_ERROR(GL_INVALID_OPERATION);573}574575// test copyTexImage2D576glCopyTexImage2D(GL_TEXTURE_2D, 0, type.format, 0, 0, 1, 1, 0);577GLuint error = glGetError();578ASSERT_TRUE(error == GL_INVALID_ENUM || error == GL_INVALID_OPERATION);579580// test real thing581glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type,582nullptr);583EXPECT_GL_NO_ERROR();584585// test texSubImage2D586glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);587if (IsGLExtensionEnabled("GL_OES_depth_texture"))588{589EXPECT_GL_NO_ERROR();590}591else592{593EXPECT_GL_ERROR(GL_INVALID_OPERATION);594}595596// test copyTexSubImage2D597glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);598EXPECT_GL_ERROR(GL_INVALID_OPERATION);599600// test generateMipmap601glGenerateMipmap(GL_TEXTURE_2D);602EXPECT_GL_ERROR(GL_INVALID_OPERATION);603604GLuint fbo = 0;605glGenFramebuffers(1, &fbo);606glBindFramebuffer(GL_FRAMEBUFFER, fbo);607if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)608{609glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);610EXPECT_GL_NO_ERROR();611glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex,6120);613EXPECT_GL_NO_ERROR();614}615else616{617glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);618EXPECT_GL_NO_ERROR();619}620621// Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24622// UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for623// UNSIGNED_INT_24_8_WEBGL.624625GLint depthBits = 0;626glGetIntegerv(GL_DEPTH_BITS, &depthBits);627EXPECT_GE(depthBits, type.depthBits);628629GLint stencilBits = 0;630glGetIntegerv(GL_STENCIL_BITS, &stencilBits);631EXPECT_GE(stencilBits, type.stencilBits);632633// TODO: remove this check if the spec is updated to require these combinations to work.634if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)635{636// try adding a color buffer.637GLuint colorTex = 0;638glGenTextures(1, &colorTex);639glBindTexture(GL_TEXTURE_2D, colorTex);640glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);641glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);642glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);643glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);644glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE,645nullptr);646glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,647colorTex, 0);648EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));649}650651EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));652653// use the default texture to render with while we return to the depth texture.654glBindTexture(GL_TEXTURE_2D, 0);655656/* Setup 2x2 depth texture:657* 1 0.6 0.8658* |659* 0 0.2 0.4660* 0---1661*/662const GLfloat d00 = 0.2;663const GLfloat d01 = 0.4;664const GLfloat d10 = 0.6;665const GLfloat d11 = 0.8;666glEnable(GL_SCISSOR_TEST);667glScissor(0, 0, 1, 1);668glClearDepthf(d00);669glClear(GL_DEPTH_BUFFER_BIT);670glScissor(1, 0, 1, 1);671glClearDepthf(d10);672glClear(GL_DEPTH_BUFFER_BIT);673glScissor(0, 1, 1, 1);674glClearDepthf(d01);675glClear(GL_DEPTH_BUFFER_BIT);676glScissor(1, 1, 1, 1);677glClearDepthf(d11);678glClear(GL_DEPTH_BUFFER_BIT);679glDisable(GL_SCISSOR_TEST);680681// render the depth texture.682glBindFramebuffer(GL_FRAMEBUFFER, 0);683glViewport(0, 0, destRes, destRes);684glBindTexture(GL_TEXTURE_2D, tex);685glDisable(GL_DITHER);686glEnable(GL_DEPTH_TEST);687glClearColor(1, 0, 0, 1);688glClearDepthf(1.0);689glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);690glDrawArrays(GL_TRIANGLES, 0, 6);691692GLubyte actualPixels[destRes * destRes * 4];693glReadPixels(0, 0, destRes, destRes, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels);694const GLfloat eps = 0.002;695std::vector<GLfloat> expectedMin;696std::vector<GLfloat> expectedMax;697if (filterMode == GL_NEAREST)698{699GLfloat init[] = {d00, d00, d10, d10, d00, d00, d10, d10,700d01, d01, d11, d11, d01, d01, d11, d11};701expectedMin.insert(expectedMin.begin(), init, init + 16);702expectedMax.insert(expectedMax.begin(), init, init + 16);703704for (int i = 0; i < 16; i++)705{706expectedMin[i] = expectedMin[i] - eps;707expectedMax[i] = expectedMax[i] + eps;708}709}710else711{712GLfloat initMin[] = {713d00 - eps, d00, d00, d10 - eps, d00, d00, d00, d10,714d00, d00, d00, d10, d01 - eps, d01, d01, d11 - eps,715};716GLfloat initMax[] = {717d00 + eps, d10, d10, d10 + eps, d01, d11, d11, d11,718d01, d11, d11, d11, d01 + eps, d11, d11, d11 + eps,719};720expectedMin.insert(expectedMin.begin(), initMin, initMin + 16);721expectedMax.insert(expectedMax.begin(), initMax, initMax + 16);722}723for (int yy = 0; yy < destRes; ++yy)724{725for (int xx = 0; xx < destRes; ++xx)726{727const int t = xx + destRes * yy;728const GLfloat was = (GLfloat)(actualPixels[4 * t] / 255.0); // 4bpp729const GLfloat eMin = expectedMin[t];730const GLfloat eMax = expectedMax[t];731EXPECT_TRUE(was >= eMin && was <= eMax)732<< "At " << xx << ", " << yy << ", expected within [" << eMin << ", "733<< eMax << "] was " << was;734}735}736737// check limitations738// Note: What happens if current attachment type is GL_DEPTH_STENCIL_ATTACHMENT739// and you try to call glFramebufferTexture2D with GL_DEPTH_ATTACHMENT?740// The webGL test this code came from expected that to fail.741// I think due to this line in ES3 spec:742// GL_INVALID_OPERATION is generated if textarget and texture are not compatible743// However, that's not the behavior I'm seeing, nor does it seem that a depth_stencil744// buffer isn't compatible with a depth attachment (e.g. stencil is unused).745if (type.attachment == GL_DEPTH_ATTACHMENT)746{747glBindFramebuffer(GL_FRAMEBUFFER, fbo);748glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, 0, 0);749glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,750tex, 0);751EXPECT_GLENUM_NE(GL_NO_ERROR, glGetError());752EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));753glClear(GL_DEPTH_BUFFER_BIT);754EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);755glBindFramebuffer(GL_FRAMEBUFFER, 0);756EXPECT_GL_NO_ERROR();757}758}759}760}761762// This test will initialize a frame buffer, attaching a color and 16-bit depth buffer,763// render to it with depth testing, and verify pixel correctness.764TEST_P(DepthStencilFormatsTest, DepthBuffer16)765{766verifyDepthRenderBuffer(GL_DEPTH_COMPONENT16);767}768769// This test will initialize a frame buffer, attaching a color and 24-bit depth buffer,770// render to it with depth testing, and verify pixel correctness.771TEST_P(DepthStencilFormatsTest, DepthBuffer24)772{773bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_depth24");774EXPECT_EQ(shouldHaveRenderbufferSupport,775checkRenderbufferFormatSupport(GL_DEPTH_COMPONENT24_OES));776777if (shouldHaveRenderbufferSupport)778{779verifyDepthRenderBuffer(GL_DEPTH_COMPONENT24_OES);780}781}782783TEST_P(DepthStencilFormatsTestES3, DrawWithDepth16)784{785GLushort data[16];786for (unsigned int i = 0; i < 16; i++)787{788data[i] = std::numeric_limits<GLushort>::max();789}790glBindTexture(GL_TEXTURE_2D, mTexture);791glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);792glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);793794glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);795glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);796797glUseProgram(mProgram);798glUniform1i(mTextureUniformLocation, 0);799800glClear(GL_COLOR_BUFFER_BIT);801drawQuad(mProgram, "position", 0.5f);802803ASSERT_GL_NO_ERROR();804805GLubyte pixel[4];806glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);807808// Only require the red and alpha channels have the correct values, the depth texture extensions809// leave the green and blue channels undefined810ASSERT_NEAR(255, pixel[0], 2.0);811ASSERT_EQ(255, pixel[3]);812}813814// This test reproduces a driver bug on Intel windows platforms on driver version815// from 4815 to 4901.816// When rendering with Stencil buffer enabled and depth buffer disabled, large817// viewport will lead to memory leak and driver crash. And the pixel result818// is a random value.819TEST_P(DepthStencilFormatsTestES3, DrawWithLargeViewport)820{821ANGLE_SKIP_TEST_IF(IsIntel() && (IsOSX() || IsWindows()));822823ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());824825glEnable(GL_STENCIL_TEST);826glDisable(GL_DEPTH_TEST);827828// The iteration is to reproduce memory leak when rendering several times.829for (int i = 0; i < 10; ++i)830{831// Create offscreen fbo and its color attachment and depth stencil attachment.832GLTexture framebufferColorTexture;833glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);834glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());835ASSERT_GL_NO_ERROR();836837GLTexture framebufferStencilTexture;838glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);839glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());840ASSERT_GL_NO_ERROR();841842GLFramebuffer fb;843glBindFramebuffer(GL_FRAMEBUFFER, fb);844glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,845framebufferColorTexture, 0);846glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,847framebufferStencilTexture, 0);848849EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));850ASSERT_GL_NO_ERROR();851852GLint kStencilRef = 4;853glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);854glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);855856float viewport[2];857glGetFloatv(GL_MAX_VIEWPORT_DIMS, viewport);858859glViewport(0, 0, static_cast<GLsizei>(viewport[0]), static_cast<GLsizei>(viewport[1]));860glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);861862drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f);863ASSERT_GL_NO_ERROR();864865glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);866EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);867ASSERT_GL_NO_ERROR();868}869}870871// Verify that stencil component of depth texture is uploaded872TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)873{874// http://anglebug.com/3683875// When bug is resolved we can remove this skip.876ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());877878// http://anglebug.com/3689879ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsAMD());880881// http://anglebug.com/4908882ANGLE_SKIP_TEST_IF(IsIntel() && IsMetal());883884// Test failure introduced by Apple's changes (anglebug.com/5505)885ANGLE_SKIP_TEST_IF(IsMetal() && IsAMD());886887// Test failure introduced by Apple's changes (anglebug.com/5505)888ANGLE_SKIP_TEST_IF(IsOSX() && IsARM64() && IsMetal());889890bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&891IsGLExtensionEnabled("GL_OES_depth_texture")) ||892(getClientMajorVersion() >= 3);893894ANGLE_SKIP_TEST_IF(!shouldHaveTextureSupport ||895!checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));896897ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());898899glEnable(GL_STENCIL_TEST);900glDisable(GL_DEPTH_TEST);901glDepthMask(GL_FALSE);902903glViewport(0, 0, getWindowWidth(), getWindowHeight());904glClearColor(0, 0, 0, 1);905906// Create offscreen fbo and its color attachment and depth stencil attachment.907GLTexture framebufferColorTexture;908glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);909glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,910GL_UNSIGNED_BYTE, nullptr);911ASSERT_GL_NO_ERROR();912913// drawQuad's depth range is -1.0 to 1.0, so a depth value of 0.5 (0x7fffff) matches a drawQuad914// depth of 0.0.915std::vector<GLuint> depthStencilData(getWindowWidth() * getWindowHeight(), 0x7fffffA9);916GLTexture framebufferStencilTexture;917glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);918glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, getWindowWidth(), getWindowHeight(), 0,919GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, depthStencilData.data());920ASSERT_GL_NO_ERROR();921922GLFramebuffer fb;923glBindFramebuffer(GL_FRAMEBUFFER, fb);924glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,925framebufferColorTexture, 0);926927if (getClientMajorVersion() >= 3)928{929glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,930framebufferStencilTexture, 0);931ASSERT_GL_NO_ERROR();932}933else934{935glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,936framebufferStencilTexture, 0);937ASSERT_GL_NO_ERROR();938glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,939framebufferStencilTexture, 0);940ASSERT_GL_NO_ERROR();941}942943ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);944945GLint kStencilRef = 0xA9;946glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);947glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);948949glBindFramebuffer(GL_FRAMEBUFFER, fb);950951glClear(GL_COLOR_BUFFER_BIT);952953drawQuad(program.get(), essl1_shaders::PositionAttrib(), 1.0f);954ASSERT_GL_NO_ERROR();955956glBindFramebuffer(GL_FRAMEBUFFER, fb);957EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);958ASSERT_GL_NO_ERROR();959960// Check Z values961962glClear(GL_COLOR_BUFFER_BIT);963glDisable(GL_STENCIL_TEST);964glEnable(GL_DEPTH_TEST);965glDepthFunc(GL_LESS);966967drawQuad(program.get(), essl1_shaders::PositionAttrib(), -0.1f);968ASSERT_GL_NO_ERROR();969970EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);971972glClear(GL_COLOR_BUFFER_BIT);973974drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.1f);975ASSERT_GL_NO_ERROR();976977EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);978}979980// Verify that depth texture's data can be uploaded correctly981TEST_P(DepthStencilFormatsTest, VerifyDepth32UploadData)982{983ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));984985GLTexture tex;986glBindTexture(GL_TEXTURE_2D, tex);987glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);988ASSERT_GL_NO_ERROR();989990// normalized 0.99 = 0xfd70a3d6991std::vector<GLuint> depthData(1, 0xfd70a3d6);992GLTexture rbDepth;993glBindTexture(GL_TEXTURE_2D, rbDepth);994glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,995depthData.data());996ASSERT_GL_NO_ERROR();997998GLFramebuffer fbo;999glBindFramebuffer(GL_FRAMEBUFFER, fbo);1000glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);1001glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);10021003EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);1004ASSERT_GL_NO_ERROR();10051006ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());1007glEnable(GL_DEPTH_TEST);1008glDepthFunc(GL_GEQUAL);1009glClearColor(0, 1, 0, 1);1010glClear(GL_COLOR_BUFFER_BIT);10111012// Fail Depth Test and color buffer is unchanged1013float depthValue = 0.98f;1014drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1015EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);10161017// Pass Depth Test and draw red1018depthValue = 1.0f;1019drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1020EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);10211022ASSERT_GL_NO_ERROR();10231024// Change depth texture data1025glBindTexture(GL_TEXTURE_2D, rbDepth);1026depthData[0] = 0x7fffffff; // 0.51027glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,1028depthData.data());1029ASSERT_GL_NO_ERROR();10301031ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());10321033// Fail Depth Test and color buffer is unchanged1034depthValue = 0.48f;1035drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1036EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);10371038ASSERT_GL_NO_ERROR();10391040ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());1041glClearDepthf(0.0f);1042glClear(GL_DEPTH_BUFFER_BIT);10431044// Pass Depth Test and draw blue1045depthValue = 0.01f;1046drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1047EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);10481049glDisable(GL_DEPTH_TEST);1050ASSERT_GL_NO_ERROR();1051}10521053// Verify that 16 bits depth texture's data can be uploaded correctly1054TEST_P(DepthStencilFormatsTest, VerifyDepth16UploadData)1055{1056ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));10571058GLTexture tex;1059glBindTexture(GL_TEXTURE_2D, tex);1060glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1061ASSERT_GL_NO_ERROR();10621063// normalized 0.99 = 0xfd6f1064std::vector<GLushort> depthData(1, 0xfd6f);1065GLTexture rbDepth;1066glBindTexture(GL_TEXTURE_2D, rbDepth);1067glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT,1068GL_UNSIGNED_SHORT, depthData.data());1069ASSERT_GL_NO_ERROR();10701071GLFramebuffer fbo;1072glBindFramebuffer(GL_FRAMEBUFFER, fbo);1073glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);1074glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);10751076EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);1077ASSERT_GL_NO_ERROR();10781079ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());1080glEnable(GL_DEPTH_TEST);1081glDepthFunc(GL_GEQUAL);1082glClearColor(0, 1, 0, 1);1083glClear(GL_COLOR_BUFFER_BIT);10841085// Fail Depth Test and color buffer is unchanged1086float depthValue = 0.98f;1087drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1088EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);10891090// Pass Depth Test and draw red1091depthValue = 1.0f;1092drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1093EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);10941095ASSERT_GL_NO_ERROR();10961097// Change depth texture data1098glBindTexture(GL_TEXTURE_2D, rbDepth);1099depthData[0] = 0x7fff; // 0.51100glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,1101depthData.data());1102ASSERT_GL_NO_ERROR();11031104ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());11051106// Fail Depth Test and color buffer is unchanged1107depthValue = 0.48f;1108drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1109EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);11101111ASSERT_GL_NO_ERROR();11121113ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());1114glClearDepthf(0.0f);1115glClear(GL_DEPTH_BUFFER_BIT);11161117// Pass Depth Test and draw blue1118depthValue = 0.01f;1119drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);1120EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);11211122glDisable(GL_DEPTH_TEST);1123ASSERT_GL_NO_ERROR();1124}11251126ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);11271128GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES3);1129ANGLE_INSTANTIATE_TEST_ES3(DepthStencilFormatsTestES3);11301131class TinyDepthStencilWorkaroundTest : public ANGLETest1132{1133public:1134TinyDepthStencilWorkaroundTest()1135{1136setWindowWidth(512);1137setWindowHeight(512);1138setConfigRedBits(8);1139setConfigGreenBits(8);1140setConfigBlueBits(8);1141setConfigAlphaBits(8);1142}11431144// Override the features to enable "tiny" depth/stencil textures.1145void overrideWorkaroundsD3D(FeaturesD3D *features) override1146{1147features->overrideFeatures({"emulate_tiny_stencil_textures"}, true);1148}1149};11501151// Tests that the tiny depth stencil textures workaround does not "stick" depth textures.1152// http://anglebug.com/16641153TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)1154{1155// http://anglebug.com/40921156ANGLE_SKIP_TEST_IF((IsAndroid() && IsOpenGLES()) || (IsLinux() && IsVulkan()));1157ANGLE_SKIP_TEST_IF(isSwiftshader());11581159// TODO(anglebug.com/5491)1160ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());11611162constexpr char kDrawVS[] =1163"#version 100\n"1164"attribute vec3 vertex;\n"1165"void main () {\n"1166" gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"1167"}\n";11681169ANGLE_GL_PROGRAM(drawProgram, kDrawVS, essl1_shaders::fs::Red());11701171constexpr char kBlitVS[] =1172"#version 100\n"1173"attribute vec2 vertex;\n"1174"varying vec2 position;\n"1175"void main () {\n"1176" position = vertex * .5 + .5;\n"1177" gl_Position = vec4(vertex, 0, 1);\n"1178"}\n";11791180constexpr char kBlitFS[] =1181"#version 100\n"1182"precision mediump float;\n"1183"uniform sampler2D texture;\n"1184"varying vec2 position;\n"1185"void main () {\n"1186" gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"1187"}\n";11881189ANGLE_GL_PROGRAM(blitProgram, kBlitVS, kBlitFS);11901191GLint blitTextureLocation = glGetUniformLocation(blitProgram.get(), "texture");1192ASSERT_NE(-1, blitTextureLocation);11931194GLTexture colorTex;1195glBindTexture(GL_TEXTURE_2D, colorTex.get());1196glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1197glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1198glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1199glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1200glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,1201GL_UNSIGNED_BYTE, nullptr);1202glBindTexture(GL_TEXTURE_2D, 0);12031204GLTexture depthTex;1205glBindTexture(GL_TEXTURE_2D, depthTex.get());1206glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1207glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1208glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1209glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);1210ASSERT_EQ(getWindowWidth(), getWindowHeight());1211int levels = gl::log2(getWindowWidth());1212for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)1213{1214int size = getWindowWidth() >> mipLevel;1215glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,1216GL_UNSIGNED_INT_24_8_OES, nullptr);1217}12181219glBindTexture(GL_TEXTURE_2D, 0);12201221ASSERT_GL_NO_ERROR();12221223GLFramebuffer framebuffer;1224glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());12251226glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex.get(), 0);1227glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex.get(), 0);12281229ASSERT_GL_NO_ERROR();12301231glDepthRangef(0.0f, 1.0f);1232glViewport(0, 0, getWindowWidth(), getWindowHeight());1233glClearColor(0, 0, 0, 1);12341235// Draw loop.1236for (unsigned int frame = 0; frame < 3; ++frame)1237{1238// draw into FBO1239glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1240glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);12411242glEnable(GL_DEPTH_TEST);12431244float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);1245drawQuad(drawProgram.get(), "vertex", depth);12461247glBindFramebuffer(GL_FRAMEBUFFER, 0);12481249// blit FBO1250glDisable(GL_DEPTH_TEST);12511252glUseProgram(blitProgram.get());1253glUniform1i(blitTextureLocation, 0);1254glBindTexture(GL_TEXTURE_2D, depthTex.get());12551256drawQuad(blitProgram.get(), "vertex", 0.5f);12571258Vector4 depthVec(depth, depth, depth, 1);1259GLColor depthColor(depthVec);12601261EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);1262ASSERT_GL_NO_ERROR();1263}1264}12651266GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TinyDepthStencilWorkaroundTest);1267ANGLE_INSTANTIATE_TEST_ES3(TinyDepthStencilWorkaroundTest);126812691270