blob: b008e9caa3e8d56883c5af252dc3543c311a0115 [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
11#include "shader_utils.h"
JiangYizhoubddc46b2016-12-09 09:50:51 +080012#include "test_utils/gl_raii.h"
13
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{
577 const std::string &fragmentShaderRequireExtension = R"(#version 310 es
578 #extension GL_OES_texture_storage_multisample_2d_array : require
579 out highp vec4 my_FragColor;
580
581 void main() {
582 my_FragColor = vec4(0.0);
583 }
584 )";
585
586 GLuint program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderRequireExtension);
587 EXPECT_EQ(0u, program);
588
589 const std::string &fragmentShaderEnableAndUseExtension = R"(#version 310 es
590 #extension GL_OES_texture_storage_multisample_2d_array : enable
591
592 uniform highp sampler2DMSArray tex;
593 out highp ivec4 outSize;
594
595 void main() {
596 outSize = ivec4(textureSize(tex), 0);
597 }
598 )";
599
600 program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderEnableAndUseExtension);
601 EXPECT_EQ(0u, program);
602}
603
Olli Etuahod310a432018-08-24 15:40:23 +0300604// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
605TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
606{
607 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
608
609 // This query returns supported sample counts in descending order. If only one sample count is
610 // queried, it should be the maximum one.
611 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300612 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300613 &maxSamplesRGBA8);
Olli Etuahofd162102018-08-27 16:14:57 +0300614 GLint maxSamplesDepth = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300615 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_DEPTH_COMPONENT24, GL_SAMPLES, 1,
616 &maxSamplesDepth);
Olli Etuahod310a432018-08-24 15:40:23 +0300617 ASSERT_GL_NO_ERROR();
618
619 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
620 GLint maxColorTextureSamples;
621 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
Olli Etuahofd162102018-08-27 16:14:57 +0300622 GLint maxDepthTextureSamples;
623 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300624 GLint maxSamples;
625 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300626
Olli Etuahofd162102018-08-27 16:14:57 +0300627 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300628 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
Olli Etuahofd162102018-08-27 16:14:57 +0300629
630 GLint maxSamplesDepthRequired = std::min(maxDepthTextureSamples, maxSamples);
631 EXPECT_GE(maxSamplesDepth, maxSamplesDepthRequired);
Olli Etuahod310a432018-08-24 15:40:23 +0300632}
633
634// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
635TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
636{
637 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
638
Olli Etuaho064458a2018-08-30 14:02:02 +0300639 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300640 ASSERT_GL_NO_ERROR();
641
Olli Etuaho064458a2018-08-30 14:02:02 +0300642 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
Olli Etuahod310a432018-08-24 15:40:23 +0300643 GL_UNSIGNED_BYTE, nullptr);
644 EXPECT_GL_ERROR(GL_INVALID_ENUM);
645}
646
647// Tests passing invalid parameters to TexStorage3DMultisample.
648TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
649{
650 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
651
Olli Etuaho064458a2018-08-30 14:02:02 +0300652 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300653 ASSERT_GL_NO_ERROR();
654
655 // Invalid target
Olli Etuaho064458a2018-08-30 14:02:02 +0300656 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300657 EXPECT_GL_ERROR(GL_INVALID_ENUM);
658
659 // Samples 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300660 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1,
661 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300662 EXPECT_GL_ERROR(GL_INVALID_VALUE);
663
664 // Unsized internalformat
Olli Etuaho064458a2018-08-30 14:02:02 +0300665 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300666 EXPECT_GL_ERROR(GL_INVALID_ENUM);
667
668 // Width 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300669 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 0, 1, 1,
670 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300671 EXPECT_GL_ERROR(GL_INVALID_VALUE);
672
673 // Height 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300674 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 0, 1,
675 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300676 EXPECT_GL_ERROR(GL_INVALID_VALUE);
677
678 // Depth 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300679 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 1, 0,
680 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300681 EXPECT_GL_ERROR(GL_INVALID_VALUE);
682}
683
684// Tests passing invalid parameters to TexParameteri.
685TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
686{
687 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
688
Olli Etuaho064458a2018-08-30 14:02:02 +0300689 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300690 ASSERT_GL_NO_ERROR();
691
Olli Etuaho064458a2018-08-30 14:02:02 +0300692 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES.
693 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300694 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300695 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300696 EXPECT_GL_ERROR(GL_INVALID_ENUM);
697
Olli Etuaho064458a2018-08-30 14:02:02 +0300698 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_S, 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_T, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300701 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300702 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300703 EXPECT_GL_ERROR(GL_INVALID_ENUM);
704
Olli Etuaho064458a2018-08-30 14:02:02 +0300705 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300706 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300707 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAX_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300708 EXPECT_GL_ERROR(GL_INVALID_ENUM);
709
Olli Etuaho064458a2018-08-30 14:02:02 +0300710 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Olli Etuahod310a432018-08-24 15:40:23 +0300711 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300712 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
Olli Etuahod310a432018-08-24 15:40:23 +0300713 EXPECT_GL_ERROR(GL_INVALID_ENUM);
714
Olli Etuaho064458a2018-08-30 14:02:02 +0300715 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES is 0.
716 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 1);
Olli Etuahod310a432018-08-24 15:40:23 +0300717 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
718}
719
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300720// Test a valid TexStorage3DMultisample call and check that the queried texture level parameters
721// match. Does not do any drawing.
722TEST_P(TextureMultisampleArrayWebGLTest, TexStorage3DMultisample)
723{
724 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
725
726 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300727 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300728 &maxSamplesRGBA8);
729
Olli Etuaho064458a2018-08-30 14:02:02 +0300730 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300731 ASSERT_GL_NO_ERROR();
732
Olli Etuaho064458a2018-08-30 14:02:02 +0300733 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 8,
734 4, 2, GL_TRUE);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300735 ASSERT_GL_NO_ERROR();
736
737 GLint width = 0, height = 0, depth = 0, samples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300738 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_WIDTH, &width);
739 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_HEIGHT, &height);
740 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_DEPTH, &depth);
741 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_SAMPLES, &samples);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300742 ASSERT_GL_NO_ERROR();
743
744 EXPECT_EQ(8, width);
745 EXPECT_EQ(4, height);
746 EXPECT_EQ(2, depth);
747 EXPECT_EQ(maxSamplesRGBA8, samples);
748}
749
Olli Etuaho064458a2018-08-30 14:02:02 +0300750// Test for invalid FramebufferTextureLayer calls with GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES
Olli Etuahofd162102018-08-27 16:14:57 +0300751// textures.
752TEST_P(TextureMultisampleArrayWebGLTest, InvalidFramebufferTextureLayer)
753{
754 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
755
756 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300757 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahofd162102018-08-27 16:14:57 +0300758 &maxSamplesRGBA8);
759
760 GLint maxArrayTextureLayers;
761 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
762
763 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300764 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
765 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 4,
766 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300767 ASSERT_GL_NO_ERROR();
768
769 // Test with mip level 1 and -1 (only level 0 is valid for multisample textures).
770 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
771 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 1, 0);
772 EXPECT_GL_ERROR(GL_INVALID_VALUE);
773 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, -1, 0);
774 EXPECT_GL_ERROR(GL_INVALID_VALUE);
775
776 // Test with layer -1 and layer == MAX_ARRAY_TEXTURE_LAYERS
777 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
778 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, -1);
779 EXPECT_GL_ERROR(GL_INVALID_VALUE);
780 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0,
781 maxArrayTextureLayers);
782 EXPECT_GL_ERROR(GL_INVALID_VALUE);
783}
784
785// Attach layers of TEXTURE_2D_MULTISAMPLE_ARRAY textures to a framebuffer and check for
786// completeness.
787TEST_P(TextureMultisampleArrayWebGLTest, FramebufferCompleteness)
788{
789 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
790
791 std::vector<GLenum> testFormats = {{GL_RGBA8, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8}};
Olli Etuaho064458a2018-08-30 14:02:02 +0300792 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300793
794 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300795 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
796 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8, 4, 4,
797 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300798 ASSERT_GL_NO_ERROR();
799
800 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
801 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
802 ASSERT_GL_NO_ERROR();
803
804 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
805 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
806
807 // Test framebuffer status with both color and depth textures attached.
808 GLTexture depthTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300809 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthTexture);
810 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
811 GL_DEPTH_COMPONENT24, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300812 ASSERT_GL_NO_ERROR();
813
814 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0);
815 ASSERT_GL_NO_ERROR();
816
817 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
818 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
819
820 // Test with color and depth/stencil textures attached.
821 GLTexture depthStencilTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300822 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthStencilTexture);
823 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
824 GL_DEPTH24_STENCIL8, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300825 ASSERT_GL_NO_ERROR();
826
827 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0,
828 0);
829 ASSERT_GL_NO_ERROR();
830
831 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
832 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
833}
834
835// Attach a layer of TEXTURE_2D_MULTISAMPLE_ARRAY texture to a framebuffer, clear it, and resolve by
836// blitting.
837TEST_P(TextureMultisampleArrayWebGLTest, FramebufferColorClearAndBlit)
838{
839 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
840
841 const GLsizei kWidth = 4;
842 const GLsizei kHeight = 4;
843
844 std::vector<GLenum> testFormats = {GL_RGBA8};
Olli Etuaho064458a2018-08-30 14:02:02 +0300845 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300846
Olli Etuaho064458a2018-08-30 14:02:02 +0300847 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
848 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
849 kWidth, kHeight, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300850
851 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
852 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
853
854 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
855 ASSERT_GL_NO_ERROR();
856 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
857
858 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
859 glClear(GL_COLOR_BUFFER_BIT);
860
861 GLFramebuffer resolveFramebuffer;
862 GLTexture resolveTexture;
863 glBindTexture(GL_TEXTURE_2D, resolveTexture);
864 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
865 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
866 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
867 0);
868 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
869 GL_NEAREST);
870 ASSERT_GL_NO_ERROR();
871
872 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFramebuffer);
873 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
874}
875
Olli Etuahodff32a02018-08-28 14:35:50 +0300876// Check the size of a multisample array texture in a shader.
877TEST_P(TextureMultisampleArrayWebGLTest, TextureSizeInShader)
878{
879 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
880
881 const std::string &fragmentShader = R"(#version 310 es
882 #extension GL_OES_texture_storage_multisample_2d_array : require
883
884 uniform highp sampler2DMSArray tex;
885 out highp vec4 my_FragColor;
886
887 void main() {
888 my_FragColor = (textureSize(tex) == ivec3(8, 4, 2)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
889 }
890 )";
891
892 ANGLE_GL_PROGRAM(texSizeProgram, essl31_shaders::vs::Simple(), fragmentShader);
893
894 GLint texLocation = glGetUniformLocation(texSizeProgram, "tex");
895 ASSERT_GE(texLocation, 0);
896
897 const GLsizei kWidth = 8;
898 const GLsizei kHeight = 4;
899
900 std::vector<GLenum> testFormats = {GL_RGBA8};
901 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
902
903 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
904 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
905 kWidth, kHeight, 2, GL_TRUE);
906 ASSERT_GL_NO_ERROR();
907
908 drawQuad(texSizeProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
909 ASSERT_GL_NO_ERROR();
910
911 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
912}
913
914// Clear the layers of a multisample array texture, and then sample all the samples from all the
915// layers in a shader.
916TEST_P(TextureMultisampleArrayWebGLTest, SimpleTexelFetch)
917{
918 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
919
920 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
921 blitArrayTextureLayerFragmentShader());
922
923 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
924 ASSERT_GE(texLocation, 0);
925 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
926 ASSERT_GE(layerLocation, 0);
927 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
928 ASSERT_GE(layerLocation, 0);
929
930 const GLsizei kWidth = 4;
931 const GLsizei kHeight = 4;
932 const GLsizei kLayerCount = 2;
933
934 std::vector<GLenum> testFormats = {GL_RGBA8};
935 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
936
937 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
938 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
939 kWidth, kHeight, kLayerCount, GL_TRUE);
940 ASSERT_GL_NO_ERROR();
941
942 // Clear layer zero to green and layer one to blue.
943 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
944 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
945 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
946 {
947 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
948 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
949 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
950 const GLColor &clearColor = clearColors[i];
951 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
952 clearColor.A / 255.0f);
953 glClear(GL_COLOR_BUFFER_BIT);
954 ASSERT_GL_NO_ERROR();
955 }
956
957 glBindFramebuffer(GL_FRAMEBUFFER, 0);
958 glUseProgram(texelFetchProgram);
959 glViewport(0, 0, kWidth, kHeight);
960 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
961 {
962 glUniform1i(layerLocation, layer);
963 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
964 {
965 glUniform1i(sampleNumLocation, sampleNum);
966 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
967 ASSERT_GL_NO_ERROR();
968 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
969 }
970 }
971}
972
973// Clear the layers of an integer multisample array texture, and then sample all the samples from
974// all the layers in a shader.
975TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
976{
977 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
978
979 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
980 blitIntArrayTextureLayerFragmentShader());
981
982 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
983 ASSERT_GE(texLocation, 0);
984 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
985 ASSERT_GE(layerLocation, 0);
986 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
987 ASSERT_GE(layerLocation, 0);
988
989 const GLsizei kWidth = 4;
990 const GLsizei kHeight = 4;
991 const GLsizei kLayerCount = 2;
992
993 std::vector<GLenum> testFormats = {GL_RGBA8I};
994 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
995
996 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
997 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8I,
998 kWidth, kHeight, kLayerCount, GL_TRUE);
999 ASSERT_GL_NO_ERROR();
1000
1001 // Clear layer zero to green and layer one to blue.
1002 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
1003 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
1004 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
1005 {
1006 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
1007 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1008 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
1009 std::array<GLint, 4> intColor;
1010 for (size_t j = 0; j < intColor.size(); ++j)
1011 {
1012 intColor[j] = clearColors[i][j] / 255;
1013 }
1014 glClearBufferiv(GL_COLOR, 0, intColor.data());
1015 ASSERT_GL_NO_ERROR();
1016 }
1017
1018 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1019 glUseProgram(texelFetchProgram);
1020 glViewport(0, 0, kWidth, kHeight);
1021 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
1022 {
1023 glUniform1i(layerLocation, layer);
1024 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
1025 {
1026 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1027 glClear(GL_COLOR_BUFFER_BIT);
1028 glUniform1i(sampleNumLocation, sampleNum);
1029 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1030 ASSERT_GL_NO_ERROR();
1031 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
1032 }
1033 }
1034}
1035
JiangYizhoubddc46b2016-12-09 09:50:51 +08001036ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
Yizhou Jiang7818a852018-09-06 15:02:04 +08001037 ES3_D3D11(),
JiangYizhou34bc3152017-03-29 14:56:01 +08001038 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +08001039 ES3_OPENGL(),
1040 ES3_OPENGLES(),
1041 ES31_OPENGL(),
1042 ES31_OPENGLES());
Yizhou Jiang7818a852018-09-06 15:02:04 +08001043ANGLE_INSTANTIATE_TEST(NegativeTextureMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +03001044ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
1045 ES31_D3D11(),
1046 ES31_OPENGL(),
1047 ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +03001048} // anonymous namespace