• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 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 
7 #ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
8 #define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
9 
10 #include "compiler/translator/Compiler.h"
11 
12 namespace sh
13 {
14 
15 constexpr const char kUniformsVar[]               = "angleUniforms";
16 constexpr const char kUnassignedAttributeString[] = " __unassigned_attribute__";
17 
18 class DriverUniform;
19 class DriverUniformMetal;
20 class SpecConst;
21 class TOutputMSL;
22 class TranslatorMetalReflection;
23 typedef std::unordered_map<size_t, std::string> originalNamesMap;
24 typedef std::unordered_map<std::string, size_t> samplerBindingMap;
25 typedef std::unordered_map<std::string, size_t> textureBindingMap;
26 typedef std::unordered_map<std::string, size_t> userUniformBufferBindingMap;
27 typedef std::pair<size_t, size_t> uboBindingInfo;
28 struct UBOBindingInfo
29 {
30     size_t bindIndex = 0;
31     size_t arraySize = 0;
32 };
33 typedef std::unordered_map<std::string, UBOBindingInfo> uniformBufferBindingMap;
34 
35 namespace mtl
36 {
37 TranslatorMetalReflection *getTranslatorMetalReflection(const TCompiler *compiler);
38 }
39 
40 class TranslatorMetalReflection
41 {
42   public:
TranslatorMetalReflection()43     TranslatorMetalReflection() : hasUBOs(false), hasFlatInput(false) {}
~TranslatorMetalReflection()44     ~TranslatorMetalReflection() {}
45 
addOriginalName(const size_t id,const std::string & name)46     void addOriginalName(const size_t id, const std::string &name)
47     {
48         originalNames.insert({id, name});
49     }
addSamplerBinding(const std::string & name,size_t samplerBinding)50     void addSamplerBinding(const std::string &name, size_t samplerBinding)
51     {
52         samplerBindings.insert({name, samplerBinding});
53     }
addTextureBinding(const std::string & name,size_t textureBinding)54     void addTextureBinding(const std::string &name, size_t textureBinding)
55     {
56         textureBindings.insert({name, textureBinding});
57     }
addUserUniformBufferBinding(const std::string & name,size_t userUniformBufferBinding)58     void addUserUniformBufferBinding(const std::string &name, size_t userUniformBufferBinding)
59     {
60         userUniformBufferBindings.insert({name, userUniformBufferBinding});
61     }
addUniformBufferBinding(const std::string & name,UBOBindingInfo bindingInfo)62     void addUniformBufferBinding(const std::string &name, UBOBindingInfo bindingInfo)
63     {
64         uniformBufferBindings.insert({name, bindingInfo});
65     }
getOriginalName(const size_t id)66     std::string getOriginalName(const size_t id) { return originalNames.at(id); }
getSamplerBindings()67     samplerBindingMap getSamplerBindings() const { return samplerBindings; }
getTextureBindings()68     textureBindingMap getTextureBindings() const { return textureBindings; }
getUserUniformBufferBindings()69     userUniformBufferBindingMap getUserUniformBufferBindings() const
70     {
71         return userUniformBufferBindings;
72     }
getUniformBufferBindings()73     uniformBufferBindingMap getUniformBufferBindings() const { return uniformBufferBindings; }
getSamplerBinding(const std::string & name)74     size_t getSamplerBinding(const std::string &name) const
75     {
76         auto it = samplerBindings.find(name);
77         if (it != samplerBindings.end())
78         {
79             return it->second;
80         }
81         // If we can't find a matching sampler, assert out on Debug, and return an invalid value on
82         // release.
83         ASSERT(0);
84         return std::numeric_limits<size_t>::max();
85     }
getTextureBinding(const std::string & name)86     size_t getTextureBinding(const std::string &name) const
87     {
88         auto it = textureBindings.find(name);
89         if (it != textureBindings.end())
90         {
91             return it->second;
92         }
93         // If we can't find a matching texture, assert out on Debug, and return an invalid value on
94         // release.
95         ASSERT(0);
96         return std::numeric_limits<size_t>::max();
97     }
getUserUniformBufferBinding(const std::string & name)98     size_t getUserUniformBufferBinding(const std::string &name) const
99     {
100         auto it = userUniformBufferBindings.find(name);
101         if (it != userUniformBufferBindings.end())
102         {
103             return it->second;
104         }
105         // If we can't find a matching Uniform binding, assert out on Debug, and return an invalid
106         // value.
107         ASSERT(0);
108         return std::numeric_limits<size_t>::max();
109     }
getUniformBufferBinding(const std::string & name)110     UBOBindingInfo getUniformBufferBinding(const std::string &name) const
111     {
112         auto it = uniformBufferBindings.find(name);
113         if (it != uniformBufferBindings.end())
114         {
115             return it->second;
116         }
117         // If we can't find a matching UBO binding by name, assert out on Debug, and return an
118         // invalid value.
119         ASSERT(0);
120         return {.bindIndex = std::numeric_limits<size_t>::max(),
121                 .arraySize = std::numeric_limits<size_t>::max()};
122     }
reset()123     void reset()
124     {
125         hasUBOs       = false;
126         hasFlatInput  = false;
127         hasAtan       = false;
128         hasInvariance = false;
129         originalNames.clear();
130         samplerBindings.clear();
131         textureBindings.clear();
132         userUniformBufferBindings.clear();
133         uniformBufferBindings.clear();
134     }
135 
136     bool hasUBOs       = false;
137     bool hasFlatInput  = false;
138     bool hasAtan       = false;
139     bool hasInvariance = false;
140 
141   private:
142     originalNamesMap originalNames;
143     samplerBindingMap samplerBindings;
144     textureBindingMap textureBindings;
145     userUniformBufferBindingMap userUniformBufferBindings;
146     uniformBufferBindingMap uniformBufferBindings;
147 };
148 
149 class TranslatorMetalDirect : public TCompiler
150 {
151   public:
152     TranslatorMetalDirect(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
153 
154 #ifdef ANGLE_ENABLE_METAL
getAsTranslatorMetalDirect()155     TranslatorMetalDirect *getAsTranslatorMetalDirect() override { return this; }
156 #endif
157 
getTranslatorMetalReflection()158     TranslatorMetalReflection *getTranslatorMetalReflection() { return &translatorMetalReflection; }
159 
160   protected:
161     bool translate(TIntermBlock *root,
162                    ShCompileOptions compileOptions,
163                    PerformanceDiagnostics *perfDiagnostics) override;
164 
165     // Need to collect variables so that RemoveInactiveInterfaceVariables works.
shouldCollectVariables(ShCompileOptions compileOptions)166     bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; }
167 
168     ANGLE_NO_DISCARD bool translateImpl(TInfoSinkBase &sink,
169                                         TIntermBlock *root,
170                                         ShCompileOptions compileOptions,
171                                         PerformanceDiagnostics *perfDiagnostics,
172                                         SpecConst *specConst,
173                                         DriverUniformMetal *driverUniforms);
174 
175     ANGLE_NO_DISCARD bool shouldFlattenPragmaStdglInvariantAll() override;
176 
177     ANGLE_NO_DISCARD bool transformDepthBeforeCorrection(TIntermBlock *root,
178                                                          const DriverUniformMetal *driverUniforms);
179 
180     ANGLE_NO_DISCARD bool appendVertexShaderDepthCorrectionToMain(TIntermBlock *root);
181 
182     ANGLE_NO_DISCARD bool insertSampleMaskWritingLogic(TIntermBlock &root,
183                                                        DriverUniformMetal &driverUniforms);
184     ANGLE_NO_DISCARD bool insertRasterizationDiscardLogic(TIntermBlock &root);
185 
186     ANGLE_NO_DISCARD TIntermSwizzle *getDriverUniformNegFlipYRef(
187         DriverUniform &driverUniforms) const;
188 
189     TranslatorMetalReflection translatorMetalReflection = {};
190 };
191 
192 }  // namespace sh
193 
194 #endif  // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
195