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_AND(SamplersTest31, WithDirectSPIRVGeneration(ES31_VULKAN()));
182 }  // namespace angle
183