Commit 8d47c114 by alokp@chromium.org

Emit "#version 120" if the shader has array as out parameter.

Review URL: https://codereview.appspot.com/6494082 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1273 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 85fee29c
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2012 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.
//
......@@ -9,17 +9,22 @@
static const int GLSL_VERSION_110 = 110;
static const int GLSL_VERSION_120 = 120;
// We need to scan for three things:
// We need to scan for the following:
// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
// but only at the global scope.
// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
// but inside any scope.
// 3. Call to a matrix constructor with another matrix as argument.
// (These constructors were reserved in GLSL version 1.10.)
//
// If it weren't for (3) then we would only need to scan the global
// scope of the vertex shader. However, we need to scan the entire
// shader in both cases.
// 4. Arrays as "out" function parameters.
// GLSL spec section 6.1.1: "When calling a function, expressions that do
// not evaluate to l-values cannot be passed to parameters declared as
// out or inout."
// GLSL 1.1 section 5.8: "Other binary or unary expressions,
// non-dereferenced arrays, function names, swizzles with repeated fields,
// and constants cannot be l-values."
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
// are built-in types, entire structures or arrays... are all l-values."
//
// TODO(alokp): The following two cases of invariant decalaration get lost
// during parsing - they do not get carried over to the intermediate tree.
......@@ -79,6 +84,26 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
}
break;
}
case EOpParameters: {
const TIntermSequence& params = node->getSequence();
for (TIntermSequence::const_iterator iter = params.begin();
iter != params.end(); ++iter)
{
const TIntermTyped* param = (*iter)->getAsTyped();
if (param->isArray())
{
TQualifier qualifier = param->getQualifier();
if ((qualifier == EvqOut) || (qualifier == EvqInOut))
{
updateVersion(GLSL_VERSION_120);
break;
}
}
}
// Fully processed. No need to visit children.
visitChildren = false;
break;
}
case EOpConstructMat2:
case EOpConstructMat3:
case EOpConstructMat4: {
......
......@@ -22,14 +22,18 @@
// - c++ style name hiding rules.
// - built-in variable gl_PointCoord for fragment shaders.
// - matrix constructors taking matrix as argument.
// - array as "out" function parameters
//
class TVersionGLSL : public TIntermTraverser {
public:
TVersionGLSL(ShShaderType type);
// Returns 120 if "invariant" keyword, "gl_PointCoord", or
// matrix/matrix constructors are used in the shader. Else 110 is
// returned.
// Returns 120 if the following is used the shader:
// - "invariant",
// - "gl_PointCoord",
// - matrix/matrix constructors
// - array "out" parameters
// Else 110 is returned.
int getVersion() { return mVersion; }
virtual void visitSymbol(TIntermSymbol*);
......
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