Hash :
fbb1c792
Author :
Date :
2018-01-19T16:26:59
Store symbol names as a ImmutableString This will enable compile-time initialization of built-in symbols as well as reducing copying strings. Most of the code that deals with names is changed to use ImmutableString where it makes sense to avoid conversions. The lexer/parser now allocate const char pointers into pool memory instead of allocating TStrings. These are then converted to ImmutableString upon entering TParseContext. BUG=angleproject:2267 TEST=angle_unittests, angle_end2end_tests Change-Id: I244d6271ea1ecf7150d4f89dfa388a7745a1150c Reviewed-on: https://chromium-review.googlesource.com/881561 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
//
// Copyright (c) 2016 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.
//
// TranslatorVulkan:
// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl.
// The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side).
// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
//
#include "compiler/translator/TranslatorVulkan.h"
#include "angle_gl.h"
#include "common/utilities.h"
#include "compiler/translator/OutputVulkanGLSL.h"
#include "compiler/translator/util.h"
namespace sh
{
class DeclareDefaultUniformsTraverser : public TIntermTraverser
{
public:
DeclareDefaultUniformsTraverser(TInfoSinkBase *sink,
ShHashFunction64 hashFunction,
NameMap *nameMap)
: TIntermTraverser(true, true, true),
mSink(sink),
mHashFunction(hashFunction),
mNameMap(nameMap),
mInDefaultUniform(false)
{
}
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
{
const TIntermSequence &sequence = *(node->getSequence());
// TODO(jmadill): Compound declarations.
ASSERT(sequence.size() == 1);
TIntermTyped *variable = sequence.front()->getAsTyped();
const TType &type = variable->getType();
bool isUniform = (type.getQualifier() == EvqUniform) && !IsOpaqueType(type.getBasicType());
if (visit == PreVisit)
{
if (isUniform)
{
(*mSink) << " " << GetTypeName(type, mHashFunction, mNameMap) << " ";
mInDefaultUniform = true;
}
}
else if (visit == InVisit)
{
mInDefaultUniform = isUniform;
}
else if (visit == PostVisit)
{
if (isUniform)
{
(*mSink) << ";\n";
// Remove the uniform declaration from the tree so it isn't parsed again.
TIntermSequence emptyReplacement;
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
getParentNode()->getAsBlock(), node, emptyReplacement));
}
mInDefaultUniform = false;
}
return true;
}
void visitSymbol(TIntermSymbol *symbol) override
{
if (mInDefaultUniform)
{
const ImmutableString &name = symbol->variable().name();
ASSERT(!name.beginsWith("gl_"));
(*mSink) << HashName(name, mHashFunction, mNameMap);
}
}
private:
TInfoSinkBase *mSink;
ShHashFunction64 mHashFunction;
NameMap *mNameMap;
bool mInDefaultUniform;
};
TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT)
{
}
void TranslatorVulkan::translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics * /*perfDiagnostics*/)
{
TInfoSinkBase &sink = getInfoSink().obj;
sink << "#version 450 core\n";
// Write out default uniforms into a uniform block assigned to a specific set/binding.
int defaultUniformCount = 0;
for (const auto &uniform : getUniforms())
{
if (!uniform.isBuiltIn() && uniform.staticUse && !gl::IsOpaqueType(uniform.type))
{
++defaultUniformCount;
}
}
if (defaultUniformCount > 0)
{
sink << "\nlayout(@@ DEFAULT-UNIFORMS-SET-BINDING @@) uniform defaultUniforms\n{\n";
DeclareDefaultUniformsTraverser defaultTraverser(&sink, getHashFunction(), &getNameMap());
root->traverse(&defaultTraverser);
defaultTraverser.updateTree();
sink << "};\n";
}
// Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
// if it's core profile shaders and they are used.
if (getShaderType() == GL_FRAGMENT_SHADER)
{
bool hasGLFragColor = false;
bool hasGLFragData = false;
for (const auto &outputVar : outputVariables)
{
if (outputVar.name == "gl_FragColor")
{
ASSERT(!hasGLFragColor);
hasGLFragColor = true;
continue;
}
else if (outputVar.name == "gl_FragData")
{
ASSERT(!hasGLFragData);
hasGLFragData = true;
continue;
}
}
ASSERT(!(hasGLFragColor && hasGLFragData));
if (hasGLFragColor)
{
sink << "layout(location = 0) out vec4 webgl_FragColor;\n";
}
if (hasGLFragData)
{
sink << "layout(location = 0) out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
}
}
// Write translated shader.
TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(),
getNameMap(), &getSymbolTable(), getShaderType(),
getShaderVersion(), getOutputType(), compileOptions);
root->traverse(&outputGLSL);
}
bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll()
{
// Not necessary.
return false;
}
} // namespace sh