blob: 51f31b0b00813ed5d8f6c5f44eb420b3a1842121 [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"
Olli Etuahodff32a02018-08-28 14:35:50 +030010
JiangYizhoubddc46b2016-12-09 09:50:51 +080011#include "test_utils/gl_raii.h"
Jamie Madillba319ba2018-12-29 10:29:33 -050012#include "util/shader_utils.h"
JiangYizhoubddc46b2016-12-09 09:50:51 +080013
14using namespace angle;
15
16namespace
17{
Jiang0e1224c2017-12-26 14:11:15 +080018// Sample positions of d3d standard pattern. Some of the sample positions might not the same as
19// opengl.
20using SamplePositionsArray = std::array<float, 32>;
21static constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
22 {{{0.5f, 0.5f}},
23 {{0.75f, 0.75f, 0.25f, 0.25f}},
24 {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
25 {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
26 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
27 {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f,
28 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
29 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
30 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
JiangYizhoubddc46b2016-12-09 09:50:51 +080031
32class TextureMultisampleTest : public ANGLETest
33{
34 protected:
35 TextureMultisampleTest()
36 {
37 setWindowWidth(64);
38 setWindowHeight(64);
39 setConfigRedBits(8);
40 setConfigGreenBits(8);
41 setConfigBlueBits(8);
42 setConfigAlphaBits(8);
43 }
44
45 void SetUp() override
46 {
47 ANGLETest::SetUp();
48
49 glGenFramebuffers(1, &mFramebuffer);
50 glGenTextures(1, &mTexture);
51
52 ASSERT_GL_NO_ERROR();
53 }
54
55 void TearDown() override
56 {
57 glDeleteFramebuffers(1, &mFramebuffer);
58 mFramebuffer = 0;
59 glDeleteTextures(1, &mTexture);
60 mTexture = 0;
61
62 ANGLETest::TearDown();
63 }
64
Yizhou Jiang7818a852018-09-06 15:02:04 +080065 void texStorageMultisample(GLenum target,
66 GLint samples,
67 GLenum format,
68 GLsizei width,
69 GLsizei height,
70 GLboolean fixedsamplelocations);
71
Yizhou Jiangc0b6c632018-09-06 15:02:04 +080072 void getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params);
73 void getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params);
74
Yizhou Jiang7310da32018-11-05 14:40:01 +080075 void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
76 void sampleMaski(GLuint maskNumber, GLbitfield mask);
77
JiangYizhoubddc46b2016-12-09 09:50:51 +080078 GLuint mFramebuffer = 0;
79 GLuint mTexture = 0;
Olli Etuahofd162102018-08-27 16:14:57 +030080
81 // Returns a sample count that can be used with the given texture target for all the given
82 // formats. Assumes that if format A supports a number of samples N and another format B
83 // supports a number of samples M > N then format B also supports number of samples N.
84 GLint getSamplesToUse(GLenum texTarget, const std::vector<GLenum> &formats)
85 {
86 GLint maxSamples = 65536;
87 for (GLenum format : formats)
88 {
89 GLint maxSamplesFormat = 0;
90 glGetInternalformativ(texTarget, format, GL_SAMPLES, 1, &maxSamplesFormat);
91 maxSamples = std::min(maxSamples, maxSamplesFormat);
92 }
93 return maxSamples;
94 }
Olli Etuahodff32a02018-08-28 14:35:50 +030095
Yizhou Jiang7818a852018-09-06 15:02:04 +080096 bool lessThanES31MultisampleExtNotSupported()
97 {
98 return getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
99 !ensureExtensionEnabled("GL_ANGLE_texture_multisample");
100 }
101
102 const char *multisampleTextureFragmentShader()
103 {
104 return R"(#version 300 es
105#extension GL_ANGLE_texture_multisample : require
106precision highp float;
107precision highp int;
108
109uniform highp sampler2DMS tex;
110uniform int sampleNum;
111
112in vec4 v_position;
113out vec4 my_FragColor;
114
115void main() {
116 ivec2 texSize = textureSize(tex);
117 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
118 my_FragColor = texelFetch(tex, sampleCoords, sampleNum);
119}
120)";
121 };
122
Olli Etuahodff32a02018-08-28 14:35:50 +0300123 const char *blitArrayTextureLayerFragmentShader()
124 {
125 return R"(#version 310 es
126#extension GL_OES_texture_storage_multisample_2d_array : require
127precision highp float;
128precision highp int;
129
130uniform highp sampler2DMSArray tex;
131uniform int layer;
132uniform int sampleNum;
133
134in vec4 v_position;
135out vec4 my_FragColor;
136
137void main() {
138 ivec3 texSize = textureSize(tex);
139 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
140 my_FragColor = texelFetch(tex, ivec3(sampleCoords, layer), sampleNum);
141}
142)";
143 };
144
145 const char *blitIntArrayTextureLayerFragmentShader()
146 {
147 return R"(#version 310 es
148#extension GL_OES_texture_storage_multisample_2d_array : require
149precision highp float;
150precision highp int;
151
152uniform highp isampler2DMSArray tex;
153uniform int layer;
154uniform int sampleNum;
155
156in vec4 v_position;
157out vec4 my_FragColor;
158
159void main() {
160 ivec3 texSize = textureSize(tex);
161 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
162 my_FragColor = vec4(texelFetch(tex, ivec3(sampleCoords, layer), sampleNum));
163}
164)";
165 };
JiangYizhoubddc46b2016-12-09 09:50:51 +0800166};
167
Yizhou Jiang7818a852018-09-06 15:02:04 +0800168class NegativeTextureMultisampleTest : public TextureMultisampleTest
JiangYizhoubddc46b2016-12-09 09:50:51 +0800169{
170 protected:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800171 NegativeTextureMultisampleTest() : TextureMultisampleTest() {}
JiangYizhoubddc46b2016-12-09 09:50:51 +0800172};
173
Olli Etuahod310a432018-08-24 15:40:23 +0300174class TextureMultisampleArrayWebGLTest : public TextureMultisampleTest
175{
176 protected:
177 TextureMultisampleArrayWebGLTest() : TextureMultisampleTest()
178 {
179 // These tests run in WebGL mode so we can test with both extension off and on.
180 setWebGLCompatibilityEnabled(true);
181 }
182
183 // Requests the ANGLE_texture_multisample_array extension and returns true if the operation
184 // succeeds.
185 bool requestArrayExtension()
186 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300187 if (extensionRequestable("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300188 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300189 glRequestExtensionANGLE("GL_OES_texture_storage_multisample_2d_array");
Olli Etuahod310a432018-08-24 15:40:23 +0300190 }
191
Olli Etuaho064458a2018-08-30 14:02:02 +0300192 if (!extensionEnabled("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300193 {
194 return false;
195 }
196 return true;
197 }
198};
199
Yizhou Jiang7818a852018-09-06 15:02:04 +0800200void TextureMultisampleTest::texStorageMultisample(GLenum target,
201 GLint samples,
202 GLenum internalformat,
203 GLsizei width,
204 GLsizei height,
205 GLboolean fixedsamplelocations)
206{
207 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
208 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
209 {
210 glTexStorage2DMultisampleANGLE(target, samples, internalformat, width, height,
211 fixedsamplelocations);
212 }
213 else
214 {
215 glTexStorage2DMultisample(target, samples, internalformat, width, height,
216 fixedsamplelocations);
217 }
218}
219
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800220void TextureMultisampleTest::getTexLevelParameterfv(GLenum target,
221 GLint level,
222 GLenum pname,
223 GLfloat *params)
224{
225 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
226 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
227 {
228 glGetTexLevelParameterfvANGLE(target, level, pname, params);
229 }
230 else
231 {
232 glGetTexLevelParameterfv(target, level, pname, params);
233 }
234}
Yizhou Jiang7310da32018-11-05 14:40:01 +0800235
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800236void TextureMultisampleTest::getTexLevelParameteriv(GLenum target,
237 GLint level,
238 GLenum pname,
239 GLint *params)
240{
241 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
242 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
243 {
244 glGetTexLevelParameterivANGLE(target, level, pname, params);
245 }
246 else
247 {
248 glGetTexLevelParameteriv(target, level, pname, params);
249 }
250}
251
Yizhou Jiang7310da32018-11-05 14:40:01 +0800252void TextureMultisampleTest::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
253{
254 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
255 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
256 {
257 glGetMultisamplefvANGLE(pname, index, val);
258 }
259 else
260 {
261 glGetMultisamplefv(pname, index, val);
262 }
263}
264
265void TextureMultisampleTest::sampleMaski(GLuint maskNumber, GLbitfield mask)
266{
267 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
268 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
269 {
270 glSampleMaskiANGLE(maskNumber, mask);
271 }
272 else
273 {
274 glSampleMaski(maskNumber, mask);
275 }
276}
277
JiangYizhoubddc46b2016-12-09 09:50:51 +0800278// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
Olli Etuahod310a432018-08-24 15:40:23 +0300279// GetInternalformativ. Checks that the number of samples returned is valid in case of ES >= 3.1.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800280TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
281{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800282 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
283
Olli Etuahod310a432018-08-24 15:40:23 +0300284 // This query returns supported sample counts in descending order. If only one sample count is
285 // queried, it should be the maximum one.
286 GLint maxSamplesR8 = 0;
287 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamplesR8);
Olli Etuahod310a432018-08-24 15:40:23 +0300288
Yizhou Jiang7818a852018-09-06 15:02:04 +0800289 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
290 GLint maxColorTextureSamples;
291 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
292 GLint maxSamples;
293 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
294 GLint maxSamplesR8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300295
Yizhou Jiang7818a852018-09-06 15:02:04 +0800296 EXPECT_GE(maxSamplesR8, maxSamplesR8Required);
297 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800298}
299
Yizhou Jiang7818a852018-09-06 15:02:04 +0800300// Tests that if es version < 3.1 and multisample extension is unsupported,
301// GL_TEXTURE_2D_MULTISAMPLE_ANGLE is not supported in FramebufferTexture2D.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800302TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
303{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800304 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
JiangYizhoubddc46b2016-12-09 09:50:51 +0800305 GLint samples = 1;
306 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800307 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800308
309 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
310 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
311 mTexture, 0);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800312
Yizhou Jiang7818a852018-09-06 15:02:04 +0800313 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800314}
315
316// Tests basic functionality of glTexStorage2DMultisample.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800317TEST_P(TextureMultisampleTest, ValidateTextureStorageMultisampleParameters)
JiangYizhoubddc46b2016-12-09 09:50:51 +0800318{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800319 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
320
JiangYizhoubddc46b2016-12-09 09:50:51 +0800321 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800322 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhou461d9a32017-01-04 16:37:26 +0800323 ASSERT_GL_NO_ERROR();
324
JiangYizhoubddc46b2016-12-09 09:50:51 +0800325 GLint params = 0;
326 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
327 EXPECT_EQ(1, params);
328
Yizhou Jiang7818a852018-09-06 15:02:04 +0800329 texStorageMultisample(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800330 ASSERT_GL_ERROR(GL_INVALID_ENUM);
331
Yizhou Jiang7818a852018-09-06 15:02:04 +0800332 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800333 ASSERT_GL_ERROR(GL_INVALID_VALUE);
334
335 GLint maxSize = 0;
336 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800337 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, maxSize + 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800338 ASSERT_GL_ERROR(GL_INVALID_VALUE);
339
340 GLint maxSamples = 0;
341 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800342 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples + 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800343 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
344
Yizhou Jiang7818a852018-09-06 15:02:04 +0800345 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800346 ASSERT_GL_ERROR(GL_INVALID_VALUE);
347
Yizhou Jiang7818a852018-09-06 15:02:04 +0800348 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800349 ASSERT_GL_ERROR(GL_INVALID_VALUE);
350
351 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800352 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800353 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
354}
355
Shao5116d682017-08-02 12:39:44 +0800356// Tests the value of MAX_INTEGER_SAMPLES is no less than 1.
357// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800358TEST_P(TextureMultisampleTest, MaxIntegerSamples)
Shao5116d682017-08-02 12:39:44 +0800359{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800360 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800361 GLint maxIntegerSamples;
362 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &maxIntegerSamples);
363 EXPECT_GE(maxIntegerSamples, 1);
364 EXPECT_NE(std::numeric_limits<GLint>::max(), maxIntegerSamples);
365}
366
367// Tests the value of MAX_COLOR_TEXTURE_SAMPLES is no less than 1.
368// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800369TEST_P(TextureMultisampleTest, MaxColorTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800370{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800371 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800372 GLint maxColorTextureSamples;
373 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
374 EXPECT_GE(maxColorTextureSamples, 1);
375 EXPECT_NE(std::numeric_limits<GLint>::max(), maxColorTextureSamples);
376}
377
378// Tests the value of MAX_DEPTH_TEXTURE_SAMPLES is no less than 1.
379// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800380TEST_P(TextureMultisampleTest, MaxDepthTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800381{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800382 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800383 GLint maxDepthTextureSamples;
384 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
385 EXPECT_GE(maxDepthTextureSamples, 1);
386 EXPECT_NE(std::numeric_limits<GLint>::max(), maxDepthTextureSamples);
387}
388
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800389// Tests that getTexLevelParameter is supported by ES 3.1 or ES 3.0 and ANGLE_texture_multisample
390TEST_P(TextureMultisampleTest, GetTexLevelParameter)
391{
392 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
393
394 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
395 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 1, 1, GL_TRUE);
396 ASSERT_GL_NO_ERROR();
397
398 GLfloat levelSamples = 0;
399 getTexLevelParameterfv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &levelSamples);
400 EXPECT_EQ(levelSamples, 4);
401
402 GLint fixedSampleLocation = false;
403 getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
404 &fixedSampleLocation);
405 EXPECT_EQ(fixedSampleLocation, 1);
406
407 ASSERT_GL_NO_ERROR();
408}
409
Jiang0e1224c2017-12-26 14:11:15 +0800410// The value of sample position should be equal to standard pattern on D3D.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800411TEST_P(TextureMultisampleTest, CheckSamplePositions)
Jiang0e1224c2017-12-26 14:11:15 +0800412{
Yizhou Jiang7310da32018-11-05 14:40:01 +0800413 ANGLE_SKIP_TEST_IF(!IsD3D11());
Jiang0e1224c2017-12-26 14:11:15 +0800414
415 GLsizei maxSamples = 0;
416 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
417
418 GLfloat samplePosition[2];
419
420 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
421
422 for (int sampleCount = 1; sampleCount <= maxSamples; sampleCount++)
423 {
424 GLTexture texture;
425 size_t indexKey = static_cast<size_t>(ceil(log2(sampleCount)));
426 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
Yizhou Jiang7310da32018-11-05 14:40:01 +0800427 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, 1, 1, GL_TRUE);
Jiang0e1224c2017-12-26 14:11:15 +0800428 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
429 texture, 0);
430 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
431 ASSERT_GL_NO_ERROR();
432
433 for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
434 {
Yizhou Jiang7310da32018-11-05 14:40:01 +0800435 getMultisamplefv(GL_SAMPLE_POSITION, sampleIndex, samplePosition);
Jiang0e1224c2017-12-26 14:11:15 +0800436 EXPECT_EQ(samplePosition[0], kSamplePositions[indexKey][2 * sampleIndex]);
437 EXPECT_EQ(samplePosition[1], kSamplePositions[indexKey][2 * sampleIndex + 1]);
438 }
439 }
440
441 ASSERT_GL_NO_ERROR();
442}
443
Yizhou Jiang7818a852018-09-06 15:02:04 +0800444// Test textureSize and texelFetch when using ANGLE_texture_multisample extension
445TEST_P(TextureMultisampleTest, SimpleTexelFetch)
446{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800447 ANGLE_SKIP_TEST_IF(!ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
448
449 ANGLE_GL_PROGRAM(texelFetchProgram, essl3_shaders::vs::Passthrough(),
450 multisampleTextureFragmentShader());
451
452 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
453 ASSERT_GE(texLocation, 0);
454 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
455 ASSERT_GE(sampleNumLocation, 0);
456
457 const GLsizei kWidth = 4;
458 const GLsizei kHeight = 4;
459
460 std::vector<GLenum> testFormats = {GL_RGBA8};
461 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, testFormats);
462
463 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, mTexture);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800464 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, samplesToUse, GL_RGBA8, kWidth, kHeight,
465 GL_TRUE);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800466 ASSERT_GL_NO_ERROR();
467
468 // Clear texture zero to green.
469 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
470 GLColor clearColor = GLColor::green;
471
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800472 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE_ANGLE,
473 mTexture, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800474 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
475 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
476 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
477 clearColor.A / 255.0f);
478 glClear(GL_COLOR_BUFFER_BIT);
479 ASSERT_GL_NO_ERROR();
480
481 glBindFramebuffer(GL_FRAMEBUFFER, 0);
482 glUseProgram(texelFetchProgram);
483 glViewport(0, 0, kWidth, kHeight);
484
485 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
486 {
487 glUniform1i(sampleNumLocation, sampleNum);
488 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
489 ASSERT_GL_NO_ERROR();
490 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColor);
491 }
492}
493
Yizhou Jiang7310da32018-11-05 14:40:01 +0800494TEST_P(TextureMultisampleTest, SampleMaski)
495{
496 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
497
498 GLint maxSampleMaskWords = 0;
499 glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
500 sampleMaski(maxSampleMaskWords - 1, 0x1);
501 ASSERT_GL_NO_ERROR();
502
503 glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
504 sampleMaski(maxSampleMaskWords, 0x1);
505 ASSERT_GL_ERROR(GL_INVALID_VALUE);
506}
507
Yizhou Jiang7818a852018-09-06 15:02:04 +0800508// Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample
509// not enabled, the feature isn't supported.
510TEST_P(NegativeTextureMultisampleTest, Negtive)
511{
512 ANGLE_SKIP_TEST_IF(ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
513
514 GLint maxSamples = 0;
515 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
516 ASSERT_GL_ERROR(GL_INVALID_ENUM);
517
518 GLint maxColorTextureSamples;
519 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
520 ASSERT_GL_ERROR(GL_INVALID_ENUM);
521
522 GLint maxDepthTextureSamples;
523 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
524 ASSERT_GL_ERROR(GL_INVALID_ENUM);
525
526 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
527 ASSERT_GL_ERROR(GL_INVALID_ENUM);
528
529 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 64, 64, GL_FALSE);
530 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
531
532 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
533 mTexture, 0);
534 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
535
536 GLint params = 0;
537 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
538 ASSERT_GL_ERROR(GL_INVALID_ENUM);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800539
540 GLfloat levelSamples = 0;
541 getTexLevelParameterfv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &levelSamples);
542 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
543
544 GLint fixedSampleLocation = false;
545 getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
546 &fixedSampleLocation);
547 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
Yizhou Jiang7310da32018-11-05 14:40:01 +0800548
549 GLint maxSampleMaskWords = 0;
550 glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &maxSampleMaskWords);
551 ASSERT_GL_ERROR(GL_INVALID_ENUM);
552 sampleMaski(maxSampleMaskWords - 1, 0x1);
553 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800554}
555
Olli Etuahod310a432018-08-24 15:40:23 +0300556// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
557// extension is not supported.
558TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
559{
560 GLint maxSamples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300561 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300562 &maxSamples);
563 ASSERT_GL_ERROR(GL_INVALID_ENUM);
564}
565
566// Attempt to bind a texture to multisample array binding point when extension is not supported.
567TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
568{
Olli Etuaho064458a2018-08-30 14:02:02 +0300569 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300570 ASSERT_GL_ERROR(GL_INVALID_ENUM);
571}
572
Olli Etuahodff32a02018-08-28 14:35:50 +0300573// Try to compile shaders using GL_OES_texture_storage_multisample_2d_array when the extension is
574// not enabled.
575TEST_P(TextureMultisampleArrayWebGLTest, ShaderWithoutExtension)
576{
Jamie Madill35cd7332018-12-02 12:03:33 -0500577 constexpr char kFSRequiresExtension[] = R"(#version 310 es
578#extension GL_OES_texture_storage_multisample_2d_array : require
579out highp vec4 my_FragColor;
Olli Etuahodff32a02018-08-28 14:35:50 +0300580
Jamie Madill35cd7332018-12-02 12:03:33 -0500581void main() {
582 my_FragColor = vec4(0.0);
583})";
Olli Etuahodff32a02018-08-28 14:35:50 +0300584
Jamie Madill35cd7332018-12-02 12:03:33 -0500585 GLuint program = CompileProgram(essl31_shaders::vs::Simple(), kFSRequiresExtension);
Olli Etuahodff32a02018-08-28 14:35:50 +0300586 EXPECT_EQ(0u, program);
587
Jamie Madill35cd7332018-12-02 12:03:33 -0500588 constexpr char kFSEnableAndUseExtension[] = R"(#version 310 es
589#extension GL_OES_texture_storage_multisample_2d_array : enable
Olli Etuahodff32a02018-08-28 14:35:50 +0300590
Jamie Madill35cd7332018-12-02 12:03:33 -0500591uniform highp sampler2DMSArray tex;
592out highp ivec4 outSize;
Olli Etuahodff32a02018-08-28 14:35:50 +0300593
Jamie Madill35cd7332018-12-02 12:03:33 -0500594void main() {
595 outSize = ivec4(textureSize(tex), 0);
596})";
Olli Etuahodff32a02018-08-28 14:35:50 +0300597
Jamie Madill35cd7332018-12-02 12:03:33 -0500598 program = CompileProgram(essl31_shaders::vs::Simple(), kFSEnableAndUseExtension);
Olli Etuahodff32a02018-08-28 14:35:50 +0300599 EXPECT_EQ(0u, program);
600}
601
Olli Etuahod310a432018-08-24 15:40:23 +0300602// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
603TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
604{
605 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
606
607 // This query returns supported sample counts in descending order. If only one sample count is
608 // queried, it should be the maximum one.
609 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300610 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300611 &maxSamplesRGBA8);
Olli Etuahofd162102018-08-27 16:14:57 +0300612 GLint maxSamplesDepth = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300613 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_DEPTH_COMPONENT24, GL_SAMPLES, 1,
614 &maxSamplesDepth);
Olli Etuahod310a432018-08-24 15:40:23 +0300615 ASSERT_GL_NO_ERROR();
616
617 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
618 GLint maxColorTextureSamples;
619 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
Olli Etuahofd162102018-08-27 16:14:57 +0300620 GLint maxDepthTextureSamples;
621 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300622 GLint maxSamples;
623 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300624
Olli Etuahofd162102018-08-27 16:14:57 +0300625 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300626 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
Olli Etuahofd162102018-08-27 16:14:57 +0300627
628 GLint maxSamplesDepthRequired = std::min(maxDepthTextureSamples, maxSamples);
629 EXPECT_GE(maxSamplesDepth, maxSamplesDepthRequired);
Olli Etuahod310a432018-08-24 15:40:23 +0300630}
631
632// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
633TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
634{
635 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
636
Olli Etuaho064458a2018-08-30 14:02:02 +0300637 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300638 ASSERT_GL_NO_ERROR();
639
Olli Etuaho064458a2018-08-30 14:02:02 +0300640 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
Olli Etuahod310a432018-08-24 15:40:23 +0300641 GL_UNSIGNED_BYTE, nullptr);
642 EXPECT_GL_ERROR(GL_INVALID_ENUM);
643}
644
645// Tests passing invalid parameters to TexStorage3DMultisample.
646TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
647{
648 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
649
Olli Etuaho064458a2018-08-30 14:02:02 +0300650 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300651 ASSERT_GL_NO_ERROR();
652
653 // Invalid target
Olli Etuaho064458a2018-08-30 14:02:02 +0300654 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300655 EXPECT_GL_ERROR(GL_INVALID_ENUM);
656
657 // Samples 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300658 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1,
659 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300660 EXPECT_GL_ERROR(GL_INVALID_VALUE);
661
662 // Unsized internalformat
Olli Etuaho064458a2018-08-30 14:02:02 +0300663 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300664 EXPECT_GL_ERROR(GL_INVALID_ENUM);
665
666 // Width 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300667 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 0, 1, 1,
668 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300669 EXPECT_GL_ERROR(GL_INVALID_VALUE);
670
671 // Height 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300672 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 0, 1,
673 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300674 EXPECT_GL_ERROR(GL_INVALID_VALUE);
675
676 // Depth 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300677 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 1, 0,
678 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300679 EXPECT_GL_ERROR(GL_INVALID_VALUE);
680}
681
682// Tests passing invalid parameters to TexParameteri.
683TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
684{
685 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
686
Olli Etuaho064458a2018-08-30 14:02:02 +0300687 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300688 ASSERT_GL_NO_ERROR();
689
Olli Etuaho064458a2018-08-30 14:02:02 +0300690 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES.
691 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300692 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300693 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300694 EXPECT_GL_ERROR(GL_INVALID_ENUM);
695
Olli Etuaho064458a2018-08-30 14:02:02 +0300696 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300697 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300698 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300699 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300700 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300701 EXPECT_GL_ERROR(GL_INVALID_ENUM);
702
Olli Etuaho064458a2018-08-30 14:02:02 +0300703 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300704 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300705 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAX_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300706 EXPECT_GL_ERROR(GL_INVALID_ENUM);
707
Olli Etuaho064458a2018-08-30 14:02:02 +0300708 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Olli Etuahod310a432018-08-24 15:40:23 +0300709 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300710 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
Olli Etuahod310a432018-08-24 15:40:23 +0300711 EXPECT_GL_ERROR(GL_INVALID_ENUM);
712
Olli Etuaho064458a2018-08-30 14:02:02 +0300713 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES is 0.
714 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 1);
Olli Etuahod310a432018-08-24 15:40:23 +0300715 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
716}
717
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300718// Test a valid TexStorage3DMultisample call and check that the queried texture level parameters
719// match. Does not do any drawing.
720TEST_P(TextureMultisampleArrayWebGLTest, TexStorage3DMultisample)
721{
722 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
723
724 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300725 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300726 &maxSamplesRGBA8);
727
Olli Etuaho064458a2018-08-30 14:02:02 +0300728 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300729 ASSERT_GL_NO_ERROR();
730
Olli Etuaho064458a2018-08-30 14:02:02 +0300731 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 8,
732 4, 2, GL_TRUE);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300733 ASSERT_GL_NO_ERROR();
734
735 GLint width = 0, height = 0, depth = 0, samples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300736 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_WIDTH, &width);
737 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_HEIGHT, &height);
738 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_DEPTH, &depth);
739 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_SAMPLES, &samples);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300740 ASSERT_GL_NO_ERROR();
741
742 EXPECT_EQ(8, width);
743 EXPECT_EQ(4, height);
744 EXPECT_EQ(2, depth);
745 EXPECT_EQ(maxSamplesRGBA8, samples);
746}
747
Olli Etuaho064458a2018-08-30 14:02:02 +0300748// Test for invalid FramebufferTextureLayer calls with GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES
Olli Etuahofd162102018-08-27 16:14:57 +0300749// textures.
750TEST_P(TextureMultisampleArrayWebGLTest, InvalidFramebufferTextureLayer)
751{
752 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
753
754 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300755 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahofd162102018-08-27 16:14:57 +0300756 &maxSamplesRGBA8);
757
758 GLint maxArrayTextureLayers;
759 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
760
761 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300762 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
763 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 4,
764 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300765 ASSERT_GL_NO_ERROR();
766
767 // Test with mip level 1 and -1 (only level 0 is valid for multisample textures).
768 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
769 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 1, 0);
770 EXPECT_GL_ERROR(GL_INVALID_VALUE);
771 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, -1, 0);
772 EXPECT_GL_ERROR(GL_INVALID_VALUE);
773
774 // Test with layer -1 and layer == MAX_ARRAY_TEXTURE_LAYERS
775 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
776 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, -1);
777 EXPECT_GL_ERROR(GL_INVALID_VALUE);
778 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0,
779 maxArrayTextureLayers);
780 EXPECT_GL_ERROR(GL_INVALID_VALUE);
781}
782
783// Attach layers of TEXTURE_2D_MULTISAMPLE_ARRAY textures to a framebuffer and check for
784// completeness.
785TEST_P(TextureMultisampleArrayWebGLTest, FramebufferCompleteness)
786{
787 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
788
789 std::vector<GLenum> testFormats = {{GL_RGBA8, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8}};
Olli Etuaho064458a2018-08-30 14:02:02 +0300790 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300791
792 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300793 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
794 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8, 4, 4,
795 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300796 ASSERT_GL_NO_ERROR();
797
798 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
799 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
800 ASSERT_GL_NO_ERROR();
801
802 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
803 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
804
805 // Test framebuffer status with both color and depth textures attached.
806 GLTexture depthTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300807 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthTexture);
808 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
809 GL_DEPTH_COMPONENT24, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300810 ASSERT_GL_NO_ERROR();
811
812 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0);
813 ASSERT_GL_NO_ERROR();
814
815 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
816 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
817
818 // Test with color and depth/stencil textures attached.
819 GLTexture depthStencilTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300820 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthStencilTexture);
821 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
822 GL_DEPTH24_STENCIL8, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300823 ASSERT_GL_NO_ERROR();
824
825 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0,
826 0);
827 ASSERT_GL_NO_ERROR();
828
829 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
830 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
831}
832
833// Attach a layer of TEXTURE_2D_MULTISAMPLE_ARRAY texture to a framebuffer, clear it, and resolve by
834// blitting.
835TEST_P(TextureMultisampleArrayWebGLTest, FramebufferColorClearAndBlit)
836{
837 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
838
839 const GLsizei kWidth = 4;
840 const GLsizei kHeight = 4;
841
842 std::vector<GLenum> testFormats = {GL_RGBA8};
Olli Etuaho064458a2018-08-30 14:02:02 +0300843 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300844
Olli Etuaho064458a2018-08-30 14:02:02 +0300845 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
846 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
847 kWidth, kHeight, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300848
849 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
850 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
851
852 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
853 ASSERT_GL_NO_ERROR();
854 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
855
856 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
857 glClear(GL_COLOR_BUFFER_BIT);
858
859 GLFramebuffer resolveFramebuffer;
860 GLTexture resolveTexture;
861 glBindTexture(GL_TEXTURE_2D, resolveTexture);
862 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
863 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
864 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
865 0);
866 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
867 GL_NEAREST);
868 ASSERT_GL_NO_ERROR();
869
870 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFramebuffer);
871 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
872}
873
Olli Etuahodff32a02018-08-28 14:35:50 +0300874// Check the size of a multisample array texture in a shader.
875TEST_P(TextureMultisampleArrayWebGLTest, TextureSizeInShader)
876{
877 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
878
Jamie Madill35cd7332018-12-02 12:03:33 -0500879 constexpr char kFS[] = R"(#version 310 es
880#extension GL_OES_texture_storage_multisample_2d_array : require
Olli Etuahodff32a02018-08-28 14:35:50 +0300881
Jamie Madill35cd7332018-12-02 12:03:33 -0500882uniform highp sampler2DMSArray tex;
883out highp vec4 my_FragColor;
Olli Etuahodff32a02018-08-28 14:35:50 +0300884
Jamie Madill35cd7332018-12-02 12:03:33 -0500885void main() {
886 my_FragColor = (textureSize(tex) == ivec3(8, 4, 2)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
887})";
Olli Etuahodff32a02018-08-28 14:35:50 +0300888
Jamie Madill35cd7332018-12-02 12:03:33 -0500889 ANGLE_GL_PROGRAM(texSizeProgram, essl31_shaders::vs::Simple(), kFS);
Olli Etuahodff32a02018-08-28 14:35:50 +0300890
891 GLint texLocation = glGetUniformLocation(texSizeProgram, "tex");
892 ASSERT_GE(texLocation, 0);
893
894 const GLsizei kWidth = 8;
895 const GLsizei kHeight = 4;
896
897 std::vector<GLenum> testFormats = {GL_RGBA8};
898 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
899
900 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
901 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
902 kWidth, kHeight, 2, GL_TRUE);
903 ASSERT_GL_NO_ERROR();
904
905 drawQuad(texSizeProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
906 ASSERT_GL_NO_ERROR();
907
908 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
909}
910
911// Clear the layers of a multisample array texture, and then sample all the samples from all the
912// layers in a shader.
913TEST_P(TextureMultisampleArrayWebGLTest, SimpleTexelFetch)
914{
915 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
916
917 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
918 blitArrayTextureLayerFragmentShader());
919
920 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
921 ASSERT_GE(texLocation, 0);
922 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
923 ASSERT_GE(layerLocation, 0);
924 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
925 ASSERT_GE(layerLocation, 0);
926
927 const GLsizei kWidth = 4;
928 const GLsizei kHeight = 4;
929 const GLsizei kLayerCount = 2;
930
931 std::vector<GLenum> testFormats = {GL_RGBA8};
932 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
933
934 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
935 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
936 kWidth, kHeight, kLayerCount, GL_TRUE);
937 ASSERT_GL_NO_ERROR();
938
939 // Clear layer zero to green and layer one to blue.
940 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
941 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
942 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
943 {
944 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
945 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
946 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
947 const GLColor &clearColor = clearColors[i];
948 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
949 clearColor.A / 255.0f);
950 glClear(GL_COLOR_BUFFER_BIT);
951 ASSERT_GL_NO_ERROR();
952 }
953
954 glBindFramebuffer(GL_FRAMEBUFFER, 0);
955 glUseProgram(texelFetchProgram);
956 glViewport(0, 0, kWidth, kHeight);
957 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
958 {
959 glUniform1i(layerLocation, layer);
960 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
961 {
962 glUniform1i(sampleNumLocation, sampleNum);
963 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
964 ASSERT_GL_NO_ERROR();
965 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
966 }
967 }
968}
969
970// Clear the layers of an integer multisample array texture, and then sample all the samples from
971// all the layers in a shader.
972TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
973{
974 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
975
976 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
977 blitIntArrayTextureLayerFragmentShader());
978
979 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
980 ASSERT_GE(texLocation, 0);
981 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
982 ASSERT_GE(layerLocation, 0);
983 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
984 ASSERT_GE(layerLocation, 0);
985
986 const GLsizei kWidth = 4;
987 const GLsizei kHeight = 4;
988 const GLsizei kLayerCount = 2;
989
990 std::vector<GLenum> testFormats = {GL_RGBA8I};
991 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
992
993 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
994 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8I,
995 kWidth, kHeight, kLayerCount, GL_TRUE);
996 ASSERT_GL_NO_ERROR();
997
998 // Clear layer zero to green and layer one to blue.
999 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
1000 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
1001 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
1002 {
1003 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
1004 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1005 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
1006 std::array<GLint, 4> intColor;
1007 for (size_t j = 0; j < intColor.size(); ++j)
1008 {
1009 intColor[j] = clearColors[i][j] / 255;
1010 }
1011 glClearBufferiv(GL_COLOR, 0, intColor.data());
1012 ASSERT_GL_NO_ERROR();
1013 }
1014
1015 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1016 glUseProgram(texelFetchProgram);
1017 glViewport(0, 0, kWidth, kHeight);
1018 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
1019 {
1020 glUniform1i(layerLocation, layer);
1021 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
1022 {
1023 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1024 glClear(GL_COLOR_BUFFER_BIT);
1025 glUniform1i(sampleNumLocation, sampleNum);
1026 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1027 ASSERT_GL_NO_ERROR();
1028 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
1029 }
1030 }
1031}
1032
JiangYizhoubddc46b2016-12-09 09:50:51 +08001033ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
Yizhou Jiang7818a852018-09-06 15:02:04 +08001034 ES3_D3D11(),
JiangYizhou34bc3152017-03-29 14:56:01 +08001035 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +08001036 ES3_OPENGL(),
1037 ES3_OPENGLES(),
1038 ES31_OPENGL(),
1039 ES31_OPENGLES());
Yizhou Jiang7818a852018-09-06 15:02:04 +08001040ANGLE_INSTANTIATE_TEST(NegativeTextureMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +03001041ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
1042 ES31_D3D11(),
1043 ES31_OPENGL(),
1044 ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +03001045} // anonymous namespace