xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 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 
7*8975f5c5SAndroid Build Coastguard Worker // ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ProgramD3D.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "common/MemoryBuffer.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Program.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ProgramLinkedResources.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Uniform.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/VertexArray.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/features.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryconversions.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ContextImpl.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ContextD3D.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ShaderD3D.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/VertexDataManager.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/renderer_utils.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/trace.h"
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker namespace rx
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker namespace
35*8975f5c5SAndroid Build Coastguard Worker {
HasFlatInterpolationVarying(const std::vector<sh::ShaderVariable> & varyings)36*8975f5c5SAndroid Build Coastguard Worker bool HasFlatInterpolationVarying(const std::vector<sh::ShaderVariable> &varyings)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker     // Note: this assumes nested structs can only be packed with one interpolation.
39*8975f5c5SAndroid Build Coastguard Worker     for (const auto &varying : varyings)
40*8975f5c5SAndroid Build Coastguard Worker     {
41*8975f5c5SAndroid Build Coastguard Worker         if (varying.interpolation == sh::INTERPOLATION_FLAT)
42*8975f5c5SAndroid Build Coastguard Worker         {
43*8975f5c5SAndroid Build Coastguard Worker             return true;
44*8975f5c5SAndroid Build Coastguard Worker         }
45*8975f5c5SAndroid Build Coastguard Worker     }
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker     return false;
48*8975f5c5SAndroid Build Coastguard Worker }
49*8975f5c5SAndroid Build Coastguard Worker 
FindFlatInterpolationVaryingPerShader(const gl::SharedCompiledShaderState & shader)50*8975f5c5SAndroid Build Coastguard Worker bool FindFlatInterpolationVaryingPerShader(const gl::SharedCompiledShaderState &shader)
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker     ASSERT(shader);
53*8975f5c5SAndroid Build Coastguard Worker     switch (shader->shaderType)
54*8975f5c5SAndroid Build Coastguard Worker     {
55*8975f5c5SAndroid Build Coastguard Worker         case gl::ShaderType::Vertex:
56*8975f5c5SAndroid Build Coastguard Worker             return HasFlatInterpolationVarying(shader->outputVaryings);
57*8975f5c5SAndroid Build Coastguard Worker         case gl::ShaderType::Fragment:
58*8975f5c5SAndroid Build Coastguard Worker             return HasFlatInterpolationVarying(shader->inputVaryings);
59*8975f5c5SAndroid Build Coastguard Worker         case gl::ShaderType::Geometry:
60*8975f5c5SAndroid Build Coastguard Worker             return HasFlatInterpolationVarying(shader->inputVaryings) ||
61*8975f5c5SAndroid Build Coastguard Worker                    HasFlatInterpolationVarying(shader->outputVaryings);
62*8975f5c5SAndroid Build Coastguard Worker         default:
63*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
64*8975f5c5SAndroid Build Coastguard Worker             return false;
65*8975f5c5SAndroid Build Coastguard Worker     }
66*8975f5c5SAndroid Build Coastguard Worker }
67*8975f5c5SAndroid Build Coastguard Worker 
FindFlatInterpolationVarying(const gl::ShaderMap<gl::SharedCompiledShaderState> & shaders)68*8975f5c5SAndroid Build Coastguard Worker bool FindFlatInterpolationVarying(const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders)
69*8975f5c5SAndroid Build Coastguard Worker {
70*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         const gl::SharedCompiledShaderState &shader = shaders[shaderType];
73*8975f5c5SAndroid Build Coastguard Worker         if (!shader)
74*8975f5c5SAndroid Build Coastguard Worker         {
75*8975f5c5SAndroid Build Coastguard Worker             continue;
76*8975f5c5SAndroid Build Coastguard Worker         }
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker         if (FindFlatInterpolationVaryingPerShader(shader))
79*8975f5c5SAndroid Build Coastguard Worker         {
80*8975f5c5SAndroid Build Coastguard Worker             return true;
81*8975f5c5SAndroid Build Coastguard Worker         }
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker 
84*8975f5c5SAndroid Build Coastguard Worker     return false;
85*8975f5c5SAndroid Build Coastguard Worker }
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker class HLSLBlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker   public:
makeEncoder()90*8975f5c5SAndroid Build Coastguard Worker     sh::BlockLayoutEncoder *makeEncoder() override
91*8975f5c5SAndroid Build Coastguard Worker     {
92*8975f5c5SAndroid Build Coastguard Worker         return new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
93*8975f5c5SAndroid Build Coastguard Worker     }
94*8975f5c5SAndroid Build Coastguard Worker };
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker // GetExecutableTask class
97*8975f5c5SAndroid Build Coastguard Worker class GetExecutableTask : public LinkSubTask, public d3d::Context
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker   public:
GetExecutableTask(ProgramD3D * program,const SharedCompiledShaderStateD3D & shader)100*8975f5c5SAndroid Build Coastguard Worker     GetExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
101*8975f5c5SAndroid Build Coastguard Worker         : mProgram(program), mExecutable(program->getExecutable()), mShader(shader)
102*8975f5c5SAndroid Build Coastguard Worker     {}
103*8975f5c5SAndroid Build Coastguard Worker     ~GetExecutableTask() override = default;
104*8975f5c5SAndroid Build Coastguard Worker 
getResult(const gl::Context * context,gl::InfoLog & infoLog)105*8975f5c5SAndroid Build Coastguard Worker     angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
106*8975f5c5SAndroid Build Coastguard Worker     {
107*8975f5c5SAndroid Build Coastguard Worker         ASSERT((mResult == angle::Result::Continue) == (mStoredHR == S_OK));
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(checkTask(context, infoLog));
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker         // Append debug info
112*8975f5c5SAndroid Build Coastguard Worker         if (mShader && mShaderExecutable != nullptr)
113*8975f5c5SAndroid Build Coastguard Worker         {
114*8975f5c5SAndroid Build Coastguard Worker             mShader->appendDebugInfo(mShaderExecutable->getDebugInfo());
115*8975f5c5SAndroid Build Coastguard Worker         }
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
118*8975f5c5SAndroid Build Coastguard Worker     }
119*8975f5c5SAndroid Build Coastguard Worker 
handleResult(HRESULT hr,const char * message,const char * file,const char * function,unsigned int line)120*8975f5c5SAndroid Build Coastguard Worker     void handleResult(HRESULT hr,
121*8975f5c5SAndroid Build Coastguard Worker                       const char *message,
122*8975f5c5SAndroid Build Coastguard Worker                       const char *file,
123*8975f5c5SAndroid Build Coastguard Worker                       const char *function,
124*8975f5c5SAndroid Build Coastguard Worker                       unsigned int line) override
125*8975f5c5SAndroid Build Coastguard Worker     {
126*8975f5c5SAndroid Build Coastguard Worker         mStoredHR       = hr;
127*8975f5c5SAndroid Build Coastguard Worker         mStoredMessage  = message;
128*8975f5c5SAndroid Build Coastguard Worker         mStoredFile     = file;
129*8975f5c5SAndroid Build Coastguard Worker         mStoredFunction = function;
130*8975f5c5SAndroid Build Coastguard Worker         mStoredLine     = line;
131*8975f5c5SAndroid Build Coastguard Worker     }
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker   protected:
popError(d3d::Context * context)134*8975f5c5SAndroid Build Coastguard Worker     void popError(d3d::Context *context)
135*8975f5c5SAndroid Build Coastguard Worker     {
136*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mStoredFile);
137*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mStoredFunction);
138*8975f5c5SAndroid Build Coastguard Worker         context->handleResult(mStoredHR, mStoredMessage.c_str(), mStoredFile, mStoredFunction,
139*8975f5c5SAndroid Build Coastguard Worker                               mStoredLine);
140*8975f5c5SAndroid Build Coastguard Worker     }
141*8975f5c5SAndroid Build Coastguard Worker 
checkTask(const gl::Context * context,gl::InfoLog & infoLog)142*8975f5c5SAndroid Build Coastguard Worker     angle::Result checkTask(const gl::Context *context, gl::InfoLog &infoLog)
143*8975f5c5SAndroid Build Coastguard Worker     {
144*8975f5c5SAndroid Build Coastguard Worker         // Forward any logs
145*8975f5c5SAndroid Build Coastguard Worker         if (!mInfoLog.empty())
146*8975f5c5SAndroid Build Coastguard Worker         {
147*8975f5c5SAndroid Build Coastguard Worker             infoLog << mInfoLog.str();
148*8975f5c5SAndroid Build Coastguard Worker         }
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker         // Forward any errors
151*8975f5c5SAndroid Build Coastguard Worker         if (mResult != angle::Result::Continue)
152*8975f5c5SAndroid Build Coastguard Worker         {
153*8975f5c5SAndroid Build Coastguard Worker             ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
154*8975f5c5SAndroid Build Coastguard Worker             popError(contextD3D);
155*8975f5c5SAndroid Build Coastguard Worker             return angle::Result::Stop;
156*8975f5c5SAndroid Build Coastguard Worker         }
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
159*8975f5c5SAndroid Build Coastguard Worker     }
160*8975f5c5SAndroid Build Coastguard Worker 
161*8975f5c5SAndroid Build Coastguard Worker     ProgramD3D *mProgram              = nullptr;
162*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableD3D *mExecutable = nullptr;
163*8975f5c5SAndroid Build Coastguard Worker     angle::Result mResult             = angle::Result::Continue;
164*8975f5c5SAndroid Build Coastguard Worker     gl::InfoLog mInfoLog;
165*8975f5c5SAndroid Build Coastguard Worker     ShaderExecutableD3D *mShaderExecutable = nullptr;
166*8975f5c5SAndroid Build Coastguard Worker     SharedCompiledShaderStateD3D mShader;
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker     // Error handling
169*8975f5c5SAndroid Build Coastguard Worker     HRESULT mStoredHR = S_OK;
170*8975f5c5SAndroid Build Coastguard Worker     std::string mStoredMessage;
171*8975f5c5SAndroid Build Coastguard Worker     const char *mStoredFile     = nullptr;
172*8975f5c5SAndroid Build Coastguard Worker     const char *mStoredFunction = nullptr;
173*8975f5c5SAndroid Build Coastguard Worker     unsigned int mStoredLine    = 0;
174*8975f5c5SAndroid Build Coastguard Worker };
175*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker // ProgramD3DMetadata Implementation
ProgramD3DMetadata(RendererD3D * renderer,const gl::SharedCompiledShaderState & fragmentShader,const gl::ShaderMap<SharedCompiledShaderStateD3D> & attachedShaders,int shaderVersion)178*8975f5c5SAndroid Build Coastguard Worker ProgramD3DMetadata::ProgramD3DMetadata(
179*8975f5c5SAndroid Build Coastguard Worker     RendererD3D *renderer,
180*8975f5c5SAndroid Build Coastguard Worker     const gl::SharedCompiledShaderState &fragmentShader,
181*8975f5c5SAndroid Build Coastguard Worker     const gl::ShaderMap<SharedCompiledShaderStateD3D> &attachedShaders,
182*8975f5c5SAndroid Build Coastguard Worker     int shaderVersion)
183*8975f5c5SAndroid Build Coastguard Worker     : mRendererMajorShaderModel(renderer->getMajorShaderModel()),
184*8975f5c5SAndroid Build Coastguard Worker       mShaderModelSuffix(renderer->getShaderModelSuffix()),
185*8975f5c5SAndroid Build Coastguard Worker       mUsesViewScale(renderer->presentPathFastEnabled()),
186*8975f5c5SAndroid Build Coastguard Worker       mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
187*8975f5c5SAndroid Build Coastguard Worker       mFragmentShader(fragmentShader),
188*8975f5c5SAndroid Build Coastguard Worker       mAttachedShaders(attachedShaders),
189*8975f5c5SAndroid Build Coastguard Worker       mShaderVersion(shaderVersion)
190*8975f5c5SAndroid Build Coastguard Worker {}
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker ProgramD3DMetadata::~ProgramD3DMetadata() = default;
193*8975f5c5SAndroid Build Coastguard Worker 
getRendererMajorShaderModel() const194*8975f5c5SAndroid Build Coastguard Worker int ProgramD3DMetadata::getRendererMajorShaderModel() const
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker     return mRendererMajorShaderModel;
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker 
usesBroadcast(const gl::Version & clientVersion) const199*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesBroadcast(const gl::Version &clientVersion) const
200*8975f5c5SAndroid Build Coastguard Worker {
201*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
202*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesFragColor && shader->usesMultipleRenderTargets &&
203*8975f5c5SAndroid Build Coastguard Worker            clientVersion.major < 3;
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker 
usesSecondaryColor() const206*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesSecondaryColor() const
207*8975f5c5SAndroid Build Coastguard Worker {
208*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
209*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesSecondaryColor;
210*8975f5c5SAndroid Build Coastguard Worker }
211*8975f5c5SAndroid Build Coastguard Worker 
getFragDepthUsage() const212*8975f5c5SAndroid Build Coastguard Worker FragDepthUsage ProgramD3DMetadata::getFragDepthUsage() const
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
215*8975f5c5SAndroid Build Coastguard Worker     return shader ? shader->fragDepthUsage : FragDepthUsage::Unused;
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker 
usesPointCoord() const218*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesPointCoord() const
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
221*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesPointCoord;
222*8975f5c5SAndroid Build Coastguard Worker }
223*8975f5c5SAndroid Build Coastguard Worker 
usesFragCoord() const224*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesFragCoord() const
225*8975f5c5SAndroid Build Coastguard Worker {
226*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
227*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesFragCoord;
228*8975f5c5SAndroid Build Coastguard Worker }
229*8975f5c5SAndroid Build Coastguard Worker 
usesPointSize() const230*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesPointSize() const
231*8975f5c5SAndroid Build Coastguard Worker {
232*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
233*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesPointSize;
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker 
usesInsertedPointCoordValue() const236*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker     return usesPointCoord() && mRendererMajorShaderModel >= 4;
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker 
usesViewScale() const241*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesViewScale() const
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker     return mUsesViewScale;
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker 
hasMultiviewEnabled() const246*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::hasMultiviewEnabled() const
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
249*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->hasMultiviewEnabled;
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker 
usesVertexID() const252*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesVertexID() const
253*8975f5c5SAndroid Build Coastguard Worker {
254*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
255*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesVertexID;
256*8975f5c5SAndroid Build Coastguard Worker }
257*8975f5c5SAndroid Build Coastguard Worker 
usesViewID() const258*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesViewID() const
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
261*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesViewID;
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker 
canSelectViewInVertexShader() const264*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::canSelectViewInVertexShader() const
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker     return mCanSelectViewInVertexShader;
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker 
addsPointCoordToVertexShader() const269*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker     // With a geometry shader, the app can render triangles or lines and reference
272*8975f5c5SAndroid Build Coastguard Worker     // gl_PointCoord in the fragment shader, requiring us to provide a placeholder value. For
273*8975f5c5SAndroid Build Coastguard Worker     // simplicity, we always add this to the vertex shader when the fragment shader
274*8975f5c5SAndroid Build Coastguard Worker     // references gl_PointCoord, even if we could skip it in the geometry shader.
275*8975f5c5SAndroid Build Coastguard Worker     return usesInsertedPointCoordValue();
276*8975f5c5SAndroid Build Coastguard Worker }
277*8975f5c5SAndroid Build Coastguard Worker 
usesTransformFeedbackGLPosition() const278*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
279*8975f5c5SAndroid Build Coastguard Worker {
280*8975f5c5SAndroid Build Coastguard Worker     // gl_Position only needs to be outputted from the vertex shader if transform feedback is
281*8975f5c5SAndroid Build Coastguard Worker     // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from
282*8975f5c5SAndroid Build Coastguard Worker     // the vertex shader in this case. This saves us 1 output vector.
283*8975f5c5SAndroid Build Coastguard Worker     return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != "");
284*8975f5c5SAndroid Build Coastguard Worker }
285*8975f5c5SAndroid Build Coastguard Worker 
usesSystemValuePointSize() const286*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesSystemValuePointSize() const
287*8975f5c5SAndroid Build Coastguard Worker {
288*8975f5c5SAndroid Build Coastguard Worker     return usesPointSize();
289*8975f5c5SAndroid Build Coastguard Worker }
290*8975f5c5SAndroid Build Coastguard Worker 
usesMultipleFragmentOuts() const291*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
294*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesMultipleRenderTargets;
295*8975f5c5SAndroid Build Coastguard Worker }
296*8975f5c5SAndroid Build Coastguard Worker 
usesCustomOutVars() const297*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesCustomOutVars() const
298*8975f5c5SAndroid Build Coastguard Worker {
299*8975f5c5SAndroid Build Coastguard Worker     return mShaderVersion >= 300;
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker 
usesSampleMask() const302*8975f5c5SAndroid Build Coastguard Worker bool ProgramD3DMetadata::usesSampleMask() const
303*8975f5c5SAndroid Build Coastguard Worker {
304*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
305*8975f5c5SAndroid Build Coastguard Worker     return shader && shader->usesSampleMask;
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker 
getFragmentShader() const308*8975f5c5SAndroid Build Coastguard Worker const gl::SharedCompiledShaderState &ProgramD3DMetadata::getFragmentShader() const
309*8975f5c5SAndroid Build Coastguard Worker {
310*8975f5c5SAndroid Build Coastguard Worker     return mFragmentShader;
311*8975f5c5SAndroid Build Coastguard Worker }
312*8975f5c5SAndroid Build Coastguard Worker 
getClipDistanceArraySize() const313*8975f5c5SAndroid Build Coastguard Worker uint8_t ProgramD3DMetadata::getClipDistanceArraySize() const
314*8975f5c5SAndroid Build Coastguard Worker {
315*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
316*8975f5c5SAndroid Build Coastguard Worker     return shader ? shader->clipDistanceSize : 0;
317*8975f5c5SAndroid Build Coastguard Worker }
318*8975f5c5SAndroid Build Coastguard Worker 
getCullDistanceArraySize() const319*8975f5c5SAndroid Build Coastguard Worker uint8_t ProgramD3DMetadata::getCullDistanceArraySize() const
320*8975f5c5SAndroid Build Coastguard Worker {
321*8975f5c5SAndroid Build Coastguard Worker     const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
322*8975f5c5SAndroid Build Coastguard Worker     return shader ? shader->cullDistanceSize : 0;
323*8975f5c5SAndroid Build Coastguard Worker }
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker // ProgramD3D Implementation
326*8975f5c5SAndroid Build Coastguard Worker 
327*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::GetVertexExecutableTask : public GetExecutableTask
328*8975f5c5SAndroid Build Coastguard Worker {
329*8975f5c5SAndroid Build Coastguard Worker   public:
GetVertexExecutableTask(ProgramD3D * program,const SharedCompiledShaderStateD3D & shader)330*8975f5c5SAndroid Build Coastguard Worker     GetVertexExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
331*8975f5c5SAndroid Build Coastguard Worker         : GetExecutableTask(program, shader)
332*8975f5c5SAndroid Build Coastguard Worker     {}
333*8975f5c5SAndroid Build Coastguard Worker     ~GetVertexExecutableTask() override = default;
334*8975f5c5SAndroid Build Coastguard Worker 
operator ()()335*8975f5c5SAndroid Build Coastguard Worker     void operator()() override
336*8975f5c5SAndroid Build Coastguard Worker     {
337*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRACE_EVENT0("gpu.angle", "GetVertexExecutableTask::run");
338*8975f5c5SAndroid Build Coastguard Worker 
339*8975f5c5SAndroid Build Coastguard Worker         mExecutable->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Vertex);
340*8975f5c5SAndroid Build Coastguard Worker         mResult = mExecutable->getVertexExecutableForCachedInputLayout(
341*8975f5c5SAndroid Build Coastguard Worker             this, mProgram->mRenderer, &mShaderExecutable, &mInfoLog);
342*8975f5c5SAndroid Build Coastguard Worker     }
343*8975f5c5SAndroid Build Coastguard Worker };
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::GetPixelExecutableTask : public GetExecutableTask
346*8975f5c5SAndroid Build Coastguard Worker {
347*8975f5c5SAndroid Build Coastguard Worker   public:
GetPixelExecutableTask(ProgramD3D * program,const SharedCompiledShaderStateD3D & shader)348*8975f5c5SAndroid Build Coastguard Worker     GetPixelExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
349*8975f5c5SAndroid Build Coastguard Worker         : GetExecutableTask(program, shader)
350*8975f5c5SAndroid Build Coastguard Worker     {}
351*8975f5c5SAndroid Build Coastguard Worker     ~GetPixelExecutableTask() override = default;
352*8975f5c5SAndroid Build Coastguard Worker 
operator ()()353*8975f5c5SAndroid Build Coastguard Worker     void operator()() override
354*8975f5c5SAndroid Build Coastguard Worker     {
355*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRACE_EVENT0("gpu.angle", "GetPixelExecutableTask::run");
356*8975f5c5SAndroid Build Coastguard Worker         if (!mShader)
357*8975f5c5SAndroid Build Coastguard Worker         {
358*8975f5c5SAndroid Build Coastguard Worker             return;
359*8975f5c5SAndroid Build Coastguard Worker         }
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker         mExecutable->updateCachedOutputLayoutFromShader();
362*8975f5c5SAndroid Build Coastguard Worker         mExecutable->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Fragment);
363*8975f5c5SAndroid Build Coastguard Worker         mResult = mExecutable->getPixelExecutableForCachedOutputLayout(
364*8975f5c5SAndroid Build Coastguard Worker             this, mProgram->mRenderer, &mShaderExecutable, &mInfoLog);
365*8975f5c5SAndroid Build Coastguard Worker     }
366*8975f5c5SAndroid Build Coastguard Worker };
367*8975f5c5SAndroid Build Coastguard Worker 
368*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::GetGeometryExecutableTask : public GetExecutableTask
369*8975f5c5SAndroid Build Coastguard Worker {
370*8975f5c5SAndroid Build Coastguard Worker   public:
GetGeometryExecutableTask(ProgramD3D * program,const SharedCompiledShaderStateD3D & shader,const gl::Caps & caps,gl::ProvokingVertexConvention provokingVertex)371*8975f5c5SAndroid Build Coastguard Worker     GetGeometryExecutableTask(ProgramD3D *program,
372*8975f5c5SAndroid Build Coastguard Worker                               const SharedCompiledShaderStateD3D &shader,
373*8975f5c5SAndroid Build Coastguard Worker                               const gl::Caps &caps,
374*8975f5c5SAndroid Build Coastguard Worker                               gl::ProvokingVertexConvention provokingVertex)
375*8975f5c5SAndroid Build Coastguard Worker         : GetExecutableTask(program, shader), mCaps(caps), mProvokingVertex(provokingVertex)
376*8975f5c5SAndroid Build Coastguard Worker     {}
377*8975f5c5SAndroid Build Coastguard Worker     ~GetGeometryExecutableTask() override = default;
378*8975f5c5SAndroid Build Coastguard Worker 
operator ()()379*8975f5c5SAndroid Build Coastguard Worker     void operator()() override
380*8975f5c5SAndroid Build Coastguard Worker     {
381*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRACE_EVENT0("gpu.angle", "GetGeometryExecutableTask::run");
382*8975f5c5SAndroid Build Coastguard Worker         // Auto-generate the geometry shader here, if we expect to be using point rendering in
383*8975f5c5SAndroid Build Coastguard Worker         // D3D11.
384*8975f5c5SAndroid Build Coastguard Worker         if (mExecutable->usesGeometryShader(mProgram->mRenderer, mProvokingVertex,
385*8975f5c5SAndroid Build Coastguard Worker                                             gl::PrimitiveMode::Points))
386*8975f5c5SAndroid Build Coastguard Worker         {
387*8975f5c5SAndroid Build Coastguard Worker             mResult = mExecutable->getGeometryExecutableForPrimitiveType(
388*8975f5c5SAndroid Build Coastguard Worker                 this, mProgram->mRenderer, mCaps, mProvokingVertex, gl::PrimitiveMode::Points,
389*8975f5c5SAndroid Build Coastguard Worker                 &mShaderExecutable, &mInfoLog);
390*8975f5c5SAndroid Build Coastguard Worker         }
391*8975f5c5SAndroid Build Coastguard Worker     }
392*8975f5c5SAndroid Build Coastguard Worker 
393*8975f5c5SAndroid Build Coastguard Worker   private:
394*8975f5c5SAndroid Build Coastguard Worker     const gl::Caps &mCaps;
395*8975f5c5SAndroid Build Coastguard Worker     gl::ProvokingVertexConvention mProvokingVertex;
396*8975f5c5SAndroid Build Coastguard Worker };
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::GetComputeExecutableTask : public GetExecutableTask
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker   public:
GetComputeExecutableTask(ProgramD3D * program,const SharedCompiledShaderStateD3D & shader)401*8975f5c5SAndroid Build Coastguard Worker     GetComputeExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
402*8975f5c5SAndroid Build Coastguard Worker         : GetExecutableTask(program, shader)
403*8975f5c5SAndroid Build Coastguard Worker     {}
404*8975f5c5SAndroid Build Coastguard Worker     ~GetComputeExecutableTask() override = default;
405*8975f5c5SAndroid Build Coastguard Worker 
operator ()()406*8975f5c5SAndroid Build Coastguard Worker     void operator()() override
407*8975f5c5SAndroid Build Coastguard Worker     {
408*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRACE_EVENT0("gpu.angle", "GetComputeExecutableTask::run");
409*8975f5c5SAndroid Build Coastguard Worker 
410*8975f5c5SAndroid Build Coastguard Worker         mExecutable->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Compute);
411*8975f5c5SAndroid Build Coastguard Worker         mResult = mExecutable->getComputeExecutableForImage2DBindLayout(
412*8975f5c5SAndroid Build Coastguard Worker             this, mProgram->mRenderer, &mShaderExecutable, &mInfoLog);
413*8975f5c5SAndroid Build Coastguard Worker     }
414*8975f5c5SAndroid Build Coastguard Worker };
415*8975f5c5SAndroid Build Coastguard Worker 
416*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::LinkLoadTaskD3D : public d3d::Context, public LinkTask
417*8975f5c5SAndroid Build Coastguard Worker {
418*8975f5c5SAndroid Build Coastguard Worker   public:
LinkLoadTaskD3D(ProgramD3D * program)419*8975f5c5SAndroid Build Coastguard Worker     LinkLoadTaskD3D(ProgramD3D *program) : mProgram(program), mExecutable(program->getExecutable())
420*8975f5c5SAndroid Build Coastguard Worker     {
421*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mProgram);
422*8975f5c5SAndroid Build Coastguard Worker     }
423*8975f5c5SAndroid Build Coastguard Worker     ~LinkLoadTaskD3D() override = default;
424*8975f5c5SAndroid Build Coastguard Worker 
getResult(const gl::Context * context,gl::InfoLog & infoLog)425*8975f5c5SAndroid Build Coastguard Worker     angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
426*8975f5c5SAndroid Build Coastguard Worker     {
427*8975f5c5SAndroid Build Coastguard Worker         if (mStoredHR != S_OK)
428*8975f5c5SAndroid Build Coastguard Worker         {
429*8975f5c5SAndroid Build Coastguard Worker             GetImplAs<ContextD3D>(context)->handleResult(mStoredHR, mStoredMessage.c_str(),
430*8975f5c5SAndroid Build Coastguard Worker                                                          mStoredFile, mStoredFunction, mStoredLine);
431*8975f5c5SAndroid Build Coastguard Worker             return angle::Result::Stop;
432*8975f5c5SAndroid Build Coastguard Worker         }
433*8975f5c5SAndroid Build Coastguard Worker 
434*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
435*8975f5c5SAndroid Build Coastguard Worker     }
436*8975f5c5SAndroid Build Coastguard Worker 
handleResult(HRESULT hr,const char * message,const char * file,const char * function,unsigned int line)437*8975f5c5SAndroid Build Coastguard Worker     void handleResult(HRESULT hr,
438*8975f5c5SAndroid Build Coastguard Worker                       const char *message,
439*8975f5c5SAndroid Build Coastguard Worker                       const char *file,
440*8975f5c5SAndroid Build Coastguard Worker                       const char *function,
441*8975f5c5SAndroid Build Coastguard Worker                       unsigned int line) override
442*8975f5c5SAndroid Build Coastguard Worker     {
443*8975f5c5SAndroid Build Coastguard Worker         mStoredHR       = hr;
444*8975f5c5SAndroid Build Coastguard Worker         mStoredMessage  = message;
445*8975f5c5SAndroid Build Coastguard Worker         mStoredFile     = file;
446*8975f5c5SAndroid Build Coastguard Worker         mStoredFunction = function;
447*8975f5c5SAndroid Build Coastguard Worker         mStoredLine     = line;
448*8975f5c5SAndroid Build Coastguard Worker     }
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker   protected:
451*8975f5c5SAndroid Build Coastguard Worker     // The front-end ensures that the program is not accessed while linking, so it is safe to
452*8975f5c5SAndroid Build Coastguard Worker     // direclty access the state from a potentially parallel job.
453*8975f5c5SAndroid Build Coastguard Worker     ProgramD3D *mProgram;
454*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableD3D *mExecutable = nullptr;
455*8975f5c5SAndroid Build Coastguard Worker 
456*8975f5c5SAndroid Build Coastguard Worker     // Error handling
457*8975f5c5SAndroid Build Coastguard Worker     HRESULT mStoredHR = S_OK;
458*8975f5c5SAndroid Build Coastguard Worker     std::string mStoredMessage;
459*8975f5c5SAndroid Build Coastguard Worker     const char *mStoredFile     = nullptr;
460*8975f5c5SAndroid Build Coastguard Worker     const char *mStoredFunction = nullptr;
461*8975f5c5SAndroid Build Coastguard Worker     unsigned int mStoredLine    = 0;
462*8975f5c5SAndroid Build Coastguard Worker };
463*8975f5c5SAndroid Build Coastguard Worker 
464*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::LinkTaskD3D final : public LinkLoadTaskD3D
465*8975f5c5SAndroid Build Coastguard Worker {
466*8975f5c5SAndroid Build Coastguard Worker   public:
LinkTaskD3D(const gl::Version & clientVersion,const gl::Caps & caps,ProgramD3D * program,gl::ProvokingVertexConvention provokingVertex)467*8975f5c5SAndroid Build Coastguard Worker     LinkTaskD3D(const gl::Version &clientVersion,
468*8975f5c5SAndroid Build Coastguard Worker                 const gl::Caps &caps,
469*8975f5c5SAndroid Build Coastguard Worker                 ProgramD3D *program,
470*8975f5c5SAndroid Build Coastguard Worker                 gl::ProvokingVertexConvention provokingVertex)
471*8975f5c5SAndroid Build Coastguard Worker         : LinkLoadTaskD3D(program),
472*8975f5c5SAndroid Build Coastguard Worker           mClientVersion(clientVersion),
473*8975f5c5SAndroid Build Coastguard Worker           mCaps(caps),
474*8975f5c5SAndroid Build Coastguard Worker           mProvokingVertex(provokingVertex)
475*8975f5c5SAndroid Build Coastguard Worker     {}
476*8975f5c5SAndroid Build Coastguard Worker     ~LinkTaskD3D() override = default;
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     void link(const gl::ProgramLinkedResources &resources,
479*8975f5c5SAndroid Build Coastguard Worker               const gl::ProgramMergedVaryings &mergedVaryings,
480*8975f5c5SAndroid Build Coastguard Worker               std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
481*8975f5c5SAndroid Build Coastguard Worker               std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override;
482*8975f5c5SAndroid Build Coastguard Worker 
483*8975f5c5SAndroid Build Coastguard Worker   private:
484*8975f5c5SAndroid Build Coastguard Worker     const gl::Version mClientVersion;
485*8975f5c5SAndroid Build Coastguard Worker     const gl::Caps &mCaps;
486*8975f5c5SAndroid Build Coastguard Worker     const gl::ProvokingVertexConvention mProvokingVertex;
487*8975f5c5SAndroid Build Coastguard Worker };
488*8975f5c5SAndroid Build Coastguard Worker 
link(const gl::ProgramLinkedResources & resources,const gl::ProgramMergedVaryings & mergedVaryings,std::vector<std::shared_ptr<LinkSubTask>> * linkSubTasksOut,std::vector<std::shared_ptr<LinkSubTask>> * postLinkSubTasksOut)489*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::LinkTaskD3D::link(const gl::ProgramLinkedResources &resources,
490*8975f5c5SAndroid Build Coastguard Worker                                    const gl::ProgramMergedVaryings &mergedVaryings,
491*8975f5c5SAndroid Build Coastguard Worker                                    std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
492*8975f5c5SAndroid Build Coastguard Worker                                    std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut)
493*8975f5c5SAndroid Build Coastguard Worker {
494*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRACE_EVENT0("gpu.angle", "LinkTaskD3D::link");
495*8975f5c5SAndroid Build Coastguard Worker 
496*8975f5c5SAndroid Build Coastguard Worker     ASSERT(linkSubTasksOut && linkSubTasksOut->empty());
497*8975f5c5SAndroid Build Coastguard Worker     ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty());
498*8975f5c5SAndroid Build Coastguard Worker 
499*8975f5c5SAndroid Build Coastguard Worker     angle::Result result =
500*8975f5c5SAndroid Build Coastguard Worker         mProgram->linkJobImpl(this, mCaps, mClientVersion, resources, mergedVaryings);
501*8975f5c5SAndroid Build Coastguard Worker     ASSERT((result == angle::Result::Continue) == (mStoredHR == S_OK));
502*8975f5c5SAndroid Build Coastguard Worker 
503*8975f5c5SAndroid Build Coastguard Worker     if (result != angle::Result::Continue)
504*8975f5c5SAndroid Build Coastguard Worker     {
505*8975f5c5SAndroid Build Coastguard Worker         return;
506*8975f5c5SAndroid Build Coastguard Worker     }
507*8975f5c5SAndroid Build Coastguard Worker 
508*8975f5c5SAndroid Build Coastguard Worker     // Create the subtasks
509*8975f5c5SAndroid Build Coastguard Worker     if (mExecutable->hasShaderStage(gl::ShaderType::Compute))
510*8975f5c5SAndroid Build Coastguard Worker     {
511*8975f5c5SAndroid Build Coastguard Worker         linkSubTasksOut->push_back(std::make_shared<GetComputeExecutableTask>(
512*8975f5c5SAndroid Build Coastguard Worker             mProgram, mProgram->getAttachedShader(gl::ShaderType::Compute)));
513*8975f5c5SAndroid Build Coastguard Worker     }
514*8975f5c5SAndroid Build Coastguard Worker     else
515*8975f5c5SAndroid Build Coastguard Worker     {
516*8975f5c5SAndroid Build Coastguard Worker         // Geometry shaders are currently only used internally, so there is no corresponding shader
517*8975f5c5SAndroid Build Coastguard Worker         // object at the interface level. For now the geometry shader debug info is prepended to the
518*8975f5c5SAndroid Build Coastguard Worker         // vertex shader.
519*8975f5c5SAndroid Build Coastguard Worker         linkSubTasksOut->push_back(std::make_shared<GetVertexExecutableTask>(
520*8975f5c5SAndroid Build Coastguard Worker             mProgram, mProgram->getAttachedShader(gl::ShaderType::Vertex)));
521*8975f5c5SAndroid Build Coastguard Worker         linkSubTasksOut->push_back(std::make_shared<GetPixelExecutableTask>(
522*8975f5c5SAndroid Build Coastguard Worker             mProgram, mProgram->getAttachedShader(gl::ShaderType::Fragment)));
523*8975f5c5SAndroid Build Coastguard Worker         linkSubTasksOut->push_back(std::make_shared<GetGeometryExecutableTask>(
524*8975f5c5SAndroid Build Coastguard Worker             mProgram, mProgram->getAttachedShader(gl::ShaderType::Vertex), mCaps,
525*8975f5c5SAndroid Build Coastguard Worker             mProvokingVertex));
526*8975f5c5SAndroid Build Coastguard Worker     }
527*8975f5c5SAndroid Build Coastguard Worker }
528*8975f5c5SAndroid Build Coastguard Worker 
529*8975f5c5SAndroid Build Coastguard Worker class ProgramD3D::LoadTaskD3D final : public LinkLoadTaskD3D
530*8975f5c5SAndroid Build Coastguard Worker {
531*8975f5c5SAndroid Build Coastguard Worker   public:
LoadTaskD3D(ProgramD3D * program,angle::MemoryBuffer && streamData)532*8975f5c5SAndroid Build Coastguard Worker     LoadTaskD3D(ProgramD3D *program, angle::MemoryBuffer &&streamData)
533*8975f5c5SAndroid Build Coastguard Worker         : LinkLoadTaskD3D(program), mStreamData(std::move(streamData))
534*8975f5c5SAndroid Build Coastguard Worker     {}
535*8975f5c5SAndroid Build Coastguard Worker     ~LoadTaskD3D() override = default;
536*8975f5c5SAndroid Build Coastguard Worker 
load(std::vector<std::shared_ptr<LinkSubTask>> * linkSubTasksOut,std::vector<std::shared_ptr<LinkSubTask>> * postLinkSubTasksOut)537*8975f5c5SAndroid Build Coastguard Worker     void load(std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
538*8975f5c5SAndroid Build Coastguard Worker               std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override
539*8975f5c5SAndroid Build Coastguard Worker     {
540*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRACE_EVENT0("gpu.angle", "LoadTaskD3D::load");
541*8975f5c5SAndroid Build Coastguard Worker 
542*8975f5c5SAndroid Build Coastguard Worker         ASSERT(linkSubTasksOut && linkSubTasksOut->empty());
543*8975f5c5SAndroid Build Coastguard Worker         ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty());
544*8975f5c5SAndroid Build Coastguard Worker 
545*8975f5c5SAndroid Build Coastguard Worker         gl::BinaryInputStream stream(mStreamData.data(), mStreamData.size());
546*8975f5c5SAndroid Build Coastguard Worker         mResult = mExecutable->loadBinaryShaderExecutables(this, mProgram->mRenderer, &stream);
547*8975f5c5SAndroid Build Coastguard Worker 
548*8975f5c5SAndroid Build Coastguard Worker         return;
549*8975f5c5SAndroid Build Coastguard Worker     }
550*8975f5c5SAndroid Build Coastguard Worker 
getResult(const gl::Context * context,gl::InfoLog & infoLog)551*8975f5c5SAndroid Build Coastguard Worker     angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
552*8975f5c5SAndroid Build Coastguard Worker     {
553*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(LinkLoadTaskD3D::getResult(context, infoLog));
554*8975f5c5SAndroid Build Coastguard Worker         return mResult;
555*8975f5c5SAndroid Build Coastguard Worker     }
556*8975f5c5SAndroid Build Coastguard Worker 
557*8975f5c5SAndroid Build Coastguard Worker   private:
558*8975f5c5SAndroid Build Coastguard Worker     angle::MemoryBuffer mStreamData;
559*8975f5c5SAndroid Build Coastguard Worker     angle::Result mResult = angle::Result::Continue;
560*8975f5c5SAndroid Build Coastguard Worker };
561*8975f5c5SAndroid Build Coastguard Worker 
ProgramD3D(const gl::ProgramState & state,RendererD3D * renderer)562*8975f5c5SAndroid Build Coastguard Worker ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
563*8975f5c5SAndroid Build Coastguard Worker     : ProgramImpl(state), mRenderer(renderer)
564*8975f5c5SAndroid Build Coastguard Worker {}
565*8975f5c5SAndroid Build Coastguard Worker 
566*8975f5c5SAndroid Build Coastguard Worker ProgramD3D::~ProgramD3D() = default;
567*8975f5c5SAndroid Build Coastguard Worker 
destroy(const gl::Context * context)568*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::destroy(const gl::Context *context)
569*8975f5c5SAndroid Build Coastguard Worker {
570*8975f5c5SAndroid Build Coastguard Worker     getExecutable()->reset();
571*8975f5c5SAndroid Build Coastguard Worker }
572*8975f5c5SAndroid Build Coastguard Worker 
load(const gl::Context * context,gl::BinaryInputStream * stream,std::shared_ptr<LinkTask> * loadTaskOut,egl::CacheGetResult * resultOut)573*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramD3D::load(const gl::Context *context,
574*8975f5c5SAndroid Build Coastguard Worker                                gl::BinaryInputStream *stream,
575*8975f5c5SAndroid Build Coastguard Worker                                std::shared_ptr<LinkTask> *loadTaskOut,
576*8975f5c5SAndroid Build Coastguard Worker                                egl::CacheGetResult *resultOut)
577*8975f5c5SAndroid Build Coastguard Worker {
578*8975f5c5SAndroid Build Coastguard Worker     if (!getExecutable()->load(context, mRenderer, stream))
579*8975f5c5SAndroid Build Coastguard Worker     {
580*8975f5c5SAndroid Build Coastguard Worker         mState.getExecutable().getInfoLog()
581*8975f5c5SAndroid Build Coastguard Worker             << "Invalid program binary, device configuration has changed.";
582*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
583*8975f5c5SAndroid Build Coastguard Worker     }
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker     // Copy the remaining data from the stream locally so that the client can't modify it when
586*8975f5c5SAndroid Build Coastguard Worker     // loading off thread.
587*8975f5c5SAndroid Build Coastguard Worker     angle::MemoryBuffer streamData;
588*8975f5c5SAndroid Build Coastguard Worker     const size_t dataSize = stream->remainingSize();
589*8975f5c5SAndroid Build Coastguard Worker     if (!streamData.resize(dataSize))
590*8975f5c5SAndroid Build Coastguard Worker     {
591*8975f5c5SAndroid Build Coastguard Worker         mState.getExecutable().getInfoLog()
592*8975f5c5SAndroid Build Coastguard Worker             << "Failed to copy program binary data to local buffer.";
593*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Stop;
594*8975f5c5SAndroid Build Coastguard Worker     }
595*8975f5c5SAndroid Build Coastguard Worker     memcpy(streamData.data(), stream->data() + stream->offset(), dataSize);
596*8975f5c5SAndroid Build Coastguard Worker 
597*8975f5c5SAndroid Build Coastguard Worker     // Note: pretty much all the above can also be moved to the task
598*8975f5c5SAndroid Build Coastguard Worker     *loadTaskOut = std::shared_ptr<LinkTask>(new LoadTaskD3D(this, std::move(streamData)));
599*8975f5c5SAndroid Build Coastguard Worker     *resultOut   = egl::CacheGetResult::Success;
600*8975f5c5SAndroid Build Coastguard Worker 
601*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
602*8975f5c5SAndroid Build Coastguard Worker }
603*8975f5c5SAndroid Build Coastguard Worker 
save(const gl::Context * context,gl::BinaryOutputStream * stream)604*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
605*8975f5c5SAndroid Build Coastguard Worker {
606*8975f5c5SAndroid Build Coastguard Worker     getExecutable()->save(context, mRenderer, stream);
607*8975f5c5SAndroid Build Coastguard Worker }
608*8975f5c5SAndroid Build Coastguard Worker 
setBinaryRetrievableHint(bool)609*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {}
610*8975f5c5SAndroid Build Coastguard Worker 
setSeparable(bool)611*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::setSeparable(bool /* separable */) {}
612*8975f5c5SAndroid Build Coastguard Worker 
prepareForLink(const gl::ShaderMap<ShaderImpl * > & shaders)613*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::prepareForLink(const gl::ShaderMap<ShaderImpl *> &shaders)
614*8975f5c5SAndroid Build Coastguard Worker {
615*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableD3D *executableD3D = getExecutable();
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : gl::AllShaderTypes())
618*8975f5c5SAndroid Build Coastguard Worker     {
619*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mAttachedShaders[shaderType].reset();
620*8975f5c5SAndroid Build Coastguard Worker 
621*8975f5c5SAndroid Build Coastguard Worker         if (shaders[shaderType] != nullptr)
622*8975f5c5SAndroid Build Coastguard Worker         {
623*8975f5c5SAndroid Build Coastguard Worker             const ShaderD3D *shaderD3D                  = GetAs<ShaderD3D>(shaders[shaderType]);
624*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mAttachedShaders[shaderType] = shaderD3D->getCompiledState();
625*8975f5c5SAndroid Build Coastguard Worker         }
626*8975f5c5SAndroid Build Coastguard Worker     }
627*8975f5c5SAndroid Build Coastguard Worker }
628*8975f5c5SAndroid Build Coastguard Worker 
link(const gl::Context * context,std::shared_ptr<LinkTask> * linkTaskOut)629*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramD3D::link(const gl::Context *context, std::shared_ptr<LinkTask> *linkTaskOut)
630*8975f5c5SAndroid Build Coastguard Worker {
631*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::link");
632*8975f5c5SAndroid Build Coastguard Worker     const gl::Version &clientVersion = context->getClientVersion();
633*8975f5c5SAndroid Build Coastguard Worker     const gl::Caps &caps             = context->getCaps();
634*8975f5c5SAndroid Build Coastguard Worker 
635*8975f5c5SAndroid Build Coastguard Worker     // Ensure the compiler is initialized to avoid race conditions.
636*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context)));
637*8975f5c5SAndroid Build Coastguard Worker 
638*8975f5c5SAndroid Build Coastguard Worker     *linkTaskOut = std::shared_ptr<LinkTask>(
639*8975f5c5SAndroid Build Coastguard Worker         new LinkTaskD3D(clientVersion, caps, this, context->getState().getProvokingVertex()));
640*8975f5c5SAndroid Build Coastguard Worker 
641*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
642*8975f5c5SAndroid Build Coastguard Worker }
643*8975f5c5SAndroid Build Coastguard Worker 
linkJobImpl(d3d::Context * context,const gl::Caps & caps,const gl::Version & clientVersion,const gl::ProgramLinkedResources & resources,const gl::ProgramMergedVaryings & mergedVaryings)644*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramD3D::linkJobImpl(d3d::Context *context,
645*8975f5c5SAndroid Build Coastguard Worker                                       const gl::Caps &caps,
646*8975f5c5SAndroid Build Coastguard Worker                                       const gl::Version &clientVersion,
647*8975f5c5SAndroid Build Coastguard Worker                                       const gl::ProgramLinkedResources &resources,
648*8975f5c5SAndroid Build Coastguard Worker                                       const gl::ProgramMergedVaryings &mergedVaryings)
649*8975f5c5SAndroid Build Coastguard Worker {
650*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableD3D *executableD3D = getExecutable();
651*8975f5c5SAndroid Build Coastguard Worker 
652*8975f5c5SAndroid Build Coastguard Worker     const gl::SharedCompiledShaderState &computeShader =
653*8975f5c5SAndroid Build Coastguard Worker         mState.getAttachedShader(gl::ShaderType::Compute);
654*8975f5c5SAndroid Build Coastguard Worker     if (computeShader)
655*8975f5c5SAndroid Build Coastguard Worker     {
656*8975f5c5SAndroid Build Coastguard Worker         const gl::SharedCompiledShaderState &shader =
657*8975f5c5SAndroid Build Coastguard Worker             mState.getAttachedShader(gl::ShaderType::Compute);
658*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mShaderHLSL[gl::ShaderType::Compute] = shader->translatedSource;
659*8975f5c5SAndroid Build Coastguard Worker 
660*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mShaderSamplers[gl::ShaderType::Compute].resize(
661*8975f5c5SAndroid Build Coastguard Worker             caps.maxShaderTextureImageUnits[gl::ShaderType::Compute]);
662*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mImages[gl::ShaderType::Compute].resize(caps.maxImageUnits);
663*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mReadonlyImages[gl::ShaderType::Compute].resize(caps.maxImageUnits);
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mShaderUniformsDirty.set(gl::ShaderType::Compute);
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker         linkResources(resources);
668*8975f5c5SAndroid Build Coastguard Worker 
669*8975f5c5SAndroid Build Coastguard Worker         for (const sh::ShaderVariable &uniform : computeShader->uniforms)
670*8975f5c5SAndroid Build Coastguard Worker         {
671*8975f5c5SAndroid Build Coastguard Worker             if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
672*8975f5c5SAndroid Build Coastguard Worker             {
673*8975f5c5SAndroid Build Coastguard Worker                 executableD3D->mImage2DUniforms[gl::ShaderType::Compute].push_back(uniform);
674*8975f5c5SAndroid Build Coastguard Worker             }
675*8975f5c5SAndroid Build Coastguard Worker         }
676*8975f5c5SAndroid Build Coastguard Worker 
677*8975f5c5SAndroid Build Coastguard Worker         executableD3D->defineUniformsAndAssignRegisters(mRenderer, mState.getAttachedShaders());
678*8975f5c5SAndroid Build Coastguard Worker 
679*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
680*8975f5c5SAndroid Build Coastguard Worker     }
681*8975f5c5SAndroid Build Coastguard Worker 
682*8975f5c5SAndroid Build Coastguard Worker     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
683*8975f5c5SAndroid Build Coastguard Worker     {
684*8975f5c5SAndroid Build Coastguard Worker         const gl::SharedCompiledShaderState &shader = mState.getAttachedShader(shaderType);
685*8975f5c5SAndroid Build Coastguard Worker         if (shader)
686*8975f5c5SAndroid Build Coastguard Worker         {
687*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mAttachedShaders[shaderType]->generateWorkarounds(
688*8975f5c5SAndroid Build Coastguard Worker                 &executableD3D->mShaderWorkarounds[shaderType]);
689*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mShaderSamplers[shaderType].resize(
690*8975f5c5SAndroid Build Coastguard Worker                 caps.maxShaderTextureImageUnits[shaderType]);
691*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mImages[shaderType].resize(caps.maxImageUnits);
692*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mReadonlyImages[shaderType].resize(caps.maxImageUnits);
693*8975f5c5SAndroid Build Coastguard Worker 
694*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mShaderUniformsDirty.set(shaderType);
695*8975f5c5SAndroid Build Coastguard Worker 
696*8975f5c5SAndroid Build Coastguard Worker             for (const sh::ShaderVariable &uniform : shader->uniforms)
697*8975f5c5SAndroid Build Coastguard Worker             {
698*8975f5c5SAndroid Build Coastguard Worker                 if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
699*8975f5c5SAndroid Build Coastguard Worker                 {
700*8975f5c5SAndroid Build Coastguard Worker                     executableD3D->mImage2DUniforms[shaderType].push_back(uniform);
701*8975f5c5SAndroid Build Coastguard Worker                 }
702*8975f5c5SAndroid Build Coastguard Worker             }
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker             for (const std::string &slowBlock :
705*8975f5c5SAndroid Build Coastguard Worker                  executableD3D->mAttachedShaders[shaderType]->slowCompilingUniformBlockSet)
706*8975f5c5SAndroid Build Coastguard Worker             {
707*8975f5c5SAndroid Build Coastguard Worker                 WARN() << "Uniform block '" << slowBlock << "' will be slow to compile. "
708*8975f5c5SAndroid Build Coastguard Worker                        << "See UniformBlockToStructuredBufferTranslation.md "
709*8975f5c5SAndroid Build Coastguard Worker                        << "(https://shorturl.at/drFY7) for details.";
710*8975f5c5SAndroid Build Coastguard Worker             }
711*8975f5c5SAndroid Build Coastguard Worker         }
712*8975f5c5SAndroid Build Coastguard Worker     }
713*8975f5c5SAndroid Build Coastguard Worker 
714*8975f5c5SAndroid Build Coastguard Worker     if (mRenderer->getNativeLimitations().noFrontFacingSupport)
715*8975f5c5SAndroid Build Coastguard Worker     {
716*8975f5c5SAndroid Build Coastguard Worker         const SharedCompiledShaderStateD3D &fragmentShader =
717*8975f5c5SAndroid Build Coastguard Worker             executableD3D->mAttachedShaders[gl::ShaderType::Fragment];
718*8975f5c5SAndroid Build Coastguard Worker         if (fragmentShader && fragmentShader->usesFrontFacing)
719*8975f5c5SAndroid Build Coastguard Worker         {
720*8975f5c5SAndroid Build Coastguard Worker             mState.getExecutable().getInfoLog()
721*8975f5c5SAndroid Build Coastguard Worker                 << "The current renderer doesn't support gl_FrontFacing";
722*8975f5c5SAndroid Build Coastguard Worker             // Fail compilation
723*8975f5c5SAndroid Build Coastguard Worker             ANGLE_CHECK_HR(context, false, "gl_FrontFacing not supported", E_NOTIMPL);
724*8975f5c5SAndroid Build Coastguard Worker         }
725*8975f5c5SAndroid Build Coastguard Worker     }
726*8975f5c5SAndroid Build Coastguard Worker 
727*8975f5c5SAndroid Build Coastguard Worker     const gl::VaryingPacking &varyingPacking =
728*8975f5c5SAndroid Build Coastguard Worker         resources.varyingPacking.getOutputPacking(gl::ShaderType::Vertex);
729*8975f5c5SAndroid Build Coastguard Worker 
730*8975f5c5SAndroid Build Coastguard Worker     ProgramD3DMetadata metadata(mRenderer, mState.getAttachedShader(gl::ShaderType::Fragment),
731*8975f5c5SAndroid Build Coastguard Worker                                 executableD3D->mAttachedShaders,
732*8975f5c5SAndroid Build Coastguard Worker                                 mState.getAttachedShader(gl::ShaderType::Vertex)->shaderVersion);
733*8975f5c5SAndroid Build Coastguard Worker     BuiltinVaryingsD3D builtins(metadata, varyingPacking);
734*8975f5c5SAndroid Build Coastguard Worker 
735*8975f5c5SAndroid Build Coastguard Worker     DynamicHLSL::GenerateShaderLinkHLSL(mRenderer, caps, mState.getAttachedShaders(),
736*8975f5c5SAndroid Build Coastguard Worker                                         executableD3D->mAttachedShaders, metadata, varyingPacking,
737*8975f5c5SAndroid Build Coastguard Worker                                         builtins, &executableD3D->mShaderHLSL);
738*8975f5c5SAndroid Build Coastguard Worker 
739*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mUsesPointSize =
740*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mAttachedShaders[gl::ShaderType::Vertex] &&
741*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mAttachedShaders[gl::ShaderType::Vertex]->usesPointSize;
742*8975f5c5SAndroid Build Coastguard Worker     DynamicHLSL::GetPixelShaderOutputKey(mRenderer, caps, clientVersion, mState.getExecutable(),
743*8975f5c5SAndroid Build Coastguard Worker                                          metadata, &executableD3D->mPixelShaderKey);
744*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mFragDepthUsage      = metadata.getFragDepthUsage();
745*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mUsesSampleMask      = metadata.usesSampleMask();
746*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mUsesVertexID        = metadata.usesVertexID();
747*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mUsesViewID          = metadata.usesViewID();
748*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mHasMultiviewEnabled = metadata.hasMultiviewEnabled();
749*8975f5c5SAndroid Build Coastguard Worker 
750*8975f5c5SAndroid Build Coastguard Worker     // Cache if we use flat shading
751*8975f5c5SAndroid Build Coastguard Worker     executableD3D->mUsesFlatInterpolation =
752*8975f5c5SAndroid Build Coastguard Worker         FindFlatInterpolationVarying(mState.getAttachedShaders());
753*8975f5c5SAndroid Build Coastguard Worker 
754*8975f5c5SAndroid Build Coastguard Worker     if (mRenderer->getMajorShaderModel() >= 4)
755*8975f5c5SAndroid Build Coastguard Worker     {
756*8975f5c5SAndroid Build Coastguard Worker         executableD3D->mGeometryShaderPreamble = DynamicHLSL::GenerateGeometryShaderPreamble(
757*8975f5c5SAndroid Build Coastguard Worker             mRenderer, varyingPacking, builtins, executableD3D->mHasMultiviewEnabled,
758*8975f5c5SAndroid Build Coastguard Worker             metadata.canSelectViewInVertexShader());
759*8975f5c5SAndroid Build Coastguard Worker     }
760*8975f5c5SAndroid Build Coastguard Worker 
761*8975f5c5SAndroid Build Coastguard Worker     executableD3D->initAttribLocationsToD3DSemantic(
762*8975f5c5SAndroid Build Coastguard Worker         mState.getAttachedShader(gl::ShaderType::Vertex));
763*8975f5c5SAndroid Build Coastguard Worker 
764*8975f5c5SAndroid Build Coastguard Worker     executableD3D->defineUniformsAndAssignRegisters(mRenderer, mState.getAttachedShaders());
765*8975f5c5SAndroid Build Coastguard Worker 
766*8975f5c5SAndroid Build Coastguard Worker     executableD3D->gatherTransformFeedbackVaryings(mRenderer, varyingPacking,
767*8975f5c5SAndroid Build Coastguard Worker                                                    mState.getTransformFeedbackVaryingNames(),
768*8975f5c5SAndroid Build Coastguard Worker                                                    builtins[gl::ShaderType::Vertex]);
769*8975f5c5SAndroid Build Coastguard Worker 
770*8975f5c5SAndroid Build Coastguard Worker     linkResources(resources);
771*8975f5c5SAndroid Build Coastguard Worker 
772*8975f5c5SAndroid Build Coastguard Worker     if (mState.getAttachedShader(gl::ShaderType::Vertex))
773*8975f5c5SAndroid Build Coastguard Worker     {
774*8975f5c5SAndroid Build Coastguard Worker         executableD3D->updateCachedInputLayoutFromShader(
775*8975f5c5SAndroid Build Coastguard Worker             mRenderer, mState.getAttachedShader(gl::ShaderType::Vertex));
776*8975f5c5SAndroid Build Coastguard Worker     }
777*8975f5c5SAndroid Build Coastguard Worker 
778*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
779*8975f5c5SAndroid Build Coastguard Worker }
780*8975f5c5SAndroid Build Coastguard Worker 
validate(const gl::Caps &)781*8975f5c5SAndroid Build Coastguard Worker GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/)
782*8975f5c5SAndroid Build Coastguard Worker {
783*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Do something useful here?
784*8975f5c5SAndroid Build Coastguard Worker     return GL_TRUE;
785*8975f5c5SAndroid Build Coastguard Worker }
786*8975f5c5SAndroid Build Coastguard Worker 
linkResources(const gl::ProgramLinkedResources & resources)787*8975f5c5SAndroid Build Coastguard Worker void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources)
788*8975f5c5SAndroid Build Coastguard Worker {
789*8975f5c5SAndroid Build Coastguard Worker     HLSLBlockLayoutEncoderFactory hlslEncoderFactory;
790*8975f5c5SAndroid Build Coastguard Worker     gl::ProgramLinkedResourcesLinker linker(&hlslEncoderFactory);
791*8975f5c5SAndroid Build Coastguard Worker 
792*8975f5c5SAndroid Build Coastguard Worker     linker.linkResources(mState, resources);
793*8975f5c5SAndroid Build Coastguard Worker 
794*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableD3D *executableD3D = getExecutable();
795*8975f5c5SAndroid Build Coastguard Worker 
796*8975f5c5SAndroid Build Coastguard Worker     executableD3D->initializeUniformBlocks();
797*8975f5c5SAndroid Build Coastguard Worker     executableD3D->initializeShaderStorageBlocks(mState.getAttachedShaders());
798*8975f5c5SAndroid Build Coastguard Worker }
799*8975f5c5SAndroid Build Coastguard Worker 
800*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
801