Hash :
2ef23e2d
Author :
Date :
2017-11-01T16:39:11
Fix writing uniform block maps to HLSL output HLSL output maps structs in std140 uniform blocks to a different layout in order to eliminate padding. The padding may have been inserted to comply with std140 packing rules. There used to be two issues in writing the maps: Sometimes the same map could be written multiple times, and the maps were not being written for uniform blocks with instance names. Rewrite how the uniform buffer struct maps get generated so that the code works correctly. Instead of flagging accesses, structs inside uniform blocks are gathered from uniform block declarations. When accesses to structs in uniform blocks are written out in OutputHLSL, it's checked whether a mapped struct needs to be used instead of the original one. This code could still be optimized further by limiting mapped structs generation to those ones that really need to be used. This is left to be done later. BUG=angleproject:2084 TEST=angle_end2end_tests Change-Id: Iee24b3ef15847d2af64554ac74b8e4be5060d18c Reviewed-on: https://chromium-review.googlesource.com/751506 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
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
//
// 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.
//
// FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator
// conflicts with the "natural" unpadded type.
#include "compiler/translator/FlagStd140Structs.h"
#include "compiler/translator/IntermTraverse.h"
namespace sh
{
namespace
{
class FlagStd140StructsTraverser : public TIntermTraverser
{
public:
FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
const std::vector<MappedStruct> getMappedStructs() const { return mMappedStructs; }
protected:
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
private:
void mapBlockStructMembers(TIntermSymbol *blockDeclarator, TInterfaceBlock *block);
std::vector<MappedStruct> mMappedStructs;
};
void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
TInterfaceBlock *block)
{
for (auto *field : block->fields())
{
if (field->type()->getBasicType() == EbtStruct)
{
MappedStruct mappedStruct;
mappedStruct.blockDeclarator = blockDeclarator;
mappedStruct.field = field;
mMappedStructs.push_back(mappedStruct);
}
}
}
bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
if (declarator->getBasicType() == EbtInterfaceBlock)
{
TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
if (block->blockStorage() == EbsStd140)
{
mapBlockStructMembers(declarator->getAsSymbolNode(), block);
}
}
return false;
}
} // anonymous namespace
std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node)
{
FlagStd140StructsTraverser flaggingTraversal;
node->traverse(&flaggingTraversal);
return flaggingTraversal.getMappedStructs();
}
} // namespace sh