1*8975f5c5SAndroid Build Coastguard Worker// 2*8975f5c5SAndroid Build Coastguard Worker// Copyright 2019 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker// found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker// 6*8975f5c5SAndroid Build Coastguard Worker// ProgramMtl.mm: 7*8975f5c5SAndroid Build Coastguard Worker// Implements the class methods for ProgramMtl. 8*8975f5c5SAndroid Build Coastguard Worker// 9*8975f5c5SAndroid Build Coastguard Worker 10*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ProgramMtl.h" 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker#include <TargetConditionals.h> 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker#include <sstream> 15*8975f5c5SAndroid Build Coastguard Worker 16*8975f5c5SAndroid Build Coastguard Worker#include "common/WorkerThread.h" 17*8975f5c5SAndroid Build Coastguard Worker#include "common/debug.h" 18*8975f5c5SAndroid Build Coastguard Worker#include "common/system_utils.h" 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/Context.h" 21*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/ProgramLinkedResources.h" 22*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/CompilerMtl.h" 23*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ContextMtl.h" 24*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/DisplayMtl.h" 25*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/blocklayoutMetal.h" 26*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_msl_utils.h" 27*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_utils.h" 28*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/renderermtl_utils.h" 29*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/renderer_utils.h" 30*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/trace.h" 31*8975f5c5SAndroid Build Coastguard Worker 32*8975f5c5SAndroid Build Coastguard Workernamespace rx 33*8975f5c5SAndroid Build Coastguard Worker{ 34*8975f5c5SAndroid Build Coastguard Worker 35*8975f5c5SAndroid Build Coastguard Workernamespace 36*8975f5c5SAndroid Build Coastguard Worker{ 37*8975f5c5SAndroid Build Coastguard Workerinline std::map<std::string, std::string> GetDefaultSubstitutionDictionary() 38*8975f5c5SAndroid Build Coastguard Worker{ 39*8975f5c5SAndroid Build Coastguard Worker return {}; 40*8975f5c5SAndroid Build Coastguard Worker} 41*8975f5c5SAndroid Build Coastguard Worker 42*8975f5c5SAndroid Build Coastguard Workerclass Std140BlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory 43*8975f5c5SAndroid Build Coastguard Worker{ 44*8975f5c5SAndroid Build Coastguard Worker public: 45*8975f5c5SAndroid Build Coastguard Worker sh::BlockLayoutEncoder *makeEncoder() override { return new sh::Std140BlockEncoder(); } 46*8975f5c5SAndroid Build Coastguard Worker}; 47*8975f5c5SAndroid Build Coastguard Worker 48*8975f5c5SAndroid Build Coastguard Workerclass CompileMslTask final : public LinkSubTask 49*8975f5c5SAndroid Build Coastguard Worker{ 50*8975f5c5SAndroid Build Coastguard Worker public: 51*8975f5c5SAndroid Build Coastguard Worker CompileMslTask(mtl::Context *context, 52*8975f5c5SAndroid Build Coastguard Worker mtl::TranslatedShaderInfo *translatedMslInfo, 53*8975f5c5SAndroid Build Coastguard Worker const std::map<std::string, std::string> &substitutionMacros) 54*8975f5c5SAndroid Build Coastguard Worker : mContext(context), 55*8975f5c5SAndroid Build Coastguard Worker mTranslatedMslInfo(translatedMslInfo), 56*8975f5c5SAndroid Build Coastguard Worker mSubstitutionMacros(substitutionMacros) 57*8975f5c5SAndroid Build Coastguard Worker {} 58*8975f5c5SAndroid Build Coastguard Worker ~CompileMslTask() override = default; 59*8975f5c5SAndroid Build Coastguard Worker 60*8975f5c5SAndroid Build Coastguard Worker void operator()() override 61*8975f5c5SAndroid Build Coastguard Worker { 62*8975f5c5SAndroid Build Coastguard Worker mResult = CreateMslShaderLib(mContext, mInfoLog, mTranslatedMslInfo, mSubstitutionMacros); 63*8975f5c5SAndroid Build Coastguard Worker } 64*8975f5c5SAndroid Build Coastguard Worker 65*8975f5c5SAndroid Build Coastguard Worker angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override 66*8975f5c5SAndroid Build Coastguard Worker { 67*8975f5c5SAndroid Build Coastguard Worker if (!mInfoLog.empty()) 68*8975f5c5SAndroid Build Coastguard Worker { 69*8975f5c5SAndroid Build Coastguard Worker infoLog << mInfoLog.str(); 70*8975f5c5SAndroid Build Coastguard Worker } 71*8975f5c5SAndroid Build Coastguard Worker 72*8975f5c5SAndroid Build Coastguard Worker return mResult; 73*8975f5c5SAndroid Build Coastguard Worker } 74*8975f5c5SAndroid Build Coastguard Worker 75*8975f5c5SAndroid Build Coastguard Worker private: 76*8975f5c5SAndroid Build Coastguard Worker mtl::Context *mContext; 77*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog mInfoLog; 78*8975f5c5SAndroid Build Coastguard Worker mtl::TranslatedShaderInfo *mTranslatedMslInfo; 79*8975f5c5SAndroid Build Coastguard Worker std::map<std::string, std::string> mSubstitutionMacros; 80*8975f5c5SAndroid Build Coastguard Worker angle::Result mResult = angle::Result::Continue; 81*8975f5c5SAndroid Build Coastguard Worker}; 82*8975f5c5SAndroid Build Coastguard Worker} // namespace 83*8975f5c5SAndroid Build Coastguard Worker 84*8975f5c5SAndroid Build Coastguard Workerclass ProgramMtl::LinkTaskMtl final : public mtl::Context, public LinkTask 85*8975f5c5SAndroid Build Coastguard Worker{ 86*8975f5c5SAndroid Build Coastguard Worker public: 87*8975f5c5SAndroid Build Coastguard Worker LinkTaskMtl(DisplayMtl *displayMtl, ProgramMtl *program) 88*8975f5c5SAndroid Build Coastguard Worker : mtl::Context(displayMtl), mProgram(program) 89*8975f5c5SAndroid Build Coastguard Worker {} 90*8975f5c5SAndroid Build Coastguard Worker ~LinkTaskMtl() override = default; 91*8975f5c5SAndroid Build Coastguard Worker 92*8975f5c5SAndroid Build Coastguard Worker void link(const gl::ProgramLinkedResources &resources, 93*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramMergedVaryings &mergedVaryings, 94*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut, 95*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override 96*8975f5c5SAndroid Build Coastguard Worker { 97*8975f5c5SAndroid Build Coastguard Worker ASSERT(linkSubTasksOut && linkSubTasksOut->empty()); 98*8975f5c5SAndroid Build Coastguard Worker ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty()); 99*8975f5c5SAndroid Build Coastguard Worker 100*8975f5c5SAndroid Build Coastguard Worker mResult = mProgram->linkJobImpl(this, resources, linkSubTasksOut); 101*8975f5c5SAndroid Build Coastguard Worker return; 102*8975f5c5SAndroid Build Coastguard Worker } 103*8975f5c5SAndroid Build Coastguard Worker 104*8975f5c5SAndroid Build Coastguard Worker angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override 105*8975f5c5SAndroid Build Coastguard Worker { 106*8975f5c5SAndroid Build Coastguard Worker // Forward any errors 107*8975f5c5SAndroid Build Coastguard Worker if (mErrorCode != GL_NO_ERROR) 108*8975f5c5SAndroid Build Coastguard Worker { 109*8975f5c5SAndroid Build Coastguard Worker mtl::GetImpl(context)->handleError(mErrorCode, mErrorMessage.c_str(), mErrorFile, 110*8975f5c5SAndroid Build Coastguard Worker mErrorFunction, mErrorLine); 111*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop; 112*8975f5c5SAndroid Build Coastguard Worker } 113*8975f5c5SAndroid Build Coastguard Worker 114*8975f5c5SAndroid Build Coastguard Worker return mResult; 115*8975f5c5SAndroid Build Coastguard Worker } 116*8975f5c5SAndroid Build Coastguard Worker 117*8975f5c5SAndroid Build Coastguard Worker // override mtl::ErrorHandler 118*8975f5c5SAndroid Build Coastguard Worker void handleError(GLenum glErrorCode, 119*8975f5c5SAndroid Build Coastguard Worker const char *message, 120*8975f5c5SAndroid Build Coastguard Worker const char *file, 121*8975f5c5SAndroid Build Coastguard Worker const char *function, 122*8975f5c5SAndroid Build Coastguard Worker unsigned int line) override 123*8975f5c5SAndroid Build Coastguard Worker { 124*8975f5c5SAndroid Build Coastguard Worker mErrorCode = glErrorCode; 125*8975f5c5SAndroid Build Coastguard Worker mErrorMessage = message; 126*8975f5c5SAndroid Build Coastguard Worker mErrorFile = file; 127*8975f5c5SAndroid Build Coastguard Worker mErrorFunction = function; 128*8975f5c5SAndroid Build Coastguard Worker mErrorLine = line; 129*8975f5c5SAndroid Build Coastguard Worker } 130*8975f5c5SAndroid Build Coastguard Worker 131*8975f5c5SAndroid Build Coastguard Worker void handleError(NSError *error, 132*8975f5c5SAndroid Build Coastguard Worker const char *message, 133*8975f5c5SAndroid Build Coastguard Worker const char *file, 134*8975f5c5SAndroid Build Coastguard Worker const char *function, 135*8975f5c5SAndroid Build Coastguard Worker unsigned int line) override 136*8975f5c5SAndroid Build Coastguard Worker { 137*8975f5c5SAndroid Build Coastguard Worker if (!error) 138*8975f5c5SAndroid Build Coastguard Worker { 139*8975f5c5SAndroid Build Coastguard Worker return; 140*8975f5c5SAndroid Build Coastguard Worker } 141*8975f5c5SAndroid Build Coastguard Worker 142*8975f5c5SAndroid Build Coastguard Worker mErrorCode = GL_INVALID_OPERATION; 143*8975f5c5SAndroid Build Coastguard Worker mErrorMessage = message; 144*8975f5c5SAndroid Build Coastguard Worker mErrorFile = file; 145*8975f5c5SAndroid Build Coastguard Worker mErrorFunction = function; 146*8975f5c5SAndroid Build Coastguard Worker mErrorLine = line; 147*8975f5c5SAndroid Build Coastguard Worker } 148*8975f5c5SAndroid Build Coastguard Worker 149*8975f5c5SAndroid Build Coastguard Worker private: 150*8975f5c5SAndroid Build Coastguard Worker ProgramMtl *mProgram; 151*8975f5c5SAndroid Build Coastguard Worker angle::Result mResult = angle::Result::Continue; 152*8975f5c5SAndroid Build Coastguard Worker 153*8975f5c5SAndroid Build Coastguard Worker // Error handling 154*8975f5c5SAndroid Build Coastguard Worker GLenum mErrorCode = GL_NO_ERROR; 155*8975f5c5SAndroid Build Coastguard Worker // Error message might be dynamically allocated at the callsite. 156*8975f5c5SAndroid Build Coastguard Worker std::string mErrorMessage; 157*8975f5c5SAndroid Build Coastguard Worker const char *mErrorFile = nullptr; 158*8975f5c5SAndroid Build Coastguard Worker const char *mErrorFunction = nullptr; 159*8975f5c5SAndroid Build Coastguard Worker unsigned int mErrorLine = 0; 160*8975f5c5SAndroid Build Coastguard Worker}; 161*8975f5c5SAndroid Build Coastguard Worker 162*8975f5c5SAndroid Build Coastguard Workerclass ProgramMtl::LoadTaskMtl final : public LinkTask 163*8975f5c5SAndroid Build Coastguard Worker{ 164*8975f5c5SAndroid Build Coastguard Worker public: 165*8975f5c5SAndroid Build Coastguard Worker LoadTaskMtl(std::vector<std::shared_ptr<LinkSubTask>> &&subTasks) 166*8975f5c5SAndroid Build Coastguard Worker : mSubTasks(std::move(subTasks)) 167*8975f5c5SAndroid Build Coastguard Worker {} 168*8975f5c5SAndroid Build Coastguard Worker ~LoadTaskMtl() override = default; 169*8975f5c5SAndroid Build Coastguard Worker 170*8975f5c5SAndroid Build Coastguard Worker void load(std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut, 171*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override 172*8975f5c5SAndroid Build Coastguard Worker { 173*8975f5c5SAndroid Build Coastguard Worker ASSERT(linkSubTasksOut && linkSubTasksOut->empty()); 174*8975f5c5SAndroid Build Coastguard Worker ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty()); 175*8975f5c5SAndroid Build Coastguard Worker 176*8975f5c5SAndroid Build Coastguard Worker *linkSubTasksOut = mSubTasks; 177*8975f5c5SAndroid Build Coastguard Worker return; 178*8975f5c5SAndroid Build Coastguard Worker } 179*8975f5c5SAndroid Build Coastguard Worker 180*8975f5c5SAndroid Build Coastguard Worker angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override 181*8975f5c5SAndroid Build Coastguard Worker { 182*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 183*8975f5c5SAndroid Build Coastguard Worker } 184*8975f5c5SAndroid Build Coastguard Worker 185*8975f5c5SAndroid Build Coastguard Worker private: 186*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> mSubTasks; 187*8975f5c5SAndroid Build Coastguard Worker}; 188*8975f5c5SAndroid Build Coastguard Worker 189*8975f5c5SAndroid Build Coastguard Worker// ProgramArgumentBufferEncoderMtl implementation 190*8975f5c5SAndroid Build Coastguard Workervoid ProgramArgumentBufferEncoderMtl::reset(ContextMtl *contextMtl) 191*8975f5c5SAndroid Build Coastguard Worker{ 192*8975f5c5SAndroid Build Coastguard Worker metalArgBufferEncoder = nil; 193*8975f5c5SAndroid Build Coastguard Worker bufferPool.destroy(contextMtl); 194*8975f5c5SAndroid Build Coastguard Worker} 195*8975f5c5SAndroid Build Coastguard Worker 196*8975f5c5SAndroid Build Coastguard Worker// ProgramShaderObjVariantMtl implementation 197*8975f5c5SAndroid Build Coastguard Workervoid ProgramShaderObjVariantMtl::reset(ContextMtl *contextMtl) 198*8975f5c5SAndroid Build Coastguard Worker{ 199*8975f5c5SAndroid Build Coastguard Worker metalShader = nil; 200*8975f5c5SAndroid Build Coastguard Worker 201*8975f5c5SAndroid Build Coastguard Worker uboArgBufferEncoder.reset(contextMtl); 202*8975f5c5SAndroid Build Coastguard Worker 203*8975f5c5SAndroid Build Coastguard Worker translatedSrcInfo = nullptr; 204*8975f5c5SAndroid Build Coastguard Worker} 205*8975f5c5SAndroid Build Coastguard Worker 206*8975f5c5SAndroid Build Coastguard Worker// ProgramMtl implementation 207*8975f5c5SAndroid Build Coastguard WorkerProgramMtl::ProgramMtl(const gl::ProgramState &state) : ProgramImpl(state) {} 208*8975f5c5SAndroid Build Coastguard Worker 209*8975f5c5SAndroid Build Coastguard WorkerProgramMtl::~ProgramMtl() = default; 210*8975f5c5SAndroid Build Coastguard Worker 211*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::destroy(const gl::Context *context) 212*8975f5c5SAndroid Build Coastguard Worker{ 213*8975f5c5SAndroid Build Coastguard Worker getExecutable()->reset(mtl::GetImpl(context)); 214*8975f5c5SAndroid Build Coastguard Worker} 215*8975f5c5SAndroid Build Coastguard Worker 216*8975f5c5SAndroid Build Coastguard Workerangle::Result ProgramMtl::load(const gl::Context *context, 217*8975f5c5SAndroid Build Coastguard Worker gl::BinaryInputStream *stream, 218*8975f5c5SAndroid Build Coastguard Worker std::shared_ptr<LinkTask> *loadTaskOut, 219*8975f5c5SAndroid Build Coastguard Worker egl::CacheGetResult *resultOut) 220*8975f5c5SAndroid Build Coastguard Worker{ 221*8975f5c5SAndroid Build Coastguard Worker 222*8975f5c5SAndroid Build Coastguard Worker ContextMtl *contextMtl = mtl::GetImpl(context); 223*8975f5c5SAndroid Build Coastguard Worker // NOTE(hqle): No transform feedbacks for now, since we only support ES 2.0 atm 224*8975f5c5SAndroid Build Coastguard Worker 225*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(getExecutable()->load(contextMtl, stream)); 226*8975f5c5SAndroid Build Coastguard Worker 227*8975f5c5SAndroid Build Coastguard Worker // TODO: parallelize the above too. http://anglebug.com/41488637 228*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> subTasks; 229*8975f5c5SAndroid Build Coastguard Worker 230*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(compileMslShaderLibs(contextMtl, &subTasks)); 231*8975f5c5SAndroid Build Coastguard Worker 232*8975f5c5SAndroid Build Coastguard Worker *loadTaskOut = std::shared_ptr<LinkTask>(new LoadTaskMtl(std::move(subTasks))); 233*8975f5c5SAndroid Build Coastguard Worker *resultOut = egl::CacheGetResult::Success; 234*8975f5c5SAndroid Build Coastguard Worker 235*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 236*8975f5c5SAndroid Build Coastguard Worker} 237*8975f5c5SAndroid Build Coastguard Worker 238*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::save(const gl::Context *context, gl::BinaryOutputStream *stream) 239*8975f5c5SAndroid Build Coastguard Worker{ 240*8975f5c5SAndroid Build Coastguard Worker getExecutable()->save(stream); 241*8975f5c5SAndroid Build Coastguard Worker} 242*8975f5c5SAndroid Build Coastguard Worker 243*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::setBinaryRetrievableHint(bool retrievable) {} 244*8975f5c5SAndroid Build Coastguard Worker 245*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::setSeparable(bool separable) 246*8975f5c5SAndroid Build Coastguard Worker{ 247*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED(); 248*8975f5c5SAndroid Build Coastguard Worker} 249*8975f5c5SAndroid Build Coastguard Worker 250*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::prepareForLink(const gl::ShaderMap<ShaderImpl *> &shaders) 251*8975f5c5SAndroid Build Coastguard Worker{ 252*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes()) 253*8975f5c5SAndroid Build Coastguard Worker { 254*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType].reset(); 255*8975f5c5SAndroid Build Coastguard Worker 256*8975f5c5SAndroid Build Coastguard Worker if (shaders[shaderType] != nullptr) 257*8975f5c5SAndroid Build Coastguard Worker { 258*8975f5c5SAndroid Build Coastguard Worker const ShaderMtl *shaderMtl = GetAs<ShaderMtl>(shaders[shaderType]); 259*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType] = shaderMtl->getCompiledState(); 260*8975f5c5SAndroid Build Coastguard Worker } 261*8975f5c5SAndroid Build Coastguard Worker } 262*8975f5c5SAndroid Build Coastguard Worker} 263*8975f5c5SAndroid Build Coastguard Worker 264*8975f5c5SAndroid Build Coastguard Workerangle::Result ProgramMtl::link(const gl::Context *context, std::shared_ptr<LinkTask> *linkTaskOut) 265*8975f5c5SAndroid Build Coastguard Worker{ 266*8975f5c5SAndroid Build Coastguard Worker DisplayMtl *displayMtl = mtl::GetImpl(context)->getDisplay(); 267*8975f5c5SAndroid Build Coastguard Worker 268*8975f5c5SAndroid Build Coastguard Worker *linkTaskOut = std::shared_ptr<LinkTask>(new LinkTaskMtl(displayMtl, this)); 269*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 270*8975f5c5SAndroid Build Coastguard Worker} 271*8975f5c5SAndroid Build Coastguard Worker 272*8975f5c5SAndroid Build Coastguard Workerangle::Result ProgramMtl::linkJobImpl(mtl::Context *context, 273*8975f5c5SAndroid Build Coastguard Worker const gl::ProgramLinkedResources &resources, 274*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *subTasksOut) 275*8975f5c5SAndroid Build Coastguard Worker{ 276*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableMtl *executableMtl = getExecutable(); 277*8975f5c5SAndroid Build Coastguard Worker 278*8975f5c5SAndroid Build Coastguard Worker // Link resources before calling GetShaderSource to make sure they are ready for the set/binding 279*8975f5c5SAndroid Build Coastguard Worker // assignment done in that function. 280*8975f5c5SAndroid Build Coastguard Worker linkResources(resources); 281*8975f5c5SAndroid Build Coastguard Worker 282*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(executableMtl->initDefaultUniformBlocks(context, mState.getAttachedShaders())); 283*8975f5c5SAndroid Build Coastguard Worker executableMtl->linkUpdateHasFlatAttributes(mState.getAttachedShader(gl::ShaderType::Vertex)); 284*8975f5c5SAndroid Build Coastguard Worker 285*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<std::string> shaderSources; 286*8975f5c5SAndroid Build Coastguard Worker mtl::MSLGetShaderSource(mState, resources, &shaderSources); 287*8975f5c5SAndroid Build Coastguard Worker 288*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mtl::MTLGetMSL(context->getDisplay()->getFeatures(), mState.getExecutable(), 289*8975f5c5SAndroid Build Coastguard Worker shaderSources, mAttachedShaders, 290*8975f5c5SAndroid Build Coastguard Worker &executableMtl->mMslShaderTranslateInfo)); 291*8975f5c5SAndroid Build Coastguard Worker executableMtl->mMslXfbOnlyVertexShaderInfo = 292*8975f5c5SAndroid Build Coastguard Worker executableMtl->mMslShaderTranslateInfo[gl::ShaderType::Vertex]; 293*8975f5c5SAndroid Build Coastguard Worker 294*8975f5c5SAndroid Build Coastguard Worker return compileMslShaderLibs(context, subTasksOut); 295*8975f5c5SAndroid Build Coastguard Worker} 296*8975f5c5SAndroid Build Coastguard Worker 297*8975f5c5SAndroid Build Coastguard Workerangle::Result ProgramMtl::compileMslShaderLibs( 298*8975f5c5SAndroid Build Coastguard Worker mtl::Context *context, 299*8975f5c5SAndroid Build Coastguard Worker std::vector<std::shared_ptr<LinkSubTask>> *subTasksOut) 300*8975f5c5SAndroid Build Coastguard Worker{ 301*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle", "ProgramMtl::compileMslShaderLibs"); 302*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog &infoLog = mState.getExecutable().getInfoLog(); 303*8975f5c5SAndroid Build Coastguard Worker 304*8975f5c5SAndroid Build Coastguard Worker DisplayMtl *displayMtl = context->getDisplay(); 305*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableMtl *executableMtl = getExecutable(); 306*8975f5c5SAndroid Build Coastguard Worker bool asyncCompile = displayMtl->getFeatures().enableParallelMtlLibraryCompilation.enabled; 307*8975f5c5SAndroid Build Coastguard Worker mtl::LibraryCache &libraryCache = displayMtl->getLibraryCache(); 308*8975f5c5SAndroid Build Coastguard Worker 309*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::kAllGLES2ShaderTypes) 310*8975f5c5SAndroid Build Coastguard Worker { 311*8975f5c5SAndroid Build Coastguard Worker mtl::TranslatedShaderInfo *translateInfo = 312*8975f5c5SAndroid Build Coastguard Worker &executableMtl->mMslShaderTranslateInfo[shaderType]; 313*8975f5c5SAndroid Build Coastguard Worker std::map<std::string, std::string> macros = GetDefaultSubstitutionDictionary(); 314*8975f5c5SAndroid Build Coastguard Worker const bool disableFastMath = displayMtl->getFeatures().intelDisableFastMath.enabled || 315*8975f5c5SAndroid Build Coastguard Worker translateInfo->hasIsnanOrIsinf; 316*8975f5c5SAndroid Build Coastguard Worker const bool usesInvariance = translateInfo->hasInvariant; 317*8975f5c5SAndroid Build Coastguard Worker 318*8975f5c5SAndroid Build Coastguard Worker // Check if the shader is already in the cache and use it instead of spawning a new thread 319*8975f5c5SAndroid Build Coastguard Worker translateInfo->metalLibrary = libraryCache.get(translateInfo->metalShaderSource, macros, 320*8975f5c5SAndroid Build Coastguard Worker disableFastMath, usesInvariance); 321*8975f5c5SAndroid Build Coastguard Worker 322*8975f5c5SAndroid Build Coastguard Worker if (!translateInfo->metalLibrary) 323*8975f5c5SAndroid Build Coastguard Worker { 324*8975f5c5SAndroid Build Coastguard Worker if (asyncCompile) 325*8975f5c5SAndroid Build Coastguard Worker { 326*8975f5c5SAndroid Build Coastguard Worker subTasksOut->emplace_back(new CompileMslTask(context, translateInfo, macros)); 327*8975f5c5SAndroid Build Coastguard Worker } 328*8975f5c5SAndroid Build Coastguard Worker else 329*8975f5c5SAndroid Build Coastguard Worker { 330*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(CreateMslShaderLib(context, infoLog, translateInfo, macros)); 331*8975f5c5SAndroid Build Coastguard Worker } 332*8975f5c5SAndroid Build Coastguard Worker } 333*8975f5c5SAndroid Build Coastguard Worker } 334*8975f5c5SAndroid Build Coastguard Worker 335*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue; 336*8975f5c5SAndroid Build Coastguard Worker} 337*8975f5c5SAndroid Build Coastguard Worker 338*8975f5c5SAndroid Build Coastguard Workervoid ProgramMtl::linkResources(const gl::ProgramLinkedResources &resources) 339*8975f5c5SAndroid Build Coastguard Worker{ 340*8975f5c5SAndroid Build Coastguard Worker Std140BlockLayoutEncoderFactory std140EncoderFactory; 341*8975f5c5SAndroid Build Coastguard Worker gl::ProgramLinkedResourcesLinker linker(&std140EncoderFactory); 342*8975f5c5SAndroid Build Coastguard Worker 343*8975f5c5SAndroid Build Coastguard Worker linker.linkResources(mState, resources); 344*8975f5c5SAndroid Build Coastguard Worker} 345*8975f5c5SAndroid Build Coastguard Worker 346*8975f5c5SAndroid Build Coastguard WorkerGLboolean ProgramMtl::validate(const gl::Caps &caps) 347*8975f5c5SAndroid Build Coastguard Worker{ 348*8975f5c5SAndroid Build Coastguard Worker // No-op. The spec is very vague about the behavior of validation. 349*8975f5c5SAndroid Build Coastguard Worker return GL_TRUE; 350*8975f5c5SAndroid Build Coastguard Worker} 351*8975f5c5SAndroid Build Coastguard Worker 352*8975f5c5SAndroid Build Coastguard Worker} // namespace rx 353