blob: 0ef5541b96a45c123b743d60b42ac1dba85fcff9 [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
JiangYizhoubddc46b2016-12-09 09:50:51 +080072 GLuint mFramebuffer = 0;
73 GLuint mTexture = 0;
Olli Etuahofd162102018-08-27 16:14:57 +030074
75 // Returns a sample count that can be used with the given texture target for all the given
76 // formats. Assumes that if format A supports a number of samples N and another format B
77 // supports a number of samples M > N then format B also supports number of samples N.
78 GLint getSamplesToUse(GLenum texTarget, const std::vector<GLenum> &formats)
79 {
80 GLint maxSamples = 65536;
81 for (GLenum format : formats)
82 {
83 GLint maxSamplesFormat = 0;
84 glGetInternalformativ(texTarget, format, GL_SAMPLES, 1, &maxSamplesFormat);
85 maxSamples = std::min(maxSamples, maxSamplesFormat);
86 }
87 return maxSamples;
88 }
Olli Etuahodff32a02018-08-28 14:35:50 +030089
Yizhou Jiang7818a852018-09-06 15:02:04 +080090 bool lessThanES31MultisampleExtNotSupported()
91 {
92 return getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
93 !ensureExtensionEnabled("GL_ANGLE_texture_multisample");
94 }
95
96 const char *multisampleTextureFragmentShader()
97 {
98 return R"(#version 300 es
99#extension GL_ANGLE_texture_multisample : require
100precision highp float;
101precision highp int;
102
103uniform highp sampler2DMS tex;
104uniform int sampleNum;
105
106in vec4 v_position;
107out vec4 my_FragColor;
108
109void main() {
110 ivec2 texSize = textureSize(tex);
111 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
112 my_FragColor = texelFetch(tex, sampleCoords, sampleNum);
113}
114)";
115 };
116
Olli Etuahodff32a02018-08-28 14:35:50 +0300117 const char *blitArrayTextureLayerFragmentShader()
118 {
119 return R"(#version 310 es
120#extension GL_OES_texture_storage_multisample_2d_array : require
121precision highp float;
122precision highp int;
123
124uniform highp sampler2DMSArray tex;
125uniform int layer;
126uniform int sampleNum;
127
128in vec4 v_position;
129out vec4 my_FragColor;
130
131void main() {
132 ivec3 texSize = textureSize(tex);
133 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
134 my_FragColor = texelFetch(tex, ivec3(sampleCoords, layer), sampleNum);
135}
136)";
137 };
138
139 const char *blitIntArrayTextureLayerFragmentShader()
140 {
141 return R"(#version 310 es
142#extension GL_OES_texture_storage_multisample_2d_array : require
143precision highp float;
144precision highp int;
145
146uniform highp isampler2DMSArray tex;
147uniform int layer;
148uniform int sampleNum;
149
150in vec4 v_position;
151out vec4 my_FragColor;
152
153void main() {
154 ivec3 texSize = textureSize(tex);
155 ivec2 sampleCoords = ivec2((v_position.xy * 0.5 + 0.5) * vec2(texSize.xy - 1));
156 my_FragColor = vec4(texelFetch(tex, ivec3(sampleCoords, layer), sampleNum));
157}
158)";
159 };
JiangYizhoubddc46b2016-12-09 09:50:51 +0800160};
161
Yizhou Jiang7818a852018-09-06 15:02:04 +0800162class NegativeTextureMultisampleTest : public TextureMultisampleTest
JiangYizhoubddc46b2016-12-09 09:50:51 +0800163{
164 protected:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800165 NegativeTextureMultisampleTest() : TextureMultisampleTest() {}
JiangYizhoubddc46b2016-12-09 09:50:51 +0800166};
167
Olli Etuahod310a432018-08-24 15:40:23 +0300168class TextureMultisampleArrayWebGLTest : public TextureMultisampleTest
169{
170 protected:
171 TextureMultisampleArrayWebGLTest() : TextureMultisampleTest()
172 {
173 // These tests run in WebGL mode so we can test with both extension off and on.
174 setWebGLCompatibilityEnabled(true);
175 }
176
177 // Requests the ANGLE_texture_multisample_array extension and returns true if the operation
178 // succeeds.
179 bool requestArrayExtension()
180 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300181 if (extensionRequestable("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300182 {
Olli Etuaho064458a2018-08-30 14:02:02 +0300183 glRequestExtensionANGLE("GL_OES_texture_storage_multisample_2d_array");
Olli Etuahod310a432018-08-24 15:40:23 +0300184 }
185
Olli Etuaho064458a2018-08-30 14:02:02 +0300186 if (!extensionEnabled("GL_OES_texture_storage_multisample_2d_array"))
Olli Etuahod310a432018-08-24 15:40:23 +0300187 {
188 return false;
189 }
190 return true;
191 }
192};
193
Yizhou Jiang7818a852018-09-06 15:02:04 +0800194void TextureMultisampleTest::texStorageMultisample(GLenum target,
195 GLint samples,
196 GLenum internalformat,
197 GLsizei width,
198 GLsizei height,
199 GLboolean fixedsamplelocations)
200{
201 if (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1 &&
202 ensureExtensionEnabled("GL_ANGLE_texture_multisample"))
203 {
204 glTexStorage2DMultisampleANGLE(target, samples, internalformat, width, height,
205 fixedsamplelocations);
206 }
207 else
208 {
209 glTexStorage2DMultisample(target, samples, internalformat, width, height,
210 fixedsamplelocations);
211 }
212}
213
JiangYizhoubddc46b2016-12-09 09:50:51 +0800214// Tests that if es version < 3.1, GL_TEXTURE_2D_MULTISAMPLE is not supported in
Olli Etuahod310a432018-08-24 15:40:23 +0300215// GetInternalformativ. Checks that the number of samples returned is valid in case of ES >= 3.1.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800216TEST_P(TextureMultisampleTest, MultisampleTargetGetInternalFormativBase)
217{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800218 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
219
Olli Etuahod310a432018-08-24 15:40:23 +0300220 // This query returns supported sample counts in descending order. If only one sample count is
221 // queried, it should be the maximum one.
222 GLint maxSamplesR8 = 0;
223 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamplesR8);
Olli Etuahod310a432018-08-24 15:40:23 +0300224
Yizhou Jiang7818a852018-09-06 15:02:04 +0800225 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
226 GLint maxColorTextureSamples;
227 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
228 GLint maxSamples;
229 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
230 GLint maxSamplesR8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300231
Yizhou Jiang7818a852018-09-06 15:02:04 +0800232 EXPECT_GE(maxSamplesR8, maxSamplesR8Required);
233 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800234}
235
Yizhou Jiang7818a852018-09-06 15:02:04 +0800236// Tests that if es version < 3.1 and multisample extension is unsupported,
237// GL_TEXTURE_2D_MULTISAMPLE_ANGLE is not supported in FramebufferTexture2D.
JiangYizhoubddc46b2016-12-09 09:50:51 +0800238TEST_P(TextureMultisampleTest, MultisampleTargetFramebufferTexture2D)
239{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800240 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
JiangYizhoubddc46b2016-12-09 09:50:51 +0800241 GLint samples = 1;
242 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800243 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 64, 64, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800244
245 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
246 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
247 mTexture, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800248 ASSERT_GL_NO_ERROR();
JiangYizhoubddc46b2016-12-09 09:50:51 +0800249}
250
251// Tests basic functionality of glTexStorage2DMultisample.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800252TEST_P(TextureMultisampleTest, ValidateTextureStorageMultisampleParameters)
JiangYizhoubddc46b2016-12-09 09:50:51 +0800253{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800254 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
255
JiangYizhoubddc46b2016-12-09 09:50:51 +0800256 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800257 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhou461d9a32017-01-04 16:37:26 +0800258 ASSERT_GL_NO_ERROR();
259
JiangYizhoubddc46b2016-12-09 09:50:51 +0800260 GLint params = 0;
261 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
262 EXPECT_EQ(1, params);
263
Yizhou Jiang7818a852018-09-06 15:02:04 +0800264 texStorageMultisample(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800265 ASSERT_GL_ERROR(GL_INVALID_ENUM);
266
Yizhou Jiang7818a852018-09-06 15:02:04 +0800267 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800268 ASSERT_GL_ERROR(GL_INVALID_VALUE);
269
270 GLint maxSize = 0;
271 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800272 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, maxSize + 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800273 ASSERT_GL_ERROR(GL_INVALID_VALUE);
274
275 GLint maxSamples = 0;
276 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800277 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxSamples + 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800278 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
279
Yizhou Jiang7818a852018-09-06 15:02:04 +0800280 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800281 ASSERT_GL_ERROR(GL_INVALID_VALUE);
282
Yizhou Jiang7818a852018-09-06 15:02:04 +0800283 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA, 0, 0, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800284 ASSERT_GL_ERROR(GL_INVALID_VALUE);
285
286 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
Yizhou Jiang7818a852018-09-06 15:02:04 +0800287 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, GL_FALSE);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800288 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
289}
290
Shao5116d682017-08-02 12:39:44 +0800291// Tests the value of MAX_INTEGER_SAMPLES is no less than 1.
292// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800293TEST_P(TextureMultisampleTest, MaxIntegerSamples)
Shao5116d682017-08-02 12:39:44 +0800294{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800295 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800296 GLint maxIntegerSamples;
297 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &maxIntegerSamples);
298 EXPECT_GE(maxIntegerSamples, 1);
299 EXPECT_NE(std::numeric_limits<GLint>::max(), maxIntegerSamples);
300}
301
302// Tests the value of MAX_COLOR_TEXTURE_SAMPLES is no less than 1.
303// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800304TEST_P(TextureMultisampleTest, MaxColorTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800305{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800306 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800307 GLint maxColorTextureSamples;
308 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
309 EXPECT_GE(maxColorTextureSamples, 1);
310 EXPECT_NE(std::numeric_limits<GLint>::max(), maxColorTextureSamples);
311}
312
313// Tests the value of MAX_DEPTH_TEXTURE_SAMPLES is no less than 1.
314// [OpenGL ES 3.1 SPEC Table 20.40]
Yizhou Jiang7818a852018-09-06 15:02:04 +0800315TEST_P(TextureMultisampleTest, MaxDepthTextureSamples)
Shao5116d682017-08-02 12:39:44 +0800316{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800317 ANGLE_SKIP_TEST_IF(lessThanES31MultisampleExtNotSupported());
Shao5116d682017-08-02 12:39:44 +0800318 GLint maxDepthTextureSamples;
319 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
320 EXPECT_GE(maxDepthTextureSamples, 1);
321 EXPECT_NE(std::numeric_limits<GLint>::max(), maxDepthTextureSamples);
322}
323
Jiang0e1224c2017-12-26 14:11:15 +0800324// The value of sample position should be equal to standard pattern on D3D.
Yizhou Jiang7818a852018-09-06 15:02:04 +0800325TEST_P(TextureMultisampleTest, CheckSamplePositions)
Jiang0e1224c2017-12-26 14:11:15 +0800326{
Yizhou Jiang7818a852018-09-06 15:02:04 +0800327 ANGLE_SKIP_TEST_IF(!IsD3D11() || (getClientMajorVersion() <= 3 && getClientMinorVersion() < 1));
Jiang0e1224c2017-12-26 14:11:15 +0800328
329 GLsizei maxSamples = 0;
330 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
331
332 GLfloat samplePosition[2];
333
334 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
335
336 for (int sampleCount = 1; sampleCount <= maxSamples; sampleCount++)
337 {
338 GLTexture texture;
339 size_t indexKey = static_cast<size_t>(ceil(log2(sampleCount)));
340 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
341 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCount, GL_RGBA8, 1, 1, GL_TRUE);
342 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
343 texture, 0);
344 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
345 ASSERT_GL_NO_ERROR();
346
347 for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
348 {
349 glGetMultisamplefv(GL_SAMPLE_POSITION, sampleIndex, samplePosition);
350 EXPECT_EQ(samplePosition[0], kSamplePositions[indexKey][2 * sampleIndex]);
351 EXPECT_EQ(samplePosition[1], kSamplePositions[indexKey][2 * sampleIndex + 1]);
352 }
353 }
354
355 ASSERT_GL_NO_ERROR();
356}
357
Yizhou Jiang7818a852018-09-06 15:02:04 +0800358// Test textureSize and texelFetch when using ANGLE_texture_multisample extension
359TEST_P(TextureMultisampleTest, SimpleTexelFetch)
360{
361 ANGLE_SKIP_TEST_IF(IsD3D11());
362 ANGLE_SKIP_TEST_IF(!ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
363
364 ANGLE_GL_PROGRAM(texelFetchProgram, essl3_shaders::vs::Passthrough(),
365 multisampleTextureFragmentShader());
366
367 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
368 ASSERT_GE(texLocation, 0);
369 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
370 ASSERT_GE(sampleNumLocation, 0);
371
372 const GLsizei kWidth = 4;
373 const GLsizei kHeight = 4;
374
375 std::vector<GLenum> testFormats = {GL_RGBA8};
376 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, testFormats);
377
378 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, mTexture);
379 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE_ANGLE, samplesToUse, GL_RGBA8, kWidth,
380 kHeight, GL_TRUE);
381 ASSERT_GL_NO_ERROR();
382
383 // Clear texture zero to green.
384 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
385 GLColor clearColor = GLColor::green;
386
387 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
388 GL_TEXTURE_2D_MULTISAMPLE_ANGLE, mTexture, 0);
389 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
390 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
391 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
392 clearColor.A / 255.0f);
393 glClear(GL_COLOR_BUFFER_BIT);
394 ASSERT_GL_NO_ERROR();
395
396 glBindFramebuffer(GL_FRAMEBUFFER, 0);
397 glUseProgram(texelFetchProgram);
398 glViewport(0, 0, kWidth, kHeight);
399
400 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
401 {
402 glUniform1i(sampleNumLocation, sampleNum);
403 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
404 ASSERT_GL_NO_ERROR();
405 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColor);
406 }
407}
408
409// Negative tests of multisample texture. When context less than ES 3.1 and ANGLE_texture_multsample
410// not enabled, the feature isn't supported.
411TEST_P(NegativeTextureMultisampleTest, Negtive)
412{
413 ANGLE_SKIP_TEST_IF(ensureExtensionEnabled("GL_ANGLE_texture_multisample"));
414
415 GLint maxSamples = 0;
416 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_R8, GL_SAMPLES, 1, &maxSamples);
417 ASSERT_GL_ERROR(GL_INVALID_ENUM);
418
419 GLint maxColorTextureSamples;
420 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
421 ASSERT_GL_ERROR(GL_INVALID_ENUM);
422
423 GLint maxDepthTextureSamples;
424 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
425 ASSERT_GL_ERROR(GL_INVALID_ENUM);
426
427 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture);
428 ASSERT_GL_ERROR(GL_INVALID_ENUM);
429
430 texStorageMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 64, 64, GL_FALSE);
431 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
432
433 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
434 mTexture, 0);
435 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
436
437 GLint params = 0;
438 glGetTexParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_IMMUTABLE_FORMAT, &params);
439 ASSERT_GL_ERROR(GL_INVALID_ENUM);
440}
441
Olli Etuahod310a432018-08-24 15:40:23 +0300442// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is not supported in GetInternalformativ when the
443// extension is not supported.
444TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativWithoutExtension)
445{
446 GLint maxSamples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300447 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300448 &maxSamples);
449 ASSERT_GL_ERROR(GL_INVALID_ENUM);
450}
451
452// Attempt to bind a texture to multisample array binding point when extension is not supported.
453TEST_P(TextureMultisampleArrayWebGLTest, BindMultisampleArrayTextureWithoutExtension)
454{
Olli Etuaho064458a2018-08-30 14:02:02 +0300455 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300456 ASSERT_GL_ERROR(GL_INVALID_ENUM);
457}
458
Olli Etuahodff32a02018-08-28 14:35:50 +0300459// Try to compile shaders using GL_OES_texture_storage_multisample_2d_array when the extension is
460// not enabled.
461TEST_P(TextureMultisampleArrayWebGLTest, ShaderWithoutExtension)
462{
463 const std::string &fragmentShaderRequireExtension = R"(#version 310 es
464 #extension GL_OES_texture_storage_multisample_2d_array : require
465 out highp vec4 my_FragColor;
466
467 void main() {
468 my_FragColor = vec4(0.0);
469 }
470 )";
471
472 GLuint program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderRequireExtension);
473 EXPECT_EQ(0u, program);
474
475 const std::string &fragmentShaderEnableAndUseExtension = R"(#version 310 es
476 #extension GL_OES_texture_storage_multisample_2d_array : enable
477
478 uniform highp sampler2DMSArray tex;
479 out highp ivec4 outSize;
480
481 void main() {
482 outSize = ivec4(textureSize(tex), 0);
483 }
484 )";
485
486 program = CompileProgram(essl31_shaders::vs::Simple(), fragmentShaderEnableAndUseExtension);
487 EXPECT_EQ(0u, program);
488}
489
Olli Etuahod310a432018-08-24 15:40:23 +0300490// Tests that GL_TEXTURE_2D_MULTISAMPLE_ARRAY is supported in GetInternalformativ.
491TEST_P(TextureMultisampleArrayWebGLTest, MultisampleArrayTargetGetInternalFormativ)
492{
493 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
494
495 // This query returns supported sample counts in descending order. If only one sample count is
496 // queried, it should be the maximum one.
497 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300498 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahod310a432018-08-24 15:40:23 +0300499 &maxSamplesRGBA8);
Olli Etuahofd162102018-08-27 16:14:57 +0300500 GLint maxSamplesDepth = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300501 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_DEPTH_COMPONENT24, GL_SAMPLES, 1,
502 &maxSamplesDepth);
Olli Etuahod310a432018-08-24 15:40:23 +0300503 ASSERT_GL_NO_ERROR();
504
505 // GLES 3.1 section 19.3.1 specifies the required minimum of how many samples are supported.
506 GLint maxColorTextureSamples;
507 glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples);
Olli Etuahofd162102018-08-27 16:14:57 +0300508 GLint maxDepthTextureSamples;
509 glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthTextureSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300510 GLint maxSamples;
511 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300512
Olli Etuahofd162102018-08-27 16:14:57 +0300513 GLint maxSamplesRGBA8Required = std::min(maxColorTextureSamples, maxSamples);
Olli Etuahod310a432018-08-24 15:40:23 +0300514 EXPECT_GE(maxSamplesRGBA8, maxSamplesRGBA8Required);
Olli Etuahofd162102018-08-27 16:14:57 +0300515
516 GLint maxSamplesDepthRequired = std::min(maxDepthTextureSamples, maxSamples);
517 EXPECT_GE(maxSamplesDepth, maxSamplesDepthRequired);
Olli Etuahod310a432018-08-24 15:40:23 +0300518}
519
520// Tests that TexImage3D call cannot be used for GL_TEXTURE_2D_MULTISAMPLE_ARRAY.
521TEST_P(TextureMultisampleArrayWebGLTest, MultiSampleArrayTexImage)
522{
523 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
524
Olli Etuaho064458a2018-08-30 14:02:02 +0300525 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300526 ASSERT_GL_NO_ERROR();
527
Olli Etuaho064458a2018-08-30 14:02:02 +0300528 glTexImage3D(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA,
Olli Etuahod310a432018-08-24 15:40:23 +0300529 GL_UNSIGNED_BYTE, nullptr);
530 EXPECT_GL_ERROR(GL_INVALID_ENUM);
531}
532
533// Tests passing invalid parameters to TexStorage3DMultisample.
534TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexStorage3DMultisample)
535{
536 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
537
Olli Etuaho064458a2018-08-30 14:02:02 +0300538 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300539 ASSERT_GL_NO_ERROR();
540
541 // Invalid target
Olli Etuaho064458a2018-08-30 14:02:02 +0300542 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300543 EXPECT_GL_ERROR(GL_INVALID_ENUM);
544
545 // Samples 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300546 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_RGBA8, 1, 1, 1,
547 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300548 EXPECT_GL_ERROR(GL_INVALID_VALUE);
549
550 // Unsized internalformat
Olli Etuaho064458a2018-08-30 14:02:02 +0300551 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA, 1, 1, 1, GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300552 EXPECT_GL_ERROR(GL_INVALID_ENUM);
553
554 // Width 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300555 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 0, 1, 1,
556 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300557 EXPECT_GL_ERROR(GL_INVALID_VALUE);
558
559 // Height 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300560 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 0, 1,
561 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300562 EXPECT_GL_ERROR(GL_INVALID_VALUE);
563
564 // Depth 0
Olli Etuaho064458a2018-08-30 14:02:02 +0300565 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, GL_RGBA8, 1, 1, 0,
566 GL_TRUE);
Olli Etuahod310a432018-08-24 15:40:23 +0300567 EXPECT_GL_ERROR(GL_INVALID_VALUE);
568}
569
570// Tests passing invalid parameters to TexParameteri.
571TEST_P(TextureMultisampleArrayWebGLTest, InvalidTexParameteri)
572{
573 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
574
Olli Etuaho064458a2018-08-30 14:02:02 +0300575 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuahod310a432018-08-24 15:40:23 +0300576 ASSERT_GL_NO_ERROR();
577
Olli Etuaho064458a2018-08-30 14:02:02 +0300578 // None of the sampler parameters can be set on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES.
579 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300580 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300581 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Olli Etuahod310a432018-08-24 15:40:23 +0300582 EXPECT_GL_ERROR(GL_INVALID_ENUM);
583
Olli Etuaho064458a2018-08-30 14:02:02 +0300584 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300585 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300586 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300587 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300588 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Olli Etuahod310a432018-08-24 15:40:23 +0300589 EXPECT_GL_ERROR(GL_INVALID_ENUM);
590
Olli Etuaho064458a2018-08-30 14:02:02 +0300591 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MIN_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300592 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300593 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_MAX_LOD, 0);
Olli Etuahod310a432018-08-24 15:40:23 +0300594 EXPECT_GL_ERROR(GL_INVALID_ENUM);
595
Olli Etuaho064458a2018-08-30 14:02:02 +0300596 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_MODE, GL_NONE);
Olli Etuahod310a432018-08-24 15:40:23 +0300597 EXPECT_GL_ERROR(GL_INVALID_ENUM);
Olli Etuaho064458a2018-08-30 14:02:02 +0300598 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
Olli Etuahod310a432018-08-24 15:40:23 +0300599 EXPECT_GL_ERROR(GL_INVALID_ENUM);
600
Olli Etuaho064458a2018-08-30 14:02:02 +0300601 // Only valid base level on GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES is 0.
602 glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 1);
Olli Etuahod310a432018-08-24 15:40:23 +0300603 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
604}
605
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300606// Test a valid TexStorage3DMultisample call and check that the queried texture level parameters
607// match. Does not do any drawing.
608TEST_P(TextureMultisampleArrayWebGLTest, TexStorage3DMultisample)
609{
610 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
611
612 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300613 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300614 &maxSamplesRGBA8);
615
Olli Etuaho064458a2018-08-30 14:02:02 +0300616 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300617 ASSERT_GL_NO_ERROR();
618
Olli Etuaho064458a2018-08-30 14:02:02 +0300619 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 8,
620 4, 2, GL_TRUE);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300621 ASSERT_GL_NO_ERROR();
622
623 GLint width = 0, height = 0, depth = 0, samples = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300624 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_WIDTH, &width);
625 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_HEIGHT, &height);
626 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_DEPTH, &depth);
627 glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0, GL_TEXTURE_SAMPLES, &samples);
Olli Etuaho0c5a9e22018-08-27 14:36:23 +0300628 ASSERT_GL_NO_ERROR();
629
630 EXPECT_EQ(8, width);
631 EXPECT_EQ(4, height);
632 EXPECT_EQ(2, depth);
633 EXPECT_EQ(maxSamplesRGBA8, samples);
634}
635
Olli Etuaho064458a2018-08-30 14:02:02 +0300636// Test for invalid FramebufferTextureLayer calls with GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES
Olli Etuahofd162102018-08-27 16:14:57 +0300637// textures.
638TEST_P(TextureMultisampleArrayWebGLTest, InvalidFramebufferTextureLayer)
639{
640 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
641
642 GLint maxSamplesRGBA8 = 0;
Olli Etuaho064458a2018-08-30 14:02:02 +0300643 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, 1,
Olli Etuahofd162102018-08-27 16:14:57 +0300644 &maxSamplesRGBA8);
645
646 GLint maxArrayTextureLayers;
647 glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
648
649 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300650 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
651 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, maxSamplesRGBA8, GL_RGBA8, 4,
652 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300653 ASSERT_GL_NO_ERROR();
654
655 // Test with mip level 1 and -1 (only level 0 is valid for multisample textures).
656 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
657 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 1, 0);
658 EXPECT_GL_ERROR(GL_INVALID_VALUE);
659 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, -1, 0);
660 EXPECT_GL_ERROR(GL_INVALID_VALUE);
661
662 // Test with layer -1 and layer == MAX_ARRAY_TEXTURE_LAYERS
663 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
664 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, -1);
665 EXPECT_GL_ERROR(GL_INVALID_VALUE);
666 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0,
667 maxArrayTextureLayers);
668 EXPECT_GL_ERROR(GL_INVALID_VALUE);
669}
670
671// Attach layers of TEXTURE_2D_MULTISAMPLE_ARRAY textures to a framebuffer and check for
672// completeness.
673TEST_P(TextureMultisampleArrayWebGLTest, FramebufferCompleteness)
674{
675 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
676
677 std::vector<GLenum> testFormats = {{GL_RGBA8, GL_DEPTH_COMPONENT24, GL_DEPTH24_STENCIL8}};
Olli Etuaho064458a2018-08-30 14:02:02 +0300678 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300679
680 // Test framebuffer status with just a color texture attached.
Olli Etuaho064458a2018-08-30 14:02:02 +0300681 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
682 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8, 4, 4,
683 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300684 ASSERT_GL_NO_ERROR();
685
686 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
687 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
688 ASSERT_GL_NO_ERROR();
689
690 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
691 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
692
693 // Test framebuffer status with both color and depth textures attached.
694 GLTexture depthTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300695 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthTexture);
696 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
697 GL_DEPTH_COMPONENT24, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300698 ASSERT_GL_NO_ERROR();
699
700 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0, 0);
701 ASSERT_GL_NO_ERROR();
702
703 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
704 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
705
706 // Test with color and depth/stencil textures attached.
707 GLTexture depthStencilTexture;
Olli Etuaho064458a2018-08-30 14:02:02 +0300708 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, depthStencilTexture);
709 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse,
710 GL_DEPTH24_STENCIL8, 4, 4, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300711 ASSERT_GL_NO_ERROR();
712
713 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture, 0,
714 0);
715 ASSERT_GL_NO_ERROR();
716
717 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
718 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
719}
720
721// Attach a layer of TEXTURE_2D_MULTISAMPLE_ARRAY texture to a framebuffer, clear it, and resolve by
722// blitting.
723TEST_P(TextureMultisampleArrayWebGLTest, FramebufferColorClearAndBlit)
724{
725 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
726
727 const GLsizei kWidth = 4;
728 const GLsizei kHeight = 4;
729
730 std::vector<GLenum> testFormats = {GL_RGBA8};
Olli Etuaho064458a2018-08-30 14:02:02 +0300731 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
Olli Etuahofd162102018-08-27 16:14:57 +0300732
Olli Etuaho064458a2018-08-30 14:02:02 +0300733 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
734 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
735 kWidth, kHeight, 2, GL_TRUE);
Olli Etuahofd162102018-08-27 16:14:57 +0300736
737 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
738 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, 0);
739
740 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
741 ASSERT_GL_NO_ERROR();
742 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
743
744 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
745 glClear(GL_COLOR_BUFFER_BIT);
746
747 GLFramebuffer resolveFramebuffer;
748 GLTexture resolveTexture;
749 glBindTexture(GL_TEXTURE_2D, resolveTexture);
750 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
751 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
752 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture,
753 0);
754 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
755 GL_NEAREST);
756 ASSERT_GL_NO_ERROR();
757
758 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFramebuffer);
759 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
760}
761
Olli Etuahodff32a02018-08-28 14:35:50 +0300762// Check the size of a multisample array texture in a shader.
763TEST_P(TextureMultisampleArrayWebGLTest, TextureSizeInShader)
764{
765 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
766
767 const std::string &fragmentShader = R"(#version 310 es
768 #extension GL_OES_texture_storage_multisample_2d_array : require
769
770 uniform highp sampler2DMSArray tex;
771 out highp vec4 my_FragColor;
772
773 void main() {
774 my_FragColor = (textureSize(tex) == ivec3(8, 4, 2)) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);
775 }
776 )";
777
778 ANGLE_GL_PROGRAM(texSizeProgram, essl31_shaders::vs::Simple(), fragmentShader);
779
780 GLint texLocation = glGetUniformLocation(texSizeProgram, "tex");
781 ASSERT_GE(texLocation, 0);
782
783 const GLsizei kWidth = 8;
784 const GLsizei kHeight = 4;
785
786 std::vector<GLenum> testFormats = {GL_RGBA8};
787 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
788
789 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
790 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
791 kWidth, kHeight, 2, GL_TRUE);
792 ASSERT_GL_NO_ERROR();
793
794 drawQuad(texSizeProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
795 ASSERT_GL_NO_ERROR();
796
797 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
798}
799
800// Clear the layers of a multisample array texture, and then sample all the samples from all the
801// layers in a shader.
802TEST_P(TextureMultisampleArrayWebGLTest, SimpleTexelFetch)
803{
804 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
805
806 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
807 blitArrayTextureLayerFragmentShader());
808
809 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
810 ASSERT_GE(texLocation, 0);
811 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
812 ASSERT_GE(layerLocation, 0);
813 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
814 ASSERT_GE(layerLocation, 0);
815
816 const GLsizei kWidth = 4;
817 const GLsizei kHeight = 4;
818 const GLsizei kLayerCount = 2;
819
820 std::vector<GLenum> testFormats = {GL_RGBA8};
821 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
822
823 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
824 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8,
825 kWidth, kHeight, kLayerCount, GL_TRUE);
826 ASSERT_GL_NO_ERROR();
827
828 // Clear layer zero to green and layer one to blue.
829 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
830 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
831 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
832 {
833 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
834 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
835 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
836 const GLColor &clearColor = clearColors[i];
837 glClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f,
838 clearColor.A / 255.0f);
839 glClear(GL_COLOR_BUFFER_BIT);
840 ASSERT_GL_NO_ERROR();
841 }
842
843 glBindFramebuffer(GL_FRAMEBUFFER, 0);
844 glUseProgram(texelFetchProgram);
845 glViewport(0, 0, kWidth, kHeight);
846 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
847 {
848 glUniform1i(layerLocation, layer);
849 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
850 {
851 glUniform1i(sampleNumLocation, sampleNum);
852 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
853 ASSERT_GL_NO_ERROR();
854 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
855 }
856 }
857}
858
859// Clear the layers of an integer multisample array texture, and then sample all the samples from
860// all the layers in a shader.
861TEST_P(TextureMultisampleArrayWebGLTest, IntegerTexelFetch)
862{
863 ANGLE_SKIP_TEST_IF(!requestArrayExtension());
864
865 ANGLE_GL_PROGRAM(texelFetchProgram, essl31_shaders::vs::Passthrough(),
866 blitIntArrayTextureLayerFragmentShader());
867
868 GLint texLocation = glGetUniformLocation(texelFetchProgram, "tex");
869 ASSERT_GE(texLocation, 0);
870 GLint layerLocation = glGetUniformLocation(texelFetchProgram, "layer");
871 ASSERT_GE(layerLocation, 0);
872 GLint sampleNumLocation = glGetUniformLocation(texelFetchProgram, "sampleNum");
873 ASSERT_GE(layerLocation, 0);
874
875 const GLsizei kWidth = 4;
876 const GLsizei kHeight = 4;
877 const GLsizei kLayerCount = 2;
878
879 std::vector<GLenum> testFormats = {GL_RGBA8I};
880 GLint samplesToUse = getSamplesToUse(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, testFormats);
881
882 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, mTexture);
883 glTexStorage3DMultisampleOES(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samplesToUse, GL_RGBA8I,
884 kWidth, kHeight, kLayerCount, GL_TRUE);
885 ASSERT_GL_NO_ERROR();
886
887 // Clear layer zero to green and layer one to blue.
888 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
889 std::vector<GLColor> clearColors = {{GLColor::green, GLColor::blue}};
890 for (GLint i = 0; static_cast<GLsizei>(i) < kLayerCount; ++i)
891 {
892 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, 0, i);
893 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
894 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, status);
895 std::array<GLint, 4> intColor;
896 for (size_t j = 0; j < intColor.size(); ++j)
897 {
898 intColor[j] = clearColors[i][j] / 255;
899 }
900 glClearBufferiv(GL_COLOR, 0, intColor.data());
901 ASSERT_GL_NO_ERROR();
902 }
903
904 glBindFramebuffer(GL_FRAMEBUFFER, 0);
905 glUseProgram(texelFetchProgram);
906 glViewport(0, 0, kWidth, kHeight);
907 for (GLint layer = 0; static_cast<GLsizei>(layer) < kLayerCount; ++layer)
908 {
909 glUniform1i(layerLocation, layer);
910 for (GLint sampleNum = 0; sampleNum < samplesToUse; ++sampleNum)
911 {
912 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
913 glClear(GL_COLOR_BUFFER_BIT);
914 glUniform1i(sampleNumLocation, sampleNum);
915 drawQuad(texelFetchProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
916 ASSERT_GL_NO_ERROR();
917 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[layer]);
918 }
919 }
920}
921
JiangYizhoubddc46b2016-12-09 09:50:51 +0800922ANGLE_INSTANTIATE_TEST(TextureMultisampleTest,
Yizhou Jiang7818a852018-09-06 15:02:04 +0800923 ES3_D3D11(),
JiangYizhou34bc3152017-03-29 14:56:01 +0800924 ES31_D3D11(),
JiangYizhoubddc46b2016-12-09 09:50:51 +0800925 ES3_OPENGL(),
926 ES3_OPENGLES(),
927 ES31_OPENGL(),
928 ES31_OPENGLES());
Yizhou Jiang7818a852018-09-06 15:02:04 +0800929ANGLE_INSTANTIATE_TEST(NegativeTextureMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300930ANGLE_INSTANTIATE_TEST(TextureMultisampleArrayWebGLTest,
931 ES31_D3D11(),
932 ES31_OPENGL(),
933 ES31_OPENGLES());
Olli Etuahod310a432018-08-24 15:40:23 +0300934} // anonymous namespace