xref: /aosp_15_r20/external/angle/src/tests/compiler_tests/TextureFunction_test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 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 // TextureFunction_test.cpp:
7 //   Tests that malformed texture function calls don't pass compilation.
8 //
9 
10 #include <array>
11 
12 #include "GLSLANG/ShaderLang.h"
13 #include "angle_gl.h"
14 #include "gtest/gtest.h"
15 #include "tests/test_utils/ShaderCompileTreeTest.h"
16 
17 using namespace sh;
18 
19 class TextureFunctionTest : public ShaderCompileTreeTest
20 {
21   public:
TextureFunctionTest()22     TextureFunctionTest() {}
23 
24   protected:
getShaderType() const25     ::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
getShaderSpec() const26     ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
27 };
28 
29 // Test that none of the texture offset functions can take a non-constant parameter.
TEST_F(TextureFunctionTest,NonConstantOffset)30 TEST_F(TextureFunctionTest, NonConstantOffset)
31 {
32     const std::string &shaderTemplate =
33         R"(#version 310 es
34         precision mediump float;
35         out vec4 my_FragColor;
36         uniform sampler2D s;
37         uniform vec4 samplePos;
38 
39         void main()
40         {
41             my_FragColor = {sample};
42         })";
43 
44     const std::array<const std::string, 10> sampleVariants(
45         {"texelFetchOffset(s, ivec2(samplePos.xy), 0, {offset})",
46          "textureLodOffset(s, samplePos.xy, 0.0, {offset})",
47          "textureProjLodOffset(s, samplePos.xyz, 0.0, {offset})",
48          "textureGradOffset(s, samplePos.xy, vec2(1.0), vec2(1.0), {offset})",
49          "textureProjGradOffset(s, samplePos.xyz, vec2(1.0), vec2(1.0), {offset})",
50          "textureOffset(s, samplePos.xy, {offset})",
51          "textureOffset(s, samplePos.xy, {offset}, 1.0)",
52          "textureProjOffset(s, samplePos.xyz, {offset})",
53          "textureProjOffset(s, samplePos.xyz, {offset}, 1.0)",
54          "textureGatherOffset(s, samplePos.xy, {offset})"});
55 
56     size_t sampleReplacePos = shaderTemplate.find("{sample}");
57 
58     for (auto &variantTemplate : sampleVariants)
59     {
60         size_t offsetReplacePos = variantTemplate.find("{offset}");
61 
62         std::string variantConst = variantTemplate;
63         variantConst.replace(offsetReplacePos, 8, "ivec2(0, 0)");
64 
65         std::string shaderValid = shaderTemplate;
66         shaderValid.replace(sampleReplacePos, 8, variantConst);
67         if (!compile(shaderValid))
68         {
69             FAIL() << "Shader compilation failed with sample function " << variantConst
70                    << ", expecting success:\n"
71                    << mInfoLog;
72         }
73 
74         std::string variantNonConst = variantTemplate;
75         variantNonConst.replace(offsetReplacePos, 8, "ivec2(samplePos.xy)");
76 
77         std::string shaderNonConst = shaderTemplate;
78         shaderNonConst.replace(sampleReplacePos, 8, variantNonConst);
79         if (compile(shaderNonConst))
80         {
81             FAIL() << "Shader compilation succeeded with sample function " << variantNonConst
82                    << ", expecting failure:\n"
83                    << mInfoLog;
84         }
85 
86         std::string variantOutOfBounds = variantTemplate;
87         variantOutOfBounds.replace(offsetReplacePos, 8, "ivec2(1000, 1000)");
88 
89         std::string shaderOutOfBounds = shaderTemplate;
90         shaderOutOfBounds.replace(sampleReplacePos, 8, variantOutOfBounds);
91         if (compile(shaderOutOfBounds))
92         {
93             FAIL() << "Shader compilation succeeded with sample function " << variantOutOfBounds
94                    << ", expecting failure:\n"
95                    << mInfoLog;
96         }
97     }
98 }
99