Hash :
570e04d8
Author :
Date :
2013-06-21T09:15:33
Add support for passing nested structs in standard layout by value. We add support for this by using global scratch values as storage for the structs in uniform blocks. Any structs in std140 layouts that are referenced by value are initialized in the shader scope, without any packing, so the type of the structs are equivalent with what a GLSL program would expect. TRAC #23327 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Authored-by: Jamie Madill
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
//
// Copyright (c) 2013 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.
//
#include "compiler/FlagStd140Structs.h"
namespace sh
{
bool FlagStd140Structs::visitBinary(Visit visit, TIntermBinary *binaryNode)
{
if (binaryNode->getRight()->getBasicType() == EbtStruct)
{
switch (binaryNode->getOp())
{
case EOpIndexDirectInterfaceBlock:
case EOpIndexDirectStruct:
if (isInStd140InterfaceBlock(binaryNode->getLeft()))
{
mFlaggedNodes.push_back(binaryNode);
}
break;
default: break;
}
return false;
}
if (binaryNode->getOp() == EOpIndexDirectStruct)
{
return false;
}
return visit == PreVisit;
}
void FlagStd140Structs::visitSymbol(TIntermSymbol *symbol)
{
if (isInStd140InterfaceBlock(symbol) && symbol->getBasicType() == EbtStruct)
{
mFlaggedNodes.push_back(symbol);
}
}
bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const
{
TIntermBinary *binaryNode = node->getAsBinaryNode();
if (binaryNode)
{
return isInStd140InterfaceBlock(binaryNode->getLeft());
}
const TType &type = node->getType();
if (type.isInterfaceBlockMember() || type.getBasicType() == EbtInterfaceBlock)
{
// determine if we are in the standard layout
const TType &interfaceBlockType = (type.isInterfaceBlockMember() ? *type.getInterfaceBlockType() : type);
return (interfaceBlockType.getLayoutQualifier().blockStorage == EbsStd140);
}
return false;
}
std::vector<TIntermTyped *> FlagStd140ValueStructs(TIntermNode *node)
{
FlagStd140Structs flaggingTraversal;
node->traverse(&flaggingTraversal);
return flaggingTraversal.getFlaggedNodes();
}
}