1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "test_utils/ANGLETest.h"
8 
9 using namespace angle;
10 
11 class DepthStencilFormatsTestBase : public ANGLETest
12 {
13   protected:
DepthStencilFormatsTestBase()14     DepthStencilFormatsTestBase()
15     {
16         setWindowWidth(128);
17         setWindowHeight(128);
18         setConfigRedBits(8);
19         setConfigGreenBits(8);
20         setConfigBlueBits(8);
21         setConfigAlphaBits(8);
22     }
23 
checkTexImageFormatSupport(GLenum format,GLenum type)24     bool checkTexImageFormatSupport(GLenum format, GLenum type)
25     {
26         EXPECT_GL_NO_ERROR();
27 
28         GLuint tex = 0;
29         glGenTextures(1, &tex);
30         glBindTexture(GL_TEXTURE_2D, tex);
31         glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, NULL);
32         glDeleteTextures(1, &tex);
33 
34         return (glGetError() == GL_NO_ERROR);
35     }
36 
checkTexStorageFormatSupport(GLenum internalFormat)37     bool checkTexStorageFormatSupport(GLenum internalFormat)
38     {
39         EXPECT_GL_NO_ERROR();
40 
41         GLuint tex = 0;
42         glGenTextures(1, &tex);
43         glBindTexture(GL_TEXTURE_2D, tex);
44         glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
45         glDeleteTextures(1, &tex);
46 
47         return (glGetError() == GL_NO_ERROR);
48     }
49 
checkRenderbufferFormatSupport(GLenum internalFormat)50     bool checkRenderbufferFormatSupport(GLenum internalFormat)
51     {
52         EXPECT_GL_NO_ERROR();
53 
54         GLuint rb = 0;
55         glGenRenderbuffers(1, &rb);
56         glBindRenderbuffer(GL_RENDERBUFFER, rb);
57         glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
58         glDeleteRenderbuffers(1, &rb);
59 
60         return (glGetError() == GL_NO_ERROR);
61     }
62 
SetUp()63     virtual void SetUp()
64     {
65         ANGLETest::SetUp();
66 
67         const std::string vertexShaderSource = SHADER_SOURCE
68         (
69             precision highp float;
70             attribute vec4 position;
71             varying vec2 texcoord;
72 
73             void main()
74             {
75                 gl_Position = position;
76                 texcoord = (position.xy * 0.5) + 0.5;
77             }
78         );
79 
80         const std::string fragmentShaderSource = SHADER_SOURCE
81         (
82             precision highp float;
83             uniform sampler2D tex;
84             varying vec2 texcoord;
85 
86             void main()
87             {
88                 gl_FragColor = texture2D(tex, texcoord);
89             }
90         );
91 
92         mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
93         if (mProgram == 0)
94         {
95             FAIL() << "shader compilation failed.";
96         }
97 
98         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
99         EXPECT_NE(-1, mTextureUniformLocation);
100 
101         glGenTextures(1, &mTexture);
102         ASSERT_GL_NO_ERROR();
103     }
104 
TearDown()105     virtual void TearDown()
106     {
107         glDeleteProgram(mProgram);
108         glDeleteTextures(1, &mTexture);
109 
110         ANGLETest::TearDown();
111     }
112 
113     GLuint mProgram;
114     GLuint mTexture;
115     GLint mTextureUniformLocation;
116 };
117 
118 class DepthStencilFormatsTest : public DepthStencilFormatsTestBase
119 {};
120 
121 class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase
122 {};
123 
TEST_P(DepthStencilFormatsTest,DepthTexture)124 TEST_P(DepthStencilFormatsTest, DepthTexture)
125 {
126     bool shouldHaveTextureSupport = extensionEnabled("GL_ANGLE_depth_texture");
127     EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
128     EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));
129 
130     if (extensionEnabled("GL_EXT_texture_storage"))
131     {
132         EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
133         EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
134     }
135 }
136 
TEST_P(DepthStencilFormatsTest,PackedDepthStencil)137 TEST_P(DepthStencilFormatsTest, PackedDepthStencil)
138 {
139     // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
140     // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not present.
141 
142     bool shouldHaveRenderbufferSupport = extensionEnabled("GL_OES_packed_depth_stencil");
143     EXPECT_EQ(shouldHaveRenderbufferSupport, checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));
144 
145     bool shouldHaveTextureSupport = extensionEnabled("GL_OES_packed_depth_stencil") &&
146                                     extensionEnabled("GL_ANGLE_depth_texture");
147     EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
148 
149     if (extensionEnabled("GL_EXT_texture_storage"))
150     {
151         EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
152     }
153 }
154 
TEST_P(DepthStencilFormatsTestES3,DrawWithDepthStencil)155 TEST_P(DepthStencilFormatsTestES3, DrawWithDepthStencil)
156 {
157     GLushort data[16];
158     for (unsigned int i = 0; i < 16; i++)
159     {
160         data[i] = std::numeric_limits<GLushort>::max();
161     }
162     glBindTexture(GL_TEXTURE_2D, mTexture);
163     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);
164     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
165 
166     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
167     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
168 
169     glUseProgram(mProgram);
170     glUniform1i(mTextureUniformLocation, 0);
171 
172     glClear(GL_COLOR_BUFFER_BIT);
173     drawQuad(mProgram, "position", 0.5f);
174 
175     ASSERT_GL_NO_ERROR();
176 
177     GLubyte pixel[4];
178     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
179 
180     // Only require the red and alpha channels have the correct values, the depth texture extensions
181     // leave the green and blue channels undefined
182     ASSERT_NEAR(255, pixel[0], 2.0);
183     ASSERT_EQ(255, pixel[3]);
184 }
185 
186 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
187 ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTest,
188                        ES2_D3D9(),
189                        ES2_D3D11(),
190                        ES2_OPENGL(),
191                        ES2_OPENGLES());
192 ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
193