1 //
2 // Copyright 2024 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 // These tests assert that textures incompatible with samplers do not cause any runtime errors.
7
8 #include "test_utils/ANGLETest.h"
9 #include "test_utils/gl_raii.h"
10
11 using namespace angle;
12
13 namespace
14 {
15
16 enum class SamplerType
17 {
18 Float,
19 SignedInteger,
20 UnsignedInteger,
21 Shadow,
22 };
23
24 enum class TextureType
25 {
26 UnsignedNormalized,
27 SignedNormalized,
28 Float,
29 UnsignedInteger,
30 SignedInteger,
31 Depth,
32 DepthStencilDepthMode,
33 DepthStencilStencilMode,
34 Stencil,
35 };
36
37 enum class TextureCompareMode
38 {
39 None,
40 Ref,
41 };
42
43 // Variations corresponding to enums above.
44 using IncompatibleTextureVariationsTestParams =
45 std::tuple<angle::PlatformParameters, SamplerType, TextureType, TextureCompareMode>;
46
operator <<(std::ostream & out,SamplerType samplerType)47 std::ostream &operator<<(std::ostream &out, SamplerType samplerType)
48 {
49 switch (samplerType)
50 {
51 case SamplerType::Float:
52 out << "Float";
53 break;
54 case SamplerType::SignedInteger:
55 out << "SignedInteger";
56 break;
57 case SamplerType::UnsignedInteger:
58 out << "UnsignedInteger";
59 break;
60 case SamplerType::Shadow:
61 out << "Shadow";
62 break;
63 }
64
65 return out;
66 }
67
operator <<(std::ostream & out,TextureType textureType)68 std::ostream &operator<<(std::ostream &out, TextureType textureType)
69 {
70 switch (textureType)
71 {
72 case TextureType::UnsignedNormalized:
73 out << "UnsignedNormalized";
74 break;
75 case TextureType::SignedNormalized:
76 out << "SignedNormalized";
77 break;
78 case TextureType::Float:
79 out << "Float";
80 break;
81 case TextureType::UnsignedInteger:
82 out << "UnsignedInteger";
83 break;
84 case TextureType::SignedInteger:
85 out << "SignedInteger";
86 break;
87 case TextureType::Depth:
88 out << "Depth";
89 break;
90 case TextureType::DepthStencilDepthMode:
91 out << "DepthStencilDepthMode";
92 break;
93 case TextureType::DepthStencilStencilMode:
94 out << "DepthStencilStencilMode";
95 break;
96 case TextureType::Stencil:
97 out << "Stencil";
98 break;
99 }
100
101 return out;
102 }
103
operator <<(std::ostream & out,TextureCompareMode textureCompareMode)104 std::ostream &operator<<(std::ostream &out, TextureCompareMode textureCompareMode)
105 {
106 switch (textureCompareMode)
107 {
108 case TextureCompareMode::None:
109 out << "None";
110 break;
111 case TextureCompareMode::Ref:
112 out << "Ref";
113 break;
114 }
115
116 return out;
117 }
118
ParseIncompatibleTextureTestParams(const IncompatibleTextureVariationsTestParams & params,SamplerType * samplerTypeOut,TextureType * textureTypeOut,TextureCompareMode * textureCompareModeOut)119 void ParseIncompatibleTextureTestParams(const IncompatibleTextureVariationsTestParams ¶ms,
120 SamplerType *samplerTypeOut,
121 TextureType *textureTypeOut,
122 TextureCompareMode *textureCompareModeOut)
123 {
124 *samplerTypeOut = std::get<1>(params);
125 *textureTypeOut = std::get<2>(params);
126 *textureCompareModeOut = std::get<3>(params);
127 }
128
IncompatibleTextureVariationsTestPrint(const::testing::TestParamInfo<IncompatibleTextureVariationsTestParams> & paramsInfo)129 std::string IncompatibleTextureVariationsTestPrint(
130 const ::testing::TestParamInfo<IncompatibleTextureVariationsTestParams> ¶msInfo)
131 {
132 const IncompatibleTextureVariationsTestParams ¶ms = paramsInfo.param;
133 std::ostringstream out;
134
135 out << std::get<0>(params);
136
137 SamplerType samplerType;
138 TextureType textureType;
139 TextureCompareMode textureCompareMode;
140 ParseIncompatibleTextureTestParams(params, &samplerType, &textureType, &textureCompareMode);
141
142 out << "__" << "SamplerType" << samplerType << "_" << "TextureType" << textureType << "_"
143 << "TextureCompareMode" << textureCompareMode;
144 return out.str();
145 }
146
147 class IncompatibleTextureTest : public ANGLETest<IncompatibleTextureVariationsTestParams>
148 {};
149
150 // Test that no errors are generated
TEST_P(IncompatibleTextureTest,Test)151 TEST_P(IncompatibleTextureTest, Test)
152 {
153 SamplerType samplerType;
154 TextureType textureType;
155 TextureCompareMode textureCompareMode;
156 ParseIncompatibleTextureTestParams(GetParam(), &samplerType, &textureType, &textureCompareMode);
157
158 std::stringstream fragmentSource;
159 fragmentSource << "#version 300 es\n" << "out mediump vec4 my_FragColor;\n";
160 switch (samplerType)
161 {
162 case SamplerType::Float:
163 fragmentSource << "uniform mediump sampler2D tex;\n";
164 break;
165 case SamplerType::SignedInteger:
166 fragmentSource << "uniform mediump isampler2D tex;\n";
167 break;
168 case SamplerType::UnsignedInteger:
169 fragmentSource << "uniform mediump usampler2D tex;\n";
170 break;
171 case SamplerType::Shadow:
172 fragmentSource << "uniform mediump sampler2DShadow tex;\n";
173 break;
174 }
175 fragmentSource << "void main()\n" << "{\n";
176 fragmentSource << " my_FragColor = vec4(texture(tex, "
177 << (samplerType == SamplerType::Shadow ? "vec3" : "vec2") << "(0)));\n";
178 fragmentSource << "}";
179 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fragmentSource.str().c_str());
180 ASSERT_GL_NO_ERROR();
181
182 GLTexture tex;
183 glBindTexture(GL_TEXTURE_2D, tex);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
186 switch (textureType)
187 {
188 case TextureType::UnsignedNormalized:
189 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
190 break;
191 case TextureType::SignedNormalized:
192 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, 1, 1, 0, GL_RGBA, GL_BYTE, nullptr);
193 break;
194 case TextureType::Float:
195 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT, nullptr);
196 break;
197 case TextureType::UnsignedInteger:
198 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1, 1, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
199 nullptr);
200 break;
201 case TextureType::SignedInteger:
202 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, 1, 1, 0, GL_RGBA_INTEGER, GL_BYTE, nullptr);
203 break;
204 case TextureType::Depth:
205 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1, 1, 0, GL_DEPTH_COMPONENT,
206 GL_UNSIGNED_SHORT, nullptr);
207 break;
208 case TextureType::DepthStencilDepthMode:
209 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL,
210 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, nullptr);
211 break;
212 case TextureType::DepthStencilStencilMode:
213 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_stencil_texturing"));
214 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL,
215 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, nullptr);
216 glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE_ANGLE, GL_STENCIL_INDEX);
217 break;
218 case TextureType::Stencil:
219 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
220 glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, 1, 1, 0, GL_STENCIL_INDEX,
221 GL_UNSIGNED_BYTE, nullptr);
222 break;
223 }
224 ASSERT_GL_NO_ERROR();
225
226 switch (textureCompareMode)
227 {
228 case TextureCompareMode::None:
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
230 break;
231 case TextureCompareMode::Ref:
232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
233 break;
234 }
235 ASSERT_GL_NO_ERROR();
236
237 drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
238 EXPECT_GL_NO_ERROR();
239 }
240
241 constexpr SamplerType kSamplerTypes[] = {
242 SamplerType::Float,
243 SamplerType::SignedInteger,
244 SamplerType::UnsignedInteger,
245 SamplerType::Shadow,
246 };
247 constexpr TextureType kTextureTypes[] = {
248 TextureType::UnsignedNormalized, TextureType::SignedNormalized, TextureType::Float,
249 TextureType::UnsignedInteger, TextureType::SignedInteger, TextureType::Depth,
250 TextureType::DepthStencilDepthMode, TextureType::DepthStencilStencilMode, TextureType::Stencil,
251 };
252 constexpr TextureCompareMode kTextureCompareModes[] = {
253 TextureCompareMode::None,
254 TextureCompareMode::Ref,
255 };
256
257 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IncompatibleTextureTest);
258 ANGLE_INSTANTIATE_TEST_COMBINE_3(IncompatibleTextureTest,
259 IncompatibleTextureVariationsTestPrint,
260 testing::ValuesIn(kSamplerTypes),
261 testing::ValuesIn(kTextureTypes),
262 testing::ValuesIn(kTextureCompareModes),
263 ANGLE_ALL_TEST_PLATFORMS_ES3);
264
265 } // anonymous namespace
266