Commit e794cd86 by Jamie Madill Committed by Commit Bot

Vulkan: Implement new GLSL translator back-end.

The Vulkan GLSL translator back-end will handle validating and translating our WebGL/ESSL shaders into Vulkan-specific GLSL. glslang (the Vulkan one) accepts both GLSL and GLSL ES shaders as inputs, and both the desktop and ESSL back-ends give incompleteness warnings when used. For now, use the desktop GL 450 as a target for Vulkan GLSL. The Vulkan-specific changes are currently only to add locations to every vertex input and fragment output. BUG=angleproject:1575 Change-Id: I7c3f32f522e9d18e5f8618eb7927336bf4fbdcf2 Reviewed-on: https://chromium-review.googlesource.com/412266Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 61bd9fe1
......@@ -201,6 +201,14 @@ static_library("translator") {
rebase_path(compiler_gypi.angle_translator_hlsl_sources, ".", "src")
defines += [ "ANGLE_ENABLE_HLSL" ]
}
if (angle_enable_vulkan || use_libfuzzer) {
sources += rebase_path(compiler_gypi.angle_translator_lib_vulkan_sources,
".",
"src")
defines += [ "ANGLE_ENABLE_VULKAN" ]
}
configs -= angle_undefine_configs
configs += [ ":internal_config" ]
public_configs = [ ":external_config" ]
......
......@@ -214,6 +214,13 @@
'compiler/translator/UtilsHLSL.cpp',
'compiler/translator/UtilsHLSL.h',
],
'angle_translator_lib_vulkan_sources':
[
'compiler/translator/OutputVulkanGLSL.cpp',
'compiler/translator/OutputVulkanGLSL.h',
'compiler/translator/TranslatorVulkan.cpp',
'compiler/translator/TranslatorVulkan.h',
],
'angle_preprocessor_sources':
[
'compiler/preprocessor/DiagnosticsBase.cpp',
......@@ -332,6 +339,24 @@
'<@(angle_translator_hlsl_sources)',
],
}],
['angle_enable_vulkan==1',
{
'defines':
[
'ANGLE_ENABLE_VULKAN',
],
'direct_dependent_settings':
{
'defines':
[
'ANGLE_ENABLE_VULKAN',
],
},
'sources':
[
'<@(angle_translator_lib_vulkan_sources)',
],
}],
],
},
],
......
......@@ -16,6 +16,10 @@
#include "compiler/translator/TranslatorHLSL.h"
#endif // ANGLE_ENABLE_HLSL
#ifdef ANGLE_ENABLE_VULKAN
#include "compiler/translator/TranslatorVulkan.h"
#endif // ANGLE_ENABLE_VULKAN
namespace sh
{
......@@ -68,9 +72,13 @@ TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput
#endif // ANGLE_ENABLE_HLSL
case SH_GLSL_VULKAN_OUTPUT:
UNIMPLEMENTED();
// TODO(jmadill): Vulkan GLSL
#ifdef ANGLE_ENABLE_VULKAN
return new TranslatorVulkan(type, spec);
#else
// This compiler is not supported in this configuration. Return NULL per the
// ShConstructCompiler API.
return nullptr;
#endif // ANGLE_ENABLE_VULKAN
default:
// Unknown format. Return NULL per the sh::ConstructCompiler API.
......
......@@ -39,7 +39,7 @@ class TOutputGLSLBase : public TIntermTraverser
TInfoSinkBase &objSink() { return mObjSink; }
void writeFloat(TInfoSinkBase &out, float f);
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
void writeLayoutQualifier(const TType &type);
virtual void writeLayoutQualifier(const TType &type);
void writeInvariantQualifier(const TType &type);
void writeVariableType(const TType &type);
virtual bool writeVariablePrecision(TPrecision precision) = 0;
......
//
// 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.
//
// OutputVulkanGLSL:
// Code 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/OutputVulkanGLSL.h"
namespace sh
{
TOutputVulkanGLSL::TOutputVulkanGLSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion,
ShShaderOutput output,
ShCompileOptions compileOptions)
: TOutputGLSLBase(objSink,
clampingStrategy,
hashFunction,
nameMap,
symbolTable,
shaderType,
shaderVersion,
output,
compileOptions)
{
}
// TODO(jmadill): This is not complete.
void TOutputVulkanGLSL::writeLayoutQualifier(const TType &type)
{
TInfoSinkBase &out = objSink();
const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
out << "layout(";
if (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut ||
type.getQualifier() == EvqVertexIn)
{
// TODO(jmadill): Multiple output locations.
out << "location = "
<< "0";
}
if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
{
ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
out << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
}
out << ") ";
}
bool TOutputVulkanGLSL::writeVariablePrecision(TPrecision precision)
{
if (precision == EbpUndefined)
return false;
TInfoSinkBase &out = objSink();
out << getPrecisionString(precision);
return true;
}
void TOutputVulkanGLSL::visitSymbol(TIntermSymbol *node)
{
TInfoSinkBase &out = objSink();
const TString &symbol = node->getSymbol();
if (symbol == "gl_FragColor")
{
out << "webgl_FragColor";
}
else if (symbol == "gl_FragData")
{
out << "webgl_FragData";
}
else
{
TOutputGLSLBase::visitSymbol(node);
}
}
} // namespace sh
//
// 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.
//
// OutputVulkanGLSL:
// Code 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/OutputGLSL.h"
namespace sh
{
class TOutputVulkanGLSL : public TOutputGLSLBase
{
public:
TOutputVulkanGLSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction,
NameMap &nameMap,
TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion,
ShShaderOutput output,
ShCompileOptions compileOptions);
protected:
void writeLayoutQualifier(const TType &type) override;
bool writeVariablePrecision(TPrecision precision) override;
void visitSymbol(TIntermSymbol *node) override;
};
} // namespace sh
//
// 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 "compiler/translator/OutputVulkanGLSL.h"
namespace sh
{
TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT)
{
}
void TranslatorVulkan::translate(TIntermNode *root, ShCompileOptions compileOptions)
{
TInfoSinkBase &sink = getInfoSink().obj;
sink << "#version 450 core\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
//
// 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
//
#ifndef COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
#define COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
#include "compiler/translator/Compiler.h"
namespace sh
{
class TranslatorVulkan : public TCompiler
{
public:
TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
protected:
void translate(TIntermNode *root, ShCompileOptions compileOptions) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
......@@ -185,6 +185,7 @@ ShHandle Compiler::getCompilerHandle(GLenum type)
}
*compiler = sh::ConstructCompiler(type, mSpec, mOutputType, &mResources);
ASSERT(*compiler);
activeCompilerHandles++;
}
......
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