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