blob: c53659175215eddc4ebafdea8acf9c3d940ae22d [file] [log] [blame]
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TextureFunction_test.cpp:
// Tests that malformed texture function calls don't pass compilation.
//
#include <array>
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h"
#include "gtest/gtest.h"
#include "tests/test_utils/ShaderCompileTreeTest.h"
using namespace sh;
class TextureFunctionTest : public ShaderCompileTreeTest
{
public:
TextureFunctionTest() {}
protected:
::GLenum getShaderType() const override { return GL_FRAGMENT_SHADER; }
ShShaderSpec getShaderSpec() const override { return SH_GLES3_1_SPEC; }
};
// Test that none of the texture offset functions can take a non-constant parameter.
TEST_F(TextureFunctionTest, NonConstantOffset)
{
const std::string &shaderTemplate =
R"(#version 310 es
precision mediump float;
out vec4 my_FragColor;
uniform sampler2D s;
uniform vec4 samplePos;
void main()
{
my_FragColor = {sample};
})";
const std::array<const std::string, 10> sampleVariants(
{"texelFetchOffset(s, ivec2(samplePos.xy), 0, {offset})",
"textureLodOffset(s, samplePos.xy, 0.0, {offset})",
"textureProjLodOffset(s, samplePos.xyz, 0.0, {offset})",
"textureGradOffset(s, samplePos.xy, vec2(1.0), vec2(1.0), {offset})",
"textureProjGradOffset(s, samplePos.xyz, vec2(1.0), vec2(1.0), {offset})",
"textureOffset(s, samplePos.xy, {offset})",
"textureOffset(s, samplePos.xy, {offset}, 1.0)",
"textureProjOffset(s, samplePos.xyz, {offset})",
"textureProjOffset(s, samplePos.xyz, {offset}, 1.0)",
"textureGatherOffset(s, samplePos.xy, {offset})"});
size_t sampleReplacePos = shaderTemplate.find("{sample}");
for (auto &variantTemplate : sampleVariants)
{
size_t offsetReplacePos = variantTemplate.find("{offset}");
std::string variantConst = variantTemplate;
variantConst.replace(offsetReplacePos, 8, "ivec2(0, 0)");
std::string shaderValid = shaderTemplate;
shaderValid.replace(sampleReplacePos, 8, variantConst);
if (!compile(shaderValid))
{
FAIL() << "Shader compilation failed with sample function " << variantConst
<< ", expecting success:\n"
<< mInfoLog;
}
std::string variantNonConst = variantTemplate;
variantNonConst.replace(offsetReplacePos, 8, "ivec2(samplePos.xy)");
std::string shaderNonConst = shaderTemplate;
shaderNonConst.replace(sampleReplacePos, 8, variantNonConst);
if (compile(shaderNonConst))
{
FAIL() << "Shader compilation succeeded with sample function " << variantNonConst
<< ", expecting failure:\n"
<< mInfoLog;
}
std::string variantOutOfBounds = variantTemplate;
variantOutOfBounds.replace(offsetReplacePos, 8, "ivec2(1000, 1000)");
std::string shaderOutOfBounds = shaderTemplate;
shaderOutOfBounds.replace(sampleReplacePos, 8, variantOutOfBounds);
if (compile(shaderOutOfBounds))
{
FAIL() << "Shader compilation succeeded with sample function " << variantOutOfBounds
<< ", expecting failure:\n"
<< mInfoLog;
}
}
}