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 GLSampler sampler;
47
48 // Exact min
49 validateValidAnisotropy(sampler, 1.0f);
50
51 GLfloat maxValue = 0.0f;
52 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxValue);
53
54 // Max value
55 validateValidAnisotropy(sampler, maxValue - 1);
56
57 // In-between
58 GLfloat between = (1.0f + maxValue) / 2;
59 validateValidAnisotropy(sampler, between);
60 }
61
62 // Verify an error is thrown if we try to go under the minimum value for
63 // GL_TEXTURE_MAX_ANISOTROPY_EXT
TEST_P(SamplersTest,InvalidUnderTextureSamplerMaxAnisotropyExt)64 TEST_P(SamplersTest, InvalidUnderTextureSamplerMaxAnisotropyExt)
65 {
66 GLSampler sampler;
67
68 // Under min
69 validateInvalidAnisotropy(sampler, 0.0f);
70 }
71
72 // Verify an error is thrown if we try to go over the max value for
73 // GL_TEXTURE_MAX_ANISOTROPY_EXT
TEST_P(SamplersTest,InvalidOverTextureSamplerMaxAnisotropyExt)74 TEST_P(SamplersTest, InvalidOverTextureSamplerMaxAnisotropyExt)
75 {
76 GLSampler sampler;
77
78 GLfloat maxValue = 0.0f;
79 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxValue);
80 maxValue += 1;
81
82 validateInvalidAnisotropy(sampler, maxValue);
83 }
84
85 // Test that updating a sampler uniform in a program behaves correctly.
TEST_P(SamplersTest31,SampleTextureAThenTextureB)86 TEST_P(SamplersTest31, SampleTextureAThenTextureB)
87 {
88 ANGLE_SKIP_TEST_IF(!IsVulkan());
89
90 constexpr int kWidth = 2;
91 constexpr int kHeight = 2;
92
93 const GLchar *vertString = R"(#version 310 es
94 precision highp float;
95 in vec2 a_position;
96 out vec2 texCoord;
97 void main()
98 {
99 gl_Position = vec4(a_position, 0, 1);
100 texCoord = a_position * 0.5 + vec2(0.5);
101 })";
102
103 const GLchar *fragString = R"(#version 310 es
104 precision highp float;
105 in vec2 texCoord;
106 uniform sampler2D tex;
107 out vec4 my_FragColor;
108 void main()
109 {
110 my_FragColor = texture(tex, texCoord);
111 })";
112
113 std::array<GLColor, kWidth * kHeight> redColor = {
114 {GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
115 std::array<GLColor, kWidth * kHeight> greenColor = {
116 {GLColor::green, GLColor::green, GLColor::green, GLColor::green}};
117
118 // Create a red texture and bind to texture unit 0
119 GLTexture redTex;
120 glActiveTexture(GL_TEXTURE0);
121 glBindTexture(GL_TEXTURE_2D, redTex);
122 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
123 redColor.data());
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
126 ASSERT_GL_NO_ERROR();
127 // Create a green texture and bind to texture unit 1
128 GLTexture greenTex;
129 glActiveTexture(GL_TEXTURE1);
130 glBindTexture(GL_TEXTURE_2D, greenTex);
131 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
132 greenColor.data());
133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
135 glActiveTexture(GL_TEXTURE0);
136 ASSERT_GL_NO_ERROR();
137
138 GLProgram program;
139 program.makeRaster(vertString, fragString);
140 ASSERT_NE(0u, program);
141 glUseProgram(program);
142
143 GLint location = glGetUniformLocation(program, "tex");
144 ASSERT_NE(location, -1);
145 ASSERT_GL_NO_ERROR();
146
147 // Draw red
148 glUniform1i(location, 0);
149 ASSERT_GL_NO_ERROR();
150 drawQuad(program, "a_position", 0.5f);
151 ASSERT_GL_NO_ERROR();
152
153 glEnable(GL_BLEND);
154 glBlendEquation(GL_FUNC_ADD);
155 glBlendFunc(GL_ONE, GL_ONE);
156
157 // Draw green
158 glUniform1i(location, 1);
159 ASSERT_GL_NO_ERROR();
160 drawQuad(program, "a_position", 0.5f);
161 ASSERT_GL_NO_ERROR();
162
163 // Draw red
164 glUniform1i(location, 0);
165 ASSERT_GL_NO_ERROR();
166 drawQuad(program, "a_position", 0.5f);
167 ASSERT_GL_NO_ERROR();
168
169 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::yellow);
170 }
171
172 // Samplers are only supported on ES3.
173 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplersTest);
174 ANGLE_INSTANTIATE_TEST_ES3(SamplersTest);
175
176 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplersTest31);
177 ANGLE_INSTANTIATE_TEST_ES31(SamplersTest31);
178 } // namespace angle
179