Commit 72111915 by Zhenyao Mo Committed by Commit Bot

Initialize all output variables.

BUG=angleproject:1441 TEST=bots Change-Id: Ia4cf415d8346c3234bf0f548a178ee3ea8cd35c4 Reviewed-on: https://chromium-review.googlesource.com/362110Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Zhenyao Mo <zmo@chromium.org>
parent dacac90a
...@@ -48,7 +48,7 @@ typedef unsigned int GLenum; ...@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 149 #define ANGLE_SH_VERSION 150
typedef enum { typedef enum {
SH_GLES2_SPEC, SH_GLES2_SPEC,
...@@ -116,101 +116,101 @@ typedef enum ...@@ -116,101 +116,101 @@ typedef enum
// Compile options. // Compile options.
typedef enum { typedef enum {
SH_VALIDATE = 0, SH_VALIDATE = 0,
SH_VALIDATE_LOOP_INDEXING = 0x0001, SH_VALIDATE_LOOP_INDEXING = 0x0001,
SH_INTERMEDIATE_TREE = 0x0002, SH_INTERMEDIATE_TREE = 0x0002,
SH_OBJECT_CODE = 0x0004, SH_OBJECT_CODE = 0x0004,
SH_VARIABLES = 0x0008, SH_VARIABLES = 0x0008,
SH_LINE_DIRECTIVES = 0x0010, SH_LINE_DIRECTIVES = 0x0010,
SH_SOURCE_PATH = 0x0020, SH_SOURCE_PATH = 0x0020,
SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0040, SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0040,
// If a sampler array index happens to be a loop index, // If a sampler array index happens to be a loop index,
// 1) if its type is integer, unroll the loop. // 1) if its type is integer, unroll the loop.
// 2) if its type is float, fail the shader compile. // 2) if its type is float, fail the shader compile.
// This is to work around a mac driver bug. // This is to work around a mac driver bug.
SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX = 0x0080, SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX = 0x0080,
// This is needed only as a workaround for certain OpenGL driver bugs. // This is needed only as a workaround for certain OpenGL driver bugs.
SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100, SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100,
// This is an experimental flag to enforce restrictions that aim to prevent // This is an experimental flag to enforce restrictions that aim to prevent
// timing attacks. // timing attacks.
// It generates compilation errors for shaders that could expose sensitive // It generates compilation errors for shaders that could expose sensitive
// texture information via the timing channel. // texture information via the timing channel.
// To use this flag, you must compile the shader under the WebGL spec // To use this flag, you must compile the shader under the WebGL spec
// (using the SH_WEBGL_SPEC flag). // (using the SH_WEBGL_SPEC flag).
SH_TIMING_RESTRICTIONS = 0x0200, SH_TIMING_RESTRICTIONS = 0x0200,
// This flag prints the dependency graph that is used to enforce timing // This flag prints the dependency graph that is used to enforce timing
// restrictions on fragment shaders. // restrictions on fragment shaders.
// This flag only has an effect if all of the following are true: // This flag only has an effect if all of the following are true:
// - The shader spec is SH_WEBGL_SPEC. // - The shader spec is SH_WEBGL_SPEC.
// - The compile options contain the SH_TIMING_RESTRICTIONS flag. // - The compile options contain the SH_TIMING_RESTRICTIONS flag.
// - The shader type is GL_FRAGMENT_SHADER. // - The shader type is GL_FRAGMENT_SHADER.
SH_DEPENDENCY_GRAPH = 0x0400, SH_DEPENDENCY_GRAPH = 0x0400,
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions. // Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
// This flag only enforces (and can only enforce) the packing // This flag only enforces (and can only enforce) the packing
// restrictions for uniform variables in both vertex and fragment // restrictions for uniform variables in both vertex and fragment
// shaders. ShCheckVariablesWithinPackingLimits() lets embedders // shaders. ShCheckVariablesWithinPackingLimits() lets embedders
// enforce the packing restrictions for varying variables during // enforce the packing restrictions for varying variables during
// program link time. // program link time.
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800, SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
// This flag ensures all indirect (expression-based) array indexing // This flag ensures all indirect (expression-based) array indexing
// is clamped to the bounds of the array. This ensures, for example, // is clamped to the bounds of the array. This ensures, for example,
// that you cannot read off the end of a uniform, whether an array // that you cannot read off the end of a uniform, whether an array
// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum, // vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
// specified in the ShBuiltInResources when constructing the // specified in the ShBuiltInResources when constructing the
// compiler, selects the strategy for the clamping implementation. // compiler, selects the strategy for the clamping implementation.
SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000, SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000,
// This flag limits the complexity of an expression. // This flag limits the complexity of an expression.
SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000, SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000,
// This flag limits the depth of the call stack. // This flag limits the depth of the call stack.
SH_LIMIT_CALL_STACK_DEPTH = 0x4000, SH_LIMIT_CALL_STACK_DEPTH = 0x4000,
// This flag initializes gl_Position to vec4(0,0,0,0) at the // This flag initializes gl_Position to vec4(0,0,0,0) at the
// beginning of the vertex shader's main(), and has no effect in the // beginning of the vertex shader's main(), and has no effect in the
// fragment shader. It is intended as a workaround for drivers which // fragment shader. It is intended as a workaround for drivers which
// incorrectly fail to link programs if gl_Position is not written. // incorrectly fail to link programs if gl_Position is not written.
SH_INIT_GL_POSITION = 0x8000, SH_INIT_GL_POSITION = 0x8000,
// This flag replaces // This flag replaces
// "a && b" with "a ? b : false", // "a && b" with "a ? b : false",
// "a || b" with "a ? true : b". // "a || b" with "a ? true : b".
// This is to work around a MacOSX driver bug that |b| is executed // This is to work around a MacOSX driver bug that |b| is executed
// independent of |a|'s value. // independent of |a|'s value.
SH_UNFOLD_SHORT_CIRCUIT = 0x10000, SH_UNFOLD_SHORT_CIRCUIT = 0x10000,
// This flag initializes varyings without static use in vertex shader // This flag initializes output variables to 0 at the beginning of main().
// at the beginning of main(), and has no effects in the fragment shader. // It is to avoid undefined behaviors.
// It is intended as a workaround for drivers which incorrectly optimize SH_INIT_OUTPUT_VARIABLES = 0x20000,
// out such varyings and cause a link failure. // TODO(zmo): obsolete, remove after ANGLE roll into Chromium.
SH_INIT_VARYINGS_WITHOUT_STATIC_USE = 0x20000, SH_INIT_VARYINGS_WITHOUT_STATIC_USE = 0x20000,
// This flag scalarizes vec/ivec/bvec/mat constructor args. // This flag scalarizes vec/ivec/bvec/mat constructor args.
// It is intended as a workaround for Linux/Mac driver bugs. // It is intended as a workaround for Linux/Mac driver bugs.
SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000, SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000,
// This flag overwrites a struct name with a unique prefix. // This flag overwrites a struct name with a unique prefix.
// It is intended as a workaround for drivers that do not handle // It is intended as a workaround for drivers that do not handle
// struct scopes correctly, including all Mac drivers and Linux AMD. // struct scopes correctly, including all Mac drivers and Linux AMD.
SH_REGENERATE_STRUCT_NAMES = 0x80000, SH_REGENERATE_STRUCT_NAMES = 0x80000,
// This flag makes the compiler not prune unused function early in the // This flag makes the compiler not prune unused function early in the
// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH // compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH
// helps avoid bad shaders causing stack overflows. // helps avoid bad shaders causing stack overflows.
SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000, SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000,
// This flag works around a bug in NVIDIA 331 series drivers related // This flag works around a bug in NVIDIA 331 series drivers related
// to pow(x, y) where y is a constant vector. // to pow(x, y) where y is a constant vector.
SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000, SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000,
// This flag works around bugs in Mac drivers related to do-while by // This flag works around bugs in Mac drivers related to do-while by
// transforming them into an other construct. // transforming them into an other construct.
SH_REWRITE_DO_WHILE_LOOPS = 0x400000, SH_REWRITE_DO_WHILE_LOOPS = 0x400000,
} ShCompileOptions; } ShCompileOptions;
// Defines alternate strategies for implementing array index clamping. // Defines alternate strategies for implementing array index clamping.
......
...@@ -362,9 +362,10 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -362,9 +362,10 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[],
infoSink.info << "too many uniforms"; infoSink.info << "too many uniforms";
} }
} }
if (success && shaderType == GL_VERTEX_SHADER && if (success && (compileOptions & SH_INIT_OUTPUT_VARIABLES))
(compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) {
initializeVaryingsWithoutStaticUse(root); initializeOutputVariables(root, shaderType);
}
} }
if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
...@@ -810,37 +811,32 @@ bool TCompiler::enforcePackingRestrictions() ...@@ -810,37 +811,32 @@ bool TCompiler::enforcePackingRestrictions()
void TCompiler::initializeGLPosition(TIntermNode* root) void TCompiler::initializeGLPosition(TIntermNode* root)
{ {
InitializeVariables::InitVariableInfoList variables; InitVariableList list;
InitializeVariables::InitVariableInfo var( sh::ShaderVariable var(GL_FLOAT_VEC4, 0);
"gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4)); var.name = "gl_Position";
variables.push_back(var); list.push_back(var);
InitializeVariables initializer(variables); InitializeVariables(root, list);
root->traverse(&initializer);
} }
void TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root) void TCompiler::initializeOutputVariables(TIntermNode *root, sh::GLenum shaderType)
{ {
InitializeVariables::InitVariableInfoList variables; InitVariableList list;
for (size_t ii = 0; ii < varyings.size(); ++ii) if (shaderType == GL_VERTEX_SHADER)
{ {
const sh::Varying& varying = varyings[ii]; for (auto var : varyings)
if (varying.staticUse)
continue;
unsigned char primarySize = static_cast<unsigned char>(gl::VariableColumnCount(varying.type));
unsigned char secondarySize = static_cast<unsigned char>(gl::VariableRowCount(varying.type));
TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray());
TString name = varying.name.c_str();
if (varying.isArray())
{ {
type.setArraySize(varying.arraySize); sh::ExpandVariable(var, var.name, var.mappedName, false, &list);
name = name.substr(0, name.find_first_of('[')); }
}
else
{
ASSERT(shaderType == GL_FRAGMENT_SHADER);
for (auto var : outputVariables)
{
list.push_back(var);
} }
InitializeVariables::InitVariableInfo var(name, type);
variables.push_back(var);
} }
InitializeVariables initializer(variables); InitializeVariables(root, list);
root->traverse(&initializer);
} }
const TExtensionBehavior& TCompiler::getExtensionBehavior() const const TExtensionBehavior& TCompiler::getExtensionBehavior() const
......
...@@ -130,11 +130,9 @@ class TCompiler : public TShHandleBase ...@@ -130,11 +130,9 @@ class TCompiler : public TShHandleBase
// Returns true if, after applying the packing rules in the GLSL 1.017 spec // Returns true if, after applying the packing rules in the GLSL 1.017 spec
// Appendix A, section 7, the shader does not use too many uniforms. // Appendix A, section 7, the shader does not use too many uniforms.
bool enforcePackingRestrictions(); bool enforcePackingRestrictions();
// Insert statements to initialize varyings without static use in the beginning // Insert statements to initialize output variables in the beginning of main().
// of main(). It is to work around a Mac driver where such varyings in a vertex // This is to avoid undefined behaviors.
// shader may be optimized out incorrectly at compile time, causing a link failure. void initializeOutputVariables(TIntermNode *root, sh::GLenum shaderType);
// This function should only be applied to vertex shaders.
void initializeVaryingsWithoutStaticUse(TIntermNode* root);
// Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
// It is to work around a Linux driver bug where missing this causes compile failure // It is to work around a Linux driver bug where missing this causes compile failure
// while spec says it is allowed. // while spec says it is allowed.
......
...@@ -6,23 +6,40 @@ ...@@ -6,23 +6,40 @@
#include "compiler/translator/InitializeVariables.h" #include "compiler/translator/InitializeVariables.h"
#include "angle_gl.h"
#include "common/debug.h" #include "common/debug.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/util.h"
namespace namespace
{ {
TIntermConstantUnion *constructFloatConstUnionNode(const TType &type) TIntermConstantUnion *constructConstUnionNode(const TType &type)
{ {
TType myType = type; TType myType = type;
unsigned char size = static_cast<unsigned char>(myType.getNominalSize());
if (myType.isMatrix())
size *= size;
TConstantUnion *u = new TConstantUnion[size];
for (int ii = 0; ii < size; ++ii)
u[ii].setFConst(0.0f);
myType.clearArrayness(); myType.clearArrayness();
myType.setQualifier(EvqConst); myType.setQualifier(EvqConst);
size_t size = myType.getObjectSize();
TConstantUnion *u = new TConstantUnion[size];
for (size_t ii = 0; ii < size; ++ii)
{
switch (type.getBasicType())
{
case EbtFloat:
u[ii].setFConst(0.0f);
break;
case EbtInt:
u[ii].setIConst(0);
break;
case EbtUInt:
u[ii].setUConst(0u);
break;
default:
UNREACHABLE();
return nullptr;
}
}
TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
return node; return node;
} }
...@@ -37,9 +54,33 @@ TIntermConstantUnion *constructIndexNode(int index) ...@@ -37,9 +54,33 @@ TIntermConstantUnion *constructIndexNode(int index)
return node; return node;
} }
} // namespace anonymous class VariableInitializer : public TIntermTraverser
{
public:
VariableInitializer(const InitVariableList &vars)
: TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
{
}
protected:
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
bool visitSelection(Visit, TIntermSelection *node) override { return false; }
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void insertInitCode(TIntermSequence *sequence);
const InitVariableList &mVariables;
bool mCodeInserted;
};
// VariableInitializer implementation.
bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
bool visitChildren = !mCodeInserted; bool visitChildren = !mCodeInserted;
switch (node->getOp()) switch (node->getOp())
...@@ -77,28 +118,33 @@ bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -77,28 +118,33 @@ bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node)
return visitChildren; return visitChildren;
} }
void InitializeVariables::insertInitCode(TIntermSequence *sequence) void VariableInitializer::insertInitCode(TIntermSequence *sequence)
{ {
for (size_t ii = 0; ii < mVariables.size(); ++ii) for (size_t ii = 0; ii < mVariables.size(); ++ii)
{ {
const InitVariableInfo &varInfo = mVariables[ii]; const sh::ShaderVariable &var = mVariables[ii];
ASSERT(!var.isStruct());
if (varInfo.type.isArray()) TType type = sh::ConvertShaderVariableTypeToTType(var.type);
TString name = TString(var.name.c_str());
if (var.isArray())
{ {
for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index) size_t pos = name.find_last_of('[');
if (pos != TString::npos)
name = name.substr(0, pos);
for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index)
{ {
TIntermBinary *assign = new TIntermBinary(EOpAssign); TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign); sequence->insert(sequence->begin(), assign);
TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
indexDirect->setLeft(symbol); indexDirect->setLeft(symbol);
TIntermConstantUnion *indexNode = constructIndexNode(index); TIntermConstantUnion *indexNode = constructIndexNode(index);
indexDirect->setRight(indexNode); indexDirect->setRight(indexNode);
assign->setLeft(indexDirect); assign->setLeft(indexDirect);
TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
assign->setRight(zeroConst); assign->setRight(zeroConst);
} }
} }
...@@ -106,12 +152,19 @@ void InitializeVariables::insertInitCode(TIntermSequence *sequence) ...@@ -106,12 +152,19 @@ void InitializeVariables::insertInitCode(TIntermSequence *sequence)
{ {
TIntermBinary *assign = new TIntermBinary(EOpAssign); TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign); sequence->insert(sequence->begin(), assign);
TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
assign->setLeft(symbol); assign->setLeft(symbol);
TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
assign->setRight(zeroConst); assign->setRight(zeroConst);
} }
} }
} }
} // namespace anonymous
void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
{
VariableInitializer initializer(vars);
root->traverse(&initializer);
}
...@@ -7,45 +7,12 @@ ...@@ -7,45 +7,12 @@
#ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
#define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
#include "compiler/translator/IntermNode.h" #include <GLSLANG/ShaderLang.h>
class InitializeVariables : public TIntermTraverser class TIntermNode;
{
public:
struct InitVariableInfo
{
TString name;
TType type;
InitVariableInfo(const TString &_name, const TType &_type) typedef std::vector<sh::ShaderVariable> InitVariableList;
: name(_name),
type(_type)
{
}
};
typedef TVector<InitVariableInfo> InitVariableInfoList;
InitializeVariables(const InitVariableInfoList &vars) void InitializeVariables(TIntermNode *root, const InitVariableList &vars);
: TIntermTraverser(true, false, false),
mVariables(vars),
mCodeInserted(false)
{
}
protected:
bool visitBinary(Visit, TIntermBinary *node) override { return false; }
bool visitUnary(Visit, TIntermUnary *node) override { return false; }
bool visitSelection(Visit, TIntermSelection *node) override { return false; }
bool visitLoop(Visit, TIntermLoop *node) override { return false; }
bool visitBranch(Visit, TIntermBranch *node) override { return false; }
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
private:
void insertInitCode(TIntermSequence *sequence);
InitVariableInfoList mVariables;
bool mCodeInserted;
};
#endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_
...@@ -278,6 +278,58 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -278,6 +278,58 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
} }
} }
TType ConvertShaderVariableTypeToTType(sh::GLenum type)
{
switch (type)
{
case GL_FLOAT:
return TType(EbtFloat);
case GL_FLOAT_VEC2:
return TType(EbtFloat, 2);
case GL_FLOAT_VEC3:
return TType(EbtFloat, 3);
case GL_FLOAT_VEC4:
return TType(EbtFloat, 4);
case GL_FLOAT_MAT2:
return TType(EbtFloat, 2, 2);
case GL_FLOAT_MAT3:
return TType(EbtFloat, 3, 3);
case GL_FLOAT_MAT4:
return TType(EbtFloat, 4, 4);
case GL_FLOAT_MAT2x3:
return TType(EbtFloat, 2, 3);
case GL_FLOAT_MAT2x4:
return TType(EbtFloat, 2, 4);
case GL_FLOAT_MAT3x2:
return TType(EbtFloat, 3, 2);
case GL_FLOAT_MAT3x4:
return TType(EbtFloat, 3, 4);
case GL_FLOAT_MAT4x2:
return TType(EbtFloat, 4, 2);
case GL_FLOAT_MAT4x3:
return TType(EbtFloat, 4, 3);
case GL_INT:
return TType(EbtInt);
case GL_INT_VEC2:
return TType(EbtInt, 2);
case GL_INT_VEC3:
return TType(EbtInt, 3);
case GL_INT_VEC4:
return TType(EbtInt, 4);
case GL_UNSIGNED_INT:
return TType(EbtUInt);
case GL_UNSIGNED_INT_VEC2:
return TType(EbtUInt, 2);
case GL_UNSIGNED_INT_VEC3:
return TType(EbtUInt, 3);
case GL_UNSIGNED_INT_VEC4:
return TType(EbtUInt, 4);
default:
UNREACHABLE();
return TType();
}
}
GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable) GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
: mSymbolTable(symbolTable) : mSymbolTable(symbolTable)
{ {
......
...@@ -36,6 +36,8 @@ bool IsVaryingOut(TQualifier qualifier); ...@@ -36,6 +36,8 @@ bool IsVaryingOut(TQualifier qualifier);
bool IsVarying(TQualifier qualifier); bool IsVarying(TQualifier qualifier);
InterpolationType GetInterpolationType(TQualifier qualifier); InterpolationType GetInterpolationType(TQualifier qualifier);
TString ArrayString(const TType &type); TString ArrayString(const TType &type);
// Handles only basic output variable types.
TType ConvertShaderVariableTypeToTType(sh::GLenum type);
class GetVariableTraverser : angle::NonCopyable class GetVariableTraverser : angle::NonCopyable
{ {
......
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