1 //
2 // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // OutputVulkanGLSL:
7 //   Code that outputs shaders that fit GL_KHR_vulkan_glsl.
8 //   The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side).
9 //   See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
10 //
11 
12 #include "compiler/translator/OutputVulkanGLSL.h"
13 
14 #include "compiler/translator/util.h"
15 
16 namespace sh
17 {
18 
TOutputVulkanGLSL(TInfoSinkBase & objSink,ShArrayIndexClampingStrategy clampingStrategy,ShHashFunction64 hashFunction,NameMap & nameMap,TSymbolTable * symbolTable,sh::GLenum shaderType,int shaderVersion,ShShaderOutput output,ShCompileOptions compileOptions)19 TOutputVulkanGLSL::TOutputVulkanGLSL(TInfoSinkBase &objSink,
20                                      ShArrayIndexClampingStrategy clampingStrategy,
21                                      ShHashFunction64 hashFunction,
22                                      NameMap &nameMap,
23                                      TSymbolTable *symbolTable,
24                                      sh::GLenum shaderType,
25                                      int shaderVersion,
26                                      ShShaderOutput output,
27                                      ShCompileOptions compileOptions)
28     : TOutputGLSL(objSink,
29                   clampingStrategy,
30                   hashFunction,
31                   nameMap,
32                   symbolTable,
33                   shaderType,
34                   shaderVersion,
35                   output,
36                   compileOptions)
37 {
38 }
39 
40 // TODO(jmadill): This is not complete.
writeLayoutQualifier(TIntermTyped * variable)41 void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable)
42 {
43     const TType &type = variable->getType();
44 
45     bool needsCustomLayout =
46         (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut ||
47          type.getQualifier() == EvqVertexIn || IsVarying(type.getQualifier()) ||
48          IsSampler(type.getBasicType()));
49 
50     if (!NeedsToWriteLayoutQualifier(type) && !needsCustomLayout)
51     {
52         return;
53     }
54 
55     TInfoSinkBase &out                      = objSink();
56     const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
57     out << "layout(";
58 
59     // This isn't super clean, but it gets the job done.
60     // See corresponding code in GlslangWrapper.cpp.
61     // TODO(jmadill): Ensure declarations are separated.
62 
63     TIntermSymbol *symbol = variable->getAsSymbolNode();
64     ASSERT(symbol);
65 
66     if (needsCustomLayout)
67     {
68         out << "@@ LAYOUT-" << symbol->getName().getString() << " @@";
69     }
70 
71     if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
72     {
73         ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
74         out << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
75     }
76 
77     out << ") ";
78 }
79 
80 }  // namespace sh
81