1 //
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 // SamplerTest.cpp : Tests for samplers.
8
9 #include "test_utils/ANGLETest.h"
10
11 #include "test_utils/gl_raii.h"
12
13 namespace angle
14 {
15
16 class SamplersTest : public ANGLETest
17 {
18 protected:
SamplersTest()19 SamplersTest() {}
20
21 // Sets a value for GL_TEXTURE_MAX_ANISOTROPY_EXT and expects it to fail.
validateInvalidAnisotropy(GLSampler & sampler,float invalidValue)22 void validateInvalidAnisotropy(GLSampler &sampler, float invalidValue)
23 {
24 glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, invalidValue);
25 EXPECT_GL_ERROR(GL_INVALID_VALUE);
26 }
27
28 // Sets a value for GL_TEXTURE_MAX_ANISOTROPY_EXT and expects it to work.
validateValidAnisotropy(GLSampler & sampler,float validValue)29 void validateValidAnisotropy(GLSampler &sampler, float validValue)
30 {
31 glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, validValue);
32 EXPECT_GL_NO_ERROR();
33
34 GLfloat valueToVerify = 0.0f;
35 glGetSamplerParameterfv(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, &valueToVerify);
36 ASSERT_EQ(valueToVerify, validValue);
37 }
38 };
39
40 class SamplersTest31 : public SamplersTest
41 {};
42
43 // Verify that samplerParameterf supports TEXTURE_MAX_ANISOTROPY_EXT valid values.
TEST_P(SamplersTest,ValidTextureSamplerMaxAnisotropyExt)44 TEST_P(SamplersTest, ValidTextureSamplerMaxAnisotropyExt)
45 {
46 // http://anglebug.com/4092
47 ANGLE_SKIP_TEST_IF(isSwiftshader());
48 GLSampler sampler;
49
50 // Exact min
51 validateValidAnisotropy(sampler, 1.0f);
52
53 GLfloat maxValue = 0.0f;
54 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxValue);
55
56 // Max value
57 validateValidAnisotropy(sampler, maxValue - 1);
58
59 // In-between
60 GLfloat between = (1.0f + maxValue) / 2;
61 validateValidAnisotropy(sampler, between);
62 }
63
64 // Verify an error is thrown if we try to go under the minimum value for
65 // GL_TEXTURE_MAX_ANISOTROPY_EXT
TEST_P(SamplersTest,InvalidUnderTextureSamplerMaxAnisotropyExt)66 TEST_P(SamplersTest, InvalidUnderTextureSamplerMaxAnisotropyExt)
67 {
68 // http://anglebug.com/4092
69 ANGLE_SKIP_TEST_IF(isSwiftshader());
70 GLSampler sampler;
71
72 // Under min
73 validateInvalidAnisotropy(sampler, 0.0f);
74 }
75
76 // Verify an error is thrown if we try to go over the max value for
77 // GL_TEXTURE_MAX_ANISOTROPY_EXT
TEST_P(SamplersTest,InvalidOverTextureSamplerMaxAnisotropyExt)78 TEST_P(SamplersTest, InvalidOverTextureSamplerMaxAnisotropyExt)
79 {
80 // http://anglebug.com/4092
81 ANGLE_SKIP_TEST_IF(isSwiftshader());
82 GLSampler sampler;
83
84 GLfloat maxValue = 0.0f;
85 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxValue);
86 maxValue += 1;
87
88 validateInvalidAnisotropy(sampler, maxValue);
89 }
90
91 // Test that updating a sampler uniform in a program behaves correctly.
TEST_P(SamplersTest31,SampleTextureAThenTextureB)92 TEST_P(SamplersTest31, SampleTextureAThenTextureB)
93 {
94 ANGLE_SKIP_TEST_IF(!IsVulkan());
95
96 constexpr int kWidth = 2;
97 constexpr int kHeight = 2;
98
99 const GLchar *vertString = R"(#version 310 es
100 precision highp float;
101 in vec2 a_position;
102 out vec2 texCoord;
103 void main()
104 {
105 gl_Position = vec4(a_position, 0, 1);
106 texCoord = a_position * 0.5 + vec2(0.5);
107 })";
108
109 const GLchar *fragString = R"(#version 310 es
110 precision highp float;
111 in vec2 texCoord;
112 uniform sampler2D tex;
113 out vec4 my_FragColor;
114 void main()
115 {
116 my_FragColor = texture(tex, texCoord);
117 })";
118
119 std::array<GLColor, kWidth *kHeight> redColor = {
120 {GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
121 std::array<GLColor, kWidth *kHeight> greenColor = {
122 {GLColor::green, GLColor::green, GLColor::green, GLColor::green}};
123
124 // Create a red texture and bind to texture unit 0
125 GLTexture redTex;
126 glActiveTexture(GL_TEXTURE0);
127 glBindTexture(GL_TEXTURE_2D, redTex);
128 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
129 redColor.data());
130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
132 ASSERT_GL_NO_ERROR();
133 // Create a green texture and bind to texture unit 1
134 GLTexture greenTex;
135 glActiveTexture(GL_TEXTURE1);
136 glBindTexture(GL_TEXTURE_2D, greenTex);
137 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
138 greenColor.data());
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
141 glActiveTexture(GL_TEXTURE0);
142 ASSERT_GL_NO_ERROR();
143
144 GLProgram program;
145 program.makeRaster(vertString, fragString);
146 ASSERT_NE(0u, program.get());
147 glUseProgram(program);
148
149 GLint location = glGetUniformLocation(program, "tex");
150 ASSERT_NE(location, -1);
151 ASSERT_GL_NO_ERROR();
152
153 // Draw red
154 glUniform1i(location, 0);
155 ASSERT_GL_NO_ERROR();
156 drawQuad(program, "a_position", 0.5f);
157 ASSERT_GL_NO_ERROR();
158
159 glEnable(GL_BLEND);
160 glBlendEquation(GL_FUNC_ADD);
161 glBlendFunc(GL_ONE, GL_ONE);
162
163 // Draw green
164 glUniform1i(location, 1);
165 ASSERT_GL_NO_ERROR();
166 drawQuad(program, "a_position", 0.5f);
167 ASSERT_GL_NO_ERROR();
168
169 // Draw red
170 glUniform1i(location, 0);
171 ASSERT_GL_NO_ERROR();
172 drawQuad(program, "a_position", 0.5f);
173 ASSERT_GL_NO_ERROR();
174
175 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::yellow);
176 }
177
178 // Samplers are only supported on ES3.
179 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplersTest);
180 ANGLE_INSTANTIATE_TEST_ES3(SamplersTest);
181 ANGLE_INSTANTIATE_TEST_ES31(SamplersTest31);
182 } // namespace angle
183