blob: f1da15ffa70ad7d57e8f6e389f3d29f5dca47b93 [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
JiangYizhoubddc46b2016-12-09 09:50:51 +080075 GLuint mFramebuffer = 0;
76 GLuint mTexture = 0;
Olli Etuahofd162102018-08-27 16:14:57 +030077
78 // Returns a sample count that can be used with the given texture target for all the given
79 // formats. Assumes that if format A supports a number of samples N and another format B
80 // supports a number of samples M > N then format B also supports number of samples N.
81 GLint getSamplesToUse(GLenum texTarget, const std::vector<GLenum> &formats)
82 {
83 GLint maxSamples = 65536;
84 for (GLenum format : formats)
85 {
86 GLint maxSamplesFormat = 0;
87 glGetInternalformativ(texTarget, format, GL_SAMPLES, 1, &maxSamplesFormat);
88 maxSamples = std::min(maxSamples, maxSamplesFormat);
89 }
90 return maxSamples;
91 }
Olli Etuahodff32a02018-08-28 14:35:50 +030092
Yizhou Jiang7818a852018-09-06 15:02:04 +080093 bool lessThanES31MultisampleExtNotSupported()
94 {
95 return getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
96 !ensureExtensionEnabled("GL_ANGLE_texture_multisample");
97 }
98
99 const char *multisampleTextureFragmentShader()
100 {
101 return R"(#version 300 es
102#extension GL_ANGLE_texture_multisample : require
103precision highp float;
104precision highp int;
105
106uniform highp sampler2DMS tex;
107uniform int sampleNum;
108
109in vec4 v_position;
110out vec4 my_FragColor;
111
112void main() {
113 ivec2 texSize = textureSize(tex);
114 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
115 my_FragColor = texelFetch(tex, sampleCoords, sampleNum);
116}
117)";
118 };
119
Olli Etuahodff32a02018-08-28 14:35:50 +0300120 const char *blitArrayTextureLayerFragmentShader()
121 {
122 return R"(#version 310 es
123#extension GL_OES_texture_storage_multisample_2d_array : require
124precision highp float;
125precision highp int;
126
127uniform highp sampler2DMSArray tex;
128uniform int layer;
129uniform int sampleNum;
130
131in vec4 v_position;
132out vec4 my_FragColor;
133
134void main() {
135 ivec3 texSize = textureSize(tex);
136 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
137 my_FragColor = texelFetch(tex, ivec3(sampleCoords, layer), sampleNum);
138}
139)";
140 };
141
142 const char *blitIntArrayTextureLayerFragmentShader()
143 {
144 return R"(#version 310 es
145#extension GL_OES_texture_storage_multisample_2d_array : require
146precision highp float;
147precision highp int;
148
149uniform highp isampler2DMSArray tex;
150uniform int layer;
151uniform int sampleNum;
152
153in vec4 v_position;
154out vec4 my_FragColor;
155
156void main() {
157 ivec3 texSize = textureSize(tex);
158 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
159 my_FragColor = vec4(texelFetch(tex, ivec3(sampleCoords, layer), sampleNum));
160}
161)";
162 };
JiangYizhoubddc46b2016-12-09 09:50:51 +0800163};
164
Yizhou Jiang7818a852018-09-06 15:02:04 +0800165class NegativeTextureMultisampleTest : public TextureMultisampleTest
JiangYizhoubddc46b2016-12-09 09:50:51 +0800166{
167 protected:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800168 NegativeTextureMultisampleTest() : TextureMultisampleTest() {}
JiangYizhoubddc46b2016-12-09 09:50:51 +0800169};
170
Olli Etuahod310a432018-08-24 15:40:23 +0300171class TextureMultisampleArrayWebGLTest : public TextureMultisampleTest
172{
173 protected:
174 TextureMultisampleArrayWebGLTest() : TextureMultisampleTest()
175 {
176 // These tests run in WebGL mode so we can test with both extension off and on.
177 setWebGLCompatibilityEnabled(true);
178 }
179
180 // Requests the ANGLE_texture_multisample_array extension and returns true if the operation
181 // succeeds.
182 bool requestArrayExtension()
183 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300184 if (extensionRequestable("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300185 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300186 glRequestExtensionANGLE("GL_OES_texture_storage_multisample_2d_array");
Olli Etuahod310a432018-08-24 15:40:23 +0300187 }
188
Olli Etuaho064458a2018-08-30 14:02:02 +0300189 if (!extensionEnabled("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300190 {
191 return false;
192 }
193 return true;
194 }
195};
196
Yizhou Jiang7818a852018-09-06 15:02:04 +0800197void TextureMultisampleTest::texStorageMultisample(GLenum target,
198 GLint samples,
199 GLenum internalformat,
200 GLsizei width,
201 GLsizei height,
202 GLboolean fixedsamplelocations)
203{
204 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
205 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
206 {
207 glTexStorage2DMultisampleANGLE(target, samples, internalformat, width, height,
208 fixedsamplelocations);
209 }
210 else
211 {
212 glTexStorage2DMultisample(target, samples, internalformat, width, height,
213 fixedsamplelocations);
214 }
215}
216
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800217void TextureMultisampleTest::getTexLevelParameterfv(GLenum target,
218 GLint level,
219 GLenum pname,
220 GLfloat *params)
221{
222 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
223 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
224 {
225 glGetTexLevelParameterfvANGLE(target, level, pname, params);
226 }
227 else
228 {
229 glGetTexLevelParameterfv(target, level, pname, params);
230 }
231}
232void TextureMultisampleTest::getTexLevelParameteriv(GLenum target,
233 GLint level,
234 GLenum pname,
235 GLint *params)
236{
237 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
238 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
239 {
240 glGetTexLevelParameterivANGLE(target, level, pname, params);
241 }
242 else
243 {
244 glGetTexLevelParameteriv(target, level, pname, params);
245 }
246}
247
JiangYizhoubddc46b2016-12-09 09:50:51 +0800248// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
Olli Etuahod310a432018-08-24 15:40:23 +0300249// GetInternalformativ. Checks that the number of samples returned is valid in case of ES >= 3.1.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800250TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
251{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800252 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
253
Olli Etuahod310a432018-08-24 15:40:23 +0300254 // This query returns supported sample counts in descending order. If only one sample count is
255 // queried, it should be the maximum one.
256 GLint maxSamplesR8 = 0;
257 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamplesR8);
Olli Etuahod310a432018-08-24 15:40:23 +0300258
Yizhou Jiang7818a852018-09-06 15:02:04 +0800259 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
260 GLint maxColorTextureSamples;
261 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
262 GLint maxSamples;
263 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
264 GLint maxSamplesR8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300265
Yizhou Jiang7818a852018-09-06 15:02:04 +0800266 EXPECT_GE(maxSamplesR8, maxSamplesR8Required);
267 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800268}
269
Yizhou Jiang7818a852018-09-06 15:02:04 +0800270// Tests that if es version < 3.1 and multisample extension is unsupported,
271// GL_TEXTURE_2D_MULTISAMPLE_ANGLE is not supported in FramebufferTexture2D.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800272TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
273{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800274 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
JiangYizhoubddc46b2016-12-09 09:50:51 +0800275 GLint samples = 1;
276 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800277 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800278
279 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
280 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
281 mTexture, 0);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800282
Yizhou Jiang7818a852018-09-06 15:02:04 +0800283 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800284}
285
286// Tests basic functionality of glTexStorage2DMultisample.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800287TEST_P(TextureMultisampleTest, ValidateTextureStorageMultisampleParameters)
JiangYizhoubddc46b2016-12-09 09:50:51 +0800288{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800289 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
290
JiangYizhoubddc46b2016-12-09 09:50:51 +0800291 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800292 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhou461d9a32017-01-04 16:37:26 +0800293 ASSERT_GL_NO_ERROR();
294
JiangYizhoubddc46b2016-12-09 09:50:51 +0800295 GLint params = 0;
296 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
297 EXPECT_EQ(1, params);
298
Yizhou Jiang7818a852018-09-06 15:02:04 +0800299 texStorageMultisample(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800300 ASSERT_GL_ERROR(GL_INVALID_ENUM);
301
Yizhou Jiang7818a852018-09-06 15:02:04 +0800302 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800303 ASSERT_GL_ERROR(GL_INVALID_VALUE);
304
305 GLint maxSize = 0;
306 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800307 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, maxSize + 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800308 ASSERT_GL_ERROR(GL_INVALID_VALUE);
309
310 GLint maxSamples = 0;
311 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800312 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples + 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800313 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
314
Yizhou Jiang7818a852018-09-06 15:02:04 +0800315 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800316 ASSERT_GL_ERROR(GL_INVALID_VALUE);
317
Yizhou Jiang7818a852018-09-06 15:02:04 +0800318 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800319 ASSERT_GL_ERROR(GL_INVALID_VALUE);
320
321 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800322 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800323 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
324}
325
Shao5116d682017-08-02 12:39:44 +0800326// Tests the value of MAX_INTEGER_SAMPLES is no less than 1.
327// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800328TEST_P(TextureMultisampleTest, MaxIntegerSamples)
Shao5116d682017-08-02 12:39:44 +0800329{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800330 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800331 GLint maxIntegerSamples;
332 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &maxIntegerSamples);
333 EXPECT_GE(maxIntegerSamples, 1);
334 EXPECT_NE(std::numeric_limits<GLint>::max(), maxIntegerSamples);
335}
336
337// Tests the value of MAX_COLOR_TEXTURE_SAMPLES is no less than 1.
338// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800339TEST_P(TextureMultisampleTest, MaxColorTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800340{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800341 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800342 GLint maxColorTextureSamples;
343 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
344 EXPECT_GE(maxColorTextureSamples, 1);
345 EXPECT_NE(std::numeric_limits<GLint>::max(), maxColorTextureSamples);
346}
347
348// Tests the value of MAX_DEPTH_TEXTURE_SAMPLES is no less than 1.
349// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800350TEST_P(TextureMultisampleTest, MaxDepthTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800351{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800352 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800353 GLint maxDepthTextureSamples;
354 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
355 EXPECT_GE(maxDepthTextureSamples, 1);
356 EXPECT_NE(std::numeric_limits<GLint>::max(), maxDepthTextureSamples);
357}
358
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800359// Tests that getTexLevelParameter is supported by ES 3.1 or ES 3.0 and ANGLE_texture_multisample
360TEST_P(TextureMultisampleTest, GetTexLevelParameter)
361{
362 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
363
364 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
365 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 1, 1, GL_TRUE);
366 ASSERT_GL_NO_ERROR();
367
368 GLfloat levelSamples = 0;
369 getTexLevelParameterfv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &levelSamples);
370 EXPECT_EQ(levelSamples, 4);
371
372 GLint fixedSampleLocation = false;
373 getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
374 &fixedSampleLocation);
375 EXPECT_EQ(fixedSampleLocation, 1);
376
377 ASSERT_GL_NO_ERROR();
378}
379
Jiang0e1224c2017-12-26 14:11:15 +0800380// The value of sample position should be equal to standard pattern on D3D.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800381TEST_P(TextureMultisampleTest, CheckSamplePositions)
Jiang0e1224c2017-12-26 14:11:15 +0800382{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800383 ANGLE_SKIP_TEST_IF(!IsD3D11() || (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1));
Jiang0e1224c2017-12-26 14:11:15 +0800384
385 GLsizei maxSamples = 0;
386 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
387
388 GLfloat samplePosition[2];
389
390 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
391
392 for (int sampleCount = 1; sampleCount <= maxSamples; sampleCount++)
393 {
394 GLTexture texture;
395 size_t indexKey = static_cast<size_t>(ceil(log2(sampleCount)));
396 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
397 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, 1, 1, GL_TRUE);
398 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
399 texture, 0);
400 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
401 ASSERT_GL_NO_ERROR();
402
403 for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
404 {
405 glGetMultisamplefv(GL_SAMPLE_POSITION, sampleIndex, samplePosition);
406 EXPECT_EQ(samplePosition[0], kSamplePositions[indexKey][2 * sampleIndex]);
407 EXPECT_EQ(samplePosition[1], kSamplePositions[indexKey][2 * sampleIndex + 1]);
408 }
409 }
410
411 ASSERT_GL_NO_ERROR();
412}
413
Yizhou Jiang7818a852018-09-06 15:02:04 +0800414// Test textureSize and texelFetch when using ANGLE_texture_multisample extension
415TEST_P(TextureMultisampleTest, SimpleTexelFetch)
416{
417 ANGLE_SKIP_TEST_IF(IsD3D11());
418 ANGLE_SKIP_TEST_IF(!ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
419
420 ANGLE_GL_PROGRAM(texelFetchProgram, essl3_shaders::vs::Passthrough(),
421 multisampleTextureFragmentShader());
422
423 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
424 ASSERT_GE(texLocation, 0);
425 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
426 ASSERT_GE(sampleNumLocation, 0);
427
428 const GLsizei kWidth = 4;
429 const GLsizei kHeight = 4;
430
431 std::vector<GLenum> testFormats = {GL_RGBA8};
432 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, testFormats);
433
434 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, mTexture);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800435 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, samplesToUse, GL_RGBA8, kWidth, kHeight,
436 GL_TRUE);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800437 ASSERT_GL_NO_ERROR();
438
439 // Clear texture zero to green.
440 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
441 GLColor clearColor = GLColor::green;
442
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800443 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE_ANGLE,
444 mTexture, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800445 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
446 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
447 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
448 clearColor.A / 255.0f);
449 glClear(GL_COLOR_BUFFER_BIT);
450 ASSERT_GL_NO_ERROR();
451
452 glBindFramebuffer(GL_FRAMEBUFFER, 0);
453 glUseProgram(texelFetchProgram);
454 glViewport(0, 0, kWidth, kHeight);
455
456 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
457 {
458 glUniform1i(sampleNumLocation, sampleNum);
459 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
460 ASSERT_GL_NO_ERROR();
461 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColor);
462 }
463}
464
465// Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample
466// not enabled, the feature isn't supported.
467TEST_P(NegativeTextureMultisampleTest, Negtive)
468{
469 ANGLE_SKIP_TEST_IF(ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
470
471 GLint maxSamples = 0;
472 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
473 ASSERT_GL_ERROR(GL_INVALID_ENUM);
474
475 GLint maxColorTextureSamples;
476 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
477 ASSERT_GL_ERROR(GL_INVALID_ENUM);
478
479 GLint maxDepthTextureSamples;
480 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
481 ASSERT_GL_ERROR(GL_INVALID_ENUM);
482
483 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
484 ASSERT_GL_ERROR(GL_INVALID_ENUM);
485
486 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 64, 64, GL_FALSE);
487 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
488
489 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
490 mTexture, 0);
491 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
492
493 GLint params = 0;
494 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
495 ASSERT_GL_ERROR(GL_INVALID_ENUM);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800496
497 GLfloat levelSamples = 0;
498 getTexLevelParameterfv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &levelSamples);
499 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
500
501 GLint fixedSampleLocation = false;
502 getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
503 &fixedSampleLocation);
504 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800505}
506
Olli Etuahod310a432018-08-24 15:40:23 +0300507// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
508// extension is not supported.
509TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
510{
511 GLint maxSamples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300512 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300513 &maxSamples);
514 ASSERT_GL_ERROR(GL_INVALID_ENUM);
515}
516
517// Attempt to bind a texture to multisample array binding point when extension is not supported.
518TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
519{
Olli Etuaho064458a2018-08-30 14:02:02 +0300520 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300521 ASSERT_GL_ERROR(GL_INVALID_ENUM);
522}
523
Olli Etuahodff32a02018-08-28 14:35:50 +0300524// Try to compile shaders using GL_OES_texture_storage_multisample_2d_array when the extension is
525// not enabled.
526TEST_P(TextureMultisampleArrayWebGLTest, ShaderWithoutExtension)
527{
528 const std::string &fragmentShaderRequireExtension = R"(#version 310 es
529 #extension GL_OES_texture_storage_multisample_2d_array : require
530 out highp vec4 my_FragColor;
531
532 void main() {
533 my_FragColor = vec4(0.0);
534 }
535 )";
536
537 GLuint program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderRequireExtension);
538 EXPECT_EQ(0u, program);
539
540 const std::string &fragmentShaderEnableAndUseExtension = R"(#version 310 es
541 #extension GL_OES_texture_storage_multisample_2d_array : enable
542
543 uniform highp sampler2DMSArray tex;
544 out highp ivec4 outSize;
545
546 void main() {
547 outSize = ivec4(textureSize(tex), 0);
548 }
549 )";
550
551 program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderEnableAndUseExtension);
552 EXPECT_EQ(0u, program);
553}
554
Olli Etuahod310a432018-08-24 15:40:23 +0300555// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
556TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
557{
558 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
559
560 // This query returns supported sample counts in descending order. If only one sample count is
561 // queried, it should be the maximum one.
562 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300563 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300564 &maxSamplesRGBA8);
Olli Etuahofd162102018-08-27 16:14:57 +0300565 GLint maxSamplesDepth = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300566 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_DEPTH_COMPONENT24, GL_SAMPLES, 1,
567 &maxSamplesDepth);
Olli Etuahod310a432018-08-24 15:40:23 +0300568 ASSERT_GL_NO_ERROR();
569
570 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
571 GLint maxColorTextureSamples;
572 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
Olli Etuahofd162102018-08-27 16:14:57 +0300573 GLint maxDepthTextureSamples;
574 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300575 GLint maxSamples;
576 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300577
Olli Etuahofd162102018-08-27 16:14:57 +0300578 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300579 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
Olli Etuahofd162102018-08-27 16:14:57 +0300580
581 GLint maxSamplesDepthRequired = std::min(maxDepthTextureSamples, maxSamples);
582 EXPECT_GE(maxSamplesDepth, maxSamplesDepthRequired);
Olli Etuahod310a432018-08-24 15:40:23 +0300583}
584
585// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
586TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
587{
588 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
589
Olli Etuaho064458a2018-08-30 14:02:02 +0300590 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300591 ASSERT_GL_NO_ERROR();
592
Olli Etuaho064458a2018-08-30 14:02:02 +0300593 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
Olli Etuahod310a432018-08-24 15:40:23 +0300594 GL_UNSIGNED_BYTE, nullptr);
595 EXPECT_GL_ERROR(GL_INVALID_ENUM);
596}
597
598// Tests passing invalid parameters to TexStorage3DMultisample.
599TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
600{
601 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
602
Olli Etuaho064458a2018-08-30 14:02:02 +0300603 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300604 ASSERT_GL_NO_ERROR();
605
606 // Invalid target
Olli Etuaho064458a2018-08-30 14:02:02 +0300607 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300608 EXPECT_GL_ERROR(GL_INVALID_ENUM);
609
610 // Samples 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300611 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1,
612 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300613 EXPECT_GL_ERROR(GL_INVALID_VALUE);
614
615 // Unsized internalformat
Olli Etuaho064458a2018-08-30 14:02:02 +0300616 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300617 EXPECT_GL_ERROR(GL_INVALID_ENUM);
618
619 // Width 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300620 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 0, 1, 1,
621 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300622 EXPECT_GL_ERROR(GL_INVALID_VALUE);
623
624 // Height 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300625 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 0, 1,
626 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300627 EXPECT_GL_ERROR(GL_INVALID_VALUE);
628
629 // Depth 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300630 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 1, 0,
631 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300632 EXPECT_GL_ERROR(GL_INVALID_VALUE);
633}
634
635// Tests passing invalid parameters to TexParameteri.
636TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
637{
638 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
639
Olli Etuaho064458a2018-08-30 14:02:02 +0300640 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300641 ASSERT_GL_NO_ERROR();
642
Olli Etuaho064458a2018-08-30 14:02:02 +0300643 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES.
644 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300645 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300646 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300647 EXPECT_GL_ERROR(GL_INVALID_ENUM);
648
Olli Etuaho064458a2018-08-30 14:02:02 +0300649 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300650 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300651 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300652 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300653 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300654 EXPECT_GL_ERROR(GL_INVALID_ENUM);
655
Olli Etuaho064458a2018-08-30 14:02:02 +0300656 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300657 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300658 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAX_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300659 EXPECT_GL_ERROR(GL_INVALID_ENUM);
660
Olli Etuaho064458a2018-08-30 14:02:02 +0300661 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Olli Etuahod310a432018-08-24 15:40:23 +0300662 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300663 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
Olli Etuahod310a432018-08-24 15:40:23 +0300664 EXPECT_GL_ERROR(GL_INVALID_ENUM);
665
Olli Etuaho064458a2018-08-30 14:02:02 +0300666 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES is 0.
667 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 1);
Olli Etuahod310a432018-08-24 15:40:23 +0300668 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
669}
670
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300671// Test a valid TexStorage3DMultisample call and check that the queried texture level parameters
672// match. Does not do any drawing.
673TEST_P(TextureMultisampleArrayWebGLTest, TexStorage3DMultisample)
674{
675 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
676
677 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300678 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300679 &maxSamplesRGBA8);
680
Olli Etuaho064458a2018-08-30 14:02:02 +0300681 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300682 ASSERT_GL_NO_ERROR();
683
Olli Etuaho064458a2018-08-30 14:02:02 +0300684 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 8,
685 4, 2, GL_TRUE);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300686 ASSERT_GL_NO_ERROR();
687
688 GLint width = 0, height = 0, depth = 0, samples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300689 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_WIDTH, &width);
690 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_HEIGHT, &height);
691 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_DEPTH, &depth);
692 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_SAMPLES, &samples);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300693 ASSERT_GL_NO_ERROR();
694
695 EXPECT_EQ(8, width);
696 EXPECT_EQ(4, height);
697 EXPECT_EQ(2, depth);
698 EXPECT_EQ(maxSamplesRGBA8, samples);
699}
700
Olli Etuaho064458a2018-08-30 14:02:02 +0300701// Test for invalid FramebufferTextureLayer calls with GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES
Olli Etuahofd162102018-08-27 16:14:57 +0300702// textures.
703TEST_P(TextureMultisampleArrayWebGLTest, InvalidFramebufferTextureLayer)
704{
705 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
706
707 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300708 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahofd162102018-08-27 16:14:57 +0300709 &maxSamplesRGBA8);
710
711 GLint maxArrayTextureLayers;
712 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
713
714 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300715 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
716 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 4,
717 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300718 ASSERT_GL_NO_ERROR();
719
720 // Test with mip level 1 and -1 (only level 0 is valid for multisample textures).
721 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
722 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 1, 0);
723 EXPECT_GL_ERROR(GL_INVALID_VALUE);
724 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, -1, 0);
725 EXPECT_GL_ERROR(GL_INVALID_VALUE);
726
727 // Test with layer -1 and layer == MAX_ARRAY_TEXTURE_LAYERS
728 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
729 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, -1);
730 EXPECT_GL_ERROR(GL_INVALID_VALUE);
731 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0,
732 maxArrayTextureLayers);
733 EXPECT_GL_ERROR(GL_INVALID_VALUE);
734}
735
736// Attach layers of TEXTURE_2D_MULTISAMPLE_ARRAY textures to a framebuffer and check for
737// completeness.
738TEST_P(TextureMultisampleArrayWebGLTest, FramebufferCompleteness)
739{
740 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
741
742 std::vector<GLenum> testFormats = {{GL_RGBA8, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8}};
Olli Etuaho064458a2018-08-30 14:02:02 +0300743 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300744
745 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300746 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
747 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8, 4, 4,
748 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300749 ASSERT_GL_NO_ERROR();
750
751 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
752 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
753 ASSERT_GL_NO_ERROR();
754
755 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
756 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
757
758 // Test framebuffer status with both color and depth textures attached.
759 GLTexture depthTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300760 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthTexture);
761 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
762 GL_DEPTH_COMPONENT24, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300763 ASSERT_GL_NO_ERROR();
764
765 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0);
766 ASSERT_GL_NO_ERROR();
767
768 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
769 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
770
771 // Test with color and depth/stencil textures attached.
772 GLTexture depthStencilTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300773 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthStencilTexture);
774 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
775 GL_DEPTH24_STENCIL8, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300776 ASSERT_GL_NO_ERROR();
777
778 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0,
779 0);
780 ASSERT_GL_NO_ERROR();
781
782 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
783 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
784}
785
786// Attach a layer of TEXTURE_2D_MULTISAMPLE_ARRAY texture to a framebuffer, clear it, and resolve by
787// blitting.
788TEST_P(TextureMultisampleArrayWebGLTest, FramebufferColorClearAndBlit)
789{
790 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
791
792 const GLsizei kWidth = 4;
793 const GLsizei kHeight = 4;
794
795 std::vector<GLenum> testFormats = {GL_RGBA8};
Olli Etuaho064458a2018-08-30 14:02:02 +0300796 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300797
Olli Etuaho064458a2018-08-30 14:02:02 +0300798 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
799 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
800 kWidth, kHeight, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300801
802 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
803 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
804
805 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
806 ASSERT_GL_NO_ERROR();
807 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
808
809 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
810 glClear(GL_COLOR_BUFFER_BIT);
811
812 GLFramebuffer resolveFramebuffer;
813 GLTexture resolveTexture;
814 glBindTexture(GL_TEXTURE_2D, resolveTexture);
815 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
816 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
817 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
818 0);
819 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
820 GL_NEAREST);
821 ASSERT_GL_NO_ERROR();
822
823 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFramebuffer);
824 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
825}
826
Olli Etuahodff32a02018-08-28 14:35:50 +0300827// Check the size of a multisample array texture in a shader.
828TEST_P(TextureMultisampleArrayWebGLTest, TextureSizeInShader)
829{
830 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
831
832 const std::string &fragmentShader = R"(#version 310 es
833 #extension GL_OES_texture_storage_multisample_2d_array : require
834
835 uniform highp sampler2DMSArray tex;
836 out highp vec4 my_FragColor;
837
838 void main() {
839 my_FragColor = (textureSize(tex) == ivec3(8, 4, 2)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
840 }
841 )";
842
843 ANGLE_GL_PROGRAM(texSizeProgram, essl31_shaders::vs::Simple(), fragmentShader);
844
845 GLint texLocation = glGetUniformLocation(texSizeProgram, "tex");
846 ASSERT_GE(texLocation, 0);
847
848 const GLsizei kWidth = 8;
849 const GLsizei kHeight = 4;
850
851 std::vector<GLenum> testFormats = {GL_RGBA8};
852 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
853
854 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
855 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
856 kWidth, kHeight, 2, GL_TRUE);
857 ASSERT_GL_NO_ERROR();
858
859 drawQuad(texSizeProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
860 ASSERT_GL_NO_ERROR();
861
862 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
863}
864
865// Clear the layers of a multisample array texture, and then sample all the samples from all the
866// layers in a shader.
867TEST_P(TextureMultisampleArrayWebGLTest, SimpleTexelFetch)
868{
869 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
870
871 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
872 blitArrayTextureLayerFragmentShader());
873
874 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
875 ASSERT_GE(texLocation, 0);
876 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
877 ASSERT_GE(layerLocation, 0);
878 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
879 ASSERT_GE(layerLocation, 0);
880
881 const GLsizei kWidth = 4;
882 const GLsizei kHeight = 4;
883 const GLsizei kLayerCount = 2;
884
885 std::vector<GLenum> testFormats = {GL_RGBA8};
886 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
887
888 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
889 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
890 kWidth, kHeight, kLayerCount, GL_TRUE);
891 ASSERT_GL_NO_ERROR();
892
893 // Clear layer zero to green and layer one to blue.
894 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
895 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
896 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
897 {
898 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
899 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
900 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
901 const GLColor &clearColor = clearColors[i];
902 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
903 clearColor.A / 255.0f);
904 glClear(GL_COLOR_BUFFER_BIT);
905 ASSERT_GL_NO_ERROR();
906 }
907
908 glBindFramebuffer(GL_FRAMEBUFFER, 0);
909 glUseProgram(texelFetchProgram);
910 glViewport(0, 0, kWidth, kHeight);
911 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
912 {
913 glUniform1i(layerLocation, layer);
914 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
915 {
916 glUniform1i(sampleNumLocation, sampleNum);
917 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
918 ASSERT_GL_NO_ERROR();
919 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
920 }
921 }
922}
923
924// Clear the layers of an integer multisample array texture, and then sample all the samples from
925// all the layers in a shader.
926TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
927{
928 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
929
930 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
931 blitIntArrayTextureLayerFragmentShader());
932
933 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
934 ASSERT_GE(texLocation, 0);
935 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
936 ASSERT_GE(layerLocation, 0);
937 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
938 ASSERT_GE(layerLocation, 0);
939
940 const GLsizei kWidth = 4;
941 const GLsizei kHeight = 4;
942 const GLsizei kLayerCount = 2;
943
944 std::vector<GLenum> testFormats = {GL_RGBA8I};
945 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
946
947 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
948 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8I,
949 kWidth, kHeight, kLayerCount, GL_TRUE);
950 ASSERT_GL_NO_ERROR();
951
952 // Clear layer zero to green and layer one to blue.
953 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
954 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
955 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
956 {
957 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
958 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
959 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
960 std::array<GLint, 4> intColor;
961 for (size_t j = 0; j < intColor.size(); ++j)
962 {
963 intColor[j] = clearColors[i][j] / 255;
964 }
965 glClearBufferiv(GL_COLOR, 0, intColor.data());
966 ASSERT_GL_NO_ERROR();
967 }
968
969 glBindFramebuffer(GL_FRAMEBUFFER, 0);
970 glUseProgram(texelFetchProgram);
971 glViewport(0, 0, kWidth, kHeight);
972 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
973 {
974 glUniform1i(layerLocation, layer);
975 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
976 {
977 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
978 glClear(GL_COLOR_BUFFER_BIT);
979 glUniform1i(sampleNumLocation, sampleNum);
980 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
981 ASSERT_GL_NO_ERROR();
982 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
983 }
984 }
985}
986
JiangYizhoubddc46b2016-12-09 09:50:51 +0800987ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
Yizhou Jiang7818a852018-09-06 15:02:04 +0800988 ES3_D3D11(),
JiangYizhou34bc3152017-03-29 14:56:01 +0800989 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +0800990 ES3_OPENGL(),
991 ES3_OPENGLES(),
992 ES31_OPENGL(),
993 ES31_OPENGLES());
Yizhou Jiang7818a852018-09-06 15:02:04 +0800994ANGLE_INSTANTIATE_TEST(NegativeTextureMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300995ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
996 ES31_D3D11(),
997 ES31_OPENGL(),
998 ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300999} // anonymous namespace