blob: 78ecfb4886f5433099b21af60b082658a17d1dab [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{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800417 ANGLE_SKIP_TEST_IF(!ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
418
419 ANGLE_GL_PROGRAM(texelFetchProgram, essl3_shaders::vs::Passthrough(),
420 multisampleTextureFragmentShader());
421
422 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
423 ASSERT_GE(texLocation, 0);
424 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
425 ASSERT_GE(sampleNumLocation, 0);
426
427 const GLsizei kWidth = 4;
428 const GLsizei kHeight = 4;
429
430 std::vector<GLenum> testFormats = {GL_RGBA8};
431 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, testFormats);
432
433 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, mTexture);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800434 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, samplesToUse, GL_RGBA8, kWidth, kHeight,
435 GL_TRUE);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800436 ASSERT_GL_NO_ERROR();
437
438 // Clear texture zero to green.
439 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
440 GLColor clearColor = GLColor::green;
441
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800442 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE_ANGLE,
443 mTexture, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800444 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
445 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
446 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
447 clearColor.A / 255.0f);
448 glClear(GL_COLOR_BUFFER_BIT);
449 ASSERT_GL_NO_ERROR();
450
451 glBindFramebuffer(GL_FRAMEBUFFER, 0);
452 glUseProgram(texelFetchProgram);
453 glViewport(0, 0, kWidth, kHeight);
454
455 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
456 {
457 glUniform1i(sampleNumLocation, sampleNum);
458 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
459 ASSERT_GL_NO_ERROR();
460 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColor);
461 }
462}
463
464// Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample
465// not enabled, the feature isn't supported.
466TEST_P(NegativeTextureMultisampleTest, Negtive)
467{
468 ANGLE_SKIP_TEST_IF(ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
469
470 GLint maxSamples = 0;
471 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
472 ASSERT_GL_ERROR(GL_INVALID_ENUM);
473
474 GLint maxColorTextureSamples;
475 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
476 ASSERT_GL_ERROR(GL_INVALID_ENUM);
477
478 GLint maxDepthTextureSamples;
479 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
480 ASSERT_GL_ERROR(GL_INVALID_ENUM);
481
482 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
483 ASSERT_GL_ERROR(GL_INVALID_ENUM);
484
485 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 64, 64, GL_FALSE);
486 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
487
488 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
489 mTexture, 0);
490 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
491
492 GLint params = 0;
493 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
494 ASSERT_GL_ERROR(GL_INVALID_ENUM);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800495
496 GLfloat levelSamples = 0;
497 getTexLevelParameterfv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &levelSamples);
498 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
499
500 GLint fixedSampleLocation = false;
501 getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS,
502 &fixedSampleLocation);
503 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800504}
505
Olli Etuahod310a432018-08-24 15:40:23 +0300506// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
507// extension is not supported.
508TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
509{
510 GLint maxSamples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300511 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300512 &maxSamples);
513 ASSERT_GL_ERROR(GL_INVALID_ENUM);
514}
515
516// Attempt to bind a texture to multisample array binding point when extension is not supported.
517TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
518{
Olli Etuaho064458a2018-08-30 14:02:02 +0300519 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300520 ASSERT_GL_ERROR(GL_INVALID_ENUM);
521}
522
Olli Etuahodff32a02018-08-28 14:35:50 +0300523// Try to compile shaders using GL_OES_texture_storage_multisample_2d_array when the extension is
524// not enabled.
525TEST_P(TextureMultisampleArrayWebGLTest, ShaderWithoutExtension)
526{
527 const std::string &fragmentShaderRequireExtension = R"(#version 310 es
528 #extension GL_OES_texture_storage_multisample_2d_array : require
529 out highp vec4 my_FragColor;
530
531 void main() {
532 my_FragColor = vec4(0.0);
533 }
534 )";
535
536 GLuint program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderRequireExtension);
537 EXPECT_EQ(0u, program);
538
539 const std::string &fragmentShaderEnableAndUseExtension = R"(#version 310 es
540 #extension GL_OES_texture_storage_multisample_2d_array : enable
541
542 uniform highp sampler2DMSArray tex;
543 out highp ivec4 outSize;
544
545 void main() {
546 outSize = ivec4(textureSize(tex), 0);
547 }
548 )";
549
550 program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderEnableAndUseExtension);
551 EXPECT_EQ(0u, program);
552}
553
Olli Etuahod310a432018-08-24 15:40:23 +0300554// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
555TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
556{
557 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
558
559 // This query returns supported sample counts in descending order. If only one sample count is
560 // queried, it should be the maximum one.
561 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300562 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300563 &maxSamplesRGBA8);
Olli Etuahofd162102018-08-27 16:14:57 +0300564 GLint maxSamplesDepth = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300565 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_DEPTH_COMPONENT24, GL_SAMPLES, 1,
566 &maxSamplesDepth);
Olli Etuahod310a432018-08-24 15:40:23 +0300567 ASSERT_GL_NO_ERROR();
568
569 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
570 GLint maxColorTextureSamples;
571 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
Olli Etuahofd162102018-08-27 16:14:57 +0300572 GLint maxDepthTextureSamples;
573 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300574 GLint maxSamples;
575 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300576
Olli Etuahofd162102018-08-27 16:14:57 +0300577 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300578 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
Olli Etuahofd162102018-08-27 16:14:57 +0300579
580 GLint maxSamplesDepthRequired = std::min(maxDepthTextureSamples, maxSamples);
581 EXPECT_GE(maxSamplesDepth, maxSamplesDepthRequired);
Olli Etuahod310a432018-08-24 15:40:23 +0300582}
583
584// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
585TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
586{
587 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
588
Olli Etuaho064458a2018-08-30 14:02:02 +0300589 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300590 ASSERT_GL_NO_ERROR();
591
Olli Etuaho064458a2018-08-30 14:02:02 +0300592 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
Olli Etuahod310a432018-08-24 15:40:23 +0300593 GL_UNSIGNED_BYTE, nullptr);
594 EXPECT_GL_ERROR(GL_INVALID_ENUM);
595}
596
597// Tests passing invalid parameters to TexStorage3DMultisample.
598TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
599{
600 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
601
Olli Etuaho064458a2018-08-30 14:02:02 +0300602 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300603 ASSERT_GL_NO_ERROR();
604
605 // Invalid target
Olli Etuaho064458a2018-08-30 14:02:02 +0300606 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300607 EXPECT_GL_ERROR(GL_INVALID_ENUM);
608
609 // Samples 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300610 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1,
611 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300612 EXPECT_GL_ERROR(GL_INVALID_VALUE);
613
614 // Unsized internalformat
Olli Etuaho064458a2018-08-30 14:02:02 +0300615 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300616 EXPECT_GL_ERROR(GL_INVALID_ENUM);
617
618 // Width 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300619 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 0, 1, 1,
620 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300621 EXPECT_GL_ERROR(GL_INVALID_VALUE);
622
623 // Height 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300624 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 0, 1,
625 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300626 EXPECT_GL_ERROR(GL_INVALID_VALUE);
627
628 // Depth 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300629 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 1, 0,
630 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300631 EXPECT_GL_ERROR(GL_INVALID_VALUE);
632}
633
634// Tests passing invalid parameters to TexParameteri.
635TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
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 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES.
643 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300644 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300645 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300646 EXPECT_GL_ERROR(GL_INVALID_ENUM);
647
Olli Etuaho064458a2018-08-30 14:02:02 +0300648 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300649 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300650 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300651 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300652 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300653 EXPECT_GL_ERROR(GL_INVALID_ENUM);
654
Olli Etuaho064458a2018-08-30 14:02:02 +0300655 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300656 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300657 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAX_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300658 EXPECT_GL_ERROR(GL_INVALID_ENUM);
659
Olli Etuaho064458a2018-08-30 14:02:02 +0300660 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Olli Etuahod310a432018-08-24 15:40:23 +0300661 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300662 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
Olli Etuahod310a432018-08-24 15:40:23 +0300663 EXPECT_GL_ERROR(GL_INVALID_ENUM);
664
Olli Etuaho064458a2018-08-30 14:02:02 +0300665 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES is 0.
666 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 1);
Olli Etuahod310a432018-08-24 15:40:23 +0300667 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
668}
669
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300670// Test a valid TexStorage3DMultisample call and check that the queried texture level parameters
671// match. Does not do any drawing.
672TEST_P(TextureMultisampleArrayWebGLTest, TexStorage3DMultisample)
673{
674 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
675
676 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300677 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300678 &maxSamplesRGBA8);
679
Olli Etuaho064458a2018-08-30 14:02:02 +0300680 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300681 ASSERT_GL_NO_ERROR();
682
Olli Etuaho064458a2018-08-30 14:02:02 +0300683 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 8,
684 4, 2, GL_TRUE);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300685 ASSERT_GL_NO_ERROR();
686
687 GLint width = 0, height = 0, depth = 0, samples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300688 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_WIDTH, &width);
689 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_HEIGHT, &height);
690 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_DEPTH, &depth);
691 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_SAMPLES, &samples);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300692 ASSERT_GL_NO_ERROR();
693
694 EXPECT_EQ(8, width);
695 EXPECT_EQ(4, height);
696 EXPECT_EQ(2, depth);
697 EXPECT_EQ(maxSamplesRGBA8, samples);
698}
699
Olli Etuaho064458a2018-08-30 14:02:02 +0300700// Test for invalid FramebufferTextureLayer calls with GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES
Olli Etuahofd162102018-08-27 16:14:57 +0300701// textures.
702TEST_P(TextureMultisampleArrayWebGLTest, InvalidFramebufferTextureLayer)
703{
704 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
705
706 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300707 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahofd162102018-08-27 16:14:57 +0300708 &maxSamplesRGBA8);
709
710 GLint maxArrayTextureLayers;
711 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
712
713 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300714 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
715 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 4,
716 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300717 ASSERT_GL_NO_ERROR();
718
719 // Test with mip level 1 and -1 (only level 0 is valid for multisample textures).
720 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
721 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 1, 0);
722 EXPECT_GL_ERROR(GL_INVALID_VALUE);
723 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, -1, 0);
724 EXPECT_GL_ERROR(GL_INVALID_VALUE);
725
726 // Test with layer -1 and layer == MAX_ARRAY_TEXTURE_LAYERS
727 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
728 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, -1);
729 EXPECT_GL_ERROR(GL_INVALID_VALUE);
730 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0,
731 maxArrayTextureLayers);
732 EXPECT_GL_ERROR(GL_INVALID_VALUE);
733}
734
735// Attach layers of TEXTURE_2D_MULTISAMPLE_ARRAY textures to a framebuffer and check for
736// completeness.
737TEST_P(TextureMultisampleArrayWebGLTest, FramebufferCompleteness)
738{
739 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
740
741 std::vector<GLenum> testFormats = {{GL_RGBA8, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8}};
Olli Etuaho064458a2018-08-30 14:02:02 +0300742 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300743
744 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300745 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
746 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8, 4, 4,
747 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300748 ASSERT_GL_NO_ERROR();
749
750 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
751 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
752 ASSERT_GL_NO_ERROR();
753
754 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
755 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
756
757 // Test framebuffer status with both color and depth textures attached.
758 GLTexture depthTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300759 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthTexture);
760 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
761 GL_DEPTH_COMPONENT24, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300762 ASSERT_GL_NO_ERROR();
763
764 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0);
765 ASSERT_GL_NO_ERROR();
766
767 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
768 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
769
770 // Test with color and depth/stencil textures attached.
771 GLTexture depthStencilTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300772 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthStencilTexture);
773 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
774 GL_DEPTH24_STENCIL8, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300775 ASSERT_GL_NO_ERROR();
776
777 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0,
778 0);
779 ASSERT_GL_NO_ERROR();
780
781 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
782 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
783}
784
785// Attach a layer of TEXTURE_2D_MULTISAMPLE_ARRAY texture to a framebuffer, clear it, and resolve by
786// blitting.
787TEST_P(TextureMultisampleArrayWebGLTest, FramebufferColorClearAndBlit)
788{
789 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
790
791 const GLsizei kWidth = 4;
792 const GLsizei kHeight = 4;
793
794 std::vector<GLenum> testFormats = {GL_RGBA8};
Olli Etuaho064458a2018-08-30 14:02:02 +0300795 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300796
Olli Etuaho064458a2018-08-30 14:02:02 +0300797 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
798 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
799 kWidth, kHeight, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300800
801 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
802 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
803
804 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
805 ASSERT_GL_NO_ERROR();
806 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
807
808 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
809 glClear(GL_COLOR_BUFFER_BIT);
810
811 GLFramebuffer resolveFramebuffer;
812 GLTexture resolveTexture;
813 glBindTexture(GL_TEXTURE_2D, resolveTexture);
814 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
815 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
816 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
817 0);
818 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
819 GL_NEAREST);
820 ASSERT_GL_NO_ERROR();
821
822 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFramebuffer);
823 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
824}
825
Olli Etuahodff32a02018-08-28 14:35:50 +0300826// Check the size of a multisample array texture in a shader.
827TEST_P(TextureMultisampleArrayWebGLTest, TextureSizeInShader)
828{
829 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
830
831 const std::string &fragmentShader = R"(#version 310 es
832 #extension GL_OES_texture_storage_multisample_2d_array : require
833
834 uniform highp sampler2DMSArray tex;
835 out highp vec4 my_FragColor;
836
837 void main() {
838 my_FragColor = (textureSize(tex) == ivec3(8, 4, 2)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
839 }
840 )";
841
842 ANGLE_GL_PROGRAM(texSizeProgram, essl31_shaders::vs::Simple(), fragmentShader);
843
844 GLint texLocation = glGetUniformLocation(texSizeProgram, "tex");
845 ASSERT_GE(texLocation, 0);
846
847 const GLsizei kWidth = 8;
848 const GLsizei kHeight = 4;
849
850 std::vector<GLenum> testFormats = {GL_RGBA8};
851 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
852
853 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
854 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
855 kWidth, kHeight, 2, GL_TRUE);
856 ASSERT_GL_NO_ERROR();
857
858 drawQuad(texSizeProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
859 ASSERT_GL_NO_ERROR();
860
861 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
862}
863
864// Clear the layers of a multisample array texture, and then sample all the samples from all the
865// layers in a shader.
866TEST_P(TextureMultisampleArrayWebGLTest, SimpleTexelFetch)
867{
868 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
869
870 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
871 blitArrayTextureLayerFragmentShader());
872
873 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
874 ASSERT_GE(texLocation, 0);
875 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
876 ASSERT_GE(layerLocation, 0);
877 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
878 ASSERT_GE(layerLocation, 0);
879
880 const GLsizei kWidth = 4;
881 const GLsizei kHeight = 4;
882 const GLsizei kLayerCount = 2;
883
884 std::vector<GLenum> testFormats = {GL_RGBA8};
885 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
886
887 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
888 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
889 kWidth, kHeight, kLayerCount, GL_TRUE);
890 ASSERT_GL_NO_ERROR();
891
892 // Clear layer zero to green and layer one to blue.
893 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
894 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
895 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
896 {
897 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
898 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
899 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
900 const GLColor &clearColor = clearColors[i];
901 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
902 clearColor.A / 255.0f);
903 glClear(GL_COLOR_BUFFER_BIT);
904 ASSERT_GL_NO_ERROR();
905 }
906
907 glBindFramebuffer(GL_FRAMEBUFFER, 0);
908 glUseProgram(texelFetchProgram);
909 glViewport(0, 0, kWidth, kHeight);
910 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
911 {
912 glUniform1i(layerLocation, layer);
913 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
914 {
915 glUniform1i(sampleNumLocation, sampleNum);
916 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
917 ASSERT_GL_NO_ERROR();
918 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
919 }
920 }
921}
922
923// Clear the layers of an integer multisample array texture, and then sample all the samples from
924// all the layers in a shader.
925TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
926{
927 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
928
929 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
930 blitIntArrayTextureLayerFragmentShader());
931
932 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
933 ASSERT_GE(texLocation, 0);
934 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
935 ASSERT_GE(layerLocation, 0);
936 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
937 ASSERT_GE(layerLocation, 0);
938
939 const GLsizei kWidth = 4;
940 const GLsizei kHeight = 4;
941 const GLsizei kLayerCount = 2;
942
943 std::vector<GLenum> testFormats = {GL_RGBA8I};
944 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
945
946 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
947 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8I,
948 kWidth, kHeight, kLayerCount, GL_TRUE);
949 ASSERT_GL_NO_ERROR();
950
951 // Clear layer zero to green and layer one to blue.
952 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
953 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
954 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
955 {
956 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
957 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
958 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
959 std::array<GLint, 4> intColor;
960 for (size_t j = 0; j < intColor.size(); ++j)
961 {
962 intColor[j] = clearColors[i][j] / 255;
963 }
964 glClearBufferiv(GL_COLOR, 0, intColor.data());
965 ASSERT_GL_NO_ERROR();
966 }
967
968 glBindFramebuffer(GL_FRAMEBUFFER, 0);
969 glUseProgram(texelFetchProgram);
970 glViewport(0, 0, kWidth, kHeight);
971 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
972 {
973 glUniform1i(layerLocation, layer);
974 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
975 {
976 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
977 glClear(GL_COLOR_BUFFER_BIT);
978 glUniform1i(sampleNumLocation, sampleNum);
979 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
980 ASSERT_GL_NO_ERROR();
981 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
982 }
983 }
984}
985
JiangYizhoubddc46b2016-12-09 09:50:51 +0800986ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
Yizhou Jiang7818a852018-09-06 15:02:04 +0800987 ES3_D3D11(),
JiangYizhou34bc3152017-03-29 14:56:01 +0800988 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +0800989 ES3_OPENGL(),
990 ES3_OPENGLES(),
991 ES31_OPENGL(),
992 ES31_OPENGLES());
Yizhou Jiang7818a852018-09-06 15:02:04 +0800993ANGLE_INSTANTIATE_TEST(NegativeTextureMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300994ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
995 ES31_D3D11(),
996 ES31_OPENGL(),
997 ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300998} // anonymous namespace