blob: a89c93640179498905789aa6c91cf396ac7129fe [file] [log] [blame]
JiangYizhoubddc46b2016-12-09 09:50:51 +08001//
2// Copyright 2017 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// TextureMultisampleTest: Tests of multisampled texture
8
9#include "test_utils/ANGLETest.h"
10#include "test_utils/gl_raii.h"
11
12using namespace angle;
13
14namespace
15{
Jiang0e1224c2017-12-26 14:11:15 +080016// Sample positions of d3d standard pattern. Some of the sample positions might not the same as
17// opengl.
18using SamplePositionsArray = std::array<float, 32>;
19static constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
20 {{{0.5f, 0.5f}},
21 {{0.75f, 0.75f, 0.25f, 0.25f}},
22 {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
23 {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
24 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
25 {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f,
26 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
27 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
28 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
JiangYizhoubddc46b2016-12-09 09:50:51 +080029
30class TextureMultisampleTest : public ANGLETest
31{
32 protected:
33 TextureMultisampleTest()
34 {
35 setWindowWidth(64);
36 setWindowHeight(64);
37 setConfigRedBits(8);
38 setConfigGreenBits(8);
39 setConfigBlueBits(8);
40 setConfigAlphaBits(8);
41 }
42
43 void SetUp() override
44 {
45 ANGLETest::SetUp();
46
47 glGenFramebuffers(1, &mFramebuffer);
48 glGenTextures(1, &mTexture);
49
50 ASSERT_GL_NO_ERROR();
51 }
52
53 void TearDown() override
54 {
55 glDeleteFramebuffers(1, &mFramebuffer);
56 mFramebuffer = 0;
57 glDeleteTextures(1, &mTexture);
58 mTexture = 0;
59
60 ANGLETest::TearDown();
61 }
62
63 GLuint mFramebuffer = 0;
64 GLuint mTexture = 0;
65};
66
67class TextureMultisampleTestES31 : public TextureMultisampleTest
68{
69 protected:
70 TextureMultisampleTestES31() : TextureMultisampleTest() {}
71};
72
Olli Etuahod310a432018-08-24 15:40:23 +030073class TextureMultisampleArrayWebGLTest : public TextureMultisampleTest
74{
75 protected:
76 TextureMultisampleArrayWebGLTest() : TextureMultisampleTest()
77 {
78 // These tests run in WebGL mode so we can test with both extension off and on.
79 setWebGLCompatibilityEnabled(true);
80 }
81
82 // Requests the ANGLE_texture_multisample_array extension and returns true if the operation
83 // succeeds.
84 bool requestArrayExtension()
85 {
86 if (extensionRequestable("GL_ANGLE_texture_multisample_array"))
87 {
88 glRequestExtensionANGLE("GL_ANGLE_texture_multisample_array");
89 }
90
91 if (!extensionEnabled("GL_ANGLE_texture_multisample_array"))
92 {
93 return false;
94 }
95 return true;
96 }
97};
98
JiangYizhoubddc46b2016-12-09 09:50:51 +080099// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
Olli Etuahod310a432018-08-24 15:40:23 +0300100// GetInternalformativ. Checks that the number of samples returned is valid in case of ES >= 3.1.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800101TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
102{
Olli Etuahod310a432018-08-24 15:40:23 +0300103 // This query returns supported sample counts in descending order. If only one sample count is
104 // queried, it should be the maximum one.
105 GLint maxSamplesR8 = 0;
106 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamplesR8);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800107 if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
108 {
Olli Etuahod310a432018-08-24 15:40:23 +0300109 ASSERT_GL_ERROR(GL_INVALID_ENUM);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800110 }
111 else
112 {
113 ASSERT_GL_NO_ERROR();
Olli Etuahod310a432018-08-24 15:40:23 +0300114
115 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
116 GLint maxColorTextureSamples;
117 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
118 GLint maxSamples;
119 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
120 GLint maxSamplesR8Required = std::min(maxColorTextureSamples, maxSamples);
121
122 EXPECT_GE(maxSamplesR8, maxSamplesR8Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800123 }
124}
125
126// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
127// FramebufferTexture2D.
128TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
129{
130 GLint samples = 1;
131 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
132 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
133 if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
134 {
135 ASSERT_GL_ERROR(GL_INVALID_ENUM);
136 }
137 else
138 {
139 ASSERT_GL_NO_ERROR();
140 }
141
142 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
143 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
144 mTexture, 0);
145 if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
146 {
147 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
148 }
149 else
150 {
151 ASSERT_GL_NO_ERROR();
152 }
153}
154
155// Tests basic functionality of glTexStorage2DMultisample.
156TEST_P(TextureMultisampleTestES31, ValidateTextureStorageMultisampleParameters)
157{
158 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
159 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhou461d9a32017-01-04 16:37:26 +0800160 ASSERT_GL_NO_ERROR();
161
JiangYizhoubddc46b2016-12-09 09:50:51 +0800162 GLint params = 0;
163 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
164 EXPECT_EQ(1, params);
165
166 glTexStorage2DMultisample(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, GL_FALSE);
167 ASSERT_GL_ERROR(GL_INVALID_ENUM);
168
169 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_FALSE);
170 ASSERT_GL_ERROR(GL_INVALID_VALUE);
171
172 GLint maxSize = 0;
173 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
174 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, maxSize + 1, 1, GL_FALSE);
175 ASSERT_GL_ERROR(GL_INVALID_VALUE);
176
177 GLint maxSamples = 0;
178 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
179 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples + 1, GL_RGBA8, 1, 1, GL_FALSE);
180 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
181
182 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, GL_FALSE);
183 ASSERT_GL_ERROR(GL_INVALID_VALUE);
184
185 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA, 0, 0, GL_FALSE);
186 ASSERT_GL_ERROR(GL_INVALID_VALUE);
187
188 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
189 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
190 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
191}
192
Shao5116d682017-08-02 12:39:44 +0800193// Tests the value of MAX_INTEGER_SAMPLES is no less than 1.
194// [OpenGL ES 3.1 SPEC Table 20.40]
195TEST_P(TextureMultisampleTestES31, MaxIntegerSamples)
196{
197 GLint maxIntegerSamples;
198 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &maxIntegerSamples);
199 EXPECT_GE(maxIntegerSamples, 1);
200 EXPECT_NE(std::numeric_limits<GLint>::max(), maxIntegerSamples);
201}
202
203// Tests the value of MAX_COLOR_TEXTURE_SAMPLES is no less than 1.
204// [OpenGL ES 3.1 SPEC Table 20.40]
205TEST_P(TextureMultisampleTestES31, MaxColorTextureSamples)
206{
207 GLint maxColorTextureSamples;
208 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
209 EXPECT_GE(maxColorTextureSamples, 1);
210 EXPECT_NE(std::numeric_limits<GLint>::max(), maxColorTextureSamples);
211}
212
213// Tests the value of MAX_DEPTH_TEXTURE_SAMPLES is no less than 1.
214// [OpenGL ES 3.1 SPEC Table 20.40]
215TEST_P(TextureMultisampleTestES31, MaxDepthTextureSamples)
216{
217 GLint maxDepthTextureSamples;
218 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
219 EXPECT_GE(maxDepthTextureSamples, 1);
220 EXPECT_NE(std::numeric_limits<GLint>::max(), maxDepthTextureSamples);
221}
222
Jiang0e1224c2017-12-26 14:11:15 +0800223// The value of sample position should be equal to standard pattern on D3D.
224TEST_P(TextureMultisampleTestES31, CheckSamplePositions)
225{
226 ANGLE_SKIP_TEST_IF(!IsD3D11());
227
228 GLsizei maxSamples = 0;
229 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
230
231 GLfloat samplePosition[2];
232
233 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
234
235 for (int sampleCount = 1; sampleCount <= maxSamples; sampleCount++)
236 {
237 GLTexture texture;
238 size_t indexKey = static_cast<size_t>(ceil(log2(sampleCount)));
239 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
240 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, 1, 1, GL_TRUE);
241 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
242 texture, 0);
243 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
244 ASSERT_GL_NO_ERROR();
245
246 for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
247 {
248 glGetMultisamplefv(GL_SAMPLE_POSITION, sampleIndex, samplePosition);
249 EXPECT_EQ(samplePosition[0], kSamplePositions[indexKey][2 * sampleIndex]);
250 EXPECT_EQ(samplePosition[1], kSamplePositions[indexKey][2 * sampleIndex + 1]);
251 }
252 }
253
254 ASSERT_GL_NO_ERROR();
255}
256
Olli Etuahod310a432018-08-24 15:40:23 +0300257// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
258// extension is not supported.
259TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
260{
261 GLint maxSamples = 0;
262 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_RGBA8, GL_SAMPLES, 1,
263 &maxSamples);
264 ASSERT_GL_ERROR(GL_INVALID_ENUM);
265}
266
267// Attempt to bind a texture to multisample array binding point when extension is not supported.
268TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
269{
270 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
271 ASSERT_GL_ERROR(GL_INVALID_ENUM);
272}
273
274// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
275TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
276{
277 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
278
279 // This query returns supported sample counts in descending order. If only one sample count is
280 // queried, it should be the maximum one.
281 GLint maxSamplesRGBA8 = 0;
282 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_RGBA8, GL_SAMPLES, 1,
283 &maxSamplesRGBA8);
284 ASSERT_GL_NO_ERROR();
285
286 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
287 GLint maxColorTextureSamples;
288 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
289 GLint maxSamples;
290 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
291 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
292
293 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
294}
295
296// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
297TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
298{
299 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
300
301 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
302 ASSERT_GL_NO_ERROR();
303
304 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
305 GL_UNSIGNED_BYTE, nullptr);
306 EXPECT_GL_ERROR(GL_INVALID_ENUM);
307}
308
309// Tests passing invalid parameters to TexStorage3DMultisample.
310TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
311{
312 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
313
314 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
315 ASSERT_GL_NO_ERROR();
316
317 // Invalid target
318 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
319 EXPECT_GL_ERROR(GL_INVALID_ENUM);
320
321 // Samples 0
322 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 0, GL_RGBA8, 1, 1, 1,
323 GL_TRUE);
324 EXPECT_GL_ERROR(GL_INVALID_VALUE);
325
326 // Unsized internalformat
327 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA, 1, 1, 1,
328 GL_TRUE);
329 EXPECT_GL_ERROR(GL_INVALID_ENUM);
330
331 // Width 0
332 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 0, 1, 1,
333 GL_TRUE);
334 EXPECT_GL_ERROR(GL_INVALID_VALUE);
335
336 // Height 0
337 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 1, 0, 1,
338 GL_TRUE);
339 EXPECT_GL_ERROR(GL_INVALID_VALUE);
340
341 // Depth 0
342 glTexStorage3DMultisampleANGLE(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, 2, GL_RGBA8, 1, 1, 0,
343 GL_TRUE);
344 EXPECT_GL_ERROR(GL_INVALID_VALUE);
345}
346
347// Tests passing invalid parameters to TexParameteri.
348TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
349{
350 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
351
352 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, mTexture);
353 ASSERT_GL_NO_ERROR();
354
355 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE.
356 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
357 EXPECT_GL_ERROR(GL_INVALID_ENUM);
358 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
359 EXPECT_GL_ERROR(GL_INVALID_ENUM);
360
361 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
362 EXPECT_GL_ERROR(GL_INVALID_ENUM);
363 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
364 EXPECT_GL_ERROR(GL_INVALID_ENUM);
365 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
366 EXPECT_GL_ERROR(GL_INVALID_ENUM);
367
368 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MIN_LOD, 0);
369 EXPECT_GL_ERROR(GL_INVALID_ENUM);
370 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_MAX_LOD, 0);
371 EXPECT_GL_ERROR(GL_INVALID_ENUM);
372
373 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_COMPARE_MODE, GL_NONE);
374 EXPECT_GL_ERROR(GL_INVALID_ENUM);
375 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
376 EXPECT_GL_ERROR(GL_INVALID_ENUM);
377
378 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE is 0.
379 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_ANGLE, GL_TEXTURE_BASE_LEVEL, 1);
380 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
381}
382
JiangYizhoubddc46b2016-12-09 09:50:51 +0800383ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
JiangYizhou34bc3152017-03-29 14:56:01 +0800384 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +0800385 ES3_OPENGL(),
386 ES3_OPENGLES(),
387 ES31_OPENGL(),
388 ES31_OPENGLES());
JiangYizhou34bc3152017-03-29 14:56:01 +0800389ANGLE_INSTANTIATE_TEST(TextureMultisampleTestES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300390ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
391 ES31_D3D11(),
392 ES31_OPENGL(),
393 ES31_OPENGLES());
394
395} // anonymous namespace