Commit 39f0247a by Sean Risser

Don't let shaders negate samplers

Prior to this change, the OpenGL compiler accepted all "non-struct" "non-array" types for unary operations (++, --, and -). This ignored the existence of sampler objects. If someone tried to negate a sampler, then the compiler would tell the assembler to negate a non- numerical type. This change makes it so the GSL compiler only accepts unary operations on numerical types (including vectors and matrices). Also added a unittest that makes sure we gracefully fail to compile bad unary operations. Bug chromium:910883 Change-Id: Ia69056b31664900c3126cab42ecb8603d1a5d7db Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32448Tested-by: 's avatarSean Risser <srisser@google.com> Presubmit-Ready: Sean Risser <srisser@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 6dd5f335
......@@ -497,7 +497,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, con
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
if (!child->getType().isScalar() && !child->getType().isVector() && !child->getType().isMatrix())
return 0;
default: break;
}
......
......@@ -444,7 +444,7 @@ public:
TInterfaceBlock *getAsInterfaceBlock() const { return isInterfaceBlock() ? getInterfaceBlock() : nullptr; }
bool isVector() const { return primarySize > 1 && !isMatrix(); }
bool isScalar() const { return primarySize == 1 && !isMatrix() && !structure && !isInterfaceBlock(); }
bool isScalar() const { return primarySize == 1 && !isMatrix() && !structure && !isInterfaceBlock() && !IsSampler(getBasicType()); }
bool isRegister() const { return !isMatrix() && !structure && !array && !isInterfaceBlock(); } // Fits in a 4-element register
bool isStruct() const { return structure != 0; }
bool isScalarInt() const { return isScalar() && IsInteger(type); }
......
......@@ -381,23 +381,26 @@ protected:
checkCompiles("", s);
}
void checkCompileFails(GLuint glShader, std::string source)
void checkCompileFails(GLenum glShaderType, std::string source)
{
GLchar buf[1024];
Initialize(3, false);
GLint compileStatus = 0;
const char *c_source[1] = { source.c_str() };
GLuint glShader = glCreateShader(glShaderType);
glShaderSource(glShader, 1, c_source, nullptr);
glCompileShader(glShader);
EXPECT_GLENUM_EQ(GL_NONE, glGetError());
EXPECT_GLENUM_EQ(GL_NO_ERROR, glGetError());
glGetShaderiv(glShader, GL_COMPILE_STATUS, &compileStatus);
glGetShaderInfoLog(glShader, sizeof(buf), nullptr, buf);
EXPECT_EQ(compileStatus, GL_FALSE) << "Compile status: " << std::endl << buf;
EXPECT_EQ(compileStatus, GL_FALSE);
glDeleteShader(glShader);
Uninitialize();
}
void checkCompileFails(std::string s)
......@@ -429,8 +432,8 @@ protected:
vs = replace(vs, "$INSERT", s);
fs = replace(fs, "$INSERT", s);
checkCompileFails(glCreateShader(GL_VERTEX_SHADER), vs);
checkCompileFails(glCreateShader(GL_FRAGMENT_SHADER), fs);
checkCompileFails(GL_VERTEX_SHADER, vs);
checkCompileFails(GL_FRAGMENT_SHADER, fs);
}
EGLDisplay getDisplay() const { return display; }
......@@ -1823,8 +1826,6 @@ TEST_F(SwiftShaderTest, CompilerLimits_SparseLabels)
// GL_MAX_{VERTEX/FRAGMENT}_UNIFORM_VECTOR.
TEST_F(SwiftShaderTest, CompilerLimits_ArraySize)
{
Initialize(3, false);
checkCompileFails(
"uniform float u_var[100000000];\n"
"float F(float f) { return u_var[2]; }\n");
......@@ -1832,8 +1833,35 @@ TEST_F(SwiftShaderTest, CompilerLimits_ArraySize)
"struct structType { mediump sampler2D m0; mediump samplerCube m1; }; \n"
"uniform structType u_var[100000000];\n"
"float F(float f) { return texture(u_var[2].m1, vec3(0.0)), vec4(0.26, 1.72, 0.60, 0.12).x; }\n");
}
Uninitialize();
// Test that the compiler rejects negations of things that can't be negated.
TEST_F(SwiftShaderTest, BadNegation)
{
checkCompileFails(
"uniform samplerCube m;\n"
"float F (float f) { vec4 ret = texture(-m, vec3(f)); return ret.x; }\n"
);
checkCompileFails(
"uniform sampler2D m[9];\n"
"vec4 G (sampler2D X[9]) { return texture(X[0], vec2(0.0f)); }"
"float F (float f) { vec4 ret = G(-m); return ret.x; }\n"
);
checkCompileFails(
"struct structType { int a; float b; };\n"
"uniform structType m;\n"
"float F (float f) { structType n = -m; return f; }\n"
);
checkCompileFails(
"struct structType { int a; float b; };\n"
"uniform structType m[4];\n"
"float F (float f) { structType n[4] = -m; return f; }\n"
);
checkCompileFails(
"uniform float m[4];\n"
"float G (float f[4]) { return f[0]; }\n"
"float F (float f) { return G(-m); }\n"
);
}
#ifndef EGL_ANGLE_iosurface_client_buffer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment