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