1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2023 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 // ProgramExecutableD3D.cpp: Implementation of ProgramExecutableD3D.
7*8975f5c5SAndroid Build Coastguard Worker
8*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ProgramExecutableD3D.h"
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/FramebufferAttachment.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/FramebufferD3D.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/trace.h"
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker namespace rx
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker namespace
21*8975f5c5SAndroid Build Coastguard Worker {
GetDefaultInputLayoutFromShader(const gl::SharedCompiledShaderState & vertexShader,gl::InputLayout * inputLayoutOut)22*8975f5c5SAndroid Build Coastguard Worker void GetDefaultInputLayoutFromShader(const gl::SharedCompiledShaderState &vertexShader,
23*8975f5c5SAndroid Build Coastguard Worker gl::InputLayout *inputLayoutOut)
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker inputLayoutOut->clear();
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker if (!vertexShader)
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker return;
30*8975f5c5SAndroid Build Coastguard Worker }
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &shaderAttr : vertexShader->activeAttributes)
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker if (shaderAttr.type != GL_NONE)
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker for (size_t rowIndex = 0;
39*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex)
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker GLenum componentType = gl::VariableComponentType(transposedType);
42*8975f5c5SAndroid Build Coastguard Worker GLuint components = static_cast<GLuint>(gl::VariableColumnCount(transposedType));
43*8975f5c5SAndroid Build Coastguard Worker bool pureInt = (componentType != GL_FLOAT);
44*8975f5c5SAndroid Build Coastguard Worker
45*8975f5c5SAndroid Build Coastguard Worker gl::VertexAttribType attribType =
46*8975f5c5SAndroid Build Coastguard Worker gl::FromGLenum<gl::VertexAttribType>(componentType);
47*8975f5c5SAndroid Build Coastguard Worker
48*8975f5c5SAndroid Build Coastguard Worker angle::FormatID defaultID =
49*8975f5c5SAndroid Build Coastguard Worker gl::GetVertexFormatID(attribType, GL_FALSE, components, pureInt);
50*8975f5c5SAndroid Build Coastguard Worker
51*8975f5c5SAndroid Build Coastguard Worker inputLayoutOut->push_back(defaultID);
52*8975f5c5SAndroid Build Coastguard Worker }
53*8975f5c5SAndroid Build Coastguard Worker }
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker }
56*8975f5c5SAndroid Build Coastguard Worker
GetMaxOutputIndex(const std::vector<PixelShaderOutputVariable> & shaderOutputVars,size_t location)57*8975f5c5SAndroid Build Coastguard Worker size_t GetMaxOutputIndex(const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
58*8975f5c5SAndroid Build Coastguard Worker size_t location)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker size_t maxIndex = 0;
61*8975f5c5SAndroid Build Coastguard Worker for (auto &outputVar : shaderOutputVars)
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker if (outputVar.outputLocation == location)
64*8975f5c5SAndroid Build Coastguard Worker {
65*8975f5c5SAndroid Build Coastguard Worker maxIndex = std::max(maxIndex, outputVar.outputIndex);
66*8975f5c5SAndroid Build Coastguard Worker }
67*8975f5c5SAndroid Build Coastguard Worker }
68*8975f5c5SAndroid Build Coastguard Worker return maxIndex;
69*8975f5c5SAndroid Build Coastguard Worker }
70*8975f5c5SAndroid Build Coastguard Worker
GetDefaultOutputLayoutFromShader(const std::vector<PixelShaderOutputVariable> & shaderOutputVars,std::vector<GLenum> * outputLayoutOut)71*8975f5c5SAndroid Build Coastguard Worker void GetDefaultOutputLayoutFromShader(
72*8975f5c5SAndroid Build Coastguard Worker const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
73*8975f5c5SAndroid Build Coastguard Worker std::vector<GLenum> *outputLayoutOut)
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker outputLayoutOut->clear();
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Worker if (!shaderOutputVars.empty())
78*8975f5c5SAndroid Build Coastguard Worker {
79*8975f5c5SAndroid Build Coastguard Worker size_t location = shaderOutputVars[0].outputLocation;
80*8975f5c5SAndroid Build Coastguard Worker size_t maxIndex = GetMaxOutputIndex(shaderOutputVars, location);
81*8975f5c5SAndroid Build Coastguard Worker outputLayoutOut->assign(maxIndex + 1,
82*8975f5c5SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT0 + static_cast<unsigned int>(location));
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker
GetDefaultImage2DBindLayoutFromShader(const std::vector<sh::ShaderVariable> & image2DUniforms,gl::ImageUnitTextureTypeMap * image2DBindLayout)86*8975f5c5SAndroid Build Coastguard Worker void GetDefaultImage2DBindLayoutFromShader(const std::vector<sh::ShaderVariable> &image2DUniforms,
87*8975f5c5SAndroid Build Coastguard Worker gl::ImageUnitTextureTypeMap *image2DBindLayout)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker image2DBindLayout->clear();
90*8975f5c5SAndroid Build Coastguard Worker
91*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &image2D : image2DUniforms)
92*8975f5c5SAndroid Build Coastguard Worker {
93*8975f5c5SAndroid Build Coastguard Worker if (gl::IsImage2DType(image2D.type))
94*8975f5c5SAndroid Build Coastguard Worker {
95*8975f5c5SAndroid Build Coastguard Worker if (image2D.binding == -1)
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker image2DBindLayout->insert(std::make_pair(0, gl::TextureType::_2D));
98*8975f5c5SAndroid Build Coastguard Worker }
99*8975f5c5SAndroid Build Coastguard Worker else
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++)
102*8975f5c5SAndroid Build Coastguard Worker {
103*8975f5c5SAndroid Build Coastguard Worker image2DBindLayout->insert(
104*8975f5c5SAndroid Build Coastguard Worker std::make_pair(image2D.binding + index, gl::TextureType::_2D));
105*8975f5c5SAndroid Build Coastguard Worker }
106*8975f5c5SAndroid Build Coastguard Worker }
107*8975f5c5SAndroid Build Coastguard Worker }
108*8975f5c5SAndroid Build Coastguard Worker }
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker
GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode)111*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode)
112*8975f5c5SAndroid Build Coastguard Worker {
113*8975f5c5SAndroid Build Coastguard Worker switch (drawMode)
114*8975f5c5SAndroid Build Coastguard Worker {
115*8975f5c5SAndroid Build Coastguard Worker // Uses the point sprite geometry shader.
116*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::Points:
117*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Points;
118*8975f5c5SAndroid Build Coastguard Worker
119*8975f5c5SAndroid Build Coastguard Worker // All line drawing uses the same geometry shader.
120*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::Lines:
121*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::LineStrip:
122*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::LineLoop:
123*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Lines;
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Worker // The triangle fan primitive is emulated with strips in D3D11.
126*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::Triangles:
127*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::TriangleFan:
128*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::Triangles;
129*8975f5c5SAndroid Build Coastguard Worker
130*8975f5c5SAndroid Build Coastguard Worker // Special case for triangle strips.
131*8975f5c5SAndroid Build Coastguard Worker case gl::PrimitiveMode::TriangleStrip:
132*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::TriangleStrip;
133*8975f5c5SAndroid Build Coastguard Worker
134*8975f5c5SAndroid Build Coastguard Worker default:
135*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
136*8975f5c5SAndroid Build Coastguard Worker return gl::PrimitiveMode::InvalidEnum;
137*8975f5c5SAndroid Build Coastguard Worker }
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker // Helper class that gathers uniform info from the default uniform block.
141*8975f5c5SAndroid Build Coastguard Worker class UniformEncodingVisitorD3D : public sh::BlockEncoderVisitor
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker public:
UniformEncodingVisitorD3D(gl::ShaderType shaderType,HLSLRegisterType registerType,sh::BlockLayoutEncoder * encoder,D3DUniformMap * uniformMapOut)144*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D(gl::ShaderType shaderType,
145*8975f5c5SAndroid Build Coastguard Worker HLSLRegisterType registerType,
146*8975f5c5SAndroid Build Coastguard Worker sh::BlockLayoutEncoder *encoder,
147*8975f5c5SAndroid Build Coastguard Worker D3DUniformMap *uniformMapOut)
148*8975f5c5SAndroid Build Coastguard Worker : sh::BlockEncoderVisitor("", "", encoder),
149*8975f5c5SAndroid Build Coastguard Worker mShaderType(shaderType),
150*8975f5c5SAndroid Build Coastguard Worker mRegisterType(registerType),
151*8975f5c5SAndroid Build Coastguard Worker mUniformMapOut(uniformMapOut)
152*8975f5c5SAndroid Build Coastguard Worker {}
153*8975f5c5SAndroid Build Coastguard Worker
visitNamedOpaqueObject(const sh::ShaderVariable & sampler,const std::string & name,const std::string & mappedName,const std::vector<unsigned int> & arraySizes)154*8975f5c5SAndroid Build Coastguard Worker void visitNamedOpaqueObject(const sh::ShaderVariable &sampler,
155*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
156*8975f5c5SAndroid Build Coastguard Worker const std::string &mappedName,
157*8975f5c5SAndroid Build Coastguard Worker const std::vector<unsigned int> &arraySizes) override
158*8975f5c5SAndroid Build Coastguard Worker {
159*8975f5c5SAndroid Build Coastguard Worker auto uniformMapEntry = mUniformMapOut->find(name);
160*8975f5c5SAndroid Build Coastguard Worker if (uniformMapEntry == mUniformMapOut->end())
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker (*mUniformMapOut)[name] =
163*8975f5c5SAndroid Build Coastguard Worker new D3DUniform(sampler.type, mRegisterType, name, sampler.arraySizes, true);
164*8975f5c5SAndroid Build Coastguard Worker }
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker
encodeVariable(const sh::ShaderVariable & variable,const sh::BlockMemberInfo & variableInfo,const std::string & name,const std::string & mappedName)167*8975f5c5SAndroid Build Coastguard Worker void encodeVariable(const sh::ShaderVariable &variable,
168*8975f5c5SAndroid Build Coastguard Worker const sh::BlockMemberInfo &variableInfo,
169*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
170*8975f5c5SAndroid Build Coastguard Worker const std::string &mappedName) override
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker auto uniformMapEntry = mUniformMapOut->find(name);
173*8975f5c5SAndroid Build Coastguard Worker D3DUniform *d3dUniform = nullptr;
174*8975f5c5SAndroid Build Coastguard Worker
175*8975f5c5SAndroid Build Coastguard Worker if (uniformMapEntry != mUniformMapOut->end())
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker d3dUniform = uniformMapEntry->second;
178*8975f5c5SAndroid Build Coastguard Worker }
179*8975f5c5SAndroid Build Coastguard Worker else
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker d3dUniform =
182*8975f5c5SAndroid Build Coastguard Worker new D3DUniform(variable.type, mRegisterType, name, variable.arraySizes, true);
183*8975f5c5SAndroid Build Coastguard Worker (*mUniformMapOut)[name] = d3dUniform;
184*8975f5c5SAndroid Build Coastguard Worker }
185*8975f5c5SAndroid Build Coastguard Worker
186*8975f5c5SAndroid Build Coastguard Worker d3dUniform->registerElement = static_cast<unsigned int>(
187*8975f5c5SAndroid Build Coastguard Worker sh::BlockLayoutEncoder::GetBlockRegisterElement(variableInfo));
188*8975f5c5SAndroid Build Coastguard Worker unsigned int reg =
189*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(sh::BlockLayoutEncoder::GetBlockRegister(variableInfo));
190*8975f5c5SAndroid Build Coastguard Worker
191*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType != gl::ShaderType::InvalidEnum);
192*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderRegisterIndexes[mShaderType] = reg;
193*8975f5c5SAndroid Build Coastguard Worker }
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker private:
196*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType mShaderType;
197*8975f5c5SAndroid Build Coastguard Worker HLSLRegisterType mRegisterType;
198*8975f5c5SAndroid Build Coastguard Worker D3DUniformMap *mUniformMapOut;
199*8975f5c5SAndroid Build Coastguard Worker };
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
202*8975f5c5SAndroid Build Coastguard Worker
203*8975f5c5SAndroid Build Coastguard Worker // D3DUniform Implementation
D3DUniform(GLenum type,HLSLRegisterType reg,const std::string & nameIn,const std::vector<unsigned int> & arraySizesIn,bool defaultBlock)204*8975f5c5SAndroid Build Coastguard Worker D3DUniform::D3DUniform(GLenum type,
205*8975f5c5SAndroid Build Coastguard Worker HLSLRegisterType reg,
206*8975f5c5SAndroid Build Coastguard Worker const std::string &nameIn,
207*8975f5c5SAndroid Build Coastguard Worker const std::vector<unsigned int> &arraySizesIn,
208*8975f5c5SAndroid Build Coastguard Worker bool defaultBlock)
209*8975f5c5SAndroid Build Coastguard Worker : typeInfo(gl::GetUniformTypeInfo(type)),
210*8975f5c5SAndroid Build Coastguard Worker name(nameIn),
211*8975f5c5SAndroid Build Coastguard Worker arraySizes(arraySizesIn),
212*8975f5c5SAndroid Build Coastguard Worker mShaderData({}),
213*8975f5c5SAndroid Build Coastguard Worker regType(reg),
214*8975f5c5SAndroid Build Coastguard Worker registerCount(0),
215*8975f5c5SAndroid Build Coastguard Worker registerElement(0)
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker // We use data storage for default block uniforms to cache values that are sent to D3D during
220*8975f5c5SAndroid Build Coastguard Worker // rendering
221*8975f5c5SAndroid Build Coastguard Worker // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
222*8975f5c5SAndroid Build Coastguard Worker if (defaultBlock)
223*8975f5c5SAndroid Build Coastguard Worker {
224*8975f5c5SAndroid Build Coastguard Worker // Use the row count as register count, will work for non-square matrices.
225*8975f5c5SAndroid Build Coastguard Worker registerCount = typeInfo.rowCount * getArraySizeProduct();
226*8975f5c5SAndroid Build Coastguard Worker }
227*8975f5c5SAndroid Build Coastguard Worker }
228*8975f5c5SAndroid Build Coastguard Worker
~D3DUniform()229*8975f5c5SAndroid Build Coastguard Worker D3DUniform::~D3DUniform() {}
230*8975f5c5SAndroid Build Coastguard Worker
getArraySizeProduct() const231*8975f5c5SAndroid Build Coastguard Worker unsigned int D3DUniform::getArraySizeProduct() const
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker return gl::ArraySizeProduct(arraySizes);
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker
getDataPtrToElement(size_t elementIndex) const236*8975f5c5SAndroid Build Coastguard Worker const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker ASSERT((!isArray() && elementIndex == 0) ||
239*8975f5c5SAndroid Build Coastguard Worker (isArray() && elementIndex < getArraySizeProduct()));
240*8975f5c5SAndroid Build Coastguard Worker
241*8975f5c5SAndroid Build Coastguard Worker if (isSampler())
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker return reinterpret_cast<const uint8_t *>(&mSamplerData[elementIndex]);
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Worker return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u);
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker
isSampler() const249*8975f5c5SAndroid Build Coastguard Worker bool D3DUniform::isSampler() const
250*8975f5c5SAndroid Build Coastguard Worker {
251*8975f5c5SAndroid Build Coastguard Worker return typeInfo.isSampler;
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker
isImage() const254*8975f5c5SAndroid Build Coastguard Worker bool D3DUniform::isImage() const
255*8975f5c5SAndroid Build Coastguard Worker {
256*8975f5c5SAndroid Build Coastguard Worker return typeInfo.isImageType;
257*8975f5c5SAndroid Build Coastguard Worker }
258*8975f5c5SAndroid Build Coastguard Worker
isImage2D() const259*8975f5c5SAndroid Build Coastguard Worker bool D3DUniform::isImage2D() const
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker return gl::IsImage2DType(typeInfo.type);
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker
isReferencedByShader(gl::ShaderType shaderType) const264*8975f5c5SAndroid Build Coastguard Worker bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker
firstNonNullData() const269*8975f5c5SAndroid Build Coastguard Worker const uint8_t *D3DUniform::firstNonNullData() const
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker if (!mSamplerData.empty())
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker return reinterpret_cast<const uint8_t *>(mSamplerData.data());
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker
276*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker if (mShaderData[shaderType])
279*8975f5c5SAndroid Build Coastguard Worker {
280*8975f5c5SAndroid Build Coastguard Worker return mShaderData[shaderType];
281*8975f5c5SAndroid Build Coastguard Worker }
282*8975f5c5SAndroid Build Coastguard Worker }
283*8975f5c5SAndroid Build Coastguard Worker
284*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
285*8975f5c5SAndroid Build Coastguard Worker return nullptr;
286*8975f5c5SAndroid Build Coastguard Worker }
287*8975f5c5SAndroid Build Coastguard Worker
288*8975f5c5SAndroid Build Coastguard Worker // D3DInterfaceBlock Implementation
D3DInterfaceBlock()289*8975f5c5SAndroid Build Coastguard Worker D3DInterfaceBlock::D3DInterfaceBlock()
290*8975f5c5SAndroid Build Coastguard Worker {
291*8975f5c5SAndroid Build Coastguard Worker mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker
294*8975f5c5SAndroid Build Coastguard Worker D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default;
295*8975f5c5SAndroid Build Coastguard Worker
D3DUniformBlock()296*8975f5c5SAndroid Build Coastguard Worker D3DUniformBlock::D3DUniformBlock()
297*8975f5c5SAndroid Build Coastguard Worker {
298*8975f5c5SAndroid Build Coastguard Worker mUseStructuredBuffers.fill(false);
299*8975f5c5SAndroid Build Coastguard Worker mByteWidths.fill(0u);
300*8975f5c5SAndroid Build Coastguard Worker mStructureByteStrides.fill(0u);
301*8975f5c5SAndroid Build Coastguard Worker }
302*8975f5c5SAndroid Build Coastguard Worker
303*8975f5c5SAndroid Build Coastguard Worker D3DUniformBlock::D3DUniformBlock(const D3DUniformBlock &other) = default;
304*8975f5c5SAndroid Build Coastguard Worker
305*8975f5c5SAndroid Build Coastguard Worker // D3DVarying Implementation
D3DVarying()306*8975f5c5SAndroid Build Coastguard Worker D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {}
307*8975f5c5SAndroid Build Coastguard Worker
D3DVarying(const std::string & semanticNameIn,unsigned int semanticIndexIn,unsigned int componentCountIn,unsigned int outputSlotIn)308*8975f5c5SAndroid Build Coastguard Worker D3DVarying::D3DVarying(const std::string &semanticNameIn,
309*8975f5c5SAndroid Build Coastguard Worker unsigned int semanticIndexIn,
310*8975f5c5SAndroid Build Coastguard Worker unsigned int componentCountIn,
311*8975f5c5SAndroid Build Coastguard Worker unsigned int outputSlotIn)
312*8975f5c5SAndroid Build Coastguard Worker : semanticName(semanticNameIn),
313*8975f5c5SAndroid Build Coastguard Worker semanticIndex(semanticIndexIn),
314*8975f5c5SAndroid Build Coastguard Worker componentCount(componentCountIn),
315*8975f5c5SAndroid Build Coastguard Worker outputSlot(outputSlotIn)
316*8975f5c5SAndroid Build Coastguard Worker {}
317*8975f5c5SAndroid Build Coastguard Worker
D3DVertexExecutable(const gl::InputLayout & inputLayout,const Signature & signature,ShaderExecutableD3D * shaderExecutable)318*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::D3DVertexExecutable(const gl::InputLayout &inputLayout,
319*8975f5c5SAndroid Build Coastguard Worker const Signature &signature,
320*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *shaderExecutable)
321*8975f5c5SAndroid Build Coastguard Worker : mInputs(inputLayout), mSignature(signature), mShaderExecutable(shaderExecutable)
322*8975f5c5SAndroid Build Coastguard Worker {}
323*8975f5c5SAndroid Build Coastguard Worker
~D3DVertexExecutable()324*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::~D3DVertexExecutable()
325*8975f5c5SAndroid Build Coastguard Worker {
326*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mShaderExecutable);
327*8975f5c5SAndroid Build Coastguard Worker }
328*8975f5c5SAndroid Build Coastguard Worker
329*8975f5c5SAndroid Build Coastguard Worker // static
GetAttribType(GLenum type)330*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::HLSLAttribType D3DVertexExecutable::GetAttribType(GLenum type)
331*8975f5c5SAndroid Build Coastguard Worker {
332*8975f5c5SAndroid Build Coastguard Worker switch (type)
333*8975f5c5SAndroid Build Coastguard Worker {
334*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
335*8975f5c5SAndroid Build Coastguard Worker return HLSLAttribType::SIGNED_INT;
336*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
337*8975f5c5SAndroid Build Coastguard Worker return HLSLAttribType::UNSIGNED_INT;
338*8975f5c5SAndroid Build Coastguard Worker case GL_SIGNED_NORMALIZED:
339*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_NORMALIZED:
340*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
341*8975f5c5SAndroid Build Coastguard Worker return HLSLAttribType::FLOAT;
342*8975f5c5SAndroid Build Coastguard Worker default:
343*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
344*8975f5c5SAndroid Build Coastguard Worker return HLSLAttribType::FLOAT;
345*8975f5c5SAndroid Build Coastguard Worker }
346*8975f5c5SAndroid Build Coastguard Worker }
347*8975f5c5SAndroid Build Coastguard Worker
348*8975f5c5SAndroid Build Coastguard Worker // static
getSignature(RendererD3D * renderer,const gl::InputLayout & inputLayout,Signature * signatureOut)349*8975f5c5SAndroid Build Coastguard Worker void D3DVertexExecutable::getSignature(RendererD3D *renderer,
350*8975f5c5SAndroid Build Coastguard Worker const gl::InputLayout &inputLayout,
351*8975f5c5SAndroid Build Coastguard Worker Signature *signatureOut)
352*8975f5c5SAndroid Build Coastguard Worker {
353*8975f5c5SAndroid Build Coastguard Worker signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT);
354*8975f5c5SAndroid Build Coastguard Worker
355*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < inputLayout.size(); ++index)
356*8975f5c5SAndroid Build Coastguard Worker {
357*8975f5c5SAndroid Build Coastguard Worker angle::FormatID vertexFormatID = inputLayout[index];
358*8975f5c5SAndroid Build Coastguard Worker if (vertexFormatID == angle::FormatID::NONE)
359*8975f5c5SAndroid Build Coastguard Worker continue;
360*8975f5c5SAndroid Build Coastguard Worker
361*8975f5c5SAndroid Build Coastguard Worker VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatID);
362*8975f5c5SAndroid Build Coastguard Worker if ((conversionType & VERTEX_CONVERT_GPU) == 0)
363*8975f5c5SAndroid Build Coastguard Worker continue;
364*8975f5c5SAndroid Build Coastguard Worker
365*8975f5c5SAndroid Build Coastguard Worker GLenum componentType = renderer->getVertexComponentType(vertexFormatID);
366*8975f5c5SAndroid Build Coastguard Worker (*signatureOut)[index] = GetAttribType(componentType);
367*8975f5c5SAndroid Build Coastguard Worker }
368*8975f5c5SAndroid Build Coastguard Worker }
369*8975f5c5SAndroid Build Coastguard Worker
matchesSignature(const Signature & signature) const370*8975f5c5SAndroid Build Coastguard Worker bool D3DVertexExecutable::matchesSignature(const Signature &signature) const
371*8975f5c5SAndroid Build Coastguard Worker {
372*8975f5c5SAndroid Build Coastguard Worker size_t limit = std::max(mSignature.size(), signature.size());
373*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < limit; ++index)
374*8975f5c5SAndroid Build Coastguard Worker {
375*8975f5c5SAndroid Build Coastguard Worker // treat undefined indexes as FLOAT
376*8975f5c5SAndroid Build Coastguard Worker auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT;
377*8975f5c5SAndroid Build Coastguard Worker auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT;
378*8975f5c5SAndroid Build Coastguard Worker if (a != b)
379*8975f5c5SAndroid Build Coastguard Worker return false;
380*8975f5c5SAndroid Build Coastguard Worker }
381*8975f5c5SAndroid Build Coastguard Worker
382*8975f5c5SAndroid Build Coastguard Worker return true;
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker
D3DPixelExecutable(const std::vector<GLenum> & outputSignature,const gl::ImageUnitTextureTypeMap & image2DSignature,ShaderExecutableD3D * shaderExecutable)385*8975f5c5SAndroid Build Coastguard Worker D3DPixelExecutable::D3DPixelExecutable(const std::vector<GLenum> &outputSignature,
386*8975f5c5SAndroid Build Coastguard Worker const gl::ImageUnitTextureTypeMap &image2DSignature,
387*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *shaderExecutable)
388*8975f5c5SAndroid Build Coastguard Worker : mOutputSignature(outputSignature),
389*8975f5c5SAndroid Build Coastguard Worker mImage2DSignature(image2DSignature),
390*8975f5c5SAndroid Build Coastguard Worker mShaderExecutable(shaderExecutable)
391*8975f5c5SAndroid Build Coastguard Worker {}
392*8975f5c5SAndroid Build Coastguard Worker
~D3DPixelExecutable()393*8975f5c5SAndroid Build Coastguard Worker D3DPixelExecutable::~D3DPixelExecutable()
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mShaderExecutable);
396*8975f5c5SAndroid Build Coastguard Worker }
397*8975f5c5SAndroid Build Coastguard Worker
D3DComputeExecutable(const gl::ImageUnitTextureTypeMap & signature,std::unique_ptr<ShaderExecutableD3D> shaderExecutable)398*8975f5c5SAndroid Build Coastguard Worker D3DComputeExecutable::D3DComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
399*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<ShaderExecutableD3D> shaderExecutable)
400*8975f5c5SAndroid Build Coastguard Worker : mSignature(signature), mShaderExecutable(std::move(shaderExecutable))
401*8975f5c5SAndroid Build Coastguard Worker {}
402*8975f5c5SAndroid Build Coastguard Worker
~D3DComputeExecutable()403*8975f5c5SAndroid Build Coastguard Worker D3DComputeExecutable::~D3DComputeExecutable() {}
404*8975f5c5SAndroid Build Coastguard Worker
D3DSampler()405*8975f5c5SAndroid Build Coastguard Worker D3DSampler::D3DSampler() : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D)
406*8975f5c5SAndroid Build Coastguard Worker {}
407*8975f5c5SAndroid Build Coastguard Worker
D3DImage()408*8975f5c5SAndroid Build Coastguard Worker D3DImage::D3DImage() : active(false), logicalImageUnit(0) {}
409*8975f5c5SAndroid Build Coastguard Worker
410*8975f5c5SAndroid Build Coastguard Worker unsigned int ProgramExecutableD3D::mCurrentSerial = 1;
411*8975f5c5SAndroid Build Coastguard Worker
ProgramExecutableD3D(const gl::ProgramExecutable * executable)412*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableD3D::ProgramExecutableD3D(const gl::ProgramExecutable *executable)
413*8975f5c5SAndroid Build Coastguard Worker : ProgramExecutableImpl(executable),
414*8975f5c5SAndroid Build Coastguard Worker mUsesPointSize(false),
415*8975f5c5SAndroid Build Coastguard Worker mUsesFlatInterpolation(false),
416*8975f5c5SAndroid Build Coastguard Worker mUsedShaderSamplerRanges({}),
417*8975f5c5SAndroid Build Coastguard Worker mDirtySamplerMapping(true),
418*8975f5c5SAndroid Build Coastguard Worker mUsedImageRange({}),
419*8975f5c5SAndroid Build Coastguard Worker mUsedReadonlyImageRange({}),
420*8975f5c5SAndroid Build Coastguard Worker mUsedAtomicCounterRange({}),
421*8975f5c5SAndroid Build Coastguard Worker mSerial(issueSerial())
422*8975f5c5SAndroid Build Coastguard Worker {
423*8975f5c5SAndroid Build Coastguard Worker reset();
424*8975f5c5SAndroid Build Coastguard Worker }
425*8975f5c5SAndroid Build Coastguard Worker
~ProgramExecutableD3D()426*8975f5c5SAndroid Build Coastguard Worker ProgramExecutableD3D::~ProgramExecutableD3D() {}
427*8975f5c5SAndroid Build Coastguard Worker
destroy(const gl::Context * context)428*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::destroy(const gl::Context *context) {}
429*8975f5c5SAndroid Build Coastguard Worker
reset()430*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::reset()
431*8975f5c5SAndroid Build Coastguard Worker {
432*8975f5c5SAndroid Build Coastguard Worker mVertexExecutables.clear();
433*8975f5c5SAndroid Build Coastguard Worker mPixelExecutables.clear();
434*8975f5c5SAndroid Build Coastguard Worker mComputeExecutables.clear();
435*8975f5c5SAndroid Build Coastguard Worker
436*8975f5c5SAndroid Build Coastguard Worker for (auto &geometryExecutable : mGeometryExecutables)
437*8975f5c5SAndroid Build Coastguard Worker {
438*8975f5c5SAndroid Build Coastguard Worker geometryExecutable.reset(nullptr);
439*8975f5c5SAndroid Build Coastguard Worker }
440*8975f5c5SAndroid Build Coastguard Worker
441*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
442*8975f5c5SAndroid Build Coastguard Worker {
443*8975f5c5SAndroid Build Coastguard Worker mShaderHLSL[shaderType].clear();
444*8975f5c5SAndroid Build Coastguard Worker }
445*8975f5c5SAndroid Build Coastguard Worker
446*8975f5c5SAndroid Build Coastguard Worker mFragDepthUsage = FragDepthUsage::Unused;
447*8975f5c5SAndroid Build Coastguard Worker mUsesSampleMask = false;
448*8975f5c5SAndroid Build Coastguard Worker mHasMultiviewEnabled = false;
449*8975f5c5SAndroid Build Coastguard Worker mUsesVertexID = false;
450*8975f5c5SAndroid Build Coastguard Worker mUsesViewID = false;
451*8975f5c5SAndroid Build Coastguard Worker mPixelShaderKey.clear();
452*8975f5c5SAndroid Build Coastguard Worker mUsesPointSize = false;
453*8975f5c5SAndroid Build Coastguard Worker mUsesFlatInterpolation = false;
454*8975f5c5SAndroid Build Coastguard Worker
455*8975f5c5SAndroid Build Coastguard Worker SafeDeleteContainer(mD3DUniforms);
456*8975f5c5SAndroid Build Coastguard Worker mD3DUniformBlocks.clear();
457*8975f5c5SAndroid Build Coastguard Worker mD3DShaderStorageBlocks.clear();
458*8975f5c5SAndroid Build Coastguard Worker mComputeAtomicCounterBufferRegisterIndices.fill({});
459*8975f5c5SAndroid Build Coastguard Worker
460*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
461*8975f5c5SAndroid Build Coastguard Worker {
462*8975f5c5SAndroid Build Coastguard Worker mShaderUniformStorages[shaderType].reset();
463*8975f5c5SAndroid Build Coastguard Worker mShaderSamplers[shaderType].clear();
464*8975f5c5SAndroid Build Coastguard Worker mImages[shaderType].clear();
465*8975f5c5SAndroid Build Coastguard Worker mReadonlyImages[shaderType].clear();
466*8975f5c5SAndroid Build Coastguard Worker }
467*8975f5c5SAndroid Build Coastguard Worker
468*8975f5c5SAndroid Build Coastguard Worker mUsedShaderSamplerRanges.fill({0, 0});
469*8975f5c5SAndroid Build Coastguard Worker mUsedAtomicCounterRange.fill({0, 0});
470*8975f5c5SAndroid Build Coastguard Worker mDirtySamplerMapping = true;
471*8975f5c5SAndroid Build Coastguard Worker mUsedImageRange.fill({0, 0});
472*8975f5c5SAndroid Build Coastguard Worker mUsedReadonlyImageRange.fill({0, 0});
473*8975f5c5SAndroid Build Coastguard Worker
474*8975f5c5SAndroid Build Coastguard Worker mAttribLocationToD3DSemantic.fill(-1);
475*8975f5c5SAndroid Build Coastguard Worker
476*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.clear();
477*8975f5c5SAndroid Build Coastguard Worker
478*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderPreamble.clear();
479*8975f5c5SAndroid Build Coastguard Worker
480*8975f5c5SAndroid Build Coastguard Worker markUniformsClean();
481*8975f5c5SAndroid Build Coastguard Worker
482*8975f5c5SAndroid Build Coastguard Worker mCachedPixelExecutableIndex.reset();
483*8975f5c5SAndroid Build Coastguard Worker mCachedVertexExecutableIndex.reset();
484*8975f5c5SAndroid Build Coastguard Worker }
485*8975f5c5SAndroid Build Coastguard Worker
load(const gl::Context * context,RendererD3D * renderer,gl::BinaryInputStream * stream)486*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::load(const gl::Context *context,
487*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
488*8975f5c5SAndroid Build Coastguard Worker gl::BinaryInputStream *stream)
489*8975f5c5SAndroid Build Coastguard Worker {
490*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog &infoLog = mExecutable->getInfoLog();
491*8975f5c5SAndroid Build Coastguard Worker
492*8975f5c5SAndroid Build Coastguard Worker reset();
493*8975f5c5SAndroid Build Coastguard Worker
494*8975f5c5SAndroid Build Coastguard Worker DeviceIdentifier binaryDeviceIdentifier = {};
495*8975f5c5SAndroid Build Coastguard Worker stream->readBytes(reinterpret_cast<unsigned char *>(&binaryDeviceIdentifier),
496*8975f5c5SAndroid Build Coastguard Worker sizeof(DeviceIdentifier));
497*8975f5c5SAndroid Build Coastguard Worker
498*8975f5c5SAndroid Build Coastguard Worker DeviceIdentifier identifier = renderer->getAdapterIdentifier();
499*8975f5c5SAndroid Build Coastguard Worker if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0)
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker infoLog << "Invalid program binary, device configuration has changed.";
502*8975f5c5SAndroid Build Coastguard Worker return false;
503*8975f5c5SAndroid Build Coastguard Worker }
504*8975f5c5SAndroid Build Coastguard Worker
505*8975f5c5SAndroid Build Coastguard Worker int compileFlags = stream->readInt<int>();
506*8975f5c5SAndroid Build Coastguard Worker if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
507*8975f5c5SAndroid Build Coastguard Worker {
508*8975f5c5SAndroid Build Coastguard Worker infoLog << "Mismatched compilation flags.";
509*8975f5c5SAndroid Build Coastguard Worker return false;
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker
512*8975f5c5SAndroid Build Coastguard Worker for (int &index : mAttribLocationToD3DSemantic)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&index);
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
518*8975f5c5SAndroid Build Coastguard Worker {
519*8975f5c5SAndroid Build Coastguard Worker size_t samplerCount = stream->readInt<size_t>();
520*8975f5c5SAndroid Build Coastguard Worker for (size_t sampleIndex = 0; sampleIndex < samplerCount; ++sampleIndex)
521*8975f5c5SAndroid Build Coastguard Worker {
522*8975f5c5SAndroid Build Coastguard Worker D3DSampler sampler;
523*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&sampler.active);
524*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&sampler.logicalTextureUnit);
525*8975f5c5SAndroid Build Coastguard Worker stream->readEnum(&sampler.textureType);
526*8975f5c5SAndroid Build Coastguard Worker mShaderSamplers[shaderType].push_back(sampler);
527*8975f5c5SAndroid Build Coastguard Worker }
528*8975f5c5SAndroid Build Coastguard Worker
529*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerRangeLow, samplerRangeHigh;
530*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&samplerRangeLow);
531*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&samplerRangeHigh);
532*8975f5c5SAndroid Build Coastguard Worker mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh);
533*8975f5c5SAndroid Build Coastguard Worker }
534*8975f5c5SAndroid Build Coastguard Worker
535*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
536*8975f5c5SAndroid Build Coastguard Worker {
537*8975f5c5SAndroid Build Coastguard Worker size_t imageCount = stream->readInt<size_t>();
538*8975f5c5SAndroid Build Coastguard Worker for (size_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
539*8975f5c5SAndroid Build Coastguard Worker {
540*8975f5c5SAndroid Build Coastguard Worker D3DImage image;
541*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&image.active);
542*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&image.logicalImageUnit);
543*8975f5c5SAndroid Build Coastguard Worker mImages[shaderType].push_back(image);
544*8975f5c5SAndroid Build Coastguard Worker }
545*8975f5c5SAndroid Build Coastguard Worker
546*8975f5c5SAndroid Build Coastguard Worker size_t readonlyImageCount = stream->readInt<size_t>();
547*8975f5c5SAndroid Build Coastguard Worker for (size_t imageIndex = 0; imageIndex < readonlyImageCount; ++imageIndex)
548*8975f5c5SAndroid Build Coastguard Worker {
549*8975f5c5SAndroid Build Coastguard Worker D3DImage image;
550*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&image.active);
551*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&image.logicalImageUnit);
552*8975f5c5SAndroid Build Coastguard Worker mReadonlyImages[shaderType].push_back(image);
553*8975f5c5SAndroid Build Coastguard Worker }
554*8975f5c5SAndroid Build Coastguard Worker
555*8975f5c5SAndroid Build Coastguard Worker unsigned int imageRangeLow, imageRangeHigh, readonlyImageRangeLow, readonlyImageRangeHigh;
556*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&imageRangeLow);
557*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&imageRangeHigh);
558*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&readonlyImageRangeLow);
559*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&readonlyImageRangeHigh);
560*8975f5c5SAndroid Build Coastguard Worker mUsedImageRange[shaderType] = gl::RangeUI(imageRangeLow, imageRangeHigh);
561*8975f5c5SAndroid Build Coastguard Worker mUsedReadonlyImageRange[shaderType] =
562*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI(readonlyImageRangeLow, readonlyImageRangeHigh);
563*8975f5c5SAndroid Build Coastguard Worker
564*8975f5c5SAndroid Build Coastguard Worker unsigned int atomicCounterRangeLow, atomicCounterRangeHigh;
565*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&atomicCounterRangeLow);
566*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&atomicCounterRangeHigh);
567*8975f5c5SAndroid Build Coastguard Worker mUsedAtomicCounterRange[shaderType] =
568*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
569*8975f5c5SAndroid Build Coastguard Worker }
570*8975f5c5SAndroid Build Coastguard Worker
571*8975f5c5SAndroid Build Coastguard Worker size_t shaderStorageBlockCount = stream->readInt<size_t>();
572*8975f5c5SAndroid Build Coastguard Worker if (stream->error())
573*8975f5c5SAndroid Build Coastguard Worker {
574*8975f5c5SAndroid Build Coastguard Worker infoLog << "Invalid program binary.";
575*8975f5c5SAndroid Build Coastguard Worker return false;
576*8975f5c5SAndroid Build Coastguard Worker }
577*8975f5c5SAndroid Build Coastguard Worker
578*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DShaderStorageBlocks.empty());
579*8975f5c5SAndroid Build Coastguard Worker for (size_t blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex)
580*8975f5c5SAndroid Build Coastguard Worker {
581*8975f5c5SAndroid Build Coastguard Worker D3DInterfaceBlock shaderStorageBlock;
582*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
585*8975f5c5SAndroid Build Coastguard Worker }
586*8975f5c5SAndroid Build Coastguard Worker mD3DShaderStorageBlocks.push_back(shaderStorageBlock);
587*8975f5c5SAndroid Build Coastguard Worker }
588*8975f5c5SAndroid Build Coastguard Worker
589*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
590*8975f5c5SAndroid Build Coastguard Worker {
591*8975f5c5SAndroid Build Coastguard Worker size_t image2DUniformCount = stream->readInt<size_t>();
592*8975f5c5SAndroid Build Coastguard Worker if (stream->error())
593*8975f5c5SAndroid Build Coastguard Worker {
594*8975f5c5SAndroid Build Coastguard Worker infoLog << "Invalid program binary.";
595*8975f5c5SAndroid Build Coastguard Worker return false;
596*8975f5c5SAndroid Build Coastguard Worker }
597*8975f5c5SAndroid Build Coastguard Worker
598*8975f5c5SAndroid Build Coastguard Worker ASSERT(mImage2DUniforms[shaderType].empty());
599*8975f5c5SAndroid Build Coastguard Worker for (size_t image2DUniformIndex = 0; image2DUniformIndex < image2DUniformCount;
600*8975f5c5SAndroid Build Coastguard Worker ++image2DUniformIndex)
601*8975f5c5SAndroid Build Coastguard Worker {
602*8975f5c5SAndroid Build Coastguard Worker sh::ShaderVariable image2Duniform;
603*8975f5c5SAndroid Build Coastguard Worker gl::LoadShaderVar(stream, &image2Duniform);
604*8975f5c5SAndroid Build Coastguard Worker mImage2DUniforms[shaderType].push_back(image2Duniform);
605*8975f5c5SAndroid Build Coastguard Worker }
606*8975f5c5SAndroid Build Coastguard Worker }
607*8975f5c5SAndroid Build Coastguard Worker
608*8975f5c5SAndroid Build Coastguard Worker for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
609*8975f5c5SAndroid Build Coastguard Worker {
610*8975f5c5SAndroid Build Coastguard Worker unsigned int index = stream->readInt<unsigned int>();
611*8975f5c5SAndroid Build Coastguard Worker mComputeAtomicCounterBufferRegisterIndices[ii] = index;
612*8975f5c5SAndroid Build Coastguard Worker }
613*8975f5c5SAndroid Build Coastguard Worker
614*8975f5c5SAndroid Build Coastguard Worker size_t uniformCount = stream->readInt<size_t>();
615*8975f5c5SAndroid Build Coastguard Worker if (stream->error())
616*8975f5c5SAndroid Build Coastguard Worker {
617*8975f5c5SAndroid Build Coastguard Worker infoLog << "Invalid program binary.";
618*8975f5c5SAndroid Build Coastguard Worker return false;
619*8975f5c5SAndroid Build Coastguard Worker }
620*8975f5c5SAndroid Build Coastguard Worker
621*8975f5c5SAndroid Build Coastguard Worker const auto &linkedUniforms = mExecutable->getUniforms();
622*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DUniforms.empty());
623*8975f5c5SAndroid Build Coastguard Worker for (size_t uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
624*8975f5c5SAndroid Build Coastguard Worker {
625*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
626*8975f5c5SAndroid Build Coastguard Worker // Could D3DUniform just change to use unsigned int instead of std::vector for arraySizes?
627*8975f5c5SAndroid Build Coastguard Worker // Frontend always flatten the array to at most 1D array.
628*8975f5c5SAndroid Build Coastguard Worker std::vector<unsigned int> arraySizes;
629*8975f5c5SAndroid Build Coastguard Worker if (linkedUniform.isArray())
630*8975f5c5SAndroid Build Coastguard Worker {
631*8975f5c5SAndroid Build Coastguard Worker arraySizes.push_back(linkedUniform.getBasicTypeElementCount());
632*8975f5c5SAndroid Build Coastguard Worker }
633*8975f5c5SAndroid Build Coastguard Worker D3DUniform *d3dUniform = new D3DUniform(linkedUniform.getType(), HLSLRegisterType::None,
634*8975f5c5SAndroid Build Coastguard Worker mExecutable->getUniformNames()[uniformIndex],
635*8975f5c5SAndroid Build Coastguard Worker arraySizes, linkedUniform.isInDefaultBlock());
636*8975f5c5SAndroid Build Coastguard Worker stream->readEnum(&d3dUniform->regType);
637*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
638*8975f5c5SAndroid Build Coastguard Worker {
639*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]);
640*8975f5c5SAndroid Build Coastguard Worker }
641*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&d3dUniform->registerCount);
642*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&d3dUniform->registerElement);
643*8975f5c5SAndroid Build Coastguard Worker
644*8975f5c5SAndroid Build Coastguard Worker mD3DUniforms.push_back(d3dUniform);
645*8975f5c5SAndroid Build Coastguard Worker }
646*8975f5c5SAndroid Build Coastguard Worker
647*8975f5c5SAndroid Build Coastguard Worker size_t blockCount = stream->readInt<size_t>();
648*8975f5c5SAndroid Build Coastguard Worker if (stream->error())
649*8975f5c5SAndroid Build Coastguard Worker {
650*8975f5c5SAndroid Build Coastguard Worker infoLog << "Invalid program binary.";
651*8975f5c5SAndroid Build Coastguard Worker return false;
652*8975f5c5SAndroid Build Coastguard Worker }
653*8975f5c5SAndroid Build Coastguard Worker
654*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DUniformBlocks.empty());
655*8975f5c5SAndroid Build Coastguard Worker for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
656*8975f5c5SAndroid Build Coastguard Worker {
657*8975f5c5SAndroid Build Coastguard Worker D3DUniformBlock uniformBlock;
658*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
659*8975f5c5SAndroid Build Coastguard Worker {
660*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
661*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&uniformBlock.mUseStructuredBuffers[shaderType]);
662*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&uniformBlock.mByteWidths[shaderType]);
663*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&uniformBlock.mStructureByteStrides[shaderType]);
664*8975f5c5SAndroid Build Coastguard Worker }
665*8975f5c5SAndroid Build Coastguard Worker mD3DUniformBlocks.push_back(uniformBlock);
666*8975f5c5SAndroid Build Coastguard Worker }
667*8975f5c5SAndroid Build Coastguard Worker
668*8975f5c5SAndroid Build Coastguard Worker size_t streamOutVaryingCount = stream->readInt<size_t>();
669*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.resize(streamOutVaryingCount);
670*8975f5c5SAndroid Build Coastguard Worker for (size_t varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex)
671*8975f5c5SAndroid Build Coastguard Worker {
672*8975f5c5SAndroid Build Coastguard Worker D3DVarying *varying = &mStreamOutVaryings[varyingIndex];
673*8975f5c5SAndroid Build Coastguard Worker
674*8975f5c5SAndroid Build Coastguard Worker stream->readString(&varying->semanticName);
675*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&varying->semanticIndex);
676*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&varying->componentCount);
677*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&varying->outputSlot);
678*8975f5c5SAndroid Build Coastguard Worker }
679*8975f5c5SAndroid Build Coastguard Worker
680*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker stream->readString(&mShaderHLSL[shaderType]);
683*8975f5c5SAndroid Build Coastguard Worker stream->readBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
684*8975f5c5SAndroid Build Coastguard Worker sizeof(CompilerWorkaroundsD3D));
685*8975f5c5SAndroid Build Coastguard Worker }
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker stream->readEnum(&mFragDepthUsage);
688*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mUsesSampleMask);
689*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mHasMultiviewEnabled);
690*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mUsesVertexID);
691*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mUsesViewID);
692*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mUsesPointSize);
693*8975f5c5SAndroid Build Coastguard Worker stream->readBool(&mUsesFlatInterpolation);
694*8975f5c5SAndroid Build Coastguard Worker
695*8975f5c5SAndroid Build Coastguard Worker const size_t pixelShaderKeySize = stream->readInt<size_t>();
696*8975f5c5SAndroid Build Coastguard Worker mPixelShaderKey.resize(pixelShaderKeySize);
697*8975f5c5SAndroid Build Coastguard Worker for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize;
698*8975f5c5SAndroid Build Coastguard Worker pixelShaderKeyIndex++)
699*8975f5c5SAndroid Build Coastguard Worker {
700*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
701*8975f5c5SAndroid Build Coastguard Worker stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
702*8975f5c5SAndroid Build Coastguard Worker stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
703*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputLocation);
704*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
705*8975f5c5SAndroid Build Coastguard Worker }
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Worker stream->readString(&mGeometryShaderPreamble);
708*8975f5c5SAndroid Build Coastguard Worker
709*8975f5c5SAndroid Build Coastguard Worker return true;
710*8975f5c5SAndroid Build Coastguard Worker }
711*8975f5c5SAndroid Build Coastguard Worker
loadBinaryShaderExecutables(d3d::Context * contextD3D,RendererD3D * renderer,gl::BinaryInputStream * stream)712*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableD3D::loadBinaryShaderExecutables(d3d::Context *contextD3D,
713*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
714*8975f5c5SAndroid Build Coastguard Worker gl::BinaryInputStream *stream)
715*8975f5c5SAndroid Build Coastguard Worker {
716*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog &infoLog = mExecutable->getInfoLog();
717*8975f5c5SAndroid Build Coastguard Worker const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data());
718*8975f5c5SAndroid Build Coastguard Worker
719*8975f5c5SAndroid Build Coastguard Worker bool separateAttribs = mExecutable->getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS;
720*8975f5c5SAndroid Build Coastguard Worker
721*8975f5c5SAndroid Build Coastguard Worker size_t vertexShaderCount = stream->readInt<size_t>();
722*8975f5c5SAndroid Build Coastguard Worker for (size_t vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
723*8975f5c5SAndroid Build Coastguard Worker {
724*8975f5c5SAndroid Build Coastguard Worker size_t inputLayoutSize = stream->readInt<size_t>();
725*8975f5c5SAndroid Build Coastguard Worker gl::InputLayout inputLayout(inputLayoutSize, angle::FormatID::NONE);
726*8975f5c5SAndroid Build Coastguard Worker
727*8975f5c5SAndroid Build Coastguard Worker for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++)
728*8975f5c5SAndroid Build Coastguard Worker {
729*8975f5c5SAndroid Build Coastguard Worker inputLayout[inputIndex] = stream->readEnum<angle::FormatID>();
730*8975f5c5SAndroid Build Coastguard Worker }
731*8975f5c5SAndroid Build Coastguard Worker
732*8975f5c5SAndroid Build Coastguard Worker size_t vertexShaderSize = stream->readInt<size_t>();
733*8975f5c5SAndroid Build Coastguard Worker const unsigned char *vertexShaderFunction = binary + stream->offset();
734*8975f5c5SAndroid Build Coastguard Worker
735*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *shaderExecutable = nullptr;
736*8975f5c5SAndroid Build Coastguard Worker
737*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->loadExecutable(contextD3D, vertexShaderFunction, vertexShaderSize,
738*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Vertex, mStreamOutVaryings,
739*8975f5c5SAndroid Build Coastguard Worker separateAttribs, &shaderExecutable));
740*8975f5c5SAndroid Build Coastguard Worker
741*8975f5c5SAndroid Build Coastguard Worker if (!shaderExecutable)
742*8975f5c5SAndroid Build Coastguard Worker {
743*8975f5c5SAndroid Build Coastguard Worker infoLog << "Could not create vertex shader.";
744*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
745*8975f5c5SAndroid Build Coastguard Worker }
746*8975f5c5SAndroid Build Coastguard Worker
747*8975f5c5SAndroid Build Coastguard Worker // generated converted input layout
748*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::Signature signature;
749*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::getSignature(renderer, inputLayout, &signature);
750*8975f5c5SAndroid Build Coastguard Worker
751*8975f5c5SAndroid Build Coastguard Worker // add new binary
752*8975f5c5SAndroid Build Coastguard Worker mVertexExecutables.push_back(std::unique_ptr<D3DVertexExecutable>(
753*8975f5c5SAndroid Build Coastguard Worker new D3DVertexExecutable(inputLayout, signature, shaderExecutable)));
754*8975f5c5SAndroid Build Coastguard Worker
755*8975f5c5SAndroid Build Coastguard Worker stream->skip(vertexShaderSize);
756*8975f5c5SAndroid Build Coastguard Worker }
757*8975f5c5SAndroid Build Coastguard Worker
758*8975f5c5SAndroid Build Coastguard Worker size_t pixelShaderCount = stream->readInt<size_t>();
759*8975f5c5SAndroid Build Coastguard Worker for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
760*8975f5c5SAndroid Build Coastguard Worker {
761*8975f5c5SAndroid Build Coastguard Worker size_t outputCount = stream->readInt<size_t>();
762*8975f5c5SAndroid Build Coastguard Worker std::vector<GLenum> outputs(outputCount);
763*8975f5c5SAndroid Build Coastguard Worker for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&outputs[outputIndex]);
766*8975f5c5SAndroid Build Coastguard Worker }
767*8975f5c5SAndroid Build Coastguard Worker
768*8975f5c5SAndroid Build Coastguard Worker const size_t image2DCount = stream->readInt<size_t>();
769*8975f5c5SAndroid Build Coastguard Worker gl::ImageUnitTextureTypeMap image2Ds;
770*8975f5c5SAndroid Build Coastguard Worker for (size_t index = 0; index < image2DCount; index++)
771*8975f5c5SAndroid Build Coastguard Worker {
772*8975f5c5SAndroid Build Coastguard Worker unsigned int imageUint;
773*8975f5c5SAndroid Build Coastguard Worker gl::TextureType textureType;
774*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&imageUint);
775*8975f5c5SAndroid Build Coastguard Worker stream->readEnum(&textureType);
776*8975f5c5SAndroid Build Coastguard Worker image2Ds.insert({imageUint, textureType});
777*8975f5c5SAndroid Build Coastguard Worker }
778*8975f5c5SAndroid Build Coastguard Worker
779*8975f5c5SAndroid Build Coastguard Worker size_t pixelShaderSize = stream->readInt<size_t>();
780*8975f5c5SAndroid Build Coastguard Worker const unsigned char *pixelShaderFunction = binary + stream->offset();
781*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *shaderExecutable = nullptr;
782*8975f5c5SAndroid Build Coastguard Worker
783*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->loadExecutable(contextD3D, pixelShaderFunction, pixelShaderSize,
784*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Fragment, mStreamOutVaryings,
785*8975f5c5SAndroid Build Coastguard Worker separateAttribs, &shaderExecutable));
786*8975f5c5SAndroid Build Coastguard Worker
787*8975f5c5SAndroid Build Coastguard Worker if (!shaderExecutable)
788*8975f5c5SAndroid Build Coastguard Worker {
789*8975f5c5SAndroid Build Coastguard Worker infoLog << "Could not create pixel shader.";
790*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
791*8975f5c5SAndroid Build Coastguard Worker }
792*8975f5c5SAndroid Build Coastguard Worker
793*8975f5c5SAndroid Build Coastguard Worker // add new binary
794*8975f5c5SAndroid Build Coastguard Worker mPixelExecutables.push_back(std::unique_ptr<D3DPixelExecutable>(
795*8975f5c5SAndroid Build Coastguard Worker new D3DPixelExecutable(outputs, image2Ds, shaderExecutable)));
796*8975f5c5SAndroid Build Coastguard Worker
797*8975f5c5SAndroid Build Coastguard Worker stream->skip(pixelShaderSize);
798*8975f5c5SAndroid Build Coastguard Worker }
799*8975f5c5SAndroid Build Coastguard Worker
800*8975f5c5SAndroid Build Coastguard Worker for (std::unique_ptr<ShaderExecutableD3D> &geometryExe : mGeometryExecutables)
801*8975f5c5SAndroid Build Coastguard Worker {
802*8975f5c5SAndroid Build Coastguard Worker size_t geometryShaderSize = stream->readInt<size_t>();
803*8975f5c5SAndroid Build Coastguard Worker if (geometryShaderSize == 0)
804*8975f5c5SAndroid Build Coastguard Worker {
805*8975f5c5SAndroid Build Coastguard Worker continue;
806*8975f5c5SAndroid Build Coastguard Worker }
807*8975f5c5SAndroid Build Coastguard Worker
808*8975f5c5SAndroid Build Coastguard Worker const unsigned char *geometryShaderFunction = binary + stream->offset();
809*8975f5c5SAndroid Build Coastguard Worker
810*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *geometryExecutable = nullptr;
811*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->loadExecutable(contextD3D, geometryShaderFunction, geometryShaderSize,
812*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Geometry, mStreamOutVaryings,
813*8975f5c5SAndroid Build Coastguard Worker separateAttribs, &geometryExecutable));
814*8975f5c5SAndroid Build Coastguard Worker
815*8975f5c5SAndroid Build Coastguard Worker if (!geometryExecutable)
816*8975f5c5SAndroid Build Coastguard Worker {
817*8975f5c5SAndroid Build Coastguard Worker infoLog << "Could not create geometry shader.";
818*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
819*8975f5c5SAndroid Build Coastguard Worker }
820*8975f5c5SAndroid Build Coastguard Worker
821*8975f5c5SAndroid Build Coastguard Worker geometryExe.reset(geometryExecutable);
822*8975f5c5SAndroid Build Coastguard Worker
823*8975f5c5SAndroid Build Coastguard Worker stream->skip(geometryShaderSize);
824*8975f5c5SAndroid Build Coastguard Worker }
825*8975f5c5SAndroid Build Coastguard Worker
826*8975f5c5SAndroid Build Coastguard Worker size_t computeShaderCount = stream->readInt<size_t>();
827*8975f5c5SAndroid Build Coastguard Worker for (size_t computeShaderIndex = 0; computeShaderIndex < computeShaderCount;
828*8975f5c5SAndroid Build Coastguard Worker computeShaderIndex++)
829*8975f5c5SAndroid Build Coastguard Worker {
830*8975f5c5SAndroid Build Coastguard Worker size_t signatureCount = stream->readInt<size_t>();
831*8975f5c5SAndroid Build Coastguard Worker gl::ImageUnitTextureTypeMap signatures;
832*8975f5c5SAndroid Build Coastguard Worker for (size_t signatureIndex = 0; signatureIndex < signatureCount; signatureIndex++)
833*8975f5c5SAndroid Build Coastguard Worker {
834*8975f5c5SAndroid Build Coastguard Worker unsigned int imageUint;
835*8975f5c5SAndroid Build Coastguard Worker gl::TextureType textureType;
836*8975f5c5SAndroid Build Coastguard Worker stream->readInt(&imageUint);
837*8975f5c5SAndroid Build Coastguard Worker stream->readEnum(&textureType);
838*8975f5c5SAndroid Build Coastguard Worker signatures.insert(std::pair<unsigned int, gl::TextureType>(imageUint, textureType));
839*8975f5c5SAndroid Build Coastguard Worker }
840*8975f5c5SAndroid Build Coastguard Worker
841*8975f5c5SAndroid Build Coastguard Worker size_t computeShaderSize = stream->readInt<size_t>();
842*8975f5c5SAndroid Build Coastguard Worker const unsigned char *computeShaderFunction = binary + stream->offset();
843*8975f5c5SAndroid Build Coastguard Worker
844*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *computeExecutable = nullptr;
845*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->loadExecutable(contextD3D, computeShaderFunction, computeShaderSize,
846*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Compute, std::vector<D3DVarying>(),
847*8975f5c5SAndroid Build Coastguard Worker false, &computeExecutable));
848*8975f5c5SAndroid Build Coastguard Worker
849*8975f5c5SAndroid Build Coastguard Worker if (!computeExecutable)
850*8975f5c5SAndroid Build Coastguard Worker {
851*8975f5c5SAndroid Build Coastguard Worker infoLog << "Could not create compute shader.";
852*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
853*8975f5c5SAndroid Build Coastguard Worker }
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker // add new binary
856*8975f5c5SAndroid Build Coastguard Worker mComputeExecutables.push_back(
857*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<D3DComputeExecutable>(new D3DComputeExecutable(
858*8975f5c5SAndroid Build Coastguard Worker signatures, std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
859*8975f5c5SAndroid Build Coastguard Worker
860*8975f5c5SAndroid Build Coastguard Worker stream->skip(computeShaderSize);
861*8975f5c5SAndroid Build Coastguard Worker }
862*8975f5c5SAndroid Build Coastguard Worker
863*8975f5c5SAndroid Build Coastguard Worker for (const gl::ShaderType shaderType :
864*8975f5c5SAndroid Build Coastguard Worker {gl::ShaderType::Vertex, gl::ShaderType::Fragment, gl::ShaderType::Compute})
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker size_t bindLayoutCount = stream->readInt<size_t>();
867*8975f5c5SAndroid Build Coastguard Worker for (size_t bindLayoutIndex = 0; bindLayoutIndex < bindLayoutCount; bindLayoutIndex++)
868*8975f5c5SAndroid Build Coastguard Worker {
869*8975f5c5SAndroid Build Coastguard Worker mImage2DBindLayoutCache[shaderType].insert(std::pair<unsigned int, gl::TextureType>(
870*8975f5c5SAndroid Build Coastguard Worker stream->readInt<unsigned int>(), gl::TextureType::_2D));
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker }
873*8975f5c5SAndroid Build Coastguard Worker
874*8975f5c5SAndroid Build Coastguard Worker initializeUniformStorage(renderer, mExecutable->getLinkedShaderStages());
875*8975f5c5SAndroid Build Coastguard Worker
876*8975f5c5SAndroid Build Coastguard Worker dirtyAllUniforms();
877*8975f5c5SAndroid Build Coastguard Worker
878*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
879*8975f5c5SAndroid Build Coastguard Worker }
880*8975f5c5SAndroid Build Coastguard Worker
save(const gl::Context * context,RendererD3D * renderer,gl::BinaryOutputStream * stream)881*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::save(const gl::Context *context,
882*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
883*8975f5c5SAndroid Build Coastguard Worker gl::BinaryOutputStream *stream)
884*8975f5c5SAndroid Build Coastguard Worker {
885*8975f5c5SAndroid Build Coastguard Worker // Output the DeviceIdentifier before we output any shader code
886*8975f5c5SAndroid Build Coastguard Worker // When we load the binary again later, we can validate the device identifier before trying to
887*8975f5c5SAndroid Build Coastguard Worker // compile any HLSL
888*8975f5c5SAndroid Build Coastguard Worker DeviceIdentifier binaryIdentifier = renderer->getAdapterIdentifier();
889*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(reinterpret_cast<unsigned char *>(&binaryIdentifier),
890*8975f5c5SAndroid Build Coastguard Worker sizeof(DeviceIdentifier));
891*8975f5c5SAndroid Build Coastguard Worker
892*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
893*8975f5c5SAndroid Build Coastguard Worker
894*8975f5c5SAndroid Build Coastguard Worker for (int d3dSemantic : mAttribLocationToD3DSemantic)
895*8975f5c5SAndroid Build Coastguard Worker {
896*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(d3dSemantic);
897*8975f5c5SAndroid Build Coastguard Worker }
898*8975f5c5SAndroid Build Coastguard Worker
899*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
900*8975f5c5SAndroid Build Coastguard Worker {
901*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mShaderSamplers[shaderType].size());
902*8975f5c5SAndroid Build Coastguard Worker for (unsigned int i = 0; i < mShaderSamplers[shaderType].size(); ++i)
903*8975f5c5SAndroid Build Coastguard Worker {
904*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mShaderSamplers[shaderType][i].active);
905*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mShaderSamplers[shaderType][i].logicalTextureUnit);
906*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
907*8975f5c5SAndroid Build Coastguard Worker }
908*8975f5c5SAndroid Build Coastguard Worker
909*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
910*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
911*8975f5c5SAndroid Build Coastguard Worker }
912*8975f5c5SAndroid Build Coastguard Worker
913*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
914*8975f5c5SAndroid Build Coastguard Worker {
915*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mImages[shaderType].size());
916*8975f5c5SAndroid Build Coastguard Worker for (size_t imageIndex = 0; imageIndex < mImages[shaderType].size(); ++imageIndex)
917*8975f5c5SAndroid Build Coastguard Worker {
918*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mImages[shaderType][imageIndex].active);
919*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mImages[shaderType][imageIndex].logicalImageUnit);
920*8975f5c5SAndroid Build Coastguard Worker }
921*8975f5c5SAndroid Build Coastguard Worker
922*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mReadonlyImages[shaderType].size());
923*8975f5c5SAndroid Build Coastguard Worker for (size_t imageIndex = 0; imageIndex < mReadonlyImages[shaderType].size(); ++imageIndex)
924*8975f5c5SAndroid Build Coastguard Worker {
925*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mReadonlyImages[shaderType][imageIndex].active);
926*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mReadonlyImages[shaderType][imageIndex].logicalImageUnit);
927*8975f5c5SAndroid Build Coastguard Worker }
928*8975f5c5SAndroid Build Coastguard Worker
929*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedImageRange[shaderType].low());
930*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedImageRange[shaderType].high());
931*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedReadonlyImageRange[shaderType].low());
932*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedReadonlyImageRange[shaderType].high());
933*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedAtomicCounterRange[shaderType].low());
934*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mUsedAtomicCounterRange[shaderType].high());
935*8975f5c5SAndroid Build Coastguard Worker }
936*8975f5c5SAndroid Build Coastguard Worker
937*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mD3DShaderStorageBlocks.size());
938*8975f5c5SAndroid Build Coastguard Worker for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks)
939*8975f5c5SAndroid Build Coastguard Worker {
940*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
941*8975f5c5SAndroid Build Coastguard Worker {
942*8975f5c5SAndroid Build Coastguard Worker stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
943*8975f5c5SAndroid Build Coastguard Worker }
944*8975f5c5SAndroid Build Coastguard Worker }
945*8975f5c5SAndroid Build Coastguard Worker
946*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
947*8975f5c5SAndroid Build Coastguard Worker {
948*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mImage2DUniforms[shaderType].size());
949*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &image2DUniform : mImage2DUniforms[shaderType])
950*8975f5c5SAndroid Build Coastguard Worker {
951*8975f5c5SAndroid Build Coastguard Worker gl::WriteShaderVar(stream, image2DUniform);
952*8975f5c5SAndroid Build Coastguard Worker }
953*8975f5c5SAndroid Build Coastguard Worker }
954*8975f5c5SAndroid Build Coastguard Worker
955*8975f5c5SAndroid Build Coastguard Worker for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
956*8975f5c5SAndroid Build Coastguard Worker {
957*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mComputeAtomicCounterBufferRegisterIndices[ii]);
958*8975f5c5SAndroid Build Coastguard Worker }
959*8975f5c5SAndroid Build Coastguard Worker
960*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mD3DUniforms.size());
961*8975f5c5SAndroid Build Coastguard Worker for (const D3DUniform *uniform : mD3DUniforms)
962*8975f5c5SAndroid Build Coastguard Worker {
963*8975f5c5SAndroid Build Coastguard Worker // Type, name and arraySize are redundant, so aren't stored in the binary.
964*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(uniform->regType);
965*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
966*8975f5c5SAndroid Build Coastguard Worker {
967*8975f5c5SAndroid Build Coastguard Worker stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]);
968*8975f5c5SAndroid Build Coastguard Worker }
969*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(uniform->registerCount);
970*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(uniform->registerElement);
971*8975f5c5SAndroid Build Coastguard Worker }
972*8975f5c5SAndroid Build Coastguard Worker
973*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mD3DUniformBlocks.size());
974*8975f5c5SAndroid Build Coastguard Worker for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
975*8975f5c5SAndroid Build Coastguard Worker {
976*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
977*8975f5c5SAndroid Build Coastguard Worker {
978*8975f5c5SAndroid Build Coastguard Worker stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
979*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(uniformBlock.mUseStructuredBuffers[shaderType]);
980*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(uniformBlock.mByteWidths[shaderType]);
981*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(uniformBlock.mStructureByteStrides[shaderType]);
982*8975f5c5SAndroid Build Coastguard Worker }
983*8975f5c5SAndroid Build Coastguard Worker }
984*8975f5c5SAndroid Build Coastguard Worker
985*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mStreamOutVaryings.size());
986*8975f5c5SAndroid Build Coastguard Worker for (const D3DVarying &varying : mStreamOutVaryings)
987*8975f5c5SAndroid Build Coastguard Worker {
988*8975f5c5SAndroid Build Coastguard Worker stream->writeString(varying.semanticName);
989*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(varying.semanticIndex);
990*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(varying.componentCount);
991*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(varying.outputSlot);
992*8975f5c5SAndroid Build Coastguard Worker }
993*8975f5c5SAndroid Build Coastguard Worker
994*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
995*8975f5c5SAndroid Build Coastguard Worker {
996*8975f5c5SAndroid Build Coastguard Worker stream->writeString(mShaderHLSL[shaderType]);
997*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
998*8975f5c5SAndroid Build Coastguard Worker sizeof(CompilerWorkaroundsD3D));
999*8975f5c5SAndroid Build Coastguard Worker }
1000*8975f5c5SAndroid Build Coastguard Worker
1001*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(mFragDepthUsage);
1002*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mUsesSampleMask);
1003*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mHasMultiviewEnabled);
1004*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mUsesVertexID);
1005*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mUsesViewID);
1006*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mUsesPointSize);
1007*8975f5c5SAndroid Build Coastguard Worker stream->writeBool(mUsesFlatInterpolation);
1008*8975f5c5SAndroid Build Coastguard Worker
1009*8975f5c5SAndroid Build Coastguard Worker const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
1010*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(pixelShaderKey.size());
1011*8975f5c5SAndroid Build Coastguard Worker for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size();
1012*8975f5c5SAndroid Build Coastguard Worker pixelShaderKeyIndex++)
1013*8975f5c5SAndroid Build Coastguard Worker {
1014*8975f5c5SAndroid Build Coastguard Worker const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
1015*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(variable.type);
1016*8975f5c5SAndroid Build Coastguard Worker stream->writeString(variable.name);
1017*8975f5c5SAndroid Build Coastguard Worker stream->writeString(variable.source);
1018*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(variable.outputLocation);
1019*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(variable.outputIndex);
1020*8975f5c5SAndroid Build Coastguard Worker }
1021*8975f5c5SAndroid Build Coastguard Worker
1022*8975f5c5SAndroid Build Coastguard Worker stream->writeString(mGeometryShaderPreamble);
1023*8975f5c5SAndroid Build Coastguard Worker
1024*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mVertexExecutables.size());
1025*8975f5c5SAndroid Build Coastguard Worker for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
1026*8975f5c5SAndroid Build Coastguard Worker vertexExecutableIndex++)
1027*8975f5c5SAndroid Build Coastguard Worker {
1028*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get();
1029*8975f5c5SAndroid Build Coastguard Worker
1030*8975f5c5SAndroid Build Coastguard Worker const gl::InputLayout &inputLayout = vertexExecutable->inputs();
1031*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(inputLayout.size());
1032*8975f5c5SAndroid Build Coastguard Worker
1033*8975f5c5SAndroid Build Coastguard Worker for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++)
1034*8975f5c5SAndroid Build Coastguard Worker {
1035*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(inputLayout[inputIndex]);
1036*8975f5c5SAndroid Build Coastguard Worker }
1037*8975f5c5SAndroid Build Coastguard Worker
1038*8975f5c5SAndroid Build Coastguard Worker size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
1039*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(vertexShaderSize);
1040*8975f5c5SAndroid Build Coastguard Worker
1041*8975f5c5SAndroid Build Coastguard Worker const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
1042*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(vertexBlob, vertexShaderSize);
1043*8975f5c5SAndroid Build Coastguard Worker }
1044*8975f5c5SAndroid Build Coastguard Worker
1045*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mPixelExecutables.size());
1046*8975f5c5SAndroid Build Coastguard Worker for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size();
1047*8975f5c5SAndroid Build Coastguard Worker pixelExecutableIndex++)
1048*8975f5c5SAndroid Build Coastguard Worker {
1049*8975f5c5SAndroid Build Coastguard Worker D3DPixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get();
1050*8975f5c5SAndroid Build Coastguard Worker
1051*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLenum> &outputs = pixelExecutable->outputSignature();
1052*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(outputs.size());
1053*8975f5c5SAndroid Build Coastguard Worker for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
1054*8975f5c5SAndroid Build Coastguard Worker {
1055*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(outputs[outputIndex]);
1056*8975f5c5SAndroid Build Coastguard Worker }
1057*8975f5c5SAndroid Build Coastguard Worker
1058*8975f5c5SAndroid Build Coastguard Worker const gl::ImageUnitTextureTypeMap &image2Ds = pixelExecutable->image2DSignature();
1059*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(image2Ds.size());
1060*8975f5c5SAndroid Build Coastguard Worker for (const auto &image2D : image2Ds)
1061*8975f5c5SAndroid Build Coastguard Worker {
1062*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(image2D.first);
1063*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(image2D.second);
1064*8975f5c5SAndroid Build Coastguard Worker }
1065*8975f5c5SAndroid Build Coastguard Worker
1066*8975f5c5SAndroid Build Coastguard Worker size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
1067*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(pixelShaderSize);
1068*8975f5c5SAndroid Build Coastguard Worker
1069*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
1070*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(pixelBlob, pixelShaderSize);
1071*8975f5c5SAndroid Build Coastguard Worker }
1072*8975f5c5SAndroid Build Coastguard Worker
1073*8975f5c5SAndroid Build Coastguard Worker for (auto const &geometryExecutable : mGeometryExecutables)
1074*8975f5c5SAndroid Build Coastguard Worker {
1075*8975f5c5SAndroid Build Coastguard Worker if (!geometryExecutable)
1076*8975f5c5SAndroid Build Coastguard Worker {
1077*8975f5c5SAndroid Build Coastguard Worker stream->writeInt<size_t>(0);
1078*8975f5c5SAndroid Build Coastguard Worker continue;
1079*8975f5c5SAndroid Build Coastguard Worker }
1080*8975f5c5SAndroid Build Coastguard Worker
1081*8975f5c5SAndroid Build Coastguard Worker size_t geometryShaderSize = geometryExecutable->getLength();
1082*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(geometryShaderSize);
1083*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize);
1084*8975f5c5SAndroid Build Coastguard Worker }
1085*8975f5c5SAndroid Build Coastguard Worker
1086*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mComputeExecutables.size());
1087*8975f5c5SAndroid Build Coastguard Worker for (size_t computeExecutableIndex = 0; computeExecutableIndex < mComputeExecutables.size();
1088*8975f5c5SAndroid Build Coastguard Worker computeExecutableIndex++)
1089*8975f5c5SAndroid Build Coastguard Worker {
1090*8975f5c5SAndroid Build Coastguard Worker D3DComputeExecutable *computeExecutable = mComputeExecutables[computeExecutableIndex].get();
1091*8975f5c5SAndroid Build Coastguard Worker
1092*8975f5c5SAndroid Build Coastguard Worker const gl::ImageUnitTextureTypeMap signatures = computeExecutable->signature();
1093*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(signatures.size());
1094*8975f5c5SAndroid Build Coastguard Worker for (const auto &signature : signatures)
1095*8975f5c5SAndroid Build Coastguard Worker {
1096*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(signature.first);
1097*8975f5c5SAndroid Build Coastguard Worker stream->writeEnum(signature.second);
1098*8975f5c5SAndroid Build Coastguard Worker }
1099*8975f5c5SAndroid Build Coastguard Worker
1100*8975f5c5SAndroid Build Coastguard Worker size_t computeShaderSize = computeExecutable->shaderExecutable()->getLength();
1101*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(computeShaderSize);
1102*8975f5c5SAndroid Build Coastguard Worker
1103*8975f5c5SAndroid Build Coastguard Worker const uint8_t *computeBlob = computeExecutable->shaderExecutable()->getFunction();
1104*8975f5c5SAndroid Build Coastguard Worker stream->writeBytes(computeBlob, computeShaderSize);
1105*8975f5c5SAndroid Build Coastguard Worker }
1106*8975f5c5SAndroid Build Coastguard Worker
1107*8975f5c5SAndroid Build Coastguard Worker for (const gl::ShaderType shaderType :
1108*8975f5c5SAndroid Build Coastguard Worker {gl::ShaderType::Vertex, gl::ShaderType::Fragment, gl::ShaderType::Compute})
1109*8975f5c5SAndroid Build Coastguard Worker {
1110*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(mImage2DBindLayoutCache[shaderType].size());
1111*8975f5c5SAndroid Build Coastguard Worker for (auto &image2DBindLayout : mImage2DBindLayoutCache[shaderType])
1112*8975f5c5SAndroid Build Coastguard Worker {
1113*8975f5c5SAndroid Build Coastguard Worker stream->writeInt(image2DBindLayout.first);
1114*8975f5c5SAndroid Build Coastguard Worker }
1115*8975f5c5SAndroid Build Coastguard Worker }
1116*8975f5c5SAndroid Build Coastguard Worker }
1117*8975f5c5SAndroid Build Coastguard Worker
hasVertexExecutableForCachedInputLayout()1118*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::hasVertexExecutableForCachedInputLayout()
1119*8975f5c5SAndroid Build Coastguard Worker {
1120*8975f5c5SAndroid Build Coastguard Worker return mCachedVertexExecutableIndex.valid();
1121*8975f5c5SAndroid Build Coastguard Worker }
1122*8975f5c5SAndroid Build Coastguard Worker
hasGeometryExecutableForPrimitiveType(RendererD3D * renderer,const gl::State & state,gl::PrimitiveMode drawMode)1123*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::hasGeometryExecutableForPrimitiveType(RendererD3D *renderer,
1124*8975f5c5SAndroid Build Coastguard Worker const gl::State &state,
1125*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode drawMode)
1126*8975f5c5SAndroid Build Coastguard Worker {
1127*8975f5c5SAndroid Build Coastguard Worker if (!usesGeometryShader(renderer, state.getProvokingVertex(), drawMode))
1128*8975f5c5SAndroid Build Coastguard Worker {
1129*8975f5c5SAndroid Build Coastguard Worker // No shader necessary mean we have the required (null) executable.
1130*8975f5c5SAndroid Build Coastguard Worker return true;
1131*8975f5c5SAndroid Build Coastguard Worker }
1132*8975f5c5SAndroid Build Coastguard Worker
1133*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
1134*8975f5c5SAndroid Build Coastguard Worker return mGeometryExecutables[geometryShaderType].get() != nullptr;
1135*8975f5c5SAndroid Build Coastguard Worker }
1136*8975f5c5SAndroid Build Coastguard Worker
hasPixelExecutableForCachedOutputLayout()1137*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::hasPixelExecutableForCachedOutputLayout()
1138*8975f5c5SAndroid Build Coastguard Worker {
1139*8975f5c5SAndroid Build Coastguard Worker return mCachedPixelExecutableIndex.valid();
1140*8975f5c5SAndroid Build Coastguard Worker }
1141*8975f5c5SAndroid Build Coastguard Worker
hasComputeExecutableForCachedImage2DBindLayout()1142*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::hasComputeExecutableForCachedImage2DBindLayout()
1143*8975f5c5SAndroid Build Coastguard Worker {
1144*8975f5c5SAndroid Build Coastguard Worker return mCachedComputeExecutableIndex.valid();
1145*8975f5c5SAndroid Build Coastguard Worker }
1146*8975f5c5SAndroid Build Coastguard Worker
dirtyAllUniforms()1147*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::dirtyAllUniforms()
1148*8975f5c5SAndroid Build Coastguard Worker {
1149*8975f5c5SAndroid Build Coastguard Worker mShaderUniformsDirty = mExecutable->getLinkedShaderStages();
1150*8975f5c5SAndroid Build Coastguard Worker }
1151*8975f5c5SAndroid Build Coastguard Worker
markUniformsClean()1152*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::markUniformsClean()
1153*8975f5c5SAndroid Build Coastguard Worker {
1154*8975f5c5SAndroid Build Coastguard Worker mShaderUniformsDirty.reset();
1155*8975f5c5SAndroid Build Coastguard Worker }
1156*8975f5c5SAndroid Build Coastguard Worker
getAtomicCounterBufferRegisterIndex(GLuint binding,gl::ShaderType shaderType) const1157*8975f5c5SAndroid Build Coastguard Worker unsigned int ProgramExecutableD3D::getAtomicCounterBufferRegisterIndex(
1158*8975f5c5SAndroid Build Coastguard Worker GLuint binding,
1159*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType) const
1160*8975f5c5SAndroid Build Coastguard Worker {
1161*8975f5c5SAndroid Build Coastguard Worker if (shaderType != gl::ShaderType::Compute)
1162*8975f5c5SAndroid Build Coastguard Worker {
1163*8975f5c5SAndroid Build Coastguard Worker // Implement atomic counters for non-compute shaders
1164*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42260658
1165*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
1166*8975f5c5SAndroid Build Coastguard Worker }
1167*8975f5c5SAndroid Build Coastguard Worker return mComputeAtomicCounterBufferRegisterIndices[binding];
1168*8975f5c5SAndroid Build Coastguard Worker }
1169*8975f5c5SAndroid Build Coastguard Worker
getShaderStorageBufferRegisterIndex(GLuint blockIndex,gl::ShaderType shaderType) const1170*8975f5c5SAndroid Build Coastguard Worker unsigned int ProgramExecutableD3D::getShaderStorageBufferRegisterIndex(
1171*8975f5c5SAndroid Build Coastguard Worker GLuint blockIndex,
1172*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType) const
1173*8975f5c5SAndroid Build Coastguard Worker {
1174*8975f5c5SAndroid Build Coastguard Worker return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
1175*8975f5c5SAndroid Build Coastguard Worker }
1176*8975f5c5SAndroid Build Coastguard Worker
getShaderUniformBufferCache(gl::ShaderType shaderType) const1177*8975f5c5SAndroid Build Coastguard Worker const std::vector<D3DUBOCache> &ProgramExecutableD3D::getShaderUniformBufferCache(
1178*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType) const
1179*8975f5c5SAndroid Build Coastguard Worker {
1180*8975f5c5SAndroid Build Coastguard Worker return mShaderUBOCaches[shaderType];
1181*8975f5c5SAndroid Build Coastguard Worker }
1182*8975f5c5SAndroid Build Coastguard Worker
getShaderUniformBufferCacheUseSB(gl::ShaderType shaderType) const1183*8975f5c5SAndroid Build Coastguard Worker const std::vector<D3DUBOCacheUseSB> &ProgramExecutableD3D::getShaderUniformBufferCacheUseSB(
1184*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType) const
1185*8975f5c5SAndroid Build Coastguard Worker {
1186*8975f5c5SAndroid Build Coastguard Worker return mShaderUBOCachesUseSB[shaderType];
1187*8975f5c5SAndroid Build Coastguard Worker }
1188*8975f5c5SAndroid Build Coastguard Worker
getSamplerMapping(gl::ShaderType type,unsigned int samplerIndex,const gl::Caps & caps) const1189*8975f5c5SAndroid Build Coastguard Worker GLint ProgramExecutableD3D::getSamplerMapping(gl::ShaderType type,
1190*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerIndex,
1191*8975f5c5SAndroid Build Coastguard Worker const gl::Caps &caps) const
1192*8975f5c5SAndroid Build Coastguard Worker {
1193*8975f5c5SAndroid Build Coastguard Worker GLint logicalTextureUnit = -1;
1194*8975f5c5SAndroid Build Coastguard Worker
1195*8975f5c5SAndroid Build Coastguard Worker ASSERT(type != gl::ShaderType::InvalidEnum);
1196*8975f5c5SAndroid Build Coastguard Worker
1197*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplerIndex < static_cast<unsigned int>(caps.maxShaderTextureImageUnits[type]));
1198*8975f5c5SAndroid Build Coastguard Worker
1199*8975f5c5SAndroid Build Coastguard Worker const auto &samplers = mShaderSamplers[type];
1200*8975f5c5SAndroid Build Coastguard Worker if (samplerIndex < samplers.size() && samplers[samplerIndex].active)
1201*8975f5c5SAndroid Build Coastguard Worker {
1202*8975f5c5SAndroid Build Coastguard Worker logicalTextureUnit = samplers[samplerIndex].logicalTextureUnit;
1203*8975f5c5SAndroid Build Coastguard Worker }
1204*8975f5c5SAndroid Build Coastguard Worker
1205*8975f5c5SAndroid Build Coastguard Worker if (logicalTextureUnit >= 0 && logicalTextureUnit < caps.maxCombinedTextureImageUnits)
1206*8975f5c5SAndroid Build Coastguard Worker {
1207*8975f5c5SAndroid Build Coastguard Worker return logicalTextureUnit;
1208*8975f5c5SAndroid Build Coastguard Worker }
1209*8975f5c5SAndroid Build Coastguard Worker
1210*8975f5c5SAndroid Build Coastguard Worker return -1;
1211*8975f5c5SAndroid Build Coastguard Worker }
1212*8975f5c5SAndroid Build Coastguard Worker
1213*8975f5c5SAndroid Build Coastguard Worker // Returns the texture type for a given Direct3D 9 sampler type and
1214*8975f5c5SAndroid Build Coastguard Worker // index (0-15 for the pixel shader and 0-3 for the vertex shader).
getSamplerTextureType(gl::ShaderType type,unsigned int samplerIndex) const1215*8975f5c5SAndroid Build Coastguard Worker gl::TextureType ProgramExecutableD3D::getSamplerTextureType(gl::ShaderType type,
1216*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerIndex) const
1217*8975f5c5SAndroid Build Coastguard Worker {
1218*8975f5c5SAndroid Build Coastguard Worker ASSERT(type != gl::ShaderType::InvalidEnum);
1219*8975f5c5SAndroid Build Coastguard Worker
1220*8975f5c5SAndroid Build Coastguard Worker const auto &samplers = mShaderSamplers[type];
1221*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplerIndex < samplers.size());
1222*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplers[samplerIndex].active);
1223*8975f5c5SAndroid Build Coastguard Worker
1224*8975f5c5SAndroid Build Coastguard Worker return samplers[samplerIndex].textureType;
1225*8975f5c5SAndroid Build Coastguard Worker }
1226*8975f5c5SAndroid Build Coastguard Worker
getUsedSamplerRange(gl::ShaderType type) const1227*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI ProgramExecutableD3D::getUsedSamplerRange(gl::ShaderType type) const
1228*8975f5c5SAndroid Build Coastguard Worker {
1229*8975f5c5SAndroid Build Coastguard Worker ASSERT(type != gl::ShaderType::InvalidEnum);
1230*8975f5c5SAndroid Build Coastguard Worker return mUsedShaderSamplerRanges[type];
1231*8975f5c5SAndroid Build Coastguard Worker }
1232*8975f5c5SAndroid Build Coastguard Worker
updateSamplerMapping()1233*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateSamplerMapping()
1234*8975f5c5SAndroid Build Coastguard Worker {
1235*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDirtySamplerMapping);
1236*8975f5c5SAndroid Build Coastguard Worker
1237*8975f5c5SAndroid Build Coastguard Worker mDirtySamplerMapping = false;
1238*8975f5c5SAndroid Build Coastguard Worker
1239*8975f5c5SAndroid Build Coastguard Worker // Retrieve sampler uniform values
1240*8975f5c5SAndroid Build Coastguard Worker for (const D3DUniform *d3dUniform : mD3DUniforms)
1241*8975f5c5SAndroid Build Coastguard Worker {
1242*8975f5c5SAndroid Build Coastguard Worker if (!d3dUniform->isSampler())
1243*8975f5c5SAndroid Build Coastguard Worker continue;
1244*8975f5c5SAndroid Build Coastguard Worker
1245*8975f5c5SAndroid Build Coastguard Worker int count = d3dUniform->getArraySizeProduct();
1246*8975f5c5SAndroid Build Coastguard Worker
1247*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1248*8975f5c5SAndroid Build Coastguard Worker {
1249*8975f5c5SAndroid Build Coastguard Worker if (!d3dUniform->isReferencedByShader(shaderType))
1250*8975f5c5SAndroid Build Coastguard Worker {
1251*8975f5c5SAndroid Build Coastguard Worker continue;
1252*8975f5c5SAndroid Build Coastguard Worker }
1253*8975f5c5SAndroid Build Coastguard Worker
1254*8975f5c5SAndroid Build Coastguard Worker unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[shaderType];
1255*8975f5c5SAndroid Build Coastguard Worker
1256*8975f5c5SAndroid Build Coastguard Worker std::vector<D3DSampler> &samplers = mShaderSamplers[shaderType];
1257*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
1258*8975f5c5SAndroid Build Coastguard Worker {
1259*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerIndex = firstIndex + i;
1260*8975f5c5SAndroid Build Coastguard Worker
1261*8975f5c5SAndroid Build Coastguard Worker if (samplerIndex < samplers.size())
1262*8975f5c5SAndroid Build Coastguard Worker {
1263*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplers[samplerIndex].active);
1264*8975f5c5SAndroid Build Coastguard Worker samplers[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i];
1265*8975f5c5SAndroid Build Coastguard Worker }
1266*8975f5c5SAndroid Build Coastguard Worker }
1267*8975f5c5SAndroid Build Coastguard Worker }
1268*8975f5c5SAndroid Build Coastguard Worker }
1269*8975f5c5SAndroid Build Coastguard Worker }
1270*8975f5c5SAndroid Build Coastguard Worker
getImageMapping(gl::ShaderType type,unsigned int imageIndex,bool readonly,const gl::Caps & caps) const1271*8975f5c5SAndroid Build Coastguard Worker GLint ProgramExecutableD3D::getImageMapping(gl::ShaderType type,
1272*8975f5c5SAndroid Build Coastguard Worker unsigned int imageIndex,
1273*8975f5c5SAndroid Build Coastguard Worker bool readonly,
1274*8975f5c5SAndroid Build Coastguard Worker const gl::Caps &caps) const
1275*8975f5c5SAndroid Build Coastguard Worker {
1276*8975f5c5SAndroid Build Coastguard Worker GLint logicalImageUnit = -1;
1277*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex < static_cast<unsigned int>(caps.maxImageUnits));
1278*8975f5c5SAndroid Build Coastguard Worker if (readonly && imageIndex < mReadonlyImages[type].size() &&
1279*8975f5c5SAndroid Build Coastguard Worker mReadonlyImages[type][imageIndex].active)
1280*8975f5c5SAndroid Build Coastguard Worker {
1281*8975f5c5SAndroid Build Coastguard Worker logicalImageUnit = mReadonlyImages[type][imageIndex].logicalImageUnit;
1282*8975f5c5SAndroid Build Coastguard Worker }
1283*8975f5c5SAndroid Build Coastguard Worker else if (imageIndex < mImages[type].size() && mImages[type][imageIndex].active)
1284*8975f5c5SAndroid Build Coastguard Worker {
1285*8975f5c5SAndroid Build Coastguard Worker logicalImageUnit = mImages[type][imageIndex].logicalImageUnit;
1286*8975f5c5SAndroid Build Coastguard Worker }
1287*8975f5c5SAndroid Build Coastguard Worker
1288*8975f5c5SAndroid Build Coastguard Worker if (logicalImageUnit >= 0 && logicalImageUnit < caps.maxImageUnits)
1289*8975f5c5SAndroid Build Coastguard Worker {
1290*8975f5c5SAndroid Build Coastguard Worker return logicalImageUnit;
1291*8975f5c5SAndroid Build Coastguard Worker }
1292*8975f5c5SAndroid Build Coastguard Worker
1293*8975f5c5SAndroid Build Coastguard Worker return -1;
1294*8975f5c5SAndroid Build Coastguard Worker }
1295*8975f5c5SAndroid Build Coastguard Worker
getUsedImageRange(gl::ShaderType type,bool readonly) const1296*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI ProgramExecutableD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
1297*8975f5c5SAndroid Build Coastguard Worker {
1298*8975f5c5SAndroid Build Coastguard Worker return readonly ? mUsedReadonlyImageRange[type] : mUsedImageRange[type];
1299*8975f5c5SAndroid Build Coastguard Worker }
1300*8975f5c5SAndroid Build Coastguard Worker
usesPointSpriteEmulation(RendererD3D * renderer) const1301*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::usesPointSpriteEmulation(RendererD3D *renderer) const
1302*8975f5c5SAndroid Build Coastguard Worker {
1303*8975f5c5SAndroid Build Coastguard Worker return mUsesPointSize && renderer->getMajorShaderModel() >= 4;
1304*8975f5c5SAndroid Build Coastguard Worker }
1305*8975f5c5SAndroid Build Coastguard Worker
usesGeometryShaderForPointSpriteEmulation(RendererD3D * renderer) const1306*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::usesGeometryShaderForPointSpriteEmulation(RendererD3D *renderer) const
1307*8975f5c5SAndroid Build Coastguard Worker {
1308*8975f5c5SAndroid Build Coastguard Worker return usesPointSpriteEmulation(renderer);
1309*8975f5c5SAndroid Build Coastguard Worker }
1310*8975f5c5SAndroid Build Coastguard Worker
usesGeometryShader(RendererD3D * renderer,const gl::ProvokingVertexConvention provokingVertex,const gl::PrimitiveMode drawMode) const1311*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::usesGeometryShader(RendererD3D *renderer,
1312*8975f5c5SAndroid Build Coastguard Worker const gl::ProvokingVertexConvention provokingVertex,
1313*8975f5c5SAndroid Build Coastguard Worker const gl::PrimitiveMode drawMode) const
1314*8975f5c5SAndroid Build Coastguard Worker {
1315*8975f5c5SAndroid Build Coastguard Worker if (mHasMultiviewEnabled && !renderer->canSelectViewInVertexShader())
1316*8975f5c5SAndroid Build Coastguard Worker {
1317*8975f5c5SAndroid Build Coastguard Worker return true;
1318*8975f5c5SAndroid Build Coastguard Worker }
1319*8975f5c5SAndroid Build Coastguard Worker if (drawMode != gl::PrimitiveMode::Points)
1320*8975f5c5SAndroid Build Coastguard Worker {
1321*8975f5c5SAndroid Build Coastguard Worker if (!mUsesFlatInterpolation)
1322*8975f5c5SAndroid Build Coastguard Worker {
1323*8975f5c5SAndroid Build Coastguard Worker return false;
1324*8975f5c5SAndroid Build Coastguard Worker }
1325*8975f5c5SAndroid Build Coastguard Worker return provokingVertex == gl::ProvokingVertexConvention::LastVertexConvention;
1326*8975f5c5SAndroid Build Coastguard Worker }
1327*8975f5c5SAndroid Build Coastguard Worker return usesGeometryShaderForPointSpriteEmulation(renderer);
1328*8975f5c5SAndroid Build Coastguard Worker }
1329*8975f5c5SAndroid Build Coastguard Worker
getVertexExecutableForCachedInputLayout(d3d::Context * context,RendererD3D * renderer,ShaderExecutableD3D ** outExectuable,gl::InfoLog * infoLog)1330*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableD3D::getVertexExecutableForCachedInputLayout(
1331*8975f5c5SAndroid Build Coastguard Worker d3d::Context *context,
1332*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1333*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D **outExectuable,
1334*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *infoLog)
1335*8975f5c5SAndroid Build Coastguard Worker {
1336*8975f5c5SAndroid Build Coastguard Worker if (mCachedVertexExecutableIndex.valid())
1337*8975f5c5SAndroid Build Coastguard Worker {
1338*8975f5c5SAndroid Build Coastguard Worker *outExectuable =
1339*8975f5c5SAndroid Build Coastguard Worker mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable();
1340*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1341*8975f5c5SAndroid Build Coastguard Worker }
1342*8975f5c5SAndroid Build Coastguard Worker
1343*8975f5c5SAndroid Build Coastguard Worker // Generate new dynamic layout with attribute conversions
1344*8975f5c5SAndroid Build Coastguard Worker std::string vertexHLSL = DynamicHLSL::GenerateVertexShaderForInputLayout(
1345*8975f5c5SAndroid Build Coastguard Worker renderer, mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout,
1346*8975f5c5SAndroid Build Coastguard Worker mExecutable->getProgramInputs(), mShaderStorageBlocks[gl::ShaderType::Vertex],
1347*8975f5c5SAndroid Build Coastguard Worker mPixelShaderKey.size());
1348*8975f5c5SAndroid Build Coastguard Worker std::string finalVertexHLSL = DynamicHLSL::GenerateShaderForImage2DBindSignature(
1349*8975f5c5SAndroid Build Coastguard Worker *this, gl::ShaderType::Vertex, mAttachedShaders[gl::ShaderType::Vertex], vertexHLSL,
1350*8975f5c5SAndroid Build Coastguard Worker mImage2DUniforms[gl::ShaderType::Vertex], mImage2DBindLayoutCache[gl::ShaderType::Vertex],
1351*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(mPixelShaderKey.size()));
1352*8975f5c5SAndroid Build Coastguard Worker
1353*8975f5c5SAndroid Build Coastguard Worker // Generate new vertex executable
1354*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *vertexExecutable = nullptr;
1355*8975f5c5SAndroid Build Coastguard Worker
1356*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog tempInfoLog;
1357*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1358*8975f5c5SAndroid Build Coastguard Worker
1359*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->compileToExecutable(
1360*8975f5c5SAndroid Build Coastguard Worker context, *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings,
1361*8975f5c5SAndroid Build Coastguard Worker mExecutable->getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS,
1362*8975f5c5SAndroid Build Coastguard Worker mShaderWorkarounds[gl::ShaderType::Vertex], &vertexExecutable));
1363*8975f5c5SAndroid Build Coastguard Worker
1364*8975f5c5SAndroid Build Coastguard Worker if (vertexExecutable)
1365*8975f5c5SAndroid Build Coastguard Worker {
1366*8975f5c5SAndroid Build Coastguard Worker mVertexExecutables.push_back(std::unique_ptr<D3DVertexExecutable>(
1367*8975f5c5SAndroid Build Coastguard Worker new D3DVertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable)));
1368*8975f5c5SAndroid Build Coastguard Worker mCachedVertexExecutableIndex = mVertexExecutables.size() - 1;
1369*8975f5c5SAndroid Build Coastguard Worker }
1370*8975f5c5SAndroid Build Coastguard Worker else if (!infoLog)
1371*8975f5c5SAndroid Build Coastguard Worker {
1372*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error compiling dynamic vertex executable:" << std::endl
1373*8975f5c5SAndroid Build Coastguard Worker << tempInfoLog.str() << std::endl;
1374*8975f5c5SAndroid Build Coastguard Worker }
1375*8975f5c5SAndroid Build Coastguard Worker
1376*8975f5c5SAndroid Build Coastguard Worker *outExectuable = vertexExecutable;
1377*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1378*8975f5c5SAndroid Build Coastguard Worker }
1379*8975f5c5SAndroid Build Coastguard Worker
getGeometryExecutableForPrimitiveType(d3d::Context * context,RendererD3D * renderer,const gl::Caps & caps,gl::ProvokingVertexConvention provokingVertex,gl::PrimitiveMode drawMode,ShaderExecutableD3D ** outExecutable,gl::InfoLog * infoLog)1380*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableD3D::getGeometryExecutableForPrimitiveType(
1381*8975f5c5SAndroid Build Coastguard Worker d3d::Context *context,
1382*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1383*8975f5c5SAndroid Build Coastguard Worker const gl::Caps &caps,
1384*8975f5c5SAndroid Build Coastguard Worker gl::ProvokingVertexConvention provokingVertex,
1385*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode drawMode,
1386*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D **outExecutable,
1387*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *infoLog)
1388*8975f5c5SAndroid Build Coastguard Worker {
1389*8975f5c5SAndroid Build Coastguard Worker if (outExecutable)
1390*8975f5c5SAndroid Build Coastguard Worker {
1391*8975f5c5SAndroid Build Coastguard Worker *outExecutable = nullptr;
1392*8975f5c5SAndroid Build Coastguard Worker }
1393*8975f5c5SAndroid Build Coastguard Worker
1394*8975f5c5SAndroid Build Coastguard Worker // Return a null shader if the current rendering doesn't use a geometry shader
1395*8975f5c5SAndroid Build Coastguard Worker if (!usesGeometryShader(renderer, provokingVertex, drawMode))
1396*8975f5c5SAndroid Build Coastguard Worker {
1397*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1398*8975f5c5SAndroid Build Coastguard Worker }
1399*8975f5c5SAndroid Build Coastguard Worker
1400*8975f5c5SAndroid Build Coastguard Worker gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
1401*8975f5c5SAndroid Build Coastguard Worker
1402*8975f5c5SAndroid Build Coastguard Worker if (mGeometryExecutables[geometryShaderType])
1403*8975f5c5SAndroid Build Coastguard Worker {
1404*8975f5c5SAndroid Build Coastguard Worker if (outExecutable)
1405*8975f5c5SAndroid Build Coastguard Worker {
1406*8975f5c5SAndroid Build Coastguard Worker *outExecutable = mGeometryExecutables[geometryShaderType].get();
1407*8975f5c5SAndroid Build Coastguard Worker }
1408*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1409*8975f5c5SAndroid Build Coastguard Worker }
1410*8975f5c5SAndroid Build Coastguard Worker
1411*8975f5c5SAndroid Build Coastguard Worker std::string geometryHLSL = DynamicHLSL::GenerateGeometryShaderHLSL(
1412*8975f5c5SAndroid Build Coastguard Worker renderer, caps, geometryShaderType, renderer->presentPathFastEnabled(),
1413*8975f5c5SAndroid Build Coastguard Worker mHasMultiviewEnabled, renderer->canSelectViewInVertexShader(),
1414*8975f5c5SAndroid Build Coastguard Worker usesGeometryShaderForPointSpriteEmulation(renderer), mGeometryShaderPreamble);
1415*8975f5c5SAndroid Build Coastguard Worker
1416*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog tempInfoLog;
1417*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1418*8975f5c5SAndroid Build Coastguard Worker
1419*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *geometryExecutable = nullptr;
1420*8975f5c5SAndroid Build Coastguard Worker angle::Result result = renderer->compileToExecutable(
1421*8975f5c5SAndroid Build Coastguard Worker context, *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings,
1422*8975f5c5SAndroid Build Coastguard Worker mExecutable->getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS,
1423*8975f5c5SAndroid Build Coastguard Worker CompilerWorkaroundsD3D(), &geometryExecutable);
1424*8975f5c5SAndroid Build Coastguard Worker
1425*8975f5c5SAndroid Build Coastguard Worker if (!infoLog && result == angle::Result::Stop)
1426*8975f5c5SAndroid Build Coastguard Worker {
1427*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error compiling dynamic geometry executable:" << std::endl
1428*8975f5c5SAndroid Build Coastguard Worker << tempInfoLog.str() << std::endl;
1429*8975f5c5SAndroid Build Coastguard Worker }
1430*8975f5c5SAndroid Build Coastguard Worker
1431*8975f5c5SAndroid Build Coastguard Worker if (geometryExecutable != nullptr)
1432*8975f5c5SAndroid Build Coastguard Worker {
1433*8975f5c5SAndroid Build Coastguard Worker mGeometryExecutables[geometryShaderType].reset(geometryExecutable);
1434*8975f5c5SAndroid Build Coastguard Worker }
1435*8975f5c5SAndroid Build Coastguard Worker
1436*8975f5c5SAndroid Build Coastguard Worker if (outExecutable)
1437*8975f5c5SAndroid Build Coastguard Worker {
1438*8975f5c5SAndroid Build Coastguard Worker *outExecutable = mGeometryExecutables[geometryShaderType].get();
1439*8975f5c5SAndroid Build Coastguard Worker }
1440*8975f5c5SAndroid Build Coastguard Worker return result;
1441*8975f5c5SAndroid Build Coastguard Worker }
1442*8975f5c5SAndroid Build Coastguard Worker
getPixelExecutableForCachedOutputLayout(d3d::Context * context,RendererD3D * renderer,ShaderExecutableD3D ** outExecutable,gl::InfoLog * infoLog)1443*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableD3D::getPixelExecutableForCachedOutputLayout(
1444*8975f5c5SAndroid Build Coastguard Worker d3d::Context *context,
1445*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1446*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D **outExecutable,
1447*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *infoLog)
1448*8975f5c5SAndroid Build Coastguard Worker {
1449*8975f5c5SAndroid Build Coastguard Worker if (mCachedPixelExecutableIndex.valid())
1450*8975f5c5SAndroid Build Coastguard Worker {
1451*8975f5c5SAndroid Build Coastguard Worker *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable();
1452*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1453*8975f5c5SAndroid Build Coastguard Worker }
1454*8975f5c5SAndroid Build Coastguard Worker
1455*8975f5c5SAndroid Build Coastguard Worker std::string pixelHLSL = DynamicHLSL::GeneratePixelShaderForOutputSignature(
1456*8975f5c5SAndroid Build Coastguard Worker renderer, mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mFragDepthUsage,
1457*8975f5c5SAndroid Build Coastguard Worker mUsesSampleMask, mPixelShaderOutputLayoutCache,
1458*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks[gl::ShaderType::Fragment], mPixelShaderKey.size());
1459*8975f5c5SAndroid Build Coastguard Worker
1460*8975f5c5SAndroid Build Coastguard Worker std::string finalPixelHLSL = DynamicHLSL::GenerateShaderForImage2DBindSignature(
1461*8975f5c5SAndroid Build Coastguard Worker *this, gl::ShaderType::Fragment, mAttachedShaders[gl::ShaderType::Fragment], pixelHLSL,
1462*8975f5c5SAndroid Build Coastguard Worker mImage2DUniforms[gl::ShaderType::Fragment],
1463*8975f5c5SAndroid Build Coastguard Worker mImage2DBindLayoutCache[gl::ShaderType::Fragment],
1464*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(mPixelShaderKey.size()));
1465*8975f5c5SAndroid Build Coastguard Worker
1466*8975f5c5SAndroid Build Coastguard Worker // Generate new pixel executable
1467*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *pixelExecutable = nullptr;
1468*8975f5c5SAndroid Build Coastguard Worker
1469*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog tempInfoLog;
1470*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1471*8975f5c5SAndroid Build Coastguard Worker
1472*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->compileToExecutable(
1473*8975f5c5SAndroid Build Coastguard Worker context, *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings,
1474*8975f5c5SAndroid Build Coastguard Worker mExecutable->getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS,
1475*8975f5c5SAndroid Build Coastguard Worker mShaderWorkarounds[gl::ShaderType::Fragment], &pixelExecutable));
1476*8975f5c5SAndroid Build Coastguard Worker
1477*8975f5c5SAndroid Build Coastguard Worker if (pixelExecutable)
1478*8975f5c5SAndroid Build Coastguard Worker {
1479*8975f5c5SAndroid Build Coastguard Worker mPixelExecutables.push_back(std::unique_ptr<D3DPixelExecutable>(new D3DPixelExecutable(
1480*8975f5c5SAndroid Build Coastguard Worker mPixelShaderOutputLayoutCache, mImage2DBindLayoutCache[gl::ShaderType::Fragment],
1481*8975f5c5SAndroid Build Coastguard Worker pixelExecutable)));
1482*8975f5c5SAndroid Build Coastguard Worker mCachedPixelExecutableIndex = mPixelExecutables.size() - 1;
1483*8975f5c5SAndroid Build Coastguard Worker }
1484*8975f5c5SAndroid Build Coastguard Worker else if (!infoLog)
1485*8975f5c5SAndroid Build Coastguard Worker {
1486*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error compiling dynamic pixel executable:" << std::endl
1487*8975f5c5SAndroid Build Coastguard Worker << tempInfoLog.str() << std::endl;
1488*8975f5c5SAndroid Build Coastguard Worker }
1489*8975f5c5SAndroid Build Coastguard Worker
1490*8975f5c5SAndroid Build Coastguard Worker *outExecutable = pixelExecutable;
1491*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1492*8975f5c5SAndroid Build Coastguard Worker }
1493*8975f5c5SAndroid Build Coastguard Worker
getComputeExecutableForImage2DBindLayout(d3d::Context * context,RendererD3D * renderer,ShaderExecutableD3D ** outExecutable,gl::InfoLog * infoLog)1494*8975f5c5SAndroid Build Coastguard Worker angle::Result ProgramExecutableD3D::getComputeExecutableForImage2DBindLayout(
1495*8975f5c5SAndroid Build Coastguard Worker d3d::Context *context,
1496*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1497*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D **outExecutable,
1498*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *infoLog)
1499*8975f5c5SAndroid Build Coastguard Worker {
1500*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRACE_EVENT0("gpu.angle",
1501*8975f5c5SAndroid Build Coastguard Worker "ProgramExecutableD3D::getComputeExecutableForImage2DBindLayout");
1502*8975f5c5SAndroid Build Coastguard Worker if (mCachedComputeExecutableIndex.valid())
1503*8975f5c5SAndroid Build Coastguard Worker {
1504*8975f5c5SAndroid Build Coastguard Worker *outExecutable =
1505*8975f5c5SAndroid Build Coastguard Worker mComputeExecutables[mCachedComputeExecutableIndex.value()]->shaderExecutable();
1506*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1507*8975f5c5SAndroid Build Coastguard Worker }
1508*8975f5c5SAndroid Build Coastguard Worker
1509*8975f5c5SAndroid Build Coastguard Worker std::string finalComputeHLSL = DynamicHLSL::GenerateShaderForImage2DBindSignature(
1510*8975f5c5SAndroid Build Coastguard Worker *this, gl::ShaderType::Compute, mAttachedShaders[gl::ShaderType::Compute],
1511*8975f5c5SAndroid Build Coastguard Worker mShaderHLSL[gl::ShaderType::Compute], mImage2DUniforms[gl::ShaderType::Compute],
1512*8975f5c5SAndroid Build Coastguard Worker mImage2DBindLayoutCache[gl::ShaderType::Compute], 0u);
1513*8975f5c5SAndroid Build Coastguard Worker
1514*8975f5c5SAndroid Build Coastguard Worker // Generate new compute executable
1515*8975f5c5SAndroid Build Coastguard Worker ShaderExecutableD3D *computeExecutable = nullptr;
1516*8975f5c5SAndroid Build Coastguard Worker
1517*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog tempInfoLog;
1518*8975f5c5SAndroid Build Coastguard Worker gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1519*8975f5c5SAndroid Build Coastguard Worker
1520*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(renderer->compileToExecutable(context, *currentInfoLog, finalComputeHLSL,
1521*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType::Compute, std::vector<D3DVarying>(),
1522*8975f5c5SAndroid Build Coastguard Worker false, CompilerWorkaroundsD3D(), &computeExecutable));
1523*8975f5c5SAndroid Build Coastguard Worker
1524*8975f5c5SAndroid Build Coastguard Worker if (computeExecutable)
1525*8975f5c5SAndroid Build Coastguard Worker {
1526*8975f5c5SAndroid Build Coastguard Worker mComputeExecutables.push_back(std::unique_ptr<D3DComputeExecutable>(
1527*8975f5c5SAndroid Build Coastguard Worker new D3DComputeExecutable(mImage2DBindLayoutCache[gl::ShaderType::Compute],
1528*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
1529*8975f5c5SAndroid Build Coastguard Worker mCachedComputeExecutableIndex = mComputeExecutables.size() - 1;
1530*8975f5c5SAndroid Build Coastguard Worker }
1531*8975f5c5SAndroid Build Coastguard Worker else if (!infoLog)
1532*8975f5c5SAndroid Build Coastguard Worker {
1533*8975f5c5SAndroid Build Coastguard Worker ERR() << "Error compiling dynamic compute executable:" << std::endl
1534*8975f5c5SAndroid Build Coastguard Worker << tempInfoLog.str() << std::endl;
1535*8975f5c5SAndroid Build Coastguard Worker }
1536*8975f5c5SAndroid Build Coastguard Worker *outExecutable = computeExecutable;
1537*8975f5c5SAndroid Build Coastguard Worker
1538*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1539*8975f5c5SAndroid Build Coastguard Worker }
1540*8975f5c5SAndroid Build Coastguard Worker
hasNamedUniform(const std::string & name)1541*8975f5c5SAndroid Build Coastguard Worker bool ProgramExecutableD3D::hasNamedUniform(const std::string &name)
1542*8975f5c5SAndroid Build Coastguard Worker {
1543*8975f5c5SAndroid Build Coastguard Worker for (D3DUniform *d3dUniform : mD3DUniforms)
1544*8975f5c5SAndroid Build Coastguard Worker {
1545*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->name == name)
1546*8975f5c5SAndroid Build Coastguard Worker {
1547*8975f5c5SAndroid Build Coastguard Worker return true;
1548*8975f5c5SAndroid Build Coastguard Worker }
1549*8975f5c5SAndroid Build Coastguard Worker }
1550*8975f5c5SAndroid Build Coastguard Worker
1551*8975f5c5SAndroid Build Coastguard Worker return false;
1552*8975f5c5SAndroid Build Coastguard Worker }
1553*8975f5c5SAndroid Build Coastguard Worker
initAttribLocationsToD3DSemantic(const gl::SharedCompiledShaderState & vertexShader)1554*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::initAttribLocationsToD3DSemantic(
1555*8975f5c5SAndroid Build Coastguard Worker const gl::SharedCompiledShaderState &vertexShader)
1556*8975f5c5SAndroid Build Coastguard Worker {
1557*8975f5c5SAndroid Build Coastguard Worker if (!vertexShader)
1558*8975f5c5SAndroid Build Coastguard Worker {
1559*8975f5c5SAndroid Build Coastguard Worker return;
1560*8975f5c5SAndroid Build Coastguard Worker }
1561*8975f5c5SAndroid Build Coastguard Worker
1562*8975f5c5SAndroid Build Coastguard Worker // Init semantic index
1563*8975f5c5SAndroid Build Coastguard Worker int semanticIndex = 0;
1564*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &attribute : vertexShader->activeAttributes)
1565*8975f5c5SAndroid Build Coastguard Worker {
1566*8975f5c5SAndroid Build Coastguard Worker int regCount = gl::VariableRegisterCount(attribute.type);
1567*8975f5c5SAndroid Build Coastguard Worker GLuint location = mExecutable->getAttributeLocation(attribute.name);
1568*8975f5c5SAndroid Build Coastguard Worker ASSERT(location != std::numeric_limits<GLuint>::max());
1569*8975f5c5SAndroid Build Coastguard Worker
1570*8975f5c5SAndroid Build Coastguard Worker for (int reg = 0; reg < regCount; ++reg)
1571*8975f5c5SAndroid Build Coastguard Worker {
1572*8975f5c5SAndroid Build Coastguard Worker mAttribLocationToD3DSemantic[location + reg] = semanticIndex++;
1573*8975f5c5SAndroid Build Coastguard Worker }
1574*8975f5c5SAndroid Build Coastguard Worker }
1575*8975f5c5SAndroid Build Coastguard Worker }
1576*8975f5c5SAndroid Build Coastguard Worker
initializeUniformBlocks()1577*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::initializeUniformBlocks()
1578*8975f5c5SAndroid Build Coastguard Worker {
1579*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->getUniformBlocks().empty())
1580*8975f5c5SAndroid Build Coastguard Worker {
1581*8975f5c5SAndroid Build Coastguard Worker return;
1582*8975f5c5SAndroid Build Coastguard Worker }
1583*8975f5c5SAndroid Build Coastguard Worker
1584*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DUniformBlocks.empty());
1585*8975f5c5SAndroid Build Coastguard Worker
1586*8975f5c5SAndroid Build Coastguard Worker // Assign registers and update sizes.
1587*8975f5c5SAndroid Build Coastguard Worker for (const gl::InterfaceBlock &uniformBlock : mExecutable->getUniformBlocks())
1588*8975f5c5SAndroid Build Coastguard Worker {
1589*8975f5c5SAndroid Build Coastguard Worker unsigned int uniformBlockElement =
1590*8975f5c5SAndroid Build Coastguard Worker uniformBlock.pod.isArray ? uniformBlock.pod.arrayElement : 0;
1591*8975f5c5SAndroid Build Coastguard Worker
1592*8975f5c5SAndroid Build Coastguard Worker D3DUniformBlock d3dUniformBlock;
1593*8975f5c5SAndroid Build Coastguard Worker
1594*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1595*8975f5c5SAndroid Build Coastguard Worker {
1596*8975f5c5SAndroid Build Coastguard Worker if (uniformBlock.isActive(shaderType))
1597*8975f5c5SAndroid Build Coastguard Worker {
1598*8975f5c5SAndroid Build Coastguard Worker ASSERT(mAttachedShaders[shaderType]);
1599*8975f5c5SAndroid Build Coastguard Worker unsigned int baseRegister =
1600*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType]->getUniformBlockRegister(uniformBlock.name);
1601*8975f5c5SAndroid Build Coastguard Worker d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
1602*8975f5c5SAndroid Build Coastguard Worker baseRegister + uniformBlockElement;
1603*8975f5c5SAndroid Build Coastguard Worker bool useStructuredBuffer =
1604*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType]->shouldUniformBlockUseStructuredBuffer(
1605*8975f5c5SAndroid Build Coastguard Worker uniformBlock.name);
1606*8975f5c5SAndroid Build Coastguard Worker if (useStructuredBuffer)
1607*8975f5c5SAndroid Build Coastguard Worker {
1608*8975f5c5SAndroid Build Coastguard Worker d3dUniformBlock.mUseStructuredBuffers[shaderType] = true;
1609*8975f5c5SAndroid Build Coastguard Worker d3dUniformBlock.mByteWidths[shaderType] = uniformBlock.pod.dataSize;
1610*8975f5c5SAndroid Build Coastguard Worker d3dUniformBlock.mStructureByteStrides[shaderType] =
1611*8975f5c5SAndroid Build Coastguard Worker uniformBlock.pod.firstFieldArraySize == 0u
1612*8975f5c5SAndroid Build Coastguard Worker ? uniformBlock.pod.dataSize
1613*8975f5c5SAndroid Build Coastguard Worker : uniformBlock.pod.dataSize / uniformBlock.pod.firstFieldArraySize;
1614*8975f5c5SAndroid Build Coastguard Worker }
1615*8975f5c5SAndroid Build Coastguard Worker }
1616*8975f5c5SAndroid Build Coastguard Worker }
1617*8975f5c5SAndroid Build Coastguard Worker
1618*8975f5c5SAndroid Build Coastguard Worker mD3DUniformBlocks.push_back(d3dUniformBlock);
1619*8975f5c5SAndroid Build Coastguard Worker }
1620*8975f5c5SAndroid Build Coastguard Worker }
1621*8975f5c5SAndroid Build Coastguard Worker
initializeShaderStorageBlocks(const gl::ShaderMap<gl::SharedCompiledShaderState> & shaders)1622*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::initializeShaderStorageBlocks(
1623*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders)
1624*8975f5c5SAndroid Build Coastguard Worker {
1625*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->getShaderStorageBlocks().empty())
1626*8975f5c5SAndroid Build Coastguard Worker {
1627*8975f5c5SAndroid Build Coastguard Worker return;
1628*8975f5c5SAndroid Build Coastguard Worker }
1629*8975f5c5SAndroid Build Coastguard Worker
1630*8975f5c5SAndroid Build Coastguard Worker ASSERT(mD3DShaderStorageBlocks.empty());
1631*8975f5c5SAndroid Build Coastguard Worker
1632*8975f5c5SAndroid Build Coastguard Worker // Assign registers and update sizes.
1633*8975f5c5SAndroid Build Coastguard Worker for (const gl::InterfaceBlock &shaderStorageBlock : mExecutable->getShaderStorageBlocks())
1634*8975f5c5SAndroid Build Coastguard Worker {
1635*8975f5c5SAndroid Build Coastguard Worker unsigned int shaderStorageBlockElement =
1636*8975f5c5SAndroid Build Coastguard Worker shaderStorageBlock.pod.isArray ? shaderStorageBlock.pod.arrayElement : 0;
1637*8975f5c5SAndroid Build Coastguard Worker D3DInterfaceBlock d3dShaderStorageBlock;
1638*8975f5c5SAndroid Build Coastguard Worker
1639*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1640*8975f5c5SAndroid Build Coastguard Worker {
1641*8975f5c5SAndroid Build Coastguard Worker if (shaderStorageBlock.isActive(shaderType))
1642*8975f5c5SAndroid Build Coastguard Worker {
1643*8975f5c5SAndroid Build Coastguard Worker ASSERT(mAttachedShaders[shaderType]);
1644*8975f5c5SAndroid Build Coastguard Worker unsigned int baseRegister =
1645*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType]->getShaderStorageBlockRegister(
1646*8975f5c5SAndroid Build Coastguard Worker shaderStorageBlock.name);
1647*8975f5c5SAndroid Build Coastguard Worker
1648*8975f5c5SAndroid Build Coastguard Worker d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] =
1649*8975f5c5SAndroid Build Coastguard Worker baseRegister + shaderStorageBlockElement;
1650*8975f5c5SAndroid Build Coastguard Worker }
1651*8975f5c5SAndroid Build Coastguard Worker }
1652*8975f5c5SAndroid Build Coastguard Worker mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock);
1653*8975f5c5SAndroid Build Coastguard Worker }
1654*8975f5c5SAndroid Build Coastguard Worker
1655*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1656*8975f5c5SAndroid Build Coastguard Worker {
1657*8975f5c5SAndroid Build Coastguard Worker const gl::SharedCompiledShaderState &shader = shaders[shaderType];
1658*8975f5c5SAndroid Build Coastguard Worker if (!shader)
1659*8975f5c5SAndroid Build Coastguard Worker {
1660*8975f5c5SAndroid Build Coastguard Worker continue;
1661*8975f5c5SAndroid Build Coastguard Worker }
1662*8975f5c5SAndroid Build Coastguard Worker for (const sh::InterfaceBlock &ssbo : shader->shaderStorageBlocks)
1663*8975f5c5SAndroid Build Coastguard Worker {
1664*8975f5c5SAndroid Build Coastguard Worker if (!ssbo.active)
1665*8975f5c5SAndroid Build Coastguard Worker {
1666*8975f5c5SAndroid Build Coastguard Worker continue;
1667*8975f5c5SAndroid Build Coastguard Worker }
1668*8975f5c5SAndroid Build Coastguard Worker ShaderStorageBlock block;
1669*8975f5c5SAndroid Build Coastguard Worker block.name = !ssbo.instanceName.empty() ? ssbo.instanceName : ssbo.name;
1670*8975f5c5SAndroid Build Coastguard Worker block.arraySize = ssbo.isArray() ? ssbo.arraySize : 0;
1671*8975f5c5SAndroid Build Coastguard Worker block.registerIndex =
1672*8975f5c5SAndroid Build Coastguard Worker mAttachedShaders[shaderType]->getShaderStorageBlockRegister(ssbo.name);
1673*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks[shaderType].push_back(block);
1674*8975f5c5SAndroid Build Coastguard Worker }
1675*8975f5c5SAndroid Build Coastguard Worker }
1676*8975f5c5SAndroid Build Coastguard Worker }
1677*8975f5c5SAndroid Build Coastguard Worker
initializeUniformStorage(RendererD3D * renderer,const gl::ShaderBitSet & availableShaderStages)1678*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::initializeUniformStorage(RendererD3D *renderer,
1679*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderBitSet &availableShaderStages)
1680*8975f5c5SAndroid Build Coastguard Worker {
1681*8975f5c5SAndroid Build Coastguard Worker // Compute total default block size
1682*8975f5c5SAndroid Build Coastguard Worker gl::ShaderMap<unsigned int> shaderRegisters = {};
1683*8975f5c5SAndroid Build Coastguard Worker for (const D3DUniform *d3dUniform : mD3DUniforms)
1684*8975f5c5SAndroid Build Coastguard Worker {
1685*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->isSampler())
1686*8975f5c5SAndroid Build Coastguard Worker {
1687*8975f5c5SAndroid Build Coastguard Worker continue;
1688*8975f5c5SAndroid Build Coastguard Worker }
1689*8975f5c5SAndroid Build Coastguard Worker
1690*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : availableShaderStages)
1691*8975f5c5SAndroid Build Coastguard Worker {
1692*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->isReferencedByShader(shaderType))
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker shaderRegisters[shaderType] = std::max(
1695*8975f5c5SAndroid Build Coastguard Worker shaderRegisters[shaderType],
1696*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount);
1697*8975f5c5SAndroid Build Coastguard Worker }
1698*8975f5c5SAndroid Build Coastguard Worker }
1699*8975f5c5SAndroid Build Coastguard Worker }
1700*8975f5c5SAndroid Build Coastguard Worker
1701*8975f5c5SAndroid Build Coastguard Worker // We only reset uniform storages for the shader stages available in the program (attached
1702*8975f5c5SAndroid Build Coastguard Worker // shaders in ProgramExecutableD3D::link() and linkedShaderStages in
1703*8975f5c5SAndroid Build Coastguard Worker // ProgramExecutableD3D::load()).
1704*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : availableShaderStages)
1705*8975f5c5SAndroid Build Coastguard Worker {
1706*8975f5c5SAndroid Build Coastguard Worker mShaderUniformStorages[shaderType].reset(
1707*8975f5c5SAndroid Build Coastguard Worker renderer->createUniformStorage(shaderRegisters[shaderType] * 16u));
1708*8975f5c5SAndroid Build Coastguard Worker }
1709*8975f5c5SAndroid Build Coastguard Worker
1710*8975f5c5SAndroid Build Coastguard Worker // Iterate the uniforms again to assign data pointers to default block uniforms.
1711*8975f5c5SAndroid Build Coastguard Worker for (D3DUniform *d3dUniform : mD3DUniforms)
1712*8975f5c5SAndroid Build Coastguard Worker {
1713*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->isSampler())
1714*8975f5c5SAndroid Build Coastguard Worker {
1715*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0);
1716*8975f5c5SAndroid Build Coastguard Worker continue;
1717*8975f5c5SAndroid Build Coastguard Worker }
1718*8975f5c5SAndroid Build Coastguard Worker
1719*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : availableShaderStages)
1720*8975f5c5SAndroid Build Coastguard Worker {
1721*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->isReferencedByShader(shaderType))
1722*8975f5c5SAndroid Build Coastguard Worker {
1723*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderData[shaderType] =
1724*8975f5c5SAndroid Build Coastguard Worker mShaderUniformStorages[shaderType]->getDataPointer(
1725*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderRegisterIndexes[shaderType],
1726*8975f5c5SAndroid Build Coastguard Worker d3dUniform->registerElement);
1727*8975f5c5SAndroid Build Coastguard Worker }
1728*8975f5c5SAndroid Build Coastguard Worker }
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker }
1731*8975f5c5SAndroid Build Coastguard Worker
updateCachedInputLayoutFromShader(RendererD3D * renderer,const gl::SharedCompiledShaderState & vertexShader)1732*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedInputLayoutFromShader(
1733*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1734*8975f5c5SAndroid Build Coastguard Worker const gl::SharedCompiledShaderState &vertexShader)
1735*8975f5c5SAndroid Build Coastguard Worker {
1736*8975f5c5SAndroid Build Coastguard Worker GetDefaultInputLayoutFromShader(vertexShader, &mCachedInputLayout);
1737*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::getSignature(renderer, mCachedInputLayout, &mCachedVertexSignature);
1738*8975f5c5SAndroid Build Coastguard Worker updateCachedVertexExecutableIndex();
1739*8975f5c5SAndroid Build Coastguard Worker }
1740*8975f5c5SAndroid Build Coastguard Worker
updateCachedOutputLayoutFromShader()1741*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedOutputLayoutFromShader()
1742*8975f5c5SAndroid Build Coastguard Worker {
1743*8975f5c5SAndroid Build Coastguard Worker GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache);
1744*8975f5c5SAndroid Build Coastguard Worker updateCachedPixelExecutableIndex();
1745*8975f5c5SAndroid Build Coastguard Worker }
1746*8975f5c5SAndroid Build Coastguard Worker
updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType)1747*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType)
1748*8975f5c5SAndroid Build Coastguard Worker {
1749*8975f5c5SAndroid Build Coastguard Worker GetDefaultImage2DBindLayoutFromShader(mImage2DUniforms[shaderType],
1750*8975f5c5SAndroid Build Coastguard Worker &mImage2DBindLayoutCache[shaderType]);
1751*8975f5c5SAndroid Build Coastguard Worker switch (shaderType)
1752*8975f5c5SAndroid Build Coastguard Worker {
1753*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Compute:
1754*8975f5c5SAndroid Build Coastguard Worker updateCachedComputeExecutableIndex();
1755*8975f5c5SAndroid Build Coastguard Worker break;
1756*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Fragment:
1757*8975f5c5SAndroid Build Coastguard Worker updateCachedPixelExecutableIndex();
1758*8975f5c5SAndroid Build Coastguard Worker break;
1759*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Vertex:
1760*8975f5c5SAndroid Build Coastguard Worker updateCachedVertexExecutableIndex();
1761*8975f5c5SAndroid Build Coastguard Worker break;
1762*8975f5c5SAndroid Build Coastguard Worker default:
1763*8975f5c5SAndroid Build Coastguard Worker ASSERT(false);
1764*8975f5c5SAndroid Build Coastguard Worker break;
1765*8975f5c5SAndroid Build Coastguard Worker }
1766*8975f5c5SAndroid Build Coastguard Worker }
1767*8975f5c5SAndroid Build Coastguard Worker
updateCachedInputLayout(RendererD3D * renderer,UniqueSerial associatedSerial,const gl::State & state)1768*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedInputLayout(RendererD3D *renderer,
1769*8975f5c5SAndroid Build Coastguard Worker UniqueSerial associatedSerial,
1770*8975f5c5SAndroid Build Coastguard Worker const gl::State &state)
1771*8975f5c5SAndroid Build Coastguard Worker {
1772*8975f5c5SAndroid Build Coastguard Worker if (mCurrentVertexArrayStateSerial == associatedSerial)
1773*8975f5c5SAndroid Build Coastguard Worker {
1774*8975f5c5SAndroid Build Coastguard Worker return;
1775*8975f5c5SAndroid Build Coastguard Worker }
1776*8975f5c5SAndroid Build Coastguard Worker
1777*8975f5c5SAndroid Build Coastguard Worker mCurrentVertexArrayStateSerial = associatedSerial;
1778*8975f5c5SAndroid Build Coastguard Worker mCachedInputLayout.clear();
1779*8975f5c5SAndroid Build Coastguard Worker
1780*8975f5c5SAndroid Build Coastguard Worker const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
1781*8975f5c5SAndroid Build Coastguard Worker const gl::AttributesMask &attributesMask = mExecutable->getActiveAttribLocationsMask();
1782*8975f5c5SAndroid Build Coastguard Worker
1783*8975f5c5SAndroid Build Coastguard Worker for (size_t locationIndex : attributesMask)
1784*8975f5c5SAndroid Build Coastguard Worker {
1785*8975f5c5SAndroid Build Coastguard Worker int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
1786*8975f5c5SAndroid Build Coastguard Worker
1787*8975f5c5SAndroid Build Coastguard Worker if (d3dSemantic != -1)
1788*8975f5c5SAndroid Build Coastguard Worker {
1789*8975f5c5SAndroid Build Coastguard Worker if (mCachedInputLayout.size() < static_cast<size_t>(d3dSemantic + 1))
1790*8975f5c5SAndroid Build Coastguard Worker {
1791*8975f5c5SAndroid Build Coastguard Worker mCachedInputLayout.resize(d3dSemantic + 1, angle::FormatID::NONE);
1792*8975f5c5SAndroid Build Coastguard Worker }
1793*8975f5c5SAndroid Build Coastguard Worker mCachedInputLayout[d3dSemantic] =
1794*8975f5c5SAndroid Build Coastguard Worker GetVertexFormatID(vertexAttributes[locationIndex],
1795*8975f5c5SAndroid Build Coastguard Worker state.getVertexAttribCurrentValue(locationIndex).Type);
1796*8975f5c5SAndroid Build Coastguard Worker }
1797*8975f5c5SAndroid Build Coastguard Worker }
1798*8975f5c5SAndroid Build Coastguard Worker
1799*8975f5c5SAndroid Build Coastguard Worker D3DVertexExecutable::getSignature(renderer, mCachedInputLayout, &mCachedVertexSignature);
1800*8975f5c5SAndroid Build Coastguard Worker
1801*8975f5c5SAndroid Build Coastguard Worker updateCachedVertexExecutableIndex();
1802*8975f5c5SAndroid Build Coastguard Worker }
1803*8975f5c5SAndroid Build Coastguard Worker
updateCachedOutputLayout(const gl::Context * context,const gl::Framebuffer * framebuffer)1804*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedOutputLayout(const gl::Context *context,
1805*8975f5c5SAndroid Build Coastguard Worker const gl::Framebuffer *framebuffer)
1806*8975f5c5SAndroid Build Coastguard Worker {
1807*8975f5c5SAndroid Build Coastguard Worker mPixelShaderOutputLayoutCache.clear();
1808*8975f5c5SAndroid Build Coastguard Worker
1809*8975f5c5SAndroid Build Coastguard Worker FramebufferD3D *fboD3D = GetImplAs<FramebufferD3D>(framebuffer);
1810*8975f5c5SAndroid Build Coastguard Worker const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context);
1811*8975f5c5SAndroid Build Coastguard Worker
1812*8975f5c5SAndroid Build Coastguard Worker for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
1813*8975f5c5SAndroid Build Coastguard Worker {
1814*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
1815*8975f5c5SAndroid Build Coastguard Worker
1816*8975f5c5SAndroid Build Coastguard Worker if (colorbuffer)
1817*8975f5c5SAndroid Build Coastguard Worker {
1818*8975f5c5SAndroid Build Coastguard Worker auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0
1819*8975f5c5SAndroid Build Coastguard Worker : colorbuffer->getBinding();
1820*8975f5c5SAndroid Build Coastguard Worker size_t maxIndex = binding != GL_NONE ? GetMaxOutputIndex(mPixelShaderKey,
1821*8975f5c5SAndroid Build Coastguard Worker binding - GL_COLOR_ATTACHMENT0)
1822*8975f5c5SAndroid Build Coastguard Worker : 0;
1823*8975f5c5SAndroid Build Coastguard Worker mPixelShaderOutputLayoutCache.insert(mPixelShaderOutputLayoutCache.end(), maxIndex + 1,
1824*8975f5c5SAndroid Build Coastguard Worker binding);
1825*8975f5c5SAndroid Build Coastguard Worker }
1826*8975f5c5SAndroid Build Coastguard Worker else
1827*8975f5c5SAndroid Build Coastguard Worker {
1828*8975f5c5SAndroid Build Coastguard Worker mPixelShaderOutputLayoutCache.push_back(GL_NONE);
1829*8975f5c5SAndroid Build Coastguard Worker }
1830*8975f5c5SAndroid Build Coastguard Worker }
1831*8975f5c5SAndroid Build Coastguard Worker
1832*8975f5c5SAndroid Build Coastguard Worker updateCachedPixelExecutableIndex();
1833*8975f5c5SAndroid Build Coastguard Worker }
1834*8975f5c5SAndroid Build Coastguard Worker
updateCachedImage2DBindLayout(const gl::Context * context,const gl::ShaderType shaderType)1835*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedImage2DBindLayout(const gl::Context *context,
1836*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderType shaderType)
1837*8975f5c5SAndroid Build Coastguard Worker {
1838*8975f5c5SAndroid Build Coastguard Worker const auto &glState = context->getState();
1839*8975f5c5SAndroid Build Coastguard Worker for (auto &image2DBindLayout : mImage2DBindLayoutCache[shaderType])
1840*8975f5c5SAndroid Build Coastguard Worker {
1841*8975f5c5SAndroid Build Coastguard Worker const gl::ImageUnit &imageUnit = glState.getImageUnit(image2DBindLayout.first);
1842*8975f5c5SAndroid Build Coastguard Worker if (imageUnit.texture.get())
1843*8975f5c5SAndroid Build Coastguard Worker {
1844*8975f5c5SAndroid Build Coastguard Worker image2DBindLayout.second = imageUnit.texture->getType();
1845*8975f5c5SAndroid Build Coastguard Worker }
1846*8975f5c5SAndroid Build Coastguard Worker else
1847*8975f5c5SAndroid Build Coastguard Worker {
1848*8975f5c5SAndroid Build Coastguard Worker image2DBindLayout.second = gl::TextureType::_2D;
1849*8975f5c5SAndroid Build Coastguard Worker }
1850*8975f5c5SAndroid Build Coastguard Worker }
1851*8975f5c5SAndroid Build Coastguard Worker
1852*8975f5c5SAndroid Build Coastguard Worker switch (shaderType)
1853*8975f5c5SAndroid Build Coastguard Worker {
1854*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Vertex:
1855*8975f5c5SAndroid Build Coastguard Worker updateCachedVertexExecutableIndex();
1856*8975f5c5SAndroid Build Coastguard Worker break;
1857*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Fragment:
1858*8975f5c5SAndroid Build Coastguard Worker updateCachedPixelExecutableIndex();
1859*8975f5c5SAndroid Build Coastguard Worker break;
1860*8975f5c5SAndroid Build Coastguard Worker case gl::ShaderType::Compute:
1861*8975f5c5SAndroid Build Coastguard Worker updateCachedComputeExecutableIndex();
1862*8975f5c5SAndroid Build Coastguard Worker break;
1863*8975f5c5SAndroid Build Coastguard Worker default:
1864*8975f5c5SAndroid Build Coastguard Worker ASSERT(false);
1865*8975f5c5SAndroid Build Coastguard Worker break;
1866*8975f5c5SAndroid Build Coastguard Worker }
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker
updateCachedVertexExecutableIndex()1869*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedVertexExecutableIndex()
1870*8975f5c5SAndroid Build Coastguard Worker {
1871*8975f5c5SAndroid Build Coastguard Worker mCachedVertexExecutableIndex.reset();
1872*8975f5c5SAndroid Build Coastguard Worker for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
1873*8975f5c5SAndroid Build Coastguard Worker {
1874*8975f5c5SAndroid Build Coastguard Worker if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature))
1875*8975f5c5SAndroid Build Coastguard Worker {
1876*8975f5c5SAndroid Build Coastguard Worker mCachedVertexExecutableIndex = executableIndex;
1877*8975f5c5SAndroid Build Coastguard Worker break;
1878*8975f5c5SAndroid Build Coastguard Worker }
1879*8975f5c5SAndroid Build Coastguard Worker }
1880*8975f5c5SAndroid Build Coastguard Worker }
1881*8975f5c5SAndroid Build Coastguard Worker
updateCachedPixelExecutableIndex()1882*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedPixelExecutableIndex()
1883*8975f5c5SAndroid Build Coastguard Worker {
1884*8975f5c5SAndroid Build Coastguard Worker mCachedPixelExecutableIndex.reset();
1885*8975f5c5SAndroid Build Coastguard Worker for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
1886*8975f5c5SAndroid Build Coastguard Worker {
1887*8975f5c5SAndroid Build Coastguard Worker if (mPixelExecutables[executableIndex]->matchesSignature(
1888*8975f5c5SAndroid Build Coastguard Worker mPixelShaderOutputLayoutCache, mImage2DBindLayoutCache[gl::ShaderType::Fragment]))
1889*8975f5c5SAndroid Build Coastguard Worker {
1890*8975f5c5SAndroid Build Coastguard Worker mCachedPixelExecutableIndex = executableIndex;
1891*8975f5c5SAndroid Build Coastguard Worker break;
1892*8975f5c5SAndroid Build Coastguard Worker }
1893*8975f5c5SAndroid Build Coastguard Worker }
1894*8975f5c5SAndroid Build Coastguard Worker }
1895*8975f5c5SAndroid Build Coastguard Worker
updateCachedComputeExecutableIndex()1896*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateCachedComputeExecutableIndex()
1897*8975f5c5SAndroid Build Coastguard Worker {
1898*8975f5c5SAndroid Build Coastguard Worker mCachedComputeExecutableIndex.reset();
1899*8975f5c5SAndroid Build Coastguard Worker for (size_t executableIndex = 0; executableIndex < mComputeExecutables.size();
1900*8975f5c5SAndroid Build Coastguard Worker executableIndex++)
1901*8975f5c5SAndroid Build Coastguard Worker {
1902*8975f5c5SAndroid Build Coastguard Worker if (mComputeExecutables[executableIndex]->matchesSignature(
1903*8975f5c5SAndroid Build Coastguard Worker mImage2DBindLayoutCache[gl::ShaderType::Compute]))
1904*8975f5c5SAndroid Build Coastguard Worker {
1905*8975f5c5SAndroid Build Coastguard Worker mCachedComputeExecutableIndex = executableIndex;
1906*8975f5c5SAndroid Build Coastguard Worker break;
1907*8975f5c5SAndroid Build Coastguard Worker }
1908*8975f5c5SAndroid Build Coastguard Worker }
1909*8975f5c5SAndroid Build Coastguard Worker }
1910*8975f5c5SAndroid Build Coastguard Worker
updateUniformBufferCache(const gl::Caps & caps)1911*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::updateUniformBufferCache(const gl::Caps &caps)
1912*8975f5c5SAndroid Build Coastguard Worker {
1913*8975f5c5SAndroid Build Coastguard Worker if (mExecutable->getUniformBlocks().empty())
1914*8975f5c5SAndroid Build Coastguard Worker {
1915*8975f5c5SAndroid Build Coastguard Worker return;
1916*8975f5c5SAndroid Build Coastguard Worker }
1917*8975f5c5SAndroid Build Coastguard Worker
1918*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1919*8975f5c5SAndroid Build Coastguard Worker {
1920*8975f5c5SAndroid Build Coastguard Worker mShaderUBOCaches[shaderType].clear();
1921*8975f5c5SAndroid Build Coastguard Worker mShaderUBOCachesUseSB[shaderType].clear();
1922*8975f5c5SAndroid Build Coastguard Worker }
1923*8975f5c5SAndroid Build Coastguard Worker
1924*8975f5c5SAndroid Build Coastguard Worker for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
1925*8975f5c5SAndroid Build Coastguard Worker uniformBlockIndex++)
1926*8975f5c5SAndroid Build Coastguard Worker {
1927*8975f5c5SAndroid Build Coastguard Worker const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
1928*8975f5c5SAndroid Build Coastguard Worker GLuint blockBinding = mExecutable->getUniformBlockBinding(uniformBlockIndex);
1929*8975f5c5SAndroid Build Coastguard Worker
1930*8975f5c5SAndroid Build Coastguard Worker // Unnecessary to apply an unreferenced standard or shared UBO
1931*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1932*8975f5c5SAndroid Build Coastguard Worker {
1933*8975f5c5SAndroid Build Coastguard Worker if (!uniformBlock.activeInShader(shaderType))
1934*8975f5c5SAndroid Build Coastguard Worker {
1935*8975f5c5SAndroid Build Coastguard Worker continue;
1936*8975f5c5SAndroid Build Coastguard Worker }
1937*8975f5c5SAndroid Build Coastguard Worker
1938*8975f5c5SAndroid Build Coastguard Worker bool useStructuredBuffer = uniformBlock.mUseStructuredBuffers[shaderType];
1939*8975f5c5SAndroid Build Coastguard Worker unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType];
1940*8975f5c5SAndroid Build Coastguard Worker if (useStructuredBuffer)
1941*8975f5c5SAndroid Build Coastguard Worker {
1942*8975f5c5SAndroid Build Coastguard Worker D3DUBOCacheUseSB cacheUseSB;
1943*8975f5c5SAndroid Build Coastguard Worker cacheUseSB.registerIndex = registerIndex;
1944*8975f5c5SAndroid Build Coastguard Worker cacheUseSB.binding = blockBinding;
1945*8975f5c5SAndroid Build Coastguard Worker cacheUseSB.byteWidth = uniformBlock.mByteWidths[shaderType];
1946*8975f5c5SAndroid Build Coastguard Worker cacheUseSB.structureByteStride = uniformBlock.mStructureByteStrides[shaderType];
1947*8975f5c5SAndroid Build Coastguard Worker mShaderUBOCachesUseSB[shaderType].push_back(cacheUseSB);
1948*8975f5c5SAndroid Build Coastguard Worker }
1949*8975f5c5SAndroid Build Coastguard Worker else
1950*8975f5c5SAndroid Build Coastguard Worker {
1951*8975f5c5SAndroid Build Coastguard Worker ASSERT(registerIndex <
1952*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
1953*8975f5c5SAndroid Build Coastguard Worker D3DUBOCache cache;
1954*8975f5c5SAndroid Build Coastguard Worker cache.registerIndex = registerIndex;
1955*8975f5c5SAndroid Build Coastguard Worker cache.binding = blockBinding;
1956*8975f5c5SAndroid Build Coastguard Worker mShaderUBOCaches[shaderType].push_back(cache);
1957*8975f5c5SAndroid Build Coastguard Worker }
1958*8975f5c5SAndroid Build Coastguard Worker }
1959*8975f5c5SAndroid Build Coastguard Worker }
1960*8975f5c5SAndroid Build Coastguard Worker
1961*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1962*8975f5c5SAndroid Build Coastguard Worker {
1963*8975f5c5SAndroid Build Coastguard Worker GLuint uniformBlockCount = static_cast<GLuint>(mShaderUBOCaches[shaderType].size() +
1964*8975f5c5SAndroid Build Coastguard Worker mShaderUBOCachesUseSB[shaderType].size());
1965*8975f5c5SAndroid Build Coastguard Worker ASSERT(uniformBlockCount <=
1966*8975f5c5SAndroid Build Coastguard Worker static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
1967*8975f5c5SAndroid Build Coastguard Worker }
1968*8975f5c5SAndroid Build Coastguard Worker }
1969*8975f5c5SAndroid Build Coastguard Worker
defineUniformsAndAssignRegisters(RendererD3D * renderer,const gl::ShaderMap<gl::SharedCompiledShaderState> & shaders)1970*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::defineUniformsAndAssignRegisters(
1971*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
1972*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders)
1973*8975f5c5SAndroid Build Coastguard Worker {
1974*8975f5c5SAndroid Build Coastguard Worker D3DUniformMap uniformMap;
1975*8975f5c5SAndroid Build Coastguard Worker
1976*8975f5c5SAndroid Build Coastguard Worker gl::ShaderBitSet attachedShaders;
1977*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
1978*8975f5c5SAndroid Build Coastguard Worker {
1979*8975f5c5SAndroid Build Coastguard Worker const gl::SharedCompiledShaderState &shader = shaders[shaderType];
1980*8975f5c5SAndroid Build Coastguard Worker if (shader)
1981*8975f5c5SAndroid Build Coastguard Worker {
1982*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &uniform : shader->uniforms)
1983*8975f5c5SAndroid Build Coastguard Worker {
1984*8975f5c5SAndroid Build Coastguard Worker if (uniform.active)
1985*8975f5c5SAndroid Build Coastguard Worker {
1986*8975f5c5SAndroid Build Coastguard Worker defineUniformBase(shader->shaderType, uniform, &uniformMap);
1987*8975f5c5SAndroid Build Coastguard Worker }
1988*8975f5c5SAndroid Build Coastguard Worker }
1989*8975f5c5SAndroid Build Coastguard Worker
1990*8975f5c5SAndroid Build Coastguard Worker attachedShaders.set(shader->shaderType);
1991*8975f5c5SAndroid Build Coastguard Worker }
1992*8975f5c5SAndroid Build Coastguard Worker }
1993*8975f5c5SAndroid Build Coastguard Worker
1994*8975f5c5SAndroid Build Coastguard Worker // Initialize the D3DUniform list to mirror the indexing of the GL layer.
1995*8975f5c5SAndroid Build Coastguard Worker for (GLuint index = 0; index < static_cast<GLuint>(mExecutable->getUniforms().size()); index++)
1996*8975f5c5SAndroid Build Coastguard Worker {
1997*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &glUniform = mExecutable->getUniforms()[index];
1998*8975f5c5SAndroid Build Coastguard Worker if (!glUniform.isInDefaultBlock())
1999*8975f5c5SAndroid Build Coastguard Worker continue;
2000*8975f5c5SAndroid Build Coastguard Worker
2001*8975f5c5SAndroid Build Coastguard Worker std::string name = mExecutable->getUniformNames()[index];
2002*8975f5c5SAndroid Build Coastguard Worker if (glUniform.isArray())
2003*8975f5c5SAndroid Build Coastguard Worker {
2004*8975f5c5SAndroid Build Coastguard Worker // In the program state, array uniform names include [0] as in the program resource
2005*8975f5c5SAndroid Build Coastguard Worker // spec. Here we don't include it.
2006*8975f5c5SAndroid Build Coastguard Worker // TODO([email protected]): consider using the same uniform naming here as in the GL
2007*8975f5c5SAndroid Build Coastguard Worker // layer.
2008*8975f5c5SAndroid Build Coastguard Worker ASSERT(angle::EndsWith(name, "[0]"));
2009*8975f5c5SAndroid Build Coastguard Worker name.resize(name.length() - 3);
2010*8975f5c5SAndroid Build Coastguard Worker }
2011*8975f5c5SAndroid Build Coastguard Worker auto mapEntry = uniformMap.find(name);
2012*8975f5c5SAndroid Build Coastguard Worker ASSERT(mapEntry != uniformMap.end());
2013*8975f5c5SAndroid Build Coastguard Worker mD3DUniforms.push_back(mapEntry->second);
2014*8975f5c5SAndroid Build Coastguard Worker }
2015*8975f5c5SAndroid Build Coastguard Worker
2016*8975f5c5SAndroid Build Coastguard Worker assignAllSamplerRegisters(shaders);
2017*8975f5c5SAndroid Build Coastguard Worker assignAllAtomicCounterRegisters();
2018*8975f5c5SAndroid Build Coastguard Worker // Samplers and readonly images share shader input resource slot, adjust low value of
2019*8975f5c5SAndroid Build Coastguard Worker // readonly image range.
2020*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
2021*8975f5c5SAndroid Build Coastguard Worker {
2022*8975f5c5SAndroid Build Coastguard Worker mUsedReadonlyImageRange[shaderType] =
2023*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI(mUsedShaderSamplerRanges[shaderType].high(),
2024*8975f5c5SAndroid Build Coastguard Worker mUsedShaderSamplerRanges[shaderType].high());
2025*8975f5c5SAndroid Build Coastguard Worker // Atomic counter buffers and non-readonly images share input resource slots
2026*8975f5c5SAndroid Build Coastguard Worker mUsedImageRange[shaderType] = gl::RangeUI(mUsedAtomicCounterRange[shaderType].high(),
2027*8975f5c5SAndroid Build Coastguard Worker mUsedAtomicCounterRange[shaderType].high());
2028*8975f5c5SAndroid Build Coastguard Worker }
2029*8975f5c5SAndroid Build Coastguard Worker assignAllImageRegisters();
2030*8975f5c5SAndroid Build Coastguard Worker initializeUniformStorage(renderer, attachedShaders);
2031*8975f5c5SAndroid Build Coastguard Worker }
2032*8975f5c5SAndroid Build Coastguard Worker
defineUniformBase(gl::ShaderType shaderType,const sh::ShaderVariable & uniform,D3DUniformMap * uniformMap)2033*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::defineUniformBase(gl::ShaderType shaderType,
2034*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable &uniform,
2035*8975f5c5SAndroid Build Coastguard Worker D3DUniformMap *uniformMap)
2036*8975f5c5SAndroid Build Coastguard Worker {
2037*8975f5c5SAndroid Build Coastguard Worker sh::StubBlockEncoder stubEncoder;
2038*8975f5c5SAndroid Build Coastguard Worker
2039*8975f5c5SAndroid Build Coastguard Worker // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their
2040*8975f5c5SAndroid Build Coastguard Worker // registers assigned in assignAllImageRegisters.
2041*8975f5c5SAndroid Build Coastguard Worker if (gl::IsSamplerType(uniform.type))
2042*8975f5c5SAndroid Build Coastguard Worker {
2043*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::Texture, &stubEncoder,
2044*8975f5c5SAndroid Build Coastguard Worker uniformMap);
2045*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2046*8975f5c5SAndroid Build Coastguard Worker return;
2047*8975f5c5SAndroid Build Coastguard Worker }
2048*8975f5c5SAndroid Build Coastguard Worker
2049*8975f5c5SAndroid Build Coastguard Worker if (gl::IsImageType(uniform.type))
2050*8975f5c5SAndroid Build Coastguard Worker {
2051*8975f5c5SAndroid Build Coastguard Worker if (uniform.readonly)
2052*8975f5c5SAndroid Build Coastguard Worker {
2053*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::Texture, &stubEncoder,
2054*8975f5c5SAndroid Build Coastguard Worker uniformMap);
2055*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2056*8975f5c5SAndroid Build Coastguard Worker }
2057*8975f5c5SAndroid Build Coastguard Worker else
2058*8975f5c5SAndroid Build Coastguard Worker {
2059*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::UnorderedAccessView,
2060*8975f5c5SAndroid Build Coastguard Worker &stubEncoder, uniformMap);
2061*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2062*8975f5c5SAndroid Build Coastguard Worker }
2063*8975f5c5SAndroid Build Coastguard Worker mImageBindingMap[uniform.name] = uniform.binding;
2064*8975f5c5SAndroid Build Coastguard Worker return;
2065*8975f5c5SAndroid Build Coastguard Worker }
2066*8975f5c5SAndroid Build Coastguard Worker
2067*8975f5c5SAndroid Build Coastguard Worker if (uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn())
2068*8975f5c5SAndroid Build Coastguard Worker {
2069*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::None, &stubEncoder,
2070*8975f5c5SAndroid Build Coastguard Worker uniformMap);
2071*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2072*8975f5c5SAndroid Build Coastguard Worker return;
2073*8975f5c5SAndroid Build Coastguard Worker }
2074*8975f5c5SAndroid Build Coastguard Worker else if (gl::IsAtomicCounterType(uniform.type))
2075*8975f5c5SAndroid Build Coastguard Worker {
2076*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::UnorderedAccessView,
2077*8975f5c5SAndroid Build Coastguard Worker &stubEncoder, uniformMap);
2078*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2079*8975f5c5SAndroid Build Coastguard Worker mAtomicBindingMap[uniform.name] = uniform.binding;
2080*8975f5c5SAndroid Build Coastguard Worker return;
2081*8975f5c5SAndroid Build Coastguard Worker }
2082*8975f5c5SAndroid Build Coastguard Worker
2083*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderStateD3D &shaderD3D = mAttachedShaders[shaderType];
2084*8975f5c5SAndroid Build Coastguard Worker unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name);
2085*8975f5c5SAndroid Build Coastguard Worker ShShaderOutput outputType = shaderD3D->compilerOutputType;
2086*8975f5c5SAndroid Build Coastguard Worker sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true);
2087*8975f5c5SAndroid Build Coastguard Worker encoder.skipRegisters(startRegister);
2088*8975f5c5SAndroid Build Coastguard Worker
2089*8975f5c5SAndroid Build Coastguard Worker UniformEncodingVisitorD3D visitor(shaderType, HLSLRegisterType::None, &encoder, uniformMap);
2090*8975f5c5SAndroid Build Coastguard Worker sh::TraverseShaderVariable(uniform, false, &visitor);
2091*8975f5c5SAndroid Build Coastguard Worker }
2092*8975f5c5SAndroid Build Coastguard Worker
assignAllSamplerRegisters(const gl::ShaderMap<gl::SharedCompiledShaderState> & shaders)2093*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignAllSamplerRegisters(
2094*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders)
2095*8975f5c5SAndroid Build Coastguard Worker {
2096*8975f5c5SAndroid Build Coastguard Worker for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
2097*8975f5c5SAndroid Build Coastguard Worker {
2098*8975f5c5SAndroid Build Coastguard Worker if (mD3DUniforms[uniformIndex]->isSampler())
2099*8975f5c5SAndroid Build Coastguard Worker {
2100*8975f5c5SAndroid Build Coastguard Worker assignSamplerRegisters(shaders, uniformIndex);
2101*8975f5c5SAndroid Build Coastguard Worker }
2102*8975f5c5SAndroid Build Coastguard Worker }
2103*8975f5c5SAndroid Build Coastguard Worker }
2104*8975f5c5SAndroid Build Coastguard Worker
assignSamplerRegisters(const gl::ShaderMap<gl::SharedCompiledShaderState> & shaders,size_t uniformIndex)2105*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignSamplerRegisters(
2106*8975f5c5SAndroid Build Coastguard Worker const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders,
2107*8975f5c5SAndroid Build Coastguard Worker size_t uniformIndex)
2108*8975f5c5SAndroid Build Coastguard Worker {
2109*8975f5c5SAndroid Build Coastguard Worker D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
2110*8975f5c5SAndroid Build Coastguard Worker ASSERT(d3dUniform->isSampler());
2111*8975f5c5SAndroid Build Coastguard Worker // If the uniform is an array of arrays, then we have separate entries for each inner array in
2112*8975f5c5SAndroid Build Coastguard Worker // mD3DUniforms. However, the sampler register info is stored in the shader only for the
2113*8975f5c5SAndroid Build Coastguard Worker // outermost array.
2114*8975f5c5SAndroid Build Coastguard Worker std::vector<unsigned int> subscripts;
2115*8975f5c5SAndroid Build Coastguard Worker const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
2116*8975f5c5SAndroid Build Coastguard Worker unsigned int registerOffset = mExecutable->getUniforms()[uniformIndex].pod.parentArrayIndex *
2117*8975f5c5SAndroid Build Coastguard Worker d3dUniform->getArraySizeProduct();
2118*8975f5c5SAndroid Build Coastguard Worker
2119*8975f5c5SAndroid Build Coastguard Worker bool hasUniform = false;
2120*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
2121*8975f5c5SAndroid Build Coastguard Worker {
2122*8975f5c5SAndroid Build Coastguard Worker if (!shaders[shaderType])
2123*8975f5c5SAndroid Build Coastguard Worker {
2124*8975f5c5SAndroid Build Coastguard Worker continue;
2125*8975f5c5SAndroid Build Coastguard Worker }
2126*8975f5c5SAndroid Build Coastguard Worker
2127*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderStateD3D &shaderD3D = mAttachedShaders[shaderType];
2128*8975f5c5SAndroid Build Coastguard Worker if (shaderD3D->hasUniform(baseName))
2129*8975f5c5SAndroid Build Coastguard Worker {
2130*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderRegisterIndexes[shaderType] =
2131*8975f5c5SAndroid Build Coastguard Worker shaderD3D->getUniformRegister(baseName) + registerOffset;
2132*8975f5c5SAndroid Build Coastguard Worker ASSERT(d3dUniform->mShaderRegisterIndexes[shaderType] != GL_INVALID_VALUE);
2133*8975f5c5SAndroid Build Coastguard Worker
2134*8975f5c5SAndroid Build Coastguard Worker AssignSamplers(d3dUniform->mShaderRegisterIndexes[shaderType], d3dUniform->typeInfo,
2135*8975f5c5SAndroid Build Coastguard Worker d3dUniform->getArraySizeProduct(), mShaderSamplers[shaderType],
2136*8975f5c5SAndroid Build Coastguard Worker &mUsedShaderSamplerRanges[shaderType]);
2137*8975f5c5SAndroid Build Coastguard Worker hasUniform = true;
2138*8975f5c5SAndroid Build Coastguard Worker }
2139*8975f5c5SAndroid Build Coastguard Worker }
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker ASSERT(hasUniform);
2142*8975f5c5SAndroid Build Coastguard Worker }
2143*8975f5c5SAndroid Build Coastguard Worker
2144*8975f5c5SAndroid Build Coastguard Worker // static
AssignSamplers(unsigned int startSamplerIndex,const gl::UniformTypeInfo & typeInfo,unsigned int samplerCount,std::vector<D3DSampler> & outSamplers,gl::RangeUI * outUsedRange)2145*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::AssignSamplers(unsigned int startSamplerIndex,
2146*8975f5c5SAndroid Build Coastguard Worker const gl::UniformTypeInfo &typeInfo,
2147*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerCount,
2148*8975f5c5SAndroid Build Coastguard Worker std::vector<D3DSampler> &outSamplers,
2149*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI *outUsedRange)
2150*8975f5c5SAndroid Build Coastguard Worker {
2151*8975f5c5SAndroid Build Coastguard Worker unsigned int samplerIndex = startSamplerIndex;
2152*8975f5c5SAndroid Build Coastguard Worker
2153*8975f5c5SAndroid Build Coastguard Worker do
2154*8975f5c5SAndroid Build Coastguard Worker {
2155*8975f5c5SAndroid Build Coastguard Worker ASSERT(samplerIndex < outSamplers.size());
2156*8975f5c5SAndroid Build Coastguard Worker D3DSampler *sampler = &outSamplers[samplerIndex];
2157*8975f5c5SAndroid Build Coastguard Worker sampler->active = true;
2158*8975f5c5SAndroid Build Coastguard Worker sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
2159*8975f5c5SAndroid Build Coastguard Worker sampler->logicalTextureUnit = 0;
2160*8975f5c5SAndroid Build Coastguard Worker outUsedRange->extend(samplerIndex);
2161*8975f5c5SAndroid Build Coastguard Worker samplerIndex++;
2162*8975f5c5SAndroid Build Coastguard Worker } while (samplerIndex < startSamplerIndex + samplerCount);
2163*8975f5c5SAndroid Build Coastguard Worker }
2164*8975f5c5SAndroid Build Coastguard Worker
assignAllImageRegisters()2165*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignAllImageRegisters()
2166*8975f5c5SAndroid Build Coastguard Worker {
2167*8975f5c5SAndroid Build Coastguard Worker for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
2168*8975f5c5SAndroid Build Coastguard Worker {
2169*8975f5c5SAndroid Build Coastguard Worker if (mD3DUniforms[uniformIndex]->isImage() && !mD3DUniforms[uniformIndex]->isImage2D())
2170*8975f5c5SAndroid Build Coastguard Worker {
2171*8975f5c5SAndroid Build Coastguard Worker assignImageRegisters(uniformIndex);
2172*8975f5c5SAndroid Build Coastguard Worker }
2173*8975f5c5SAndroid Build Coastguard Worker }
2174*8975f5c5SAndroid Build Coastguard Worker }
2175*8975f5c5SAndroid Build Coastguard Worker
assignAllAtomicCounterRegisters()2176*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignAllAtomicCounterRegisters()
2177*8975f5c5SAndroid Build Coastguard Worker {
2178*8975f5c5SAndroid Build Coastguard Worker if (mAtomicBindingMap.empty())
2179*8975f5c5SAndroid Build Coastguard Worker {
2180*8975f5c5SAndroid Build Coastguard Worker return;
2181*8975f5c5SAndroid Build Coastguard Worker }
2182*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderStateD3D &computeShader = mAttachedShaders[gl::ShaderType::Compute];
2183*8975f5c5SAndroid Build Coastguard Worker if (computeShader)
2184*8975f5c5SAndroid Build Coastguard Worker {
2185*8975f5c5SAndroid Build Coastguard Worker auto ®isterIndices = mComputeAtomicCounterBufferRegisterIndices;
2186*8975f5c5SAndroid Build Coastguard Worker for (auto &atomicBinding : mAtomicBindingMap)
2187*8975f5c5SAndroid Build Coastguard Worker {
2188*8975f5c5SAndroid Build Coastguard Worker ASSERT(computeShader->hasUniform(atomicBinding.first));
2189*8975f5c5SAndroid Build Coastguard Worker unsigned int currentRegister = computeShader->getUniformRegister(atomicBinding.first);
2190*8975f5c5SAndroid Build Coastguard Worker ASSERT(currentRegister != GL_INVALID_INDEX);
2191*8975f5c5SAndroid Build Coastguard Worker const int kBinding = atomicBinding.second;
2192*8975f5c5SAndroid Build Coastguard Worker
2193*8975f5c5SAndroid Build Coastguard Worker registerIndices[kBinding] = currentRegister;
2194*8975f5c5SAndroid Build Coastguard Worker
2195*8975f5c5SAndroid Build Coastguard Worker mUsedAtomicCounterRange[gl::ShaderType::Compute].extend(currentRegister);
2196*8975f5c5SAndroid Build Coastguard Worker }
2197*8975f5c5SAndroid Build Coastguard Worker }
2198*8975f5c5SAndroid Build Coastguard Worker else
2199*8975f5c5SAndroid Build Coastguard Worker {
2200*8975f5c5SAndroid Build Coastguard Worker // Implement atomic counters for non-compute shaders
2201*8975f5c5SAndroid Build Coastguard Worker // http://anglebug.com/42260658
2202*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
2203*8975f5c5SAndroid Build Coastguard Worker }
2204*8975f5c5SAndroid Build Coastguard Worker }
2205*8975f5c5SAndroid Build Coastguard Worker
assignImageRegisters(size_t uniformIndex)2206*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignImageRegisters(size_t uniformIndex)
2207*8975f5c5SAndroid Build Coastguard Worker {
2208*8975f5c5SAndroid Build Coastguard Worker D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
2209*8975f5c5SAndroid Build Coastguard Worker ASSERT(d3dUniform->isImage());
2210*8975f5c5SAndroid Build Coastguard Worker // If the uniform is an array of arrays, then we have separate entries for each inner array in
2211*8975f5c5SAndroid Build Coastguard Worker // mD3DUniforms. However, the image register info is stored in the shader only for the
2212*8975f5c5SAndroid Build Coastguard Worker // outermost array.
2213*8975f5c5SAndroid Build Coastguard Worker std::vector<unsigned int> subscripts;
2214*8975f5c5SAndroid Build Coastguard Worker const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
2215*8975f5c5SAndroid Build Coastguard Worker unsigned int registerOffset = mExecutable->getUniforms()[uniformIndex].pod.parentArrayIndex *
2216*8975f5c5SAndroid Build Coastguard Worker d3dUniform->getArraySizeProduct();
2217*8975f5c5SAndroid Build Coastguard Worker
2218*8975f5c5SAndroid Build Coastguard Worker const SharedCompiledShaderStateD3D &computeShader = mAttachedShaders[gl::ShaderType::Compute];
2219*8975f5c5SAndroid Build Coastguard Worker if (computeShader)
2220*8975f5c5SAndroid Build Coastguard Worker {
2221*8975f5c5SAndroid Build Coastguard Worker ASSERT(computeShader->hasUniform(baseName));
2222*8975f5c5SAndroid Build Coastguard Worker d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
2223*8975f5c5SAndroid Build Coastguard Worker computeShader->getUniformRegister(baseName) + registerOffset;
2224*8975f5c5SAndroid Build Coastguard Worker ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
2225*8975f5c5SAndroid Build Coastguard Worker auto bindingIter = mImageBindingMap.find(baseName);
2226*8975f5c5SAndroid Build Coastguard Worker ASSERT(bindingIter != mImageBindingMap.end());
2227*8975f5c5SAndroid Build Coastguard Worker if (d3dUniform->regType == HLSLRegisterType::Texture)
2228*8975f5c5SAndroid Build Coastguard Worker {
2229*8975f5c5SAndroid Build Coastguard Worker AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
2230*8975f5c5SAndroid Build Coastguard Worker bindingIter->second, d3dUniform->getArraySizeProduct(),
2231*8975f5c5SAndroid Build Coastguard Worker mReadonlyImages[gl::ShaderType::Compute],
2232*8975f5c5SAndroid Build Coastguard Worker &mUsedReadonlyImageRange[gl::ShaderType::Compute]);
2233*8975f5c5SAndroid Build Coastguard Worker }
2234*8975f5c5SAndroid Build Coastguard Worker else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
2235*8975f5c5SAndroid Build Coastguard Worker {
2236*8975f5c5SAndroid Build Coastguard Worker AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
2237*8975f5c5SAndroid Build Coastguard Worker bindingIter->second, d3dUniform->getArraySizeProduct(),
2238*8975f5c5SAndroid Build Coastguard Worker mImages[gl::ShaderType::Compute],
2239*8975f5c5SAndroid Build Coastguard Worker &mUsedImageRange[gl::ShaderType::Compute]);
2240*8975f5c5SAndroid Build Coastguard Worker }
2241*8975f5c5SAndroid Build Coastguard Worker else
2242*8975f5c5SAndroid Build Coastguard Worker {
2243*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2244*8975f5c5SAndroid Build Coastguard Worker }
2245*8975f5c5SAndroid Build Coastguard Worker }
2246*8975f5c5SAndroid Build Coastguard Worker else
2247*8975f5c5SAndroid Build Coastguard Worker {
2248*8975f5c5SAndroid Build Coastguard Worker // TODO([email protected]): Implement image variables in vertex shader and pixel shader.
2249*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
2250*8975f5c5SAndroid Build Coastguard Worker }
2251*8975f5c5SAndroid Build Coastguard Worker }
2252*8975f5c5SAndroid Build Coastguard Worker
2253*8975f5c5SAndroid Build Coastguard Worker // static
AssignImages(unsigned int startImageIndex,int startLogicalImageUnit,unsigned int imageCount,std::vector<D3DImage> & outImages,gl::RangeUI * outUsedRange)2254*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::AssignImages(unsigned int startImageIndex,
2255*8975f5c5SAndroid Build Coastguard Worker int startLogicalImageUnit,
2256*8975f5c5SAndroid Build Coastguard Worker unsigned int imageCount,
2257*8975f5c5SAndroid Build Coastguard Worker std::vector<D3DImage> &outImages,
2258*8975f5c5SAndroid Build Coastguard Worker gl::RangeUI *outUsedRange)
2259*8975f5c5SAndroid Build Coastguard Worker {
2260*8975f5c5SAndroid Build Coastguard Worker unsigned int imageIndex = startImageIndex;
2261*8975f5c5SAndroid Build Coastguard Worker
2262*8975f5c5SAndroid Build Coastguard Worker // If declare without a binding qualifier, any uniform image variable (include all elements of
2263*8975f5c5SAndroid Build Coastguard Worker // unbound image array) shoud be bound to unit zero.
2264*8975f5c5SAndroid Build Coastguard Worker if (startLogicalImageUnit == -1)
2265*8975f5c5SAndroid Build Coastguard Worker {
2266*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex < outImages.size());
2267*8975f5c5SAndroid Build Coastguard Worker D3DImage *image = &outImages[imageIndex];
2268*8975f5c5SAndroid Build Coastguard Worker image->active = true;
2269*8975f5c5SAndroid Build Coastguard Worker image->logicalImageUnit = 0;
2270*8975f5c5SAndroid Build Coastguard Worker outUsedRange->extend(imageIndex);
2271*8975f5c5SAndroid Build Coastguard Worker return;
2272*8975f5c5SAndroid Build Coastguard Worker }
2273*8975f5c5SAndroid Build Coastguard Worker
2274*8975f5c5SAndroid Build Coastguard Worker unsigned int logcalImageUnit = startLogicalImageUnit;
2275*8975f5c5SAndroid Build Coastguard Worker do
2276*8975f5c5SAndroid Build Coastguard Worker {
2277*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageIndex < outImages.size());
2278*8975f5c5SAndroid Build Coastguard Worker D3DImage *image = &outImages[imageIndex];
2279*8975f5c5SAndroid Build Coastguard Worker image->active = true;
2280*8975f5c5SAndroid Build Coastguard Worker image->logicalImageUnit = logcalImageUnit;
2281*8975f5c5SAndroid Build Coastguard Worker outUsedRange->extend(imageIndex);
2282*8975f5c5SAndroid Build Coastguard Worker imageIndex++;
2283*8975f5c5SAndroid Build Coastguard Worker logcalImageUnit++;
2284*8975f5c5SAndroid Build Coastguard Worker } while (imageIndex < startImageIndex + imageCount);
2285*8975f5c5SAndroid Build Coastguard Worker }
2286*8975f5c5SAndroid Build Coastguard Worker
assignImage2DRegisters(gl::ShaderType shaderType,unsigned int startImageIndex,int startLogicalImageUnit,bool readonly)2287*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::assignImage2DRegisters(gl::ShaderType shaderType,
2288*8975f5c5SAndroid Build Coastguard Worker unsigned int startImageIndex,
2289*8975f5c5SAndroid Build Coastguard Worker int startLogicalImageUnit,
2290*8975f5c5SAndroid Build Coastguard Worker bool readonly)
2291*8975f5c5SAndroid Build Coastguard Worker {
2292*8975f5c5SAndroid Build Coastguard Worker if (readonly)
2293*8975f5c5SAndroid Build Coastguard Worker {
2294*8975f5c5SAndroid Build Coastguard Worker AssignImages(startImageIndex, startLogicalImageUnit, 1, mReadonlyImages[shaderType],
2295*8975f5c5SAndroid Build Coastguard Worker &mUsedReadonlyImageRange[shaderType]);
2296*8975f5c5SAndroid Build Coastguard Worker }
2297*8975f5c5SAndroid Build Coastguard Worker else
2298*8975f5c5SAndroid Build Coastguard Worker {
2299*8975f5c5SAndroid Build Coastguard Worker AssignImages(startImageIndex, startLogicalImageUnit, 1, mImages[shaderType],
2300*8975f5c5SAndroid Build Coastguard Worker &mUsedImageRange[shaderType]);
2301*8975f5c5SAndroid Build Coastguard Worker }
2302*8975f5c5SAndroid Build Coastguard Worker }
2303*8975f5c5SAndroid Build Coastguard Worker
gatherTransformFeedbackVaryings(RendererD3D * renderer,const gl::VaryingPacking & varyingPacking,const std::vector<std::string> & tfVaryingNames,const BuiltinInfo & builtins)2304*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::gatherTransformFeedbackVaryings(
2305*8975f5c5SAndroid Build Coastguard Worker RendererD3D *renderer,
2306*8975f5c5SAndroid Build Coastguard Worker const gl::VaryingPacking &varyingPacking,
2307*8975f5c5SAndroid Build Coastguard Worker const std::vector<std::string> &tfVaryingNames,
2308*8975f5c5SAndroid Build Coastguard Worker const BuiltinInfo &builtins)
2309*8975f5c5SAndroid Build Coastguard Worker {
2310*8975f5c5SAndroid Build Coastguard Worker const std::string &varyingSemantic =
2311*8975f5c5SAndroid Build Coastguard Worker GetVaryingSemantic(renderer->getMajorShaderModel(), usesPointSize());
2312*8975f5c5SAndroid Build Coastguard Worker
2313*8975f5c5SAndroid Build Coastguard Worker // Gather the linked varyings that are used for transform feedback, they should all exist.
2314*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.clear();
2315*8975f5c5SAndroid Build Coastguard Worker
2316*8975f5c5SAndroid Build Coastguard Worker for (unsigned int outputSlot = 0; outputSlot < static_cast<unsigned int>(tfVaryingNames.size());
2317*8975f5c5SAndroid Build Coastguard Worker ++outputSlot)
2318*8975f5c5SAndroid Build Coastguard Worker {
2319*8975f5c5SAndroid Build Coastguard Worker const auto &tfVaryingName = tfVaryingNames[outputSlot];
2320*8975f5c5SAndroid Build Coastguard Worker if (tfVaryingName == "gl_Position")
2321*8975f5c5SAndroid Build Coastguard Worker {
2322*8975f5c5SAndroid Build Coastguard Worker if (builtins.glPosition.enabled)
2323*8975f5c5SAndroid Build Coastguard Worker {
2324*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.emplace_back(builtins.glPosition.semantic,
2325*8975f5c5SAndroid Build Coastguard Worker builtins.glPosition.indexOrSize, 4, outputSlot);
2326*8975f5c5SAndroid Build Coastguard Worker }
2327*8975f5c5SAndroid Build Coastguard Worker }
2328*8975f5c5SAndroid Build Coastguard Worker else if (tfVaryingName == "gl_FragCoord")
2329*8975f5c5SAndroid Build Coastguard Worker {
2330*8975f5c5SAndroid Build Coastguard Worker if (builtins.glFragCoord.enabled)
2331*8975f5c5SAndroid Build Coastguard Worker {
2332*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.emplace_back(builtins.glFragCoord.semantic,
2333*8975f5c5SAndroid Build Coastguard Worker builtins.glFragCoord.indexOrSize, 4, outputSlot);
2334*8975f5c5SAndroid Build Coastguard Worker }
2335*8975f5c5SAndroid Build Coastguard Worker }
2336*8975f5c5SAndroid Build Coastguard Worker else if (tfVaryingName == "gl_PointSize")
2337*8975f5c5SAndroid Build Coastguard Worker {
2338*8975f5c5SAndroid Build Coastguard Worker if (builtins.glPointSize.enabled)
2339*8975f5c5SAndroid Build Coastguard Worker {
2340*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.emplace_back("PSIZE", 0, 1, outputSlot);
2341*8975f5c5SAndroid Build Coastguard Worker }
2342*8975f5c5SAndroid Build Coastguard Worker }
2343*8975f5c5SAndroid Build Coastguard Worker else
2344*8975f5c5SAndroid Build Coastguard Worker {
2345*8975f5c5SAndroid Build Coastguard Worker const auto ®isterInfos = varyingPacking.getRegisterList();
2346*8975f5c5SAndroid Build Coastguard Worker for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
2347*8975f5c5SAndroid Build Coastguard Worker {
2348*8975f5c5SAndroid Build Coastguard Worker const auto ®isterInfo = registerInfos[registerIndex];
2349*8975f5c5SAndroid Build Coastguard Worker const auto &varying = registerInfo.packedVarying->varying();
2350*8975f5c5SAndroid Build Coastguard Worker GLenum transposedType = gl::TransposeMatrixType(varying.type);
2351*8975f5c5SAndroid Build Coastguard Worker int componentCount = gl::VariableColumnCount(transposedType);
2352*8975f5c5SAndroid Build Coastguard Worker ASSERT(!varying.isBuiltIn() && !varying.isStruct());
2353*8975f5c5SAndroid Build Coastguard Worker
2354*8975f5c5SAndroid Build Coastguard Worker // There can be more than one register assigned to a particular varying, and each
2355*8975f5c5SAndroid Build Coastguard Worker // register needs its own stream out entry.
2356*8975f5c5SAndroid Build Coastguard Worker if (registerInfo.tfVaryingName() == tfVaryingName)
2357*8975f5c5SAndroid Build Coastguard Worker {
2358*8975f5c5SAndroid Build Coastguard Worker mStreamOutVaryings.emplace_back(varyingSemantic, registerIndex, componentCount,
2359*8975f5c5SAndroid Build Coastguard Worker outputSlot);
2360*8975f5c5SAndroid Build Coastguard Worker }
2361*8975f5c5SAndroid Build Coastguard Worker }
2362*8975f5c5SAndroid Build Coastguard Worker }
2363*8975f5c5SAndroid Build Coastguard Worker }
2364*8975f5c5SAndroid Build Coastguard Worker }
2365*8975f5c5SAndroid Build Coastguard Worker
getD3DUniformFromLocation(const gl::VariableLocation & locationInfo)2366*8975f5c5SAndroid Build Coastguard Worker D3DUniform *ProgramExecutableD3D::getD3DUniformFromLocation(
2367*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo)
2368*8975f5c5SAndroid Build Coastguard Worker {
2369*8975f5c5SAndroid Build Coastguard Worker return mD3DUniforms[locationInfo.index];
2370*8975f5c5SAndroid Build Coastguard Worker }
2371*8975f5c5SAndroid Build Coastguard Worker
getD3DUniformFromLocation(const gl::VariableLocation & locationInfo) const2372*8975f5c5SAndroid Build Coastguard Worker const D3DUniform *ProgramExecutableD3D::getD3DUniformFromLocation(
2373*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo) const
2374*8975f5c5SAndroid Build Coastguard Worker {
2375*8975f5c5SAndroid Build Coastguard Worker return mD3DUniforms[locationInfo.index];
2376*8975f5c5SAndroid Build Coastguard Worker }
2377*8975f5c5SAndroid Build Coastguard Worker
issueSerial()2378*8975f5c5SAndroid Build Coastguard Worker unsigned int ProgramExecutableD3D::issueSerial()
2379*8975f5c5SAndroid Build Coastguard Worker {
2380*8975f5c5SAndroid Build Coastguard Worker return mCurrentSerial++;
2381*8975f5c5SAndroid Build Coastguard Worker }
2382*8975f5c5SAndroid Build Coastguard Worker
setUniform1fv(GLint location,GLsizei count,const GLfloat * v)2383*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
2384*8975f5c5SAndroid Build Coastguard Worker {
2385*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_FLOAT);
2386*8975f5c5SAndroid Build Coastguard Worker }
2387*8975f5c5SAndroid Build Coastguard Worker
setUniform2fv(GLint location,GLsizei count,const GLfloat * v)2388*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
2389*8975f5c5SAndroid Build Coastguard Worker {
2390*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_FLOAT_VEC2);
2391*8975f5c5SAndroid Build Coastguard Worker }
2392*8975f5c5SAndroid Build Coastguard Worker
setUniform3fv(GLint location,GLsizei count,const GLfloat * v)2393*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
2394*8975f5c5SAndroid Build Coastguard Worker {
2395*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_FLOAT_VEC3);
2396*8975f5c5SAndroid Build Coastguard Worker }
2397*8975f5c5SAndroid Build Coastguard Worker
setUniform4fv(GLint location,GLsizei count,const GLfloat * v)2398*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
2399*8975f5c5SAndroid Build Coastguard Worker {
2400*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_FLOAT_VEC4);
2401*8975f5c5SAndroid Build Coastguard Worker }
2402*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2403*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix2fv(GLint location,
2404*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2405*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2406*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2407*8975f5c5SAndroid Build Coastguard Worker {
2408*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<2, 2>(location, count, transpose, value);
2409*8975f5c5SAndroid Build Coastguard Worker }
2410*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2411*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix3fv(GLint location,
2412*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2413*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2414*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2415*8975f5c5SAndroid Build Coastguard Worker {
2416*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<3, 3>(location, count, transpose, value);
2417*8975f5c5SAndroid Build Coastguard Worker }
2418*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2419*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix4fv(GLint location,
2420*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2421*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2422*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2423*8975f5c5SAndroid Build Coastguard Worker {
2424*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<4, 4>(location, count, transpose, value);
2425*8975f5c5SAndroid Build Coastguard Worker }
2426*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2427*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix2x3fv(GLint location,
2428*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2429*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2430*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2431*8975f5c5SAndroid Build Coastguard Worker {
2432*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<2, 3>(location, count, transpose, value);
2433*8975f5c5SAndroid Build Coastguard Worker }
2434*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2435*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix3x2fv(GLint location,
2436*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2437*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2438*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2439*8975f5c5SAndroid Build Coastguard Worker {
2440*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<3, 2>(location, count, transpose, value);
2441*8975f5c5SAndroid Build Coastguard Worker }
2442*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2443*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix2x4fv(GLint location,
2444*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2445*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2446*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2447*8975f5c5SAndroid Build Coastguard Worker {
2448*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<2, 4>(location, count, transpose, value);
2449*8975f5c5SAndroid Build Coastguard Worker }
2450*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2451*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix4x2fv(GLint location,
2452*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2453*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2454*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2455*8975f5c5SAndroid Build Coastguard Worker {
2456*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<4, 2>(location, count, transpose, value);
2457*8975f5c5SAndroid Build Coastguard Worker }
2458*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2459*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix3x4fv(GLint location,
2460*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2461*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2462*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2463*8975f5c5SAndroid Build Coastguard Worker {
2464*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<3, 4>(location, count, transpose, value);
2465*8975f5c5SAndroid Build Coastguard Worker }
2466*8975f5c5SAndroid Build Coastguard Worker
setUniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2467*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrix4x3fv(GLint location,
2468*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2469*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2470*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2471*8975f5c5SAndroid Build Coastguard Worker {
2472*8975f5c5SAndroid Build Coastguard Worker setUniformMatrixfvInternal<4, 3>(location, count, transpose, value);
2473*8975f5c5SAndroid Build Coastguard Worker }
2474*8975f5c5SAndroid Build Coastguard Worker
setUniform1iv(GLint location,GLsizei count,const GLint * v)2475*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
2476*8975f5c5SAndroid Build Coastguard Worker {
2477*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_INT);
2478*8975f5c5SAndroid Build Coastguard Worker }
2479*8975f5c5SAndroid Build Coastguard Worker
setUniform2iv(GLint location,GLsizei count,const GLint * v)2480*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
2481*8975f5c5SAndroid Build Coastguard Worker {
2482*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_INT_VEC2);
2483*8975f5c5SAndroid Build Coastguard Worker }
2484*8975f5c5SAndroid Build Coastguard Worker
setUniform3iv(GLint location,GLsizei count,const GLint * v)2485*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
2486*8975f5c5SAndroid Build Coastguard Worker {
2487*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_INT_VEC3);
2488*8975f5c5SAndroid Build Coastguard Worker }
2489*8975f5c5SAndroid Build Coastguard Worker
setUniform4iv(GLint location,GLsizei count,const GLint * v)2490*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
2491*8975f5c5SAndroid Build Coastguard Worker {
2492*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_INT_VEC4);
2493*8975f5c5SAndroid Build Coastguard Worker }
2494*8975f5c5SAndroid Build Coastguard Worker
setUniform1uiv(GLint location,GLsizei count,const GLuint * v)2495*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
2496*8975f5c5SAndroid Build Coastguard Worker {
2497*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_UNSIGNED_INT);
2498*8975f5c5SAndroid Build Coastguard Worker }
2499*8975f5c5SAndroid Build Coastguard Worker
setUniform2uiv(GLint location,GLsizei count,const GLuint * v)2500*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
2501*8975f5c5SAndroid Build Coastguard Worker {
2502*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2);
2503*8975f5c5SAndroid Build Coastguard Worker }
2504*8975f5c5SAndroid Build Coastguard Worker
setUniform3uiv(GLint location,GLsizei count,const GLuint * v)2505*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
2506*8975f5c5SAndroid Build Coastguard Worker {
2507*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3);
2508*8975f5c5SAndroid Build Coastguard Worker }
2509*8975f5c5SAndroid Build Coastguard Worker
setUniform4uiv(GLint location,GLsizei count,const GLuint * v)2510*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
2511*8975f5c5SAndroid Build Coastguard Worker {
2512*8975f5c5SAndroid Build Coastguard Worker setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4);
2513*8975f5c5SAndroid Build Coastguard Worker }
2514*8975f5c5SAndroid Build Coastguard Worker
2515*8975f5c5SAndroid Build Coastguard Worker // Assume count is already clamped.
2516*8975f5c5SAndroid Build Coastguard Worker template <typename T>
setUniformImpl(D3DUniform * targetUniform,const gl::VariableLocation & locationInfo,GLsizei count,const T * v,uint8_t * targetState,GLenum uniformType)2517*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformImpl(D3DUniform *targetUniform,
2518*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo,
2519*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2520*8975f5c5SAndroid Build Coastguard Worker const T *v,
2521*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetState,
2522*8975f5c5SAndroid Build Coastguard Worker GLenum uniformType)
2523*8975f5c5SAndroid Build Coastguard Worker {
2524*8975f5c5SAndroid Build Coastguard Worker const int components = targetUniform->typeInfo.componentCount;
2525*8975f5c5SAndroid Build Coastguard Worker const unsigned int arrayElementOffset = locationInfo.arrayIndex;
2526*8975f5c5SAndroid Build Coastguard Worker const int blockSize = 4;
2527*8975f5c5SAndroid Build Coastguard Worker
2528*8975f5c5SAndroid Build Coastguard Worker if (targetUniform->typeInfo.type == uniformType)
2529*8975f5c5SAndroid Build Coastguard Worker {
2530*8975f5c5SAndroid Build Coastguard Worker T *dest = reinterpret_cast<T *>(targetState) + arrayElementOffset * blockSize;
2531*8975f5c5SAndroid Build Coastguard Worker const T *source = v;
2532*8975f5c5SAndroid Build Coastguard Worker
2533*8975f5c5SAndroid Build Coastguard Worker // If the component is equal to the block size, we can optimize to a single memcpy.
2534*8975f5c5SAndroid Build Coastguard Worker // Otherwise, we have to do partial block writes.
2535*8975f5c5SAndroid Build Coastguard Worker if (components == blockSize)
2536*8975f5c5SAndroid Build Coastguard Worker {
2537*8975f5c5SAndroid Build Coastguard Worker memcpy(dest, source, components * count * sizeof(T));
2538*8975f5c5SAndroid Build Coastguard Worker }
2539*8975f5c5SAndroid Build Coastguard Worker else
2540*8975f5c5SAndroid Build Coastguard Worker {
2541*8975f5c5SAndroid Build Coastguard Worker for (GLint i = 0; i < count; i++, dest += blockSize, source += components)
2542*8975f5c5SAndroid Build Coastguard Worker {
2543*8975f5c5SAndroid Build Coastguard Worker memcpy(dest, source, components * sizeof(T));
2544*8975f5c5SAndroid Build Coastguard Worker }
2545*8975f5c5SAndroid Build Coastguard Worker }
2546*8975f5c5SAndroid Build Coastguard Worker }
2547*8975f5c5SAndroid Build Coastguard Worker else
2548*8975f5c5SAndroid Build Coastguard Worker {
2549*8975f5c5SAndroid Build Coastguard Worker ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType));
2550*8975f5c5SAndroid Build Coastguard Worker GLint *boolParams = reinterpret_cast<GLint *>(targetState) + arrayElementOffset * 4;
2551*8975f5c5SAndroid Build Coastguard Worker
2552*8975f5c5SAndroid Build Coastguard Worker for (GLint i = 0; i < count; i++)
2553*8975f5c5SAndroid Build Coastguard Worker {
2554*8975f5c5SAndroid Build Coastguard Worker GLint *dest = boolParams + (i * 4);
2555*8975f5c5SAndroid Build Coastguard Worker const T *source = v + (i * components);
2556*8975f5c5SAndroid Build Coastguard Worker
2557*8975f5c5SAndroid Build Coastguard Worker for (int c = 0; c < components; c++)
2558*8975f5c5SAndroid Build Coastguard Worker {
2559*8975f5c5SAndroid Build Coastguard Worker dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
2560*8975f5c5SAndroid Build Coastguard Worker }
2561*8975f5c5SAndroid Build Coastguard Worker }
2562*8975f5c5SAndroid Build Coastguard Worker }
2563*8975f5c5SAndroid Build Coastguard Worker }
2564*8975f5c5SAndroid Build Coastguard Worker
2565*8975f5c5SAndroid Build Coastguard Worker template <typename T>
setUniformInternal(GLint location,GLsizei count,const T * v,GLenum uniformType)2566*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformInternal(GLint location,
2567*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2568*8975f5c5SAndroid Build Coastguard Worker const T *v,
2569*8975f5c5SAndroid Build Coastguard Worker GLenum uniformType)
2570*8975f5c5SAndroid Build Coastguard Worker {
2571*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = mExecutable->getUniformLocations()[location];
2572*8975f5c5SAndroid Build Coastguard Worker D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
2573*8975f5c5SAndroid Build Coastguard Worker
2574*8975f5c5SAndroid Build Coastguard Worker if (targetUniform->typeInfo.isSampler)
2575*8975f5c5SAndroid Build Coastguard Worker {
2576*8975f5c5SAndroid Build Coastguard Worker ASSERT(uniformType == GL_INT);
2577*8975f5c5SAndroid Build Coastguard Worker size_t size = count * sizeof(T);
2578*8975f5c5SAndroid Build Coastguard Worker GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex];
2579*8975f5c5SAndroid Build Coastguard Worker if (memcmp(dest, v, size) != 0)
2580*8975f5c5SAndroid Build Coastguard Worker {
2581*8975f5c5SAndroid Build Coastguard Worker memcpy(dest, v, size);
2582*8975f5c5SAndroid Build Coastguard Worker mDirtySamplerMapping = true;
2583*8975f5c5SAndroid Build Coastguard Worker }
2584*8975f5c5SAndroid Build Coastguard Worker return;
2585*8975f5c5SAndroid Build Coastguard Worker }
2586*8975f5c5SAndroid Build Coastguard Worker
2587*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
2588*8975f5c5SAndroid Build Coastguard Worker {
2589*8975f5c5SAndroid Build Coastguard Worker uint8_t *targetState = targetUniform->mShaderData[shaderType];
2590*8975f5c5SAndroid Build Coastguard Worker if (targetState)
2591*8975f5c5SAndroid Build Coastguard Worker {
2592*8975f5c5SAndroid Build Coastguard Worker setUniformImpl(targetUniform, locationInfo, count, v, targetState, uniformType);
2593*8975f5c5SAndroid Build Coastguard Worker mShaderUniformsDirty.set(shaderType);
2594*8975f5c5SAndroid Build Coastguard Worker }
2595*8975f5c5SAndroid Build Coastguard Worker }
2596*8975f5c5SAndroid Build Coastguard Worker }
2597*8975f5c5SAndroid Build Coastguard Worker
2598*8975f5c5SAndroid Build Coastguard Worker template <int cols, int rows>
setUniformMatrixfvInternal(GLint location,GLsizei countIn,GLboolean transpose,const GLfloat * value)2599*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::setUniformMatrixfvInternal(GLint location,
2600*8975f5c5SAndroid Build Coastguard Worker GLsizei countIn,
2601*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose,
2602*8975f5c5SAndroid Build Coastguard Worker const GLfloat *value)
2603*8975f5c5SAndroid Build Coastguard Worker {
2604*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &uniformLocation = mExecutable->getUniformLocations()[location];
2605*8975f5c5SAndroid Build Coastguard Worker D3DUniform *targetUniform = getD3DUniformFromLocation(uniformLocation);
2606*8975f5c5SAndroid Build Coastguard Worker unsigned int arrayElementOffset = uniformLocation.arrayIndex;
2607*8975f5c5SAndroid Build Coastguard Worker unsigned int elementCount = targetUniform->getArraySizeProduct();
2608*8975f5c5SAndroid Build Coastguard Worker
2609*8975f5c5SAndroid Build Coastguard Worker for (gl::ShaderType shaderType : gl::AllShaderTypes())
2610*8975f5c5SAndroid Build Coastguard Worker {
2611*8975f5c5SAndroid Build Coastguard Worker if (targetUniform->mShaderData[shaderType])
2612*8975f5c5SAndroid Build Coastguard Worker {
2613*8975f5c5SAndroid Build Coastguard Worker SetFloatUniformMatrixHLSL<cols, rows>::Run(arrayElementOffset, elementCount, countIn,
2614*8975f5c5SAndroid Build Coastguard Worker transpose, value,
2615*8975f5c5SAndroid Build Coastguard Worker targetUniform->mShaderData[shaderType]);
2616*8975f5c5SAndroid Build Coastguard Worker mShaderUniformsDirty.set(shaderType);
2617*8975f5c5SAndroid Build Coastguard Worker }
2618*8975f5c5SAndroid Build Coastguard Worker }
2619*8975f5c5SAndroid Build Coastguard Worker }
2620*8975f5c5SAndroid Build Coastguard Worker
2621*8975f5c5SAndroid Build Coastguard Worker template <typename DestT>
getUniformInternal(GLint location,DestT * dataOut) const2622*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::getUniformInternal(GLint location, DestT *dataOut) const
2623*8975f5c5SAndroid Build Coastguard Worker {
2624*8975f5c5SAndroid Build Coastguard Worker const gl::VariableLocation &locationInfo = mExecutable->getUniformLocations()[location];
2625*8975f5c5SAndroid Build Coastguard Worker const gl::LinkedUniform &uniform = mExecutable->getUniforms()[locationInfo.index];
2626*8975f5c5SAndroid Build Coastguard Worker
2627*8975f5c5SAndroid Build Coastguard Worker const D3DUniform *targetUniform = getD3DUniformFromLocation(locationInfo);
2628*8975f5c5SAndroid Build Coastguard Worker const uint8_t *srcPointer = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
2629*8975f5c5SAndroid Build Coastguard Worker
2630*8975f5c5SAndroid Build Coastguard Worker if (gl::IsMatrixType(uniform.getType()))
2631*8975f5c5SAndroid Build Coastguard Worker {
2632*8975f5c5SAndroid Build Coastguard Worker GetMatrixUniform(uniform.getType(), dataOut, reinterpret_cast<const DestT *>(srcPointer),
2633*8975f5c5SAndroid Build Coastguard Worker true);
2634*8975f5c5SAndroid Build Coastguard Worker }
2635*8975f5c5SAndroid Build Coastguard Worker else
2636*8975f5c5SAndroid Build Coastguard Worker {
2637*8975f5c5SAndroid Build Coastguard Worker memcpy(dataOut, srcPointer, uniform.getElementSize());
2638*8975f5c5SAndroid Build Coastguard Worker }
2639*8975f5c5SAndroid Build Coastguard Worker }
2640*8975f5c5SAndroid Build Coastguard Worker
getUniformfv(const gl::Context * context,GLint location,GLfloat * params) const2641*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::getUniformfv(const gl::Context *context,
2642*8975f5c5SAndroid Build Coastguard Worker GLint location,
2643*8975f5c5SAndroid Build Coastguard Worker GLfloat *params) const
2644*8975f5c5SAndroid Build Coastguard Worker {
2645*8975f5c5SAndroid Build Coastguard Worker getUniformInternal(location, params);
2646*8975f5c5SAndroid Build Coastguard Worker }
2647*8975f5c5SAndroid Build Coastguard Worker
getUniformiv(const gl::Context * context,GLint location,GLint * params) const2648*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::getUniformiv(const gl::Context *context,
2649*8975f5c5SAndroid Build Coastguard Worker GLint location,
2650*8975f5c5SAndroid Build Coastguard Worker GLint *params) const
2651*8975f5c5SAndroid Build Coastguard Worker {
2652*8975f5c5SAndroid Build Coastguard Worker getUniformInternal(location, params);
2653*8975f5c5SAndroid Build Coastguard Worker }
2654*8975f5c5SAndroid Build Coastguard Worker
getUniformuiv(const gl::Context * context,GLint location,GLuint * params) const2655*8975f5c5SAndroid Build Coastguard Worker void ProgramExecutableD3D::getUniformuiv(const gl::Context *context,
2656*8975f5c5SAndroid Build Coastguard Worker GLint location,
2657*8975f5c5SAndroid Build Coastguard Worker GLuint *params) const
2658*8975f5c5SAndroid Build Coastguard Worker {
2659*8975f5c5SAndroid Build Coastguard Worker getUniformInternal(location, params);
2660*8975f5c5SAndroid Build Coastguard Worker }
2661*8975f5c5SAndroid Build Coastguard Worker
2662*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
2663