blob: 2983c1917fcb4776a83d9b963a02356feb4e2780 [file] [log] [blame]
Brandon Jonesc9610c52014-08-25 17:02:59 -07001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/renderer/d3d/ProgramD3D.h"
Jamie Madill437d2662014-12-05 14:23:35 -050010
Jamie Madill20e005b2017-04-07 14:19:22 -040011#include "common/bitset_utils.h"
Olli Etuahod2551232017-10-26 20:03:33 +030012#include "common/string_utils.h"
Jamie Madill437d2662014-12-05 14:23:35 -050013#include "common/utilities.h"
Jamie Madillc564c072017-06-01 12:45:42 -040014#include "libANGLE/Context.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/Framebuffer.h"
16#include "libANGLE/FramebufferAttachment.h"
17#include "libANGLE/Program.h"
Jamie Madill7af0de52017-11-06 17:09:33 -050018#include "libANGLE/ProgramLinkedResources.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040019#include "libANGLE/Uniform.h"
Jamie Madilld3dfda22015-07-06 08:28:49 -040020#include "libANGLE/VertexArray.h"
Jamie Madill6df9b372015-02-18 21:28:19 +000021#include "libANGLE/features.h"
Jamie Madill54164b02017-08-28 15:17:37 -040022#include "libANGLE/queryconversions.h"
Jamie Madill8ecf7f92017-01-13 17:29:52 -050023#include "libANGLE/renderer/ContextImpl.h"
Jamie Madill785e8a02018-10-04 17:42:00 -040024#include "libANGLE/renderer/d3d/ContextD3D.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050025#include "libANGLE/renderer/d3d/DynamicHLSL.h"
Jamie Madill85a18042015-03-05 15:41:41 -050026#include "libANGLE/renderer/d3d/FramebufferD3D.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050027#include "libANGLE/renderer/d3d/ShaderD3D.h"
Geoff Lang359ef262015-01-05 14:42:29 -050028#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
Jamie Madill437d2662014-12-05 14:23:35 -050029#include "libANGLE/renderer/d3d/VertexDataManager.h"
Luc Ferron46bcea52018-05-31 09:48:36 -040030#include "libANGLE/renderer/renderer_utils.h"
Geoff Lang22072132014-11-20 15:15:01 -050031
Jamie Madill01074252016-11-28 15:55:51 -050032using namespace angle;
33
Brandon Jonesc9610c52014-08-25 17:02:59 -070034namespace rx
35{
36
Brandon Joneseb994362014-09-24 10:27:28 -070037namespace
38{
39
jchen103fd614d2018-08-13 12:21:58 +080040void GetDefaultInputLayoutFromShader(gl::Shader *vertexShader, gl::InputLayout *inputLayoutOut)
Brandon Joneseb994362014-09-24 10:27:28 -070041{
Jamie Madill4c19a8a2017-07-24 11:46:06 -040042 inputLayoutOut->clear();
43
jchen103fd614d2018-08-13 12:21:58 +080044 for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes())
Brandon Joneseb994362014-09-24 10:27:28 -070045 {
Brandon Joneseb994362014-09-24 10:27:28 -070046 if (shaderAttr.type != GL_NONE)
47 {
48 GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
49
Jamie Madilld3dfda22015-07-06 08:28:49 -040050 for (size_t rowIndex = 0;
Jamie Madill334d6152015-10-22 14:00:28 -040051 static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex)
Brandon Joneseb994362014-09-24 10:27:28 -070052 {
Jamie Madilld3dfda22015-07-06 08:28:49 -040053 GLenum componentType = gl::VariableComponentType(transposedType);
Jamie Madill334d6152015-10-22 14:00:28 -040054 GLuint components = static_cast<GLuint>(gl::VariableColumnCount(transposedType));
Xinghua Cao26143fd2017-11-01 18:19:05 +080055 bool pureInt = (componentType != GL_FLOAT);
Frank Henigmand633b152018-10-04 23:34:31 -040056 angle::FormatID defaultID =
57 gl::GetVertexFormatID(componentType, GL_FALSE, components, pureInt);
Brandon Joneseb994362014-09-24 10:27:28 -070058
Frank Henigmand633b152018-10-04 23:34:31 -040059 inputLayoutOut->push_back(defaultID);
Brandon Joneseb994362014-09-24 10:27:28 -070060 }
61 }
62 }
63}
64
Jamie Madill4c19a8a2017-07-24 11:46:06 -040065void GetDefaultOutputLayoutFromShader(
66 const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
67 std::vector<GLenum> *outputLayoutOut)
Brandon Joneseb994362014-09-24 10:27:28 -070068{
Jamie Madill4c19a8a2017-07-24 11:46:06 -040069 outputLayoutOut->clear();
Brandon Joneseb994362014-09-24 10:27:28 -070070
Jamie Madillb4463142014-12-19 14:56:54 -050071 if (!shaderOutputVars.empty())
72 {
Jamie Madill4c19a8a2017-07-24 11:46:06 -040073 outputLayoutOut->push_back(GL_COLOR_ATTACHMENT0 +
74 static_cast<unsigned int>(shaderOutputVars[0].outputIndex));
Jamie Madillb4463142014-12-19 14:56:54 -050075 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -040076}
Brandon Joneseb994362014-09-24 10:27:28 -070077
Xinghua Caof3179a62018-07-12 16:22:06 +080078void GetDefaultImage2DBindLayoutFromComputeShader(const std::vector<sh::Uniform> &image2DUniforms,
79 gl::ImageUnitTextureTypeMap *image2DBindLayout)
80{
81 image2DBindLayout->clear();
82
83 for (const sh::Uniform &image2D : image2DUniforms)
84 {
85 if (gl::IsImage2DType(image2D.type))
86 {
87 if (image2D.binding == -1)
88 {
89 image2DBindLayout->insert(std::make_pair(0, gl::TextureType::_2D));
90 }
91 else
92 {
93 for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++)
94 {
95 image2DBindLayout->insert(
96 std::make_pair(image2D.binding + index, gl::TextureType::_2D));
97 }
98 }
99 }
100 }
101}
102
Jamie Madill04796cd2018-05-24 19:52:16 -0400103gl::PrimitiveMode GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode)
Jamie Madill4e31ad52015-10-29 10:32:57 -0400104{
105 switch (drawMode)
106 {
107 // Uses the point sprite geometry shader.
Jamie Madill493f9572018-05-24 19:52:15 -0400108 case gl::PrimitiveMode::Points:
Jamie Madill04796cd2018-05-24 19:52:16 -0400109 return gl::PrimitiveMode::Points;
Jamie Madill4e31ad52015-10-29 10:32:57 -0400110
111 // All line drawing uses the same geometry shader.
Jamie Madill493f9572018-05-24 19:52:15 -0400112 case gl::PrimitiveMode::Lines:
113 case gl::PrimitiveMode::LineStrip:
114 case gl::PrimitiveMode::LineLoop:
Jamie Madill04796cd2018-05-24 19:52:16 -0400115 return gl::PrimitiveMode::Lines;
Jamie Madill4e31ad52015-10-29 10:32:57 -0400116
117 // The triangle fan primitive is emulated with strips in D3D11.
Jamie Madill493f9572018-05-24 19:52:15 -0400118 case gl::PrimitiveMode::Triangles:
119 case gl::PrimitiveMode::TriangleFan:
Jamie Madill04796cd2018-05-24 19:52:16 -0400120 return gl::PrimitiveMode::Triangles;
Jamie Madill4e31ad52015-10-29 10:32:57 -0400121
122 // Special case for triangle strips.
Jamie Madill493f9572018-05-24 19:52:15 -0400123 case gl::PrimitiveMode::TriangleStrip:
Jamie Madill04796cd2018-05-24 19:52:16 -0400124 return gl::PrimitiveMode::TriangleStrip;
Jamie Madill4e31ad52015-10-29 10:32:57 -0400125
126 default:
127 UNREACHABLE();
Jamie Madill04796cd2018-05-24 19:52:16 -0400128 return gl::PrimitiveMode::InvalidEnum;
Jamie Madill4e31ad52015-10-29 10:32:57 -0400129 }
130}
131
Jiawei Shao467c15f2018-04-24 15:04:26 +0800132bool HasFlatInterpolationVarying(const std::vector<sh::Varying> &varyings)
Jamie Madill192745a2016-12-22 15:58:21 -0500133{
134 // Note: this assumes nested structs can only be packed with one interpolation.
135 for (const auto &varying : varyings)
136 {
137 if (varying.interpolation == sh::INTERPOLATION_FLAT)
138 {
139 return true;
140 }
141 }
142
143 return false;
144}
145
jchen103fd614d2018-08-13 12:21:58 +0800146bool FindFlatInterpolationVaryingPerShader(gl::Shader *shader)
Jiawei Shao467c15f2018-04-24 15:04:26 +0800147{
jchen103fd614d2018-08-13 12:21:58 +0800148 ASSERT(shader);
Jiawei Shao467c15f2018-04-24 15:04:26 +0800149 switch (shader->getType())
150 {
151 case gl::ShaderType::Vertex:
jchen103fd614d2018-08-13 12:21:58 +0800152 return HasFlatInterpolationVarying(shader->getOutputVaryings());
Jiawei Shao467c15f2018-04-24 15:04:26 +0800153 case gl::ShaderType::Fragment:
jchen103fd614d2018-08-13 12:21:58 +0800154 return HasFlatInterpolationVarying(shader->getInputVaryings());
Jiawei Shao467c15f2018-04-24 15:04:26 +0800155 case gl::ShaderType::Geometry:
jchen103fd614d2018-08-13 12:21:58 +0800156 return HasFlatInterpolationVarying(shader->getInputVaryings()) ||
157 HasFlatInterpolationVarying(shader->getOutputVaryings());
Jiawei Shao467c15f2018-04-24 15:04:26 +0800158 default:
159 UNREACHABLE();
160 return false;
161 }
162}
163
jchen103fd614d2018-08-13 12:21:58 +0800164bool FindFlatInterpolationVarying(const gl::ShaderMap<gl::Shader *> &shaders)
Jiawei Shao467c15f2018-04-24 15:04:26 +0800165{
Jiawei Shao467c15f2018-04-24 15:04:26 +0800166 for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
167 {
168 gl::Shader *shader = shaders[shaderType];
169 if (!shader)
170 {
171 continue;
172 }
173
jchen103fd614d2018-08-13 12:21:58 +0800174 if (FindFlatInterpolationVaryingPerShader(shader))
Jiawei Shao467c15f2018-04-24 15:04:26 +0800175 {
176 return true;
177 }
178 }
179
180 return false;
181}
182
Qin Jiajia3026f112018-10-09 12:13:38 +0800183class InterfaceBlockInfo final : angle::NonCopyable
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500184{
185 public:
Qin Jiajia3026f112018-10-09 12:13:38 +0800186 InterfaceBlockInfo() {}
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500187
Qin Jiajia3026f112018-10-09 12:13:38 +0800188 void getShaderBlockInfo(const std::vector<sh::InterfaceBlock> &interfaceBlocks);
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500189
190 bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut);
191 bool getBlockMemberInfo(const std::string &name,
192 const std::string &mappedName,
193 sh::BlockMemberInfo *infoOut);
194
195 private:
196 size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock);
197
198 std::map<std::string, size_t> mBlockSizes;
199 sh::BlockLayoutMap mBlockLayout;
200};
201
Qin Jiajia3026f112018-10-09 12:13:38 +0800202void InterfaceBlockInfo::getShaderBlockInfo(const std::vector<sh::InterfaceBlock> &interfaceBlocks)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500203{
Qin Jiajia3026f112018-10-09 12:13:38 +0800204 for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500205 {
Olli Etuaho107c7242018-03-20 15:45:35 +0200206 if (!interfaceBlock.active && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500207 continue;
208
209 if (mBlockSizes.count(interfaceBlock.name) > 0)
210 continue;
211
212 size_t dataSize = getBlockInfo(interfaceBlock);
213 mBlockSizes[interfaceBlock.name] = dataSize;
214 }
215}
216
Qin Jiajia3026f112018-10-09 12:13:38 +0800217size_t InterfaceBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500218{
Olli Etuaho107c7242018-03-20 15:45:35 +0200219 ASSERT(interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED);
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500220
221 // define member uniforms
222 sh::Std140BlockEncoder std140Encoder;
Qin Jiajia5df1d282019-01-04 14:22:59 +0800223 sh::Std430BlockEncoder std430Encoder;
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500224 sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
225 sh::BlockLayoutEncoder *encoder = nullptr;
226
227 if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
228 {
229 encoder = &std140Encoder;
230 }
Qin Jiajia5df1d282019-01-04 14:22:59 +0800231 else if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD430)
232 {
233 encoder = &std430Encoder;
234 }
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500235 else
236 {
237 encoder = &hlslEncoder;
238 }
239
Qin Jiajia3026f112018-10-09 12:13:38 +0800240 sh::GetInterfaceBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
241 &mBlockLayout);
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500242
Jamie Madill4e712be2019-01-03 13:53:59 -0500243 return encoder->getCurrentOffset();
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500244}
245
Qin Jiajia3026f112018-10-09 12:13:38 +0800246bool InterfaceBlockInfo::getBlockSize(const std::string &name,
247 const std::string &mappedName,
248 size_t *sizeOut)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500249{
250 size_t nameLengthWithoutArrayIndex;
251 gl::ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
252 std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
253 auto sizeIter = mBlockSizes.find(baseName);
254 if (sizeIter == mBlockSizes.end())
255 {
256 *sizeOut = 0;
257 return false;
258 }
259
260 *sizeOut = sizeIter->second;
261 return true;
262};
263
Qin Jiajia3026f112018-10-09 12:13:38 +0800264bool InterfaceBlockInfo::getBlockMemberInfo(const std::string &name,
265 const std::string &mappedName,
266 sh::BlockMemberInfo *infoOut)
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500267{
268 auto infoIter = mBlockLayout.find(name);
269 if (infoIter == mBlockLayout.end())
270 {
Jamie Madill04ea03e2019-01-01 15:14:25 -0500271 *infoOut = sh::kDefaultBlockMemberInfo;
Jamie Madill6db1c2e2017-11-08 09:17:40 -0500272 return false;
273 }
274
275 *infoOut = infoIter->second;
276 return true;
277};
Jamie Madill8c78ce42018-12-16 19:14:58 -0500278
279// Helper class that gathers uniform info from the default uniform block.
280class UniformEncodingVisitorD3D : public sh::BlockEncoderVisitor
281{
282 public:
283 UniformEncodingVisitorD3D(gl::ShaderType shaderType,
284 HLSLRegisterType registerType,
285 sh::BlockLayoutEncoder *encoder,
286 D3DUniformMap *uniformMapOut)
287 : sh::BlockEncoderVisitor("", "", encoder),
288 mShaderType(shaderType),
289 mRegisterType(registerType),
290 mUniformMapOut(uniformMapOut)
291 {}
292
293 void visitNamedSampler(const sh::ShaderVariable &sampler,
294 const std::string &name,
295 const std::string &mappedName) override
296 {
297 auto uniformMapEntry = mUniformMapOut->find(name);
298 if (uniformMapEntry == mUniformMapOut->end())
299 {
300 (*mUniformMapOut)[name] =
301 new D3DUniform(sampler.type, mRegisterType, name, sampler.arraySizes, true);
302 }
303 }
304
305 void encodeVariable(const sh::ShaderVariable &variable,
306 const sh::BlockMemberInfo &variableInfo,
307 const std::string &name,
308 const std::string &mappedName) override
309 {
310 auto uniformMapEntry = mUniformMapOut->find(name);
311 D3DUniform *d3dUniform = nullptr;
312
313 if (uniformMapEntry != mUniformMapOut->end())
314 {
315 d3dUniform = uniformMapEntry->second;
316 }
317 else
318 {
319 d3dUniform =
320 new D3DUniform(variable.type, mRegisterType, name, variable.arraySizes, true);
321 (*mUniformMapOut)[name] = d3dUniform;
322 }
323
324 d3dUniform->registerElement = static_cast<unsigned int>(
325 sh::BlockLayoutEncoder::GetBlockRegisterElement(variableInfo));
326 unsigned int reg =
327 static_cast<unsigned int>(sh::BlockLayoutEncoder::GetBlockRegister(variableInfo));
328
329 ASSERT(mShaderType != gl::ShaderType::InvalidEnum);
330 d3dUniform->mShaderRegisterIndexes[mShaderType] = reg;
331 }
332
333 private:
334 gl::ShaderType mShaderType;
335 HLSLRegisterType mRegisterType;
336 D3DUniformMap *mUniformMapOut;
337};
Jamie Madillada9ecc2015-08-17 12:53:37 -0400338} // anonymous namespace
339
Jamie Madill28afae52015-11-09 15:07:57 -0500340// D3DUniform Implementation
341
Jamie Madill33bb7c42017-09-09 23:32:51 -0400342D3DUniform::D3DUniform(GLenum type,
Xinghua Cao26143fd2017-11-01 18:19:05 +0800343 HLSLRegisterType reg,
Jamie Madill62d31cb2015-09-11 13:25:51 -0400344 const std::string &nameIn,
Olli Etuaho465835d2017-09-26 13:34:10 +0300345 const std::vector<unsigned int> &arraySizesIn,
Jamie Madill62d31cb2015-09-11 13:25:51 -0400346 bool defaultBlock)
Jamie Madill33bb7c42017-09-09 23:32:51 -0400347 : typeInfo(gl::GetUniformTypeInfo(type)),
Jamie Madill62d31cb2015-09-11 13:25:51 -0400348 name(nameIn),
Olli Etuaho465835d2017-09-26 13:34:10 +0300349 arraySizes(arraySizesIn),
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800350 mShaderData({}),
Xinghua Cao26143fd2017-11-01 18:19:05 +0800351 regType(reg),
Jamie Madill62d31cb2015-09-11 13:25:51 -0400352 registerCount(0),
353 registerElement(0)
354{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800355 mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
356
Jamie Madill62d31cb2015-09-11 13:25:51 -0400357 // We use data storage for default block uniforms to cache values that are sent to D3D during
358 // rendering
359 // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
360 if (defaultBlock)
361 {
Jamie Madillcc2ed612017-03-14 15:59:00 -0400362 // Use the row count as register count, will work for non-square matrices.
Olli Etuaho465835d2017-09-26 13:34:10 +0300363 registerCount = typeInfo.rowCount * getArraySizeProduct();
Jamie Madill62d31cb2015-09-11 13:25:51 -0400364 }
365}
366
Jamie Madillb980c562018-11-27 11:34:27 -0500367D3DUniform::~D3DUniform() {}
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400368
Olli Etuaho465835d2017-09-26 13:34:10 +0300369unsigned int D3DUniform::getArraySizeProduct() const
370{
371 return gl::ArraySizeProduct(arraySizes);
372}
373
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400374const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const
375{
Olli Etuaho465835d2017-09-26 13:34:10 +0300376 ASSERT((!isArray() && elementIndex == 0) ||
377 (isArray() && elementIndex < getArraySizeProduct()));
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400378
379 if (isSampler())
380 {
381 return reinterpret_cast<const uint8_t *>(&mSamplerData[elementIndex]);
382 }
383
Jamie Madill33bb7c42017-09-09 23:32:51 -0400384 return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400385}
386
387bool D3DUniform::isSampler() const
388{
Jamie Madill33bb7c42017-09-09 23:32:51 -0400389 return typeInfo.isSampler;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400390}
391
Xinghua Cao26143fd2017-11-01 18:19:05 +0800392bool D3DUniform::isImage() const
393{
394 return typeInfo.isImageType;
395}
396
Xinghua Caof3179a62018-07-12 16:22:06 +0800397bool D3DUniform::isImage2D() const
398{
399 return gl::IsImage2DType(typeInfo.type);
400}
401
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800402bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const
Jamie Madill62d31cb2015-09-11 13:25:51 -0400403{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800404 return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
Xinghua Caob1239382016-12-13 15:07:05 +0800405}
406
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400407const uint8_t *D3DUniform::firstNonNullData() const
408{
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400409 if (!mSamplerData.empty())
410 {
411 return reinterpret_cast<const uint8_t *>(mSamplerData.data());
412 }
413
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800414 for (gl::ShaderType shaderType : gl::AllShaderTypes())
415 {
416 if (mShaderData[shaderType])
417 {
418 return mShaderData[shaderType];
419 }
420 }
421
422 UNREACHABLE();
423 return nullptr;
Jamie Madillbe5e2ec2017-08-31 13:28:28 -0400424}
425
Jamie Madill28afae52015-11-09 15:07:57 -0500426// D3DVarying Implementation
427
Jamie Madillb980c562018-11-27 11:34:27 -0500428D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {}
Jamie Madill28afae52015-11-09 15:07:57 -0500429
Jamie Madill9fc36822015-11-18 13:08:07 -0500430D3DVarying::D3DVarying(const std::string &semanticNameIn,
431 unsigned int semanticIndexIn,
432 unsigned int componentCountIn,
433 unsigned int outputSlotIn)
434 : semanticName(semanticNameIn),
435 semanticIndex(semanticIndexIn),
436 componentCount(componentCountIn),
437 outputSlot(outputSlotIn)
Jamie Madillb980c562018-11-27 11:34:27 -0500438{}
Jamie Madill28afae52015-11-09 15:07:57 -0500439
Jamie Madille39a3f02015-11-17 20:42:15 -0500440// ProgramD3DMetadata Implementation
441
Jamie Madillc9bde922016-07-24 17:58:50 -0400442ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800443 const gl::ShaderMap<const ShaderD3D *> &attachedShaders)
Jamie Madillc9bde922016-07-24 17:58:50 -0400444 : mRendererMajorShaderModel(renderer->getMajorShaderModel()),
445 mShaderModelSuffix(renderer->getShaderModelSuffix()),
446 mUsesInstancedPointSpriteEmulation(
447 renderer->getWorkarounds().useInstancedPointSpriteEmulation),
448 mUsesViewScale(renderer->presentPathFastEnabled()),
Martin Radevc1d4e552017-08-21 12:01:10 +0300449 mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800450 mAttachedShaders(attachedShaders)
Jamie Madillb980c562018-11-27 11:34:27 -0500451{}
Jamie Madille39a3f02015-11-17 20:42:15 -0500452
453int ProgramD3DMetadata::getRendererMajorShaderModel() const
454{
455 return mRendererMajorShaderModel;
456}
457
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500458bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const
Jamie Madille39a3f02015-11-17 20:42:15 -0500459{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800460 return (mAttachedShaders[gl::ShaderType::Fragment]->usesFragColor() &&
461 mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets() &&
Corentin Wallezc084de12017-06-05 14:28:52 -0700462 data.getClientMajorVersion() < 3);
Jamie Madille39a3f02015-11-17 20:42:15 -0500463}
464
Jamie Madill48ef11b2016-04-27 15:21:52 -0400465bool ProgramD3DMetadata::usesFragDepth() const
Jamie Madille39a3f02015-11-17 20:42:15 -0500466{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800467 return mAttachedShaders[gl::ShaderType::Fragment]->usesFragDepth();
Jamie Madille39a3f02015-11-17 20:42:15 -0500468}
469
470bool ProgramD3DMetadata::usesPointCoord() const
471{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800472 return mAttachedShaders[gl::ShaderType::Fragment]->usesPointCoord();
Jamie Madille39a3f02015-11-17 20:42:15 -0500473}
474
475bool ProgramD3DMetadata::usesFragCoord() const
476{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800477 return mAttachedShaders[gl::ShaderType::Fragment]->usesFragCoord();
Jamie Madille39a3f02015-11-17 20:42:15 -0500478}
479
480bool ProgramD3DMetadata::usesPointSize() const
481{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800482 return mAttachedShaders[gl::ShaderType::Vertex]->usesPointSize();
Jamie Madille39a3f02015-11-17 20:42:15 -0500483}
484
485bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
486{
Jamie Madillc9bde922016-07-24 17:58:50 -0400487 return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() &&
488 mRendererMajorShaderModel >= 4;
Jamie Madille39a3f02015-11-17 20:42:15 -0500489}
490
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800491bool ProgramD3DMetadata::usesViewScale() const
492{
493 return mUsesViewScale;
494}
495
Martin Radev41ac68e2017-06-06 12:16:58 +0300496bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
497{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800498 return mAttachedShaders[gl::ShaderType::Vertex]->hasANGLEMultiviewEnabled();
Martin Radev41ac68e2017-06-06 12:16:58 +0300499}
500
501bool ProgramD3DMetadata::usesViewID() const
502{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800503 return mAttachedShaders[gl::ShaderType::Fragment]->usesViewID();
Martin Radev41ac68e2017-06-06 12:16:58 +0300504}
505
Martin Radevc1d4e552017-08-21 12:01:10 +0300506bool ProgramD3DMetadata::canSelectViewInVertexShader() const
507{
508 return mCanSelectViewInVertexShader;
509}
510
Jamie Madille39a3f02015-11-17 20:42:15 -0500511bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
512{
Jamie Madillc9bde922016-07-24 17:58:50 -0400513 // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader
Jamie Madille39a3f02015-11-17 20:42:15 -0500514 // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader.
Jamie Madillc9bde922016-07-24 17:58:50 -0400515 // Even with a geometry shader, the app can render triangles or lines and reference
516 // gl_PointCoord in the fragment shader, requiring us to provide a dummy value. For
517 // simplicity, we always add this to the vertex shader when the fragment shader
518 // references gl_PointCoord, even if we could skip it in the geometry shader.
Jamie Madille39a3f02015-11-17 20:42:15 -0500519 return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) ||
520 usesInsertedPointCoordValue();
521}
522
523bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
524{
525 // gl_Position only needs to be outputted from the vertex shader if transform feedback is
526 // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from
527 // the vertex shader in this case. This saves us 1 output vector.
528 return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != "");
529}
530
531bool ProgramD3DMetadata::usesSystemValuePointSize() const
532{
533 return !mUsesInstancedPointSpriteEmulation && usesPointSize();
534}
535
536bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
537{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800538 return mAttachedShaders[gl::ShaderType::Fragment]->usesMultipleRenderTargets();
Jamie Madille39a3f02015-11-17 20:42:15 -0500539}
540
541GLint ProgramD3DMetadata::getMajorShaderVersion() const
542{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800543 return mAttachedShaders[gl::ShaderType::Vertex]->getData().getShaderVersion();
Jamie Madille39a3f02015-11-17 20:42:15 -0500544}
545
546const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const
547{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800548 return mAttachedShaders[gl::ShaderType::Fragment];
Jamie Madille39a3f02015-11-17 20:42:15 -0500549}
550
Jamie Madill28afae52015-11-09 15:07:57 -0500551// ProgramD3D Implementation
552
Jamie Madilld3dfda22015-07-06 08:28:49 -0400553ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
554 const Signature &signature,
Geoff Lang359ef262015-01-05 14:42:29 -0500555 ShaderExecutableD3D *shaderExecutable)
Jamie Madill334d6152015-10-22 14:00:28 -0400556 : mInputs(inputLayout), mSignature(signature), mShaderExecutable(shaderExecutable)
Jamie Madillb980c562018-11-27 11:34:27 -0500557{}
Brandon Joneseb994362014-09-24 10:27:28 -0700558
559ProgramD3D::VertexExecutable::~VertexExecutable()
560{
561 SafeDelete(mShaderExecutable);
562}
563
Jamie Madilld3dfda22015-07-06 08:28:49 -0400564// static
Jamie Madillbdec2f42016-03-02 16:35:32 -0500565ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType(
566 GLenum type)
567{
568 switch (type)
569 {
570 case GL_INT:
571 return HLSLAttribType::SIGNED_INT;
572 case GL_UNSIGNED_INT:
573 return HLSLAttribType::UNSIGNED_INT;
574 case GL_SIGNED_NORMALIZED:
575 case GL_UNSIGNED_NORMALIZED:
576 case GL_FLOAT:
577 return HLSLAttribType::FLOAT;
578 default:
579 UNREACHABLE();
580 return HLSLAttribType::FLOAT;
581 }
582}
583
584// static
Jamie Madilld3dfda22015-07-06 08:28:49 -0400585void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer,
586 const gl::InputLayout &inputLayout,
587 Signature *signatureOut)
Brandon Joneseb994362014-09-24 10:27:28 -0700588{
Jamie Madillbdec2f42016-03-02 16:35:32 -0500589 signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT);
Jamie Madilld3dfda22015-07-06 08:28:49 -0400590
591 for (size_t index = 0; index < inputLayout.size(); ++index)
Brandon Joneseb994362014-09-24 10:27:28 -0700592 {
Frank Henigmand633b152018-10-04 23:34:31 -0400593 angle::FormatID vertexFormatID = inputLayout[index];
594 if (vertexFormatID == angle::FormatID::NONE)
Jamie Madillbdec2f42016-03-02 16:35:32 -0500595 continue;
Jamie Madillbd136f92015-08-10 14:51:37 -0400596
Frank Henigmand633b152018-10-04 23:34:31 -0400597 VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatID);
Jamie Madillbdec2f42016-03-02 16:35:32 -0500598 if ((conversionType & VERTEX_CONVERT_GPU) == 0)
599 continue;
600
Frank Henigmand633b152018-10-04 23:34:31 -0400601 GLenum componentType = renderer->getVertexComponentType(vertexFormatID);
Jamie Madillbdec2f42016-03-02 16:35:32 -0500602 (*signatureOut)[index] = GetAttribType(componentType);
Brandon Joneseb994362014-09-24 10:27:28 -0700603 }
Brandon Joneseb994362014-09-24 10:27:28 -0700604}
605
Jamie Madilld3dfda22015-07-06 08:28:49 -0400606bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) const
607{
Jamie Madillbd136f92015-08-10 14:51:37 -0400608 size_t limit = std::max(mSignature.size(), signature.size());
609 for (size_t index = 0; index < limit; ++index)
610 {
Jamie Madillbdec2f42016-03-02 16:35:32 -0500611 // treat undefined indexes as FLOAT
612 auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT;
613 auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT;
Jamie Madillbd136f92015-08-10 14:51:37 -0400614 if (a != b)
615 return false;
616 }
617
618 return true;
Jamie Madilld3dfda22015-07-06 08:28:49 -0400619}
620
621ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature,
622 ShaderExecutableD3D *shaderExecutable)
Jamie Madill334d6152015-10-22 14:00:28 -0400623 : mOutputSignature(outputSignature), mShaderExecutable(shaderExecutable)
Jamie Madillb980c562018-11-27 11:34:27 -0500624{}
Brandon Joneseb994362014-09-24 10:27:28 -0700625
626ProgramD3D::PixelExecutable::~PixelExecutable()
627{
628 SafeDelete(mShaderExecutable);
629}
630
Xinghua Caof3179a62018-07-12 16:22:06 +0800631ProgramD3D::ComputeExecutable::ComputeExecutable(
632 const gl::ImageUnitTextureTypeMap &signature,
633 std::unique_ptr<ShaderExecutableD3D> shaderExecutable)
634 : mSignature(signature), mShaderExecutable(std::move(shaderExecutable))
635{}
636
637ProgramD3D::ComputeExecutable::~ComputeExecutable() {}
638
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800639ProgramD3D::Sampler::Sampler()
640 : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D)
Jamie Madillb980c562018-11-27 11:34:27 -0500641{}
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700642
Jamie Madillb980c562018-11-27 11:34:27 -0500643ProgramD3D::Image::Image() : active(false), logicalImageUnit(0) {}
Xinghua Cao26143fd2017-11-01 18:19:05 +0800644
Geoff Lang7dd2e102014-11-10 15:19:26 -0500645unsigned int ProgramD3D::mCurrentSerial = 1;
646
Jamie Madill48ef11b2016-04-27 15:21:52 -0400647ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
648 : ProgramImpl(state),
Brandon Jonesc9610c52014-08-25 17:02:59 -0700649 mRenderer(renderer),
Xinghua Caob1239382016-12-13 15:07:05 +0800650 mDynamicHLSL(nullptr),
Brandon Jones44151a92014-09-10 11:32:25 -0700651 mUsesPointSize(false),
Jamie Madill3e14e2b2015-10-29 14:38:53 -0400652 mUsesFlatInterpolation(false),
Jiawei Shao467c15f2018-04-24 15:04:26 +0800653 mUsedShaderSamplerRanges({}),
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700654 mDirtySamplerMapping(true),
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800655 mUsedComputeImageRange(0, 0),
656 mUsedComputeReadonlyImageRange(0, 0),
Jiawei Shao3dd8d2912018-03-30 09:39:09 +0800657 mSerial(issueSerial())
Brandon Jonesc9610c52014-08-25 17:02:59 -0700658{
Brandon Joneseb994362014-09-24 10:27:28 -0700659 mDynamicHLSL = new DynamicHLSL(renderer);
Brandon Jonesc9610c52014-08-25 17:02:59 -0700660}
661
662ProgramD3D::~ProgramD3D()
663{
664 reset();
665 SafeDelete(mDynamicHLSL);
666}
667
Brandon Jones44151a92014-09-10 11:32:25 -0700668bool ProgramD3D::usesPointSpriteEmulation() const
669{
670 return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
671}
672
Martin Radev41ac68e2017-06-06 12:16:58 +0300673bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
674{
675 return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
676}
677
Jamie Madill493f9572018-05-24 19:52:15 -0400678bool ProgramD3D::usesGeometryShader(gl::PrimitiveMode drawMode) const
Brandon Jones44151a92014-09-10 11:32:25 -0700679{
Martin Radevc1d4e552017-08-21 12:01:10 +0300680 if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader())
Martin Radev41ac68e2017-06-06 12:16:58 +0300681 {
682 return true;
683 }
Jamie Madill493f9572018-05-24 19:52:15 -0400684 if (drawMode != gl::PrimitiveMode::Points)
Jamie Madill3e14e2b2015-10-29 14:38:53 -0400685 {
686 return mUsesFlatInterpolation;
687 }
Martin Radev41ac68e2017-06-06 12:16:58 +0300688 return usesGeometryShaderForPointSpriteEmulation();
Cooper Partine6664f02015-01-09 16:22:24 -0800689}
690
691bool ProgramD3D::usesInstancedPointSpriteEmulation() const
692{
693 return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
Brandon Jones44151a92014-09-10 11:32:25 -0700694}
695
Xinghua Cao37584b32017-12-01 11:04:03 +0800696GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
Jamie Madill334d6152015-10-22 14:00:28 -0400697 unsigned int samplerIndex,
698 const gl::Caps &caps) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700699{
700 GLint logicalTextureUnit = -1;
701
Jiawei Shao467c15f2018-04-24 15:04:26 +0800702 ASSERT(type != gl::ShaderType::InvalidEnum);
703
Jiawei Shao54aafe52018-04-27 14:54:57 +0800704 ASSERT(samplerIndex < caps.maxShaderTextureImageUnits[type]);
Jiawei Shao467c15f2018-04-24 15:04:26 +0800705
706 const auto &samplers = mShaderSamplers[type];
707 if (samplerIndex < samplers.size() && samplers[samplerIndex].active)
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700708 {
Jiawei Shao467c15f2018-04-24 15:04:26 +0800709 logicalTextureUnit = samplers[samplerIndex].logicalTextureUnit;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700710 }
711
Jamie Madill334d6152015-10-22 14:00:28 -0400712 if (logicalTextureUnit >= 0 &&
713 logicalTextureUnit < static_cast<GLint>(caps.maxCombinedTextureImageUnits))
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700714 {
715 return logicalTextureUnit;
716 }
717
718 return -1;
719}
720
721// Returns the texture type for a given Direct3D 9 sampler type and
722// index (0-15 for the pixel shader and 0-3 for the vertex shader).
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800723gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type,
724 unsigned int samplerIndex) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700725{
Jiawei Shao467c15f2018-04-24 15:04:26 +0800726 ASSERT(type != gl::ShaderType::InvalidEnum);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700727
Jiawei Shao467c15f2018-04-24 15:04:26 +0800728 const auto &samplers = mShaderSamplers[type];
729 ASSERT(samplerIndex < samplers.size());
730 ASSERT(samplers[samplerIndex].active);
731
732 return samplers[samplerIndex].textureType;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700733}
734
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800735gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700736{
Jiawei Shao467c15f2018-04-24 15:04:26 +0800737 ASSERT(type != gl::ShaderType::InvalidEnum);
738 return mUsedShaderSamplerRanges[type];
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700739}
740
Jamie Madillaf4ffe02017-09-09 23:32:48 -0400741ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700742{
743 if (!mDirtySamplerMapping)
744 {
Jamie Madillaf4ffe02017-09-09 23:32:48 -0400745 return SamplerMapping::WasClean;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700746 }
747
748 mDirtySamplerMapping = false;
749
750 // Retrieve sampler uniform values
Jamie Madill62d31cb2015-09-11 13:25:51 -0400751 for (const D3DUniform *d3dUniform : mD3DUniforms)
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700752 {
Jamie Madill62d31cb2015-09-11 13:25:51 -0400753 if (!d3dUniform->isSampler())
754 continue;
755
Olli Etuaho465835d2017-09-26 13:34:10 +0300756 int count = d3dUniform->getArraySizeProduct();
Jamie Madill62d31cb2015-09-11 13:25:51 -0400757
Jiawei Shao467c15f2018-04-24 15:04:26 +0800758 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700759 {
Jiawei Shao467c15f2018-04-24 15:04:26 +0800760 if (!d3dUniform->isReferencedByShader(shaderType))
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700761 {
Jiawei Shao467c15f2018-04-24 15:04:26 +0800762 continue;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400763 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700764
Jiawei Shao467c15f2018-04-24 15:04:26 +0800765 unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[shaderType];
Jamie Madill62d31cb2015-09-11 13:25:51 -0400766
Jiawei Shao467c15f2018-04-24 15:04:26 +0800767 std::vector<Sampler> &samplers = mShaderSamplers[shaderType];
Jamie Madill62d31cb2015-09-11 13:25:51 -0400768 for (int i = 0; i < count; i++)
769 {
770 unsigned int samplerIndex = firstIndex + i;
771
Jiawei Shao467c15f2018-04-24 15:04:26 +0800772 if (samplerIndex < samplers.size())
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700773 {
Jiawei Shao467c15f2018-04-24 15:04:26 +0800774 ASSERT(samplers[samplerIndex].active);
775 samplers[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i];
Xinghua Caob1239382016-12-13 15:07:05 +0800776 }
777 }
778 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700779 }
Jamie Madillaf4ffe02017-09-09 23:32:48 -0400780
781 return SamplerMapping::WasDirty;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700782}
783
Xinghua Cao26143fd2017-11-01 18:19:05 +0800784GLint ProgramD3D::getImageMapping(gl::ShaderType type,
785 unsigned int imageIndex,
786 bool readonly,
787 const gl::Caps &caps) const
788{
789 GLint logicalImageUnit = -1;
790 ASSERT(imageIndex < caps.maxImageUnits);
791 switch (type)
792 {
Jiawei Shao385b3e02018-03-21 09:43:28 +0800793 case gl::ShaderType::Compute:
Xinghua Cao26143fd2017-11-01 18:19:05 +0800794 if (readonly && imageIndex < mReadonlyImagesCS.size() &&
795 mReadonlyImagesCS[imageIndex].active)
796 {
797 logicalImageUnit = mReadonlyImagesCS[imageIndex].logicalImageUnit;
798 }
799 else if (imageIndex < mImagesCS.size() && mImagesCS[imageIndex].active)
800 {
801 logicalImageUnit = mImagesCS[imageIndex].logicalImageUnit;
802 }
803 break;
804 // TODO(xinghua.cao@intel.com): add image mapping for vertex shader and pixel shader.
805 default:
806 UNREACHABLE();
807 }
808
809 if (logicalImageUnit >= 0 && logicalImageUnit < static_cast<GLint>(caps.maxImageUnits))
810 {
811 return logicalImageUnit;
812 }
813
814 return -1;
815}
816
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800817gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
Xinghua Cao26143fd2017-11-01 18:19:05 +0800818{
819 switch (type)
820 {
Jiawei Shao385b3e02018-03-21 09:43:28 +0800821 case gl::ShaderType::Compute:
Xinghua Cao26143fd2017-11-01 18:19:05 +0800822 return readonly ? mUsedComputeReadonlyImageRange : mUsedComputeImageRange;
Qin Jiajia155bfd12018-08-31 17:27:10 +0800823 // TODO(xinghua.cao@intel.com): add real image range of vertex shader and pixel shader.
824 case gl::ShaderType::Vertex:
825 case gl::ShaderType::Fragment:
826 return {0, 0};
Xinghua Cao26143fd2017-11-01 18:19:05 +0800827 default:
828 UNREACHABLE();
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800829 return {0, 0};
Xinghua Cao26143fd2017-11-01 18:19:05 +0800830 }
831}
832
Jamie Madill785e8a02018-10-04 17:42:00 -0400833angle::Result ProgramD3D::load(const gl::Context *context,
834 gl::InfoLog &infoLog,
835 gl::BinaryInputStream *stream)
Brandon Jones22502d52014-08-29 16:58:36 -0700836{
Jamie Madilla7d12dc2016-12-13 15:08:19 -0500837 // TODO(jmadill): Use Renderer from contextImpl.
838
Jamie Madill62d31cb2015-09-11 13:25:51 -0400839 reset();
840
Jamie Madill334d6152015-10-22 14:00:28 -0400841 DeviceIdentifier binaryDeviceIdentifier = {0};
842 stream->readBytes(reinterpret_cast<unsigned char *>(&binaryDeviceIdentifier),
843 sizeof(DeviceIdentifier));
Austin Kinross137b1512015-06-17 16:14:53 -0700844
845 DeviceIdentifier identifier = mRenderer->getAdapterIdentifier();
846 if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0)
847 {
848 infoLog << "Invalid program binary, device configuration has changed.";
Jamie Madill7c985f52018-11-29 18:16:17 -0500849 return angle::Result::Incomplete;
Austin Kinross137b1512015-06-17 16:14:53 -0700850 }
851
Jamie Madill2db1fbb2014-12-03 10:58:55 -0500852 int compileFlags = stream->readInt<int>();
853 if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
854 {
Jamie Madillf6113162015-05-07 11:49:21 -0400855 infoLog << "Mismatched compilation flags.";
Jamie Madill7c985f52018-11-29 18:16:17 -0500856 return angle::Result::Incomplete;
Jamie Madill2db1fbb2014-12-03 10:58:55 -0500857 }
858
Jamie Madill8047c0d2016-03-07 13:02:12 -0500859 for (int &index : mAttribLocationToD3DSemantic)
Jamie Madill63805b42015-08-25 13:17:39 -0400860 {
Jamie Madill8047c0d2016-03-07 13:02:12 -0500861 stream->readInt(&index);
Jamie Madill63805b42015-08-25 13:17:39 -0400862 }
863
Jiawei Shao467c15f2018-04-24 15:04:26 +0800864 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700865 {
Jiawei Shao467c15f2018-04-24 15:04:26 +0800866 const unsigned int samplerCount = stream->readInt<unsigned int>();
867 for (unsigned int i = 0; i < samplerCount; ++i)
868 {
869 Sampler sampler;
870 stream->readBool(&sampler.active);
871 stream->readInt(&sampler.logicalTextureUnit);
872 stream->readEnum(&sampler.textureType);
873 mShaderSamplers[shaderType].push_back(sampler);
874 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700875
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800876 unsigned int samplerRangeLow, samplerRangeHigh;
877 stream->readInt(&samplerRangeLow);
878 stream->readInt(&samplerRangeHigh);
879 mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh);
Xinghua Caob1239382016-12-13 15:07:05 +0800880 }
881
Xinghua Cao26143fd2017-11-01 18:19:05 +0800882 const unsigned int csImageCount = stream->readInt<unsigned int>();
883 for (unsigned int i = 0; i < csImageCount; ++i)
884 {
885 Image image;
886 stream->readBool(&image.active);
887 stream->readInt(&image.logicalImageUnit);
888 mImagesCS.push_back(image);
889 }
890
891 const unsigned int csReadonlyImageCount = stream->readInt<unsigned int>();
892 for (unsigned int i = 0; i < csReadonlyImageCount; ++i)
893 {
894 Image image;
895 stream->readBool(&image.active);
896 stream->readInt(&image.logicalImageUnit);
897 mReadonlyImagesCS.push_back(image);
898 }
899
Xinghua Cao6dfdca82018-08-03 17:10:55 +0800900 unsigned int computeImageRangeLow, computeImageRangeHigh, computeReadonlyImageRangeLow,
901 computeReadonlyImageRangeHigh;
902 stream->readInt(&computeImageRangeLow);
903 stream->readInt(&computeImageRangeHigh);
904 stream->readInt(&computeReadonlyImageRangeLow);
905 stream->readInt(&computeReadonlyImageRangeHigh);
906 mUsedComputeImageRange = gl::RangeUI(computeImageRangeLow, computeImageRangeHigh);
907 mUsedComputeReadonlyImageRange =
908 gl::RangeUI(computeReadonlyImageRangeLow, computeReadonlyImageRangeHigh);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700909
Qin Jiajiaa602f902018-09-11 14:40:24 +0800910 const unsigned int shaderStorageBlockCount = stream->readInt<unsigned int>();
911 if (stream->error())
912 {
913 infoLog << "Invalid program binary.";
Jamie Madill7c985f52018-11-29 18:16:17 -0500914 return angle::Result::Incomplete;
Qin Jiajiaa602f902018-09-11 14:40:24 +0800915 }
916
917 ASSERT(mD3DShaderStorageBlocks.empty());
918 for (unsigned int blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex)
919 {
920 D3DInterfaceBlock shaderStorageBlock;
921 for (gl::ShaderType shaderType : gl::AllShaderTypes())
922 {
923 stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
924 }
925 mD3DShaderStorageBlocks.push_back(shaderStorageBlock);
926 }
927
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700928 const unsigned int uniformCount = stream->readInt<unsigned int>();
929 if (stream->error())
930 {
Jamie Madillf6113162015-05-07 11:49:21 -0400931 infoLog << "Invalid program binary.";
Jamie Madill7c985f52018-11-29 18:16:17 -0500932 return angle::Result::Incomplete;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700933 }
934
Jamie Madill48ef11b2016-04-27 15:21:52 -0400935 const auto &linkedUniforms = mState.getUniforms();
Jamie Madill62d31cb2015-09-11 13:25:51 -0400936 ASSERT(mD3DUniforms.empty());
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700937 for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
938 {
Jamie Madill62d31cb2015-09-11 13:25:51 -0400939 const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700940
Jamie Madill62d31cb2015-09-11 13:25:51 -0400941 D3DUniform *d3dUniform =
Xinghua Cao26143fd2017-11-01 18:19:05 +0800942 new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name,
943 linkedUniform.arraySizes, linkedUniform.isInDefaultBlock());
944 stream->readInt<HLSLRegisterType>(&d3dUniform->regType);
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800945 for (gl::ShaderType shaderType : gl::AllShaderTypes())
946 {
947 stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]);
948 }
Jamie Madill62d31cb2015-09-11 13:25:51 -0400949 stream->readInt(&d3dUniform->registerCount);
950 stream->readInt(&d3dUniform->registerElement);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700951
Jamie Madill62d31cb2015-09-11 13:25:51 -0400952 mD3DUniforms.push_back(d3dUniform);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700953 }
954
Jamie Madill4a3c2342015-10-08 12:58:45 -0400955 const unsigned int blockCount = stream->readInt<unsigned int>();
956 if (stream->error())
957 {
958 infoLog << "Invalid program binary.";
Jamie Madill7c985f52018-11-29 18:16:17 -0500959 return angle::Result::Incomplete;
Jamie Madill4a3c2342015-10-08 12:58:45 -0400960 }
961
962 ASSERT(mD3DUniformBlocks.empty());
963 for (unsigned int blockIndex = 0; blockIndex < blockCount; ++blockIndex)
964 {
Qin Jiajiaa602f902018-09-11 14:40:24 +0800965 D3DInterfaceBlock uniformBlock;
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +0800966 for (gl::ShaderType shaderType : gl::AllShaderTypes())
967 {
968 stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
969 }
Jamie Madill4a3c2342015-10-08 12:58:45 -0400970 mD3DUniformBlocks.push_back(uniformBlock);
971 }
972
Jamie Madill9fc36822015-11-18 13:08:07 -0500973 const unsigned int streamOutVaryingCount = stream->readInt<unsigned int>();
974 mStreamOutVaryings.resize(streamOutVaryingCount);
975 for (unsigned int varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex)
Brandon Joneseb994362014-09-24 10:27:28 -0700976 {
Jamie Madill9fc36822015-11-18 13:08:07 -0500977 D3DVarying *varying = &mStreamOutVaryings[varyingIndex];
Brandon Joneseb994362014-09-24 10:27:28 -0700978
Jamie Madill28afae52015-11-09 15:07:57 -0500979 stream->readString(&varying->semanticName);
980 stream->readInt(&varying->semanticIndex);
Jamie Madill9fc36822015-11-18 13:08:07 -0500981 stream->readInt(&varying->componentCount);
982 stream->readInt(&varying->outputSlot);
Brandon Joneseb994362014-09-24 10:27:28 -0700983 }
984
Jiawei Shao467c15f2018-04-24 15:04:26 +0800985 for (gl::ShaderType shaderType : gl::AllShaderTypes())
986 {
987 stream->readString(&mShaderHLSL[shaderType]);
988 stream->readBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
989 sizeof(angle::CompilerWorkaroundsD3D));
990 }
991
Brandon Jones22502d52014-08-29 16:58:36 -0700992 stream->readBool(&mUsesFragDepth);
Martin Radev41ac68e2017-06-06 12:16:58 +0300993 stream->readBool(&mHasANGLEMultiviewEnabled);
994 stream->readBool(&mUsesViewID);
Brandon Jones44151a92014-09-10 11:32:25 -0700995 stream->readBool(&mUsesPointSize);
Jamie Madill3e14e2b2015-10-29 14:38:53 -0400996 stream->readBool(&mUsesFlatInterpolation);
Brandon Jones22502d52014-08-29 16:58:36 -0700997
998 const size_t pixelShaderKeySize = stream->readInt<unsigned int>();
999 mPixelShaderKey.resize(pixelShaderKeySize);
Jamie Madill334d6152015-10-22 14:00:28 -04001000 for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize;
1001 pixelShaderKeyIndex++)
Brandon Jones22502d52014-08-29 16:58:36 -07001002 {
1003 stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
1004 stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
1005 stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
1006 stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
1007 }
1008
Jamie Madill4e31ad52015-10-29 10:32:57 -04001009 stream->readString(&mGeometryShaderPreamble);
1010
Jamie Madill334d6152015-10-22 14:00:28 -04001011 const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data());
Brandon Joneseb994362014-09-24 10:27:28 -07001012
Jamie Madillb0a838b2016-11-13 20:02:12 -05001013 bool separateAttribs = (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS);
1014
Jamie Madill785e8a02018-10-04 17:42:00 -04001015 d3d::Context *contextD3D = GetImplAs<ContextD3D>(context);
1016
Brandon Joneseb994362014-09-24 10:27:28 -07001017 const unsigned int vertexShaderCount = stream->readInt<unsigned int>();
Jamie Madill334d6152015-10-22 14:00:28 -04001018 for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount;
1019 vertexShaderIndex++)
Brandon Joneseb994362014-09-24 10:27:28 -07001020 {
Jamie Madilld3dfda22015-07-06 08:28:49 -04001021 size_t inputLayoutSize = stream->readInt<size_t>();
Frank Henigmand633b152018-10-04 23:34:31 -04001022 gl::InputLayout inputLayout(inputLayoutSize, angle::FormatID::NONE);
Brandon Joneseb994362014-09-24 10:27:28 -07001023
Jamie Madilld3dfda22015-07-06 08:28:49 -04001024 for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++)
Brandon Joneseb994362014-09-24 10:27:28 -07001025 {
Frank Henigmand633b152018-10-04 23:34:31 -04001026 inputLayout[inputIndex] = stream->readInt<angle::FormatID>();
Brandon Joneseb994362014-09-24 10:27:28 -07001027 }
1028
Jamie Madill334d6152015-10-22 14:00:28 -04001029 unsigned int vertexShaderSize = stream->readInt<unsigned int>();
Brandon Joneseb994362014-09-24 10:27:28 -07001030 const unsigned char *vertexShaderFunction = binary + stream->offset();
Geoff Langb543aff2014-09-30 14:52:54 -04001031
Jamie Madillada9ecc2015-08-17 12:53:37 -04001032 ShaderExecutableD3D *shaderExecutable = nullptr;
1033
Jamie Madill785e8a02018-10-04 17:42:00 -04001034 ANGLE_TRY(mRenderer->loadExecutable(contextD3D, vertexShaderFunction, vertexShaderSize,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001035 gl::ShaderType::Vertex, mStreamOutVaryings,
1036 separateAttribs, &shaderExecutable));
Geoff Langb543aff2014-09-30 14:52:54 -04001037
Brandon Joneseb994362014-09-24 10:27:28 -07001038 if (!shaderExecutable)
1039 {
Jamie Madillf6113162015-05-07 11:49:21 -04001040 infoLog << "Could not create vertex shader.";
Jamie Madill7c985f52018-11-29 18:16:17 -05001041 return angle::Result::Incomplete;
Brandon Joneseb994362014-09-24 10:27:28 -07001042 }
1043
1044 // generated converted input layout
Jamie Madilld3dfda22015-07-06 08:28:49 -04001045 VertexExecutable::Signature signature;
1046 VertexExecutable::getSignature(mRenderer, inputLayout, &signature);
Brandon Joneseb994362014-09-24 10:27:28 -07001047
1048 // add new binary
Xinghua Caob1239382016-12-13 15:07:05 +08001049 mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
1050 new VertexExecutable(inputLayout, signature, shaderExecutable)));
Brandon Joneseb994362014-09-24 10:27:28 -07001051
1052 stream->skip(vertexShaderSize);
1053 }
1054
1055 const size_t pixelShaderCount = stream->readInt<unsigned int>();
1056 for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
1057 {
1058 const size_t outputCount = stream->readInt<unsigned int>();
1059 std::vector<GLenum> outputs(outputCount);
1060 for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
1061 {
1062 stream->readInt(&outputs[outputIndex]);
1063 }
1064
Jamie Madill334d6152015-10-22 14:00:28 -04001065 const size_t pixelShaderSize = stream->readInt<unsigned int>();
Brandon Joneseb994362014-09-24 10:27:28 -07001066 const unsigned char *pixelShaderFunction = binary + stream->offset();
Jamie Madillada9ecc2015-08-17 12:53:37 -04001067 ShaderExecutableD3D *shaderExecutable = nullptr;
1068
Jamie Madill785e8a02018-10-04 17:42:00 -04001069 ANGLE_TRY(mRenderer->loadExecutable(contextD3D, pixelShaderFunction, pixelShaderSize,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001070 gl::ShaderType::Fragment, mStreamOutVaryings,
Yunchao He85072e82017-11-14 15:43:28 +08001071 separateAttribs, &shaderExecutable));
Brandon Joneseb994362014-09-24 10:27:28 -07001072
1073 if (!shaderExecutable)
1074 {
Jamie Madillf6113162015-05-07 11:49:21 -04001075 infoLog << "Could not create pixel shader.";
Jamie Madill7c985f52018-11-29 18:16:17 -05001076 return angle::Result::Incomplete;
Brandon Joneseb994362014-09-24 10:27:28 -07001077 }
1078
1079 // add new binary
Xinghua Caob1239382016-12-13 15:07:05 +08001080 mPixelExecutables.push_back(
1081 std::unique_ptr<PixelExecutable>(new PixelExecutable(outputs, shaderExecutable)));
Brandon Joneseb994362014-09-24 10:27:28 -07001082
1083 stream->skip(pixelShaderSize);
1084 }
1085
Jamie Madill04796cd2018-05-24 19:52:16 -04001086 for (auto &geometryExe : mGeometryExecutables)
Brandon Joneseb994362014-09-24 10:27:28 -07001087 {
Jamie Madill4e31ad52015-10-29 10:32:57 -04001088 unsigned int geometryShaderSize = stream->readInt<unsigned int>();
1089 if (geometryShaderSize == 0)
1090 {
Jamie Madill4e31ad52015-10-29 10:32:57 -04001091 continue;
1092 }
1093
Brandon Joneseb994362014-09-24 10:27:28 -07001094 const unsigned char *geometryShaderFunction = binary + stream->offset();
Jamie Madill4e31ad52015-10-29 10:32:57 -04001095
Xinghua Caob1239382016-12-13 15:07:05 +08001096 ShaderExecutableD3D *geometryExecutable = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04001097 ANGLE_TRY(mRenderer->loadExecutable(contextD3D, geometryShaderFunction, geometryShaderSize,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001098 gl::ShaderType::Geometry, mStreamOutVaryings,
Yunchao He85072e82017-11-14 15:43:28 +08001099 separateAttribs, &geometryExecutable));
Brandon Joneseb994362014-09-24 10:27:28 -07001100
Xinghua Caob1239382016-12-13 15:07:05 +08001101 if (!geometryExecutable)
Brandon Joneseb994362014-09-24 10:27:28 -07001102 {
Jamie Madillf6113162015-05-07 11:49:21 -04001103 infoLog << "Could not create geometry shader.";
Jamie Madill7c985f52018-11-29 18:16:17 -05001104 return angle::Result::Incomplete;
Brandon Joneseb994362014-09-24 10:27:28 -07001105 }
Xinghua Caob1239382016-12-13 15:07:05 +08001106
Jamie Madill04796cd2018-05-24 19:52:16 -04001107 geometryExe.reset(geometryExecutable);
Xinghua Caob1239382016-12-13 15:07:05 +08001108
Brandon Joneseb994362014-09-24 10:27:28 -07001109 stream->skip(geometryShaderSize);
1110 }
1111
Xinghua Caof3179a62018-07-12 16:22:06 +08001112 const size_t computeShaderCount = stream->readInt<unsigned int>();
1113 for (size_t computeShaderIndex = 0; computeShaderIndex < computeShaderCount;
1114 computeShaderIndex++)
Xinghua Caob1239382016-12-13 15:07:05 +08001115 {
Xinghua Caof3179a62018-07-12 16:22:06 +08001116 const size_t signatureCount = stream->readInt<unsigned int>();
1117 gl::ImageUnitTextureTypeMap signatures;
1118 for (size_t signatureIndex = 0; signatureIndex < signatureCount; signatureIndex++)
1119 {
1120 unsigned int imageUint;
1121 gl::TextureType textureType;
1122 stream->readInt<unsigned int>(&imageUint);
1123 stream->readInt<gl::TextureType>(&textureType);
1124 signatures.insert(std::pair<unsigned int, gl::TextureType>(imageUint, textureType));
1125 }
1126
1127 const size_t computeShaderSize = stream->readInt<unsigned int>();
Xinghua Caob1239382016-12-13 15:07:05 +08001128 const unsigned char *computeShaderFunction = binary + stream->offset();
1129
1130 ShaderExecutableD3D *computeExecutable = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04001131 ANGLE_TRY(mRenderer->loadExecutable(contextD3D, computeShaderFunction, computeShaderSize,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001132 gl::ShaderType::Compute, std::vector<D3DVarying>(),
1133 false, &computeExecutable));
Xinghua Caob1239382016-12-13 15:07:05 +08001134
1135 if (!computeExecutable)
1136 {
1137 infoLog << "Could not create compute shader.";
Jamie Madill7c985f52018-11-29 18:16:17 -05001138 return angle::Result::Incomplete;
Xinghua Caob1239382016-12-13 15:07:05 +08001139 }
1140
Xinghua Caof3179a62018-07-12 16:22:06 +08001141 // add new binary
1142 mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(new ComputeExecutable(
1143 signatures, std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
1144
1145 stream->skip(computeShaderSize);
1146 }
1147
1148 const size_t bindLayoutCount = stream->readInt<unsigned int>();
1149 for (size_t bindLayoutIndex = 0; bindLayoutIndex < bindLayoutCount; bindLayoutIndex++)
1150 {
1151 mComputeShaderImage2DBindLayoutCache.insert(std::pair<unsigned int, gl::TextureType>(
1152 stream->readInt<unsigned int>(), gl::TextureType::_2D));
Xinghua Caob1239382016-12-13 15:07:05 +08001153 }
1154
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001155 initializeUniformStorage(mState.getLinkedShaderStages());
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001156
Jiawei Shao3dd8d2912018-03-30 09:39:09 +08001157 dirtyAllUniforms();
1158
Jamie Madill7c985f52018-11-29 18:16:17 -05001159 return angle::Result::Continue;
Brandon Jones22502d52014-08-29 16:58:36 -07001160}
1161
Jamie Madill27a60632017-06-30 15:12:01 -04001162void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
Brandon Jones22502d52014-08-29 16:58:36 -07001163{
Austin Kinross137b1512015-06-17 16:14:53 -07001164 // Output the DeviceIdentifier before we output any shader code
Jamie Madill334d6152015-10-22 14:00:28 -04001165 // When we load the binary again later, we can validate the device identifier before trying to
1166 // compile any HLSL
Austin Kinross137b1512015-06-17 16:14:53 -07001167 DeviceIdentifier binaryIdentifier = mRenderer->getAdapterIdentifier();
Jamie Madill334d6152015-10-22 14:00:28 -04001168 stream->writeBytes(reinterpret_cast<unsigned char *>(&binaryIdentifier),
1169 sizeof(DeviceIdentifier));
Austin Kinross137b1512015-06-17 16:14:53 -07001170
Jamie Madill2db1fbb2014-12-03 10:58:55 -05001171 stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
1172
Jamie Madill8047c0d2016-03-07 13:02:12 -05001173 for (int d3dSemantic : mAttribLocationToD3DSemantic)
Jamie Madill63805b42015-08-25 13:17:39 -04001174 {
Jamie Madill8047c0d2016-03-07 13:02:12 -05001175 stream->writeInt(d3dSemantic);
Jamie Madill63805b42015-08-25 13:17:39 -04001176 }
1177
Jiawei Shao467c15f2018-04-24 15:04:26 +08001178 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001179 {
Jiawei Shao467c15f2018-04-24 15:04:26 +08001180 stream->writeInt(mShaderSamplers[shaderType].size());
1181 for (unsigned int i = 0; i < mShaderSamplers[shaderType].size(); ++i)
1182 {
1183 stream->writeInt(mShaderSamplers[shaderType][i].active);
1184 stream->writeInt(mShaderSamplers[shaderType][i].logicalTextureUnit);
1185 stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
1186 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001187
Xinghua Cao6dfdca82018-08-03 17:10:55 +08001188 stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
1189 stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
Xinghua Caob1239382016-12-13 15:07:05 +08001190 }
1191
Xinghua Cao26143fd2017-11-01 18:19:05 +08001192 stream->writeInt(mImagesCS.size());
1193 for (unsigned int i = 0; i < mImagesCS.size(); ++i)
1194 {
1195 stream->writeInt(mImagesCS[i].active);
1196 stream->writeInt(mImagesCS[i].logicalImageUnit);
1197 }
1198
1199 stream->writeInt(mReadonlyImagesCS.size());
1200 for (unsigned int i = 0; i < mReadonlyImagesCS.size(); ++i)
1201 {
1202 stream->writeInt(mReadonlyImagesCS[i].active);
1203 stream->writeInt(mReadonlyImagesCS[i].logicalImageUnit);
1204 }
1205
Xinghua Cao6dfdca82018-08-03 17:10:55 +08001206 stream->writeInt(mUsedComputeImageRange.low());
1207 stream->writeInt(mUsedComputeImageRange.high());
1208 stream->writeInt(mUsedComputeReadonlyImageRange.low());
1209 stream->writeInt(mUsedComputeReadonlyImageRange.high());
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001210
Qin Jiajiaa602f902018-09-11 14:40:24 +08001211 stream->writeInt(mD3DShaderStorageBlocks.size());
1212 for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks)
1213 {
1214 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1215 {
1216 stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
1217 }
1218 }
1219
Jamie Madill62d31cb2015-09-11 13:25:51 -04001220 stream->writeInt(mD3DUniforms.size());
Jamie Madill4a3c2342015-10-08 12:58:45 -04001221 for (const D3DUniform *uniform : mD3DUniforms)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001222 {
Jamie Madill62d31cb2015-09-11 13:25:51 -04001223 // Type, name and arraySize are redundant, so aren't stored in the binary.
Xinghua Cao26143fd2017-11-01 18:19:05 +08001224 stream->writeInt(static_cast<unsigned int>(uniform->regType));
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001225 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1226 {
1227 stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]);
1228 }
Jamie Madill4a3c2342015-10-08 12:58:45 -04001229 stream->writeInt(uniform->registerCount);
1230 stream->writeInt(uniform->registerElement);
1231 }
1232
1233 stream->writeInt(mD3DUniformBlocks.size());
Qin Jiajiaa602f902018-09-11 14:40:24 +08001234 for (const D3DInterfaceBlock &uniformBlock : mD3DUniformBlocks)
Jamie Madill4a3c2342015-10-08 12:58:45 -04001235 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001236 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1237 {
1238 stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
1239 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -07001240 }
1241
Jamie Madill9fc36822015-11-18 13:08:07 -05001242 stream->writeInt(mStreamOutVaryings.size());
1243 for (const auto &varying : mStreamOutVaryings)
Brandon Joneseb994362014-09-24 10:27:28 -07001244 {
Brandon Joneseb994362014-09-24 10:27:28 -07001245 stream->writeString(varying.semanticName);
1246 stream->writeInt(varying.semanticIndex);
Jamie Madill9fc36822015-11-18 13:08:07 -05001247 stream->writeInt(varying.componentCount);
1248 stream->writeInt(varying.outputSlot);
Brandon Joneseb994362014-09-24 10:27:28 -07001249 }
1250
Jiawei Shao467c15f2018-04-24 15:04:26 +08001251 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1252 {
1253 stream->writeString(mShaderHLSL[shaderType]);
1254 stream->writeBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
1255 sizeof(angle::CompilerWorkaroundsD3D));
1256 }
1257
Brandon Jones22502d52014-08-29 16:58:36 -07001258 stream->writeInt(mUsesFragDepth);
Martin Radev41ac68e2017-06-06 12:16:58 +03001259 stream->writeInt(mHasANGLEMultiviewEnabled);
1260 stream->writeInt(mUsesViewID);
Brandon Jones44151a92014-09-10 11:32:25 -07001261 stream->writeInt(mUsesPointSize);
Jamie Madill3e14e2b2015-10-29 14:38:53 -04001262 stream->writeInt(mUsesFlatInterpolation);
Brandon Jones22502d52014-08-29 16:58:36 -07001263
Brandon Joneseb994362014-09-24 10:27:28 -07001264 const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
Brandon Jones22502d52014-08-29 16:58:36 -07001265 stream->writeInt(pixelShaderKey.size());
Jamie Madill334d6152015-10-22 14:00:28 -04001266 for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size();
1267 pixelShaderKeyIndex++)
Brandon Jones22502d52014-08-29 16:58:36 -07001268 {
Brandon Joneseb994362014-09-24 10:27:28 -07001269 const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
Brandon Jones22502d52014-08-29 16:58:36 -07001270 stream->writeInt(variable.type);
1271 stream->writeString(variable.name);
1272 stream->writeString(variable.source);
1273 stream->writeInt(variable.outputIndex);
1274 }
1275
Jamie Madill4e31ad52015-10-29 10:32:57 -04001276 stream->writeString(mGeometryShaderPreamble);
1277
Brandon Joneseb994362014-09-24 10:27:28 -07001278 stream->writeInt(mVertexExecutables.size());
Jamie Madill334d6152015-10-22 14:00:28 -04001279 for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
1280 vertexExecutableIndex++)
Brandon Joneseb994362014-09-24 10:27:28 -07001281 {
Xinghua Caob1239382016-12-13 15:07:05 +08001282 VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get();
Brandon Joneseb994362014-09-24 10:27:28 -07001283
Jamie Madilld3dfda22015-07-06 08:28:49 -04001284 const auto &inputLayout = vertexExecutable->inputs();
1285 stream->writeInt(inputLayout.size());
1286
1287 for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++)
Brandon Joneseb994362014-09-24 10:27:28 -07001288 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001289 stream->writeInt(static_cast<unsigned int>(inputLayout[inputIndex]));
Brandon Joneseb994362014-09-24 10:27:28 -07001290 }
1291
1292 size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
1293 stream->writeInt(vertexShaderSize);
1294
1295 const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
1296 stream->writeBytes(vertexBlob, vertexShaderSize);
1297 }
1298
1299 stream->writeInt(mPixelExecutables.size());
Jamie Madill334d6152015-10-22 14:00:28 -04001300 for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size();
1301 pixelExecutableIndex++)
Brandon Joneseb994362014-09-24 10:27:28 -07001302 {
Xinghua Caob1239382016-12-13 15:07:05 +08001303 PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get();
Brandon Joneseb994362014-09-24 10:27:28 -07001304
1305 const std::vector<GLenum> outputs = pixelExecutable->outputSignature();
1306 stream->writeInt(outputs.size());
1307 for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
1308 {
1309 stream->writeInt(outputs[outputIndex]);
1310 }
1311
1312 size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
1313 stream->writeInt(pixelShaderSize);
1314
1315 const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
1316 stream->writeBytes(pixelBlob, pixelShaderSize);
1317 }
1318
Xinghua Caob1239382016-12-13 15:07:05 +08001319 for (auto const &geometryExecutable : mGeometryExecutables)
Brandon Joneseb994362014-09-24 10:27:28 -07001320 {
Xinghua Caob1239382016-12-13 15:07:05 +08001321 if (!geometryExecutable)
Jamie Madill4e31ad52015-10-29 10:32:57 -04001322 {
1323 stream->writeInt(0);
1324 continue;
1325 }
1326
Xinghua Caob1239382016-12-13 15:07:05 +08001327 size_t geometryShaderSize = geometryExecutable->getLength();
Jamie Madill4e31ad52015-10-29 10:32:57 -04001328 stream->writeInt(geometryShaderSize);
Xinghua Caob1239382016-12-13 15:07:05 +08001329 stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize);
1330 }
1331
Xinghua Caof3179a62018-07-12 16:22:06 +08001332 stream->writeInt(mComputeExecutables.size());
1333 for (size_t computeExecutableIndex = 0; computeExecutableIndex < mComputeExecutables.size();
1334 computeExecutableIndex++)
Xinghua Caob1239382016-12-13 15:07:05 +08001335 {
Xinghua Caof3179a62018-07-12 16:22:06 +08001336 ComputeExecutable *computeExecutable = mComputeExecutables[computeExecutableIndex].get();
1337
1338 const gl::ImageUnitTextureTypeMap signatures = computeExecutable->signature();
1339 stream->writeInt(signatures.size());
1340 for (const auto &signature : signatures)
1341 {
1342 stream->writeInt(signature.first);
1343 stream->writeInt(static_cast<unsigned int>(signature.second));
1344 }
1345
1346 size_t computeShaderSize = computeExecutable->shaderExecutable()->getLength();
Xinghua Caob1239382016-12-13 15:07:05 +08001347 stream->writeInt(computeShaderSize);
Xinghua Caof3179a62018-07-12 16:22:06 +08001348
1349 const uint8_t *computeBlob = computeExecutable->shaderExecutable()->getFunction();
1350 stream->writeBytes(computeBlob, computeShaderSize);
Xinghua Caob1239382016-12-13 15:07:05 +08001351 }
Xinghua Caof3179a62018-07-12 16:22:06 +08001352
1353 stream->writeInt(mComputeShaderImage2DBindLayoutCache.size());
1354 for (auto &image2DBindLayout : mComputeShaderImage2DBindLayoutCache)
Xinghua Caob1239382016-12-13 15:07:05 +08001355 {
Xinghua Caof3179a62018-07-12 16:22:06 +08001356 stream->writeInt(image2DBindLayout.first);
Brandon Joneseb994362014-09-24 10:27:28 -07001357 }
Brandon Jones22502d52014-08-29 16:58:36 -07001358}
1359
Jamie Madillb980c562018-11-27 11:34:27 -05001360void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {}
Geoff Langc5629752015-12-07 16:29:04 -05001361
Jamie Madillb980c562018-11-27 11:34:27 -05001362void ProgramD3D::setSeparable(bool /* separable */) {}
Yunchao He61afff12017-03-14 15:34:03 +08001363
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001364angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout(
Jamie Madill785e8a02018-10-04 17:42:00 -04001365 d3d::Context *context,
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001366 ShaderExecutableD3D **outExecutable,
1367 gl::InfoLog *infoLog)
Brandon Joneseb994362014-09-24 10:27:28 -07001368{
Jamie Madill0e7f1732017-09-09 23:32:50 -04001369 if (mCachedPixelExecutableIndex.valid())
Brandon Joneseb994362014-09-24 10:27:28 -07001370 {
Jamie Madill0e7f1732017-09-09 23:32:50 -04001371 *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable();
Jamie Madill7c985f52018-11-29 18:16:17 -05001372 return angle::Result::Continue;
Brandon Joneseb994362014-09-24 10:27:28 -07001373 }
1374
Jamie Madill334d6152015-10-22 14:00:28 -04001375 std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(
Jiawei Shao467c15f2018-04-24 15:04:26 +08001376 mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth,
1377 mPixelShaderOutputLayoutCache);
Brandon Jones22502d52014-08-29 16:58:36 -07001378
1379 // Generate new pixel executable
Yunchao Hed7297bf2017-04-19 15:27:10 +08001380 ShaderExecutableD3D *pixelExecutable = nullptr;
Jamie Madill97399232014-12-23 12:31:15 -05001381
1382 gl::InfoLog tempInfoLog;
1383 gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1384
Jamie Madill01074252016-11-28 15:55:51 -05001385 ANGLE_TRY(mRenderer->compileToExecutable(
Jamie Madillb1565902018-07-27 08:12:48 -04001386 context, *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings,
Jiawei Shao467c15f2018-04-24 15:04:26 +08001387 (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
1388 mShaderWorkarounds[gl::ShaderType::Fragment], &pixelExecutable));
Brandon Joneseb994362014-09-24 10:27:28 -07001389
Jamie Madill97399232014-12-23 12:31:15 -05001390 if (pixelExecutable)
1391 {
Xinghua Caob1239382016-12-13 15:07:05 +08001392 mPixelExecutables.push_back(std::unique_ptr<PixelExecutable>(
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001393 new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable)));
Jamie Madill0e7f1732017-09-09 23:32:50 -04001394 mCachedPixelExecutableIndex = mPixelExecutables.size() - 1;
Jamie Madill97399232014-12-23 12:31:15 -05001395 }
1396 else if (!infoLog)
Brandon Joneseb994362014-09-24 10:27:28 -07001397 {
Yuly Novikovd73f8522017-01-13 17:48:57 -05001398 ERR() << "Error compiling dynamic pixel executable:" << std::endl
1399 << tempInfoLog.str() << std::endl;
Brandon Joneseb994362014-09-24 10:27:28 -07001400 }
Brandon Jones22502d52014-08-29 16:58:36 -07001401
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001402 *outExecutable = pixelExecutable;
Jamie Madill7c985f52018-11-29 18:16:17 -05001403 return angle::Result::Continue;
Brandon Jones22502d52014-08-29 16:58:36 -07001404}
1405
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001406angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout(
Jamie Madill785e8a02018-10-04 17:42:00 -04001407 d3d::Context *context,
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001408 ShaderExecutableD3D **outExectuable,
1409 gl::InfoLog *infoLog)
Brandon Jones22502d52014-08-29 16:58:36 -07001410{
Jamie Madill0e7f1732017-09-09 23:32:50 -04001411 if (mCachedVertexExecutableIndex.valid())
Brandon Joneseb994362014-09-24 10:27:28 -07001412 {
Jamie Madill0e7f1732017-09-09 23:32:50 -04001413 *outExectuable =
1414 mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable();
Jamie Madill7c985f52018-11-29 18:16:17 -05001415 return angle::Result::Continue;
Brandon Joneseb994362014-09-24 10:27:28 -07001416 }
1417
Brandon Jones22502d52014-08-29 16:58:36 -07001418 // Generate new dynamic layout with attribute conversions
Jamie Madillc349ec02015-08-21 16:53:12 -04001419 std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
Jiawei Shao467c15f2018-04-24 15:04:26 +08001420 mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getAttributes());
Brandon Jones22502d52014-08-29 16:58:36 -07001421
1422 // Generate new vertex executable
Yunchao Hed7297bf2017-04-19 15:27:10 +08001423 ShaderExecutableD3D *vertexExecutable = nullptr;
Jamie Madill97399232014-12-23 12:31:15 -05001424
1425 gl::InfoLog tempInfoLog;
1426 gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1427
Jamie Madill01074252016-11-28 15:55:51 -05001428 ANGLE_TRY(mRenderer->compileToExecutable(
Jamie Madillb1565902018-07-27 08:12:48 -04001429 context, *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings,
Jiawei Shao467c15f2018-04-24 15:04:26 +08001430 (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
1431 mShaderWorkarounds[gl::ShaderType::Vertex], &vertexExecutable));
Geoff Langb543aff2014-09-30 14:52:54 -04001432
Jamie Madill97399232014-12-23 12:31:15 -05001433 if (vertexExecutable)
Brandon Joneseb994362014-09-24 10:27:28 -07001434 {
Xinghua Caob1239382016-12-13 15:07:05 +08001435 mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001436 new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable)));
Jamie Madill0e7f1732017-09-09 23:32:50 -04001437 mCachedVertexExecutableIndex = mVertexExecutables.size() - 1;
Brandon Joneseb994362014-09-24 10:27:28 -07001438 }
Jamie Madill97399232014-12-23 12:31:15 -05001439 else if (!infoLog)
1440 {
Yuly Novikovd73f8522017-01-13 17:48:57 -05001441 ERR() << "Error compiling dynamic vertex executable:" << std::endl
1442 << tempInfoLog.str() << std::endl;
Jamie Madill97399232014-12-23 12:31:15 -05001443 }
Brandon Jones22502d52014-08-29 16:58:36 -07001444
Geoff Langb543aff2014-09-30 14:52:54 -04001445 *outExectuable = vertexExecutable;
Jamie Madill7c985f52018-11-29 18:16:17 -05001446 return angle::Result::Continue;
Brandon Jones22502d52014-08-29 16:58:36 -07001447}
1448
Jamie Madill785e8a02018-10-04 17:42:00 -04001449angle::Result ProgramD3D::getGeometryExecutableForPrimitiveType(d3d::Context *context,
1450 const gl::Caps &caps,
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001451 gl::PrimitiveMode drawMode,
1452 ShaderExecutableD3D **outExecutable,
1453 gl::InfoLog *infoLog)
Jamie Madill4e31ad52015-10-29 10:32:57 -04001454{
Jamie Madill3e14e2b2015-10-29 14:38:53 -04001455 if (outExecutable)
1456 {
1457 *outExecutable = nullptr;
1458 }
1459
Austin Kinross88829e82016-01-12 13:04:41 -08001460 // Return a null shader if the current rendering doesn't use a geometry shader
1461 if (!usesGeometryShader(drawMode))
Jamie Madill3e14e2b2015-10-29 14:38:53 -04001462 {
Jamie Madill7c985f52018-11-29 18:16:17 -05001463 return angle::Result::Continue;
Jamie Madill3e14e2b2015-10-29 14:38:53 -04001464 }
1465
Jamie Madill04796cd2018-05-24 19:52:16 -04001466 gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
Jamie Madill4e31ad52015-10-29 10:32:57 -04001467
Xinghua Caob1239382016-12-13 15:07:05 +08001468 if (mGeometryExecutables[geometryShaderType])
Jamie Madill4e31ad52015-10-29 10:32:57 -04001469 {
1470 if (outExecutable)
1471 {
Xinghua Caob1239382016-12-13 15:07:05 +08001472 *outExecutable = mGeometryExecutables[geometryShaderType].get();
Jamie Madill4e31ad52015-10-29 10:32:57 -04001473 }
Jamie Madill7c985f52018-11-29 18:16:17 -05001474 return angle::Result::Continue;
Jamie Madill4e31ad52015-10-29 10:32:57 -04001475 }
1476
1477 std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
Jamie Madill785e8a02018-10-04 17:42:00 -04001478 caps, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
Martin Radevc1d4e552017-08-21 12:01:10 +03001479 mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
1480 usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
Jamie Madill4e31ad52015-10-29 10:32:57 -04001481
1482 gl::InfoLog tempInfoLog;
1483 gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1484
Xinghua Caob1239382016-12-13 15:07:05 +08001485 ShaderExecutableD3D *geometryExecutable = nullptr;
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001486 angle::Result result = mRenderer->compileToExecutable(
Jamie Madillb1565902018-07-27 08:12:48 -04001487 context, *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings,
Jamie Madill408293f2016-12-20 10:11:45 -05001488 (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
Xinghua Caob1239382016-12-13 15:07:05 +08001489 angle::CompilerWorkaroundsD3D(), &geometryExecutable);
Jamie Madill4e31ad52015-10-29 10:32:57 -04001490
Jamie Madill7c985f52018-11-29 18:16:17 -05001491 if (!infoLog && result == angle::Result::Stop)
Jamie Madill4e31ad52015-10-29 10:32:57 -04001492 {
Yuly Novikovd73f8522017-01-13 17:48:57 -05001493 ERR() << "Error compiling dynamic geometry executable:" << std::endl
1494 << tempInfoLog.str() << std::endl;
Jamie Madill4e31ad52015-10-29 10:32:57 -04001495 }
1496
Xinghua Caob1239382016-12-13 15:07:05 +08001497 if (geometryExecutable != nullptr)
1498 {
1499 mGeometryExecutables[geometryShaderType].reset(geometryExecutable);
1500 }
1501
Jamie Madill4e31ad52015-10-29 10:32:57 -04001502 if (outExecutable)
1503 {
Xinghua Caob1239382016-12-13 15:07:05 +08001504 *outExecutable = mGeometryExecutables[geometryShaderType].get();
Jamie Madill4e31ad52015-10-29 10:32:57 -04001505 }
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001506 return result;
Jamie Madill4e31ad52015-10-29 10:32:57 -04001507}
1508
Jamie Madill785e8a02018-10-04 17:42:00 -04001509class ProgramD3D::GetExecutableTask : public Closure, public d3d::Context
Brandon Jones44151a92014-09-10 11:32:25 -07001510{
Jamie Madill01074252016-11-28 15:55:51 -05001511 public:
Jamie Madill785e8a02018-10-04 17:42:00 -04001512 GetExecutableTask(ProgramD3D *program) : mProgram(program) {}
Brandon Joneseb994362014-09-24 10:27:28 -07001513
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001514 virtual angle::Result run() = 0;
Jamie Madill01074252016-11-28 15:55:51 -05001515
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001516 void operator()() override { mResult = run(); }
Jamie Madill01074252016-11-28 15:55:51 -05001517
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001518 angle::Result getResult() const { return mResult; }
Jamie Madill01074252016-11-28 15:55:51 -05001519 const gl::InfoLog &getInfoLog() const { return mInfoLog; }
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001520 ShaderExecutableD3D *getExecutable() { return mExecutable; }
Jamie Madill01074252016-11-28 15:55:51 -05001521
Jamie Madillc1fd7372018-10-26 22:48:39 -04001522 void handleResult(HRESULT hr,
1523 const char *message,
1524 const char *file,
1525 const char *function,
1526 unsigned int line) override
Jamie Madill785e8a02018-10-04 17:42:00 -04001527 {
1528 mStoredHR = hr;
1529 mStoredMessage = message;
1530 mStoredFile = file;
1531 mStoredFunction = function;
1532 mStoredLine = line;
1533 }
1534
1535 void popError(d3d::Context *context)
1536 {
Jamie Madillc1fd7372018-10-26 22:48:39 -04001537 context->handleResult(mStoredHR, mStoredMessage, mStoredFile, mStoredFunction, mStoredLine);
Jamie Madill785e8a02018-10-04 17:42:00 -04001538 }
1539
Jamie Madill01074252016-11-28 15:55:51 -05001540 protected:
Jamie Madill785e8a02018-10-04 17:42:00 -04001541 ProgramD3D *mProgram = nullptr;
Jamie Madill7c985f52018-11-29 18:16:17 -05001542 angle::Result mResult = angle::Result::Continue;
Jamie Madill01074252016-11-28 15:55:51 -05001543 gl::InfoLog mInfoLog;
Jamie Madill785e8a02018-10-04 17:42:00 -04001544 ShaderExecutableD3D *mExecutable = nullptr;
1545 HRESULT mStoredHR = S_OK;
1546 const char *mStoredMessage = nullptr;
1547 const char *mStoredFile = nullptr;
1548 const char *mStoredFunction = nullptr;
1549 unsigned int mStoredLine = 0;
Jamie Madill01074252016-11-28 15:55:51 -05001550};
1551
1552class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
1553{
1554 public:
Jamie Madill785e8a02018-10-04 17:42:00 -04001555 GetVertexExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {}
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001556 angle::Result run() override
Jamie Madill01074252016-11-28 15:55:51 -05001557 {
jchen103fd614d2018-08-13 12:21:58 +08001558 mProgram->updateCachedInputLayoutFromShader();
Jamie Madill01074252016-11-28 15:55:51 -05001559
Jamie Madill785e8a02018-10-04 17:42:00 -04001560 ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
Jamie Madill01074252016-11-28 15:55:51 -05001561
Jamie Madill7c985f52018-11-29 18:16:17 -05001562 return angle::Result::Continue;
Jamie Madill01074252016-11-28 15:55:51 -05001563 }
1564};
1565
jchen103fd614d2018-08-13 12:21:58 +08001566void ProgramD3D::updateCachedInputLayoutFromShader()
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001567{
jchen103fd614d2018-08-13 12:21:58 +08001568 GetDefaultInputLayoutFromShader(mState.getAttachedShader(gl::ShaderType::Vertex),
Jiawei Shao385b3e02018-03-21 09:43:28 +08001569 &mCachedInputLayout);
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001570 VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
Jamie Madill0e7f1732017-09-09 23:32:50 -04001571 updateCachedVertexExecutableIndex();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001572}
1573
Jamie Madill01074252016-11-28 15:55:51 -05001574class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
1575{
1576 public:
Jamie Madill785e8a02018-10-04 17:42:00 -04001577 GetPixelExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {}
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001578 angle::Result run() override
Jamie Madill01074252016-11-28 15:55:51 -05001579 {
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001580 mProgram->updateCachedOutputLayoutFromShader();
Jamie Madill01074252016-11-28 15:55:51 -05001581
Jamie Madill785e8a02018-10-04 17:42:00 -04001582 ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog));
Jamie Madill01074252016-11-28 15:55:51 -05001583
Jamie Madill7c985f52018-11-29 18:16:17 -05001584 return angle::Result::Continue;
Jamie Madill01074252016-11-28 15:55:51 -05001585 }
1586};
1587
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001588void ProgramD3D::updateCachedOutputLayoutFromShader()
1589{
1590 GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache);
Jamie Madill0e7f1732017-09-09 23:32:50 -04001591 updateCachedPixelExecutableIndex();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04001592}
1593
Xinghua Caof3179a62018-07-12 16:22:06 +08001594void ProgramD3D::updateCachedImage2DBindLayoutFromComputeShader()
1595{
1596 GetDefaultImage2DBindLayoutFromComputeShader(mImage2DUniforms,
1597 &mComputeShaderImage2DBindLayoutCache);
1598 updateCachedComputeExecutableIndex();
1599}
1600
Jamie Madill01074252016-11-28 15:55:51 -05001601class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask
1602{
1603 public:
Jamie Madill785e8a02018-10-04 17:42:00 -04001604 GetGeometryExecutableTask(ProgramD3D *program, const gl::Caps &caps)
1605 : GetExecutableTask(program), mCaps(caps)
Jamie Madillb980c562018-11-27 11:34:27 -05001606 {}
Jamie Madill01074252016-11-28 15:55:51 -05001607
Jamie Madillec1fe5b2018-08-10 10:05:52 -04001608 angle::Result run() override
Jamie Madill01074252016-11-28 15:55:51 -05001609 {
1610 // Auto-generate the geometry shader here, if we expect to be using point rendering in
1611 // D3D11.
Jamie Madill493f9572018-05-24 19:52:15 -04001612 if (mProgram->usesGeometryShader(gl::PrimitiveMode::Points))
Jamie Madill01074252016-11-28 15:55:51 -05001613 {
Jamie Madill493f9572018-05-24 19:52:15 -04001614 ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(
Jamie Madill785e8a02018-10-04 17:42:00 -04001615 this, mCaps, gl::PrimitiveMode::Points, &mExecutable, &mInfoLog));
Jamie Madill01074252016-11-28 15:55:51 -05001616 }
1617
Jamie Madill7c985f52018-11-29 18:16:17 -05001618 return angle::Result::Continue;
Jamie Madill01074252016-11-28 15:55:51 -05001619 }
Jamie Madill785e8a02018-10-04 17:42:00 -04001620
1621 private:
1622 const gl::Caps &mCaps;
Jamie Madill01074252016-11-28 15:55:51 -05001623};
1624
jchen107ae70d82018-07-06 13:47:01 +08001625// The LinkEvent implementation for linking a rendering(VS, FS, GS) program.
1626class ProgramD3D::GraphicsProgramLinkEvent final : public LinkEvent
1627{
1628 public:
1629 GraphicsProgramLinkEvent(gl::InfoLog &infoLog,
1630 std::shared_ptr<WorkerThreadPool> workerPool,
1631 std::shared_ptr<ProgramD3D::GetVertexExecutableTask> vertexTask,
1632 std::shared_ptr<ProgramD3D::GetPixelExecutableTask> pixelTask,
1633 std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> geometryTask,
1634 bool useGS,
1635 const ShaderD3D *vertexShader,
1636 const ShaderD3D *fragmentShader)
1637 : mInfoLog(infoLog),
1638 mWorkerPool(workerPool),
1639 mVertexTask(vertexTask),
1640 mPixelTask(pixelTask),
1641 mGeometryTask(geometryTask),
1642 mWaitEvents(
1643 {{std::shared_ptr<WaitableEvent>(workerPool->postWorkerTask(mVertexTask)),
1644 std::shared_ptr<WaitableEvent>(workerPool->postWorkerTask(mPixelTask)),
1645 std::shared_ptr<WaitableEvent>(workerPool->postWorkerTask(mGeometryTask))}}),
1646 mUseGS(useGS),
1647 mVertexShader(vertexShader),
1648 mFragmentShader(fragmentShader)
Jamie Madillb980c562018-11-27 11:34:27 -05001649 {}
jchen107ae70d82018-07-06 13:47:01 +08001650
Jamie Madill785e8a02018-10-04 17:42:00 -04001651 angle::Result wait(const gl::Context *context) override
jchen107ae70d82018-07-06 13:47:01 +08001652 {
1653 WaitableEvent::WaitMany(&mWaitEvents);
1654
Jamie Madill785e8a02018-10-04 17:42:00 -04001655 ANGLE_TRY(checkTask(context, mVertexTask.get()));
1656 ANGLE_TRY(checkTask(context, mPixelTask.get()));
1657 ANGLE_TRY(checkTask(context, mGeometryTask.get()));
1658
Jamie Madill7c985f52018-11-29 18:16:17 -05001659 if (mVertexTask.get()->getResult() == angle::Result::Incomplete ||
1660 mPixelTask.get()->getResult() == angle::Result::Incomplete ||
1661 mGeometryTask.get()->getResult() == angle::Result::Incomplete)
jchen107ae70d82018-07-06 13:47:01 +08001662 {
Jamie Madill7c985f52018-11-29 18:16:17 -05001663 return angle::Result::Incomplete;
jchen107ae70d82018-07-06 13:47:01 +08001664 }
1665
1666 ShaderExecutableD3D *defaultVertexExecutable = mVertexTask->getExecutable();
1667 ShaderExecutableD3D *defaultPixelExecutable = mPixelTask->getExecutable();
1668 ShaderExecutableD3D *pointGS = mGeometryTask->getExecutable();
1669
1670 if (mUseGS && pointGS)
1671 {
1672 // Geometry shaders are currently only used internally, so there is no corresponding
1673 // shader object at the interface level. For now the geometry shader debug info is
1674 // prepended to the vertex shader.
1675 mVertexShader->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
1676 mVertexShader->appendDebugInfo(pointGS->getDebugInfo());
1677 mVertexShader->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
1678 }
1679
1680 if (defaultVertexExecutable)
1681 {
1682 mVertexShader->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
1683 }
1684
1685 if (defaultPixelExecutable)
1686 {
1687 mFragmentShader->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
1688 }
1689
1690 bool isLinked = (defaultVertexExecutable && defaultPixelExecutable && (!mUseGS || pointGS));
1691 if (!isLinked)
1692 {
1693 mInfoLog << "Failed to create D3D Shaders";
1694 }
Jamie Madill7c985f52018-11-29 18:16:17 -05001695 return isLinked ? angle::Result::Continue : angle::Result::Incomplete;
jchen107ae70d82018-07-06 13:47:01 +08001696 }
1697
1698 bool isLinking() override
1699 {
1700 for (auto &event : mWaitEvents)
1701 {
1702 if (!event->isReady())
1703 {
1704 return true;
1705 }
1706 }
1707 return false;
1708 }
1709
1710 private:
Jamie Madill785e8a02018-10-04 17:42:00 -04001711 angle::Result checkTask(const gl::Context *context, ProgramD3D::GetExecutableTask *task)
jchen107ae70d82018-07-06 13:47:01 +08001712 {
1713 if (!task->getInfoLog().empty())
1714 {
1715 mInfoLog << task->getInfoLog().str();
1716 }
Jamie Madill785e8a02018-10-04 17:42:00 -04001717
1718 // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D.
Jamie Madill7c985f52018-11-29 18:16:17 -05001719 if (task->getResult() != angle::Result::Stop)
jchen107ae70d82018-07-06 13:47:01 +08001720 {
Jamie Madill7c985f52018-11-29 18:16:17 -05001721 return angle::Result::Continue;
jchen107ae70d82018-07-06 13:47:01 +08001722 }
Jamie Madill785e8a02018-10-04 17:42:00 -04001723
1724 ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
1725 task->popError(contextD3D);
Jamie Madill7c985f52018-11-29 18:16:17 -05001726 return angle::Result::Stop;
jchen107ae70d82018-07-06 13:47:01 +08001727 }
1728
1729 gl::InfoLog &mInfoLog;
1730 std::shared_ptr<WorkerThreadPool> mWorkerPool;
1731 std::shared_ptr<ProgramD3D::GetVertexExecutableTask> mVertexTask;
1732 std::shared_ptr<ProgramD3D::GetPixelExecutableTask> mPixelTask;
1733 std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> mGeometryTask;
1734 std::array<std::shared_ptr<WaitableEvent>, 3> mWaitEvents;
1735 bool mUseGS;
1736 const ShaderD3D *mVertexShader;
1737 const ShaderD3D *mFragmentShader;
1738};
1739
1740std::unique_ptr<LinkEvent> ProgramD3D::compileProgramExecutables(const gl::Context *context,
1741 gl::InfoLog &infoLog)
Jamie Madill01074252016-11-28 15:55:51 -05001742{
1743 // Ensure the compiler is initialized to avoid race conditions.
Jamie Madill785e8a02018-10-04 17:42:00 -04001744 angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context));
Jamie Madill7c985f52018-11-29 18:16:17 -05001745 if (result != angle::Result::Continue)
Jiawei Shao02f15232017-12-27 10:10:28 +08001746 {
jchen107ae70d82018-07-06 13:47:01 +08001747 return std::make_unique<LinkEventDone>(result);
Jiawei Shao02f15232017-12-27 10:10:28 +08001748 }
Jamie Madill01074252016-11-28 15:55:51 -05001749
Jamie Madill785e8a02018-10-04 17:42:00 -04001750 auto vertexTask = std::make_shared<GetVertexExecutableTask>(this);
1751 auto pixelTask = std::make_shared<GetPixelExecutableTask>(this);
1752 auto geometryTask = std::make_shared<GetGeometryExecutableTask>(this, context->getCaps());
jchen107ae70d82018-07-06 13:47:01 +08001753 bool useGS = usesGeometryShader(gl::PrimitiveMode::Points);
Jiawei Shao385b3e02018-03-21 09:43:28 +08001754 const ShaderD3D *vertexShaderD3D =
1755 GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Vertex));
jchen107ae70d82018-07-06 13:47:01 +08001756 const ShaderD3D *fragmentShaderD3D =
1757 GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Fragment));
Jamie Madill847638a2015-11-20 13:01:41 -05001758
jchen107ae70d82018-07-06 13:47:01 +08001759 return std::make_unique<GraphicsProgramLinkEvent>(infoLog, context->getWorkerThreadPool(),
1760 vertexTask, pixelTask, geometryTask, useGS,
1761 vertexShaderD3D, fragmentShaderD3D);
Brandon Jones18bd4102014-09-22 14:21:44 -07001762}
1763
Xinghua Caof3179a62018-07-12 16:22:06 +08001764angle::Result ProgramD3D::getComputeExecutableForImage2DBindLayout(
1765 d3d::Context *context,
1766 ShaderExecutableD3D **outExecutable,
1767 gl::InfoLog *infoLog)
1768{
1769 if (mCachedComputeExecutableIndex.valid())
1770 {
1771 *outExecutable =
1772 mComputeExecutables[mCachedComputeExecutableIndex.value()]->shaderExecutable();
1773 return angle::Result::Continue;
1774 }
1775
1776 std::string finalComputeHLSL = mDynamicHLSL->generateComputeShaderForImage2DBindSignature(
1777 context, *this, mState, mImage2DUniforms, mComputeShaderImage2DBindLayoutCache);
1778
1779 // Generate new compute executable
1780 ShaderExecutableD3D *computeExecutable = nullptr;
1781
1782 gl::InfoLog tempInfoLog;
1783 gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
1784
1785 ANGLE_TRY(mRenderer->compileToExecutable(
1786 context, *currentInfoLog, finalComputeHLSL, gl::ShaderType::Compute,
1787 std::vector<D3DVarying>(), false, angle::CompilerWorkaroundsD3D(), &computeExecutable));
1788
1789 if (computeExecutable)
1790 {
1791 mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(
1792 new ComputeExecutable(mComputeShaderImage2DBindLayoutCache,
1793 std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
1794 mCachedComputeExecutableIndex = mComputeExecutables.size() - 1;
1795 }
1796 else if (!infoLog)
1797 {
1798 ERR() << "Error compiling dynamic compute executable:" << std::endl
1799 << tempInfoLog.str() << std::endl;
1800 }
1801 *outExecutable = computeExecutable;
1802
1803 return angle::Result::Continue;
1804}
1805
Jamie Madill785e8a02018-10-04 17:42:00 -04001806angle::Result ProgramD3D::compileComputeExecutable(d3d::Context *context, gl::InfoLog &infoLog)
Xinghua Caob1239382016-12-13 15:07:05 +08001807{
1808 // Ensure the compiler is initialized to avoid race conditions.
Jamie Madillb1565902018-07-27 08:12:48 -04001809 ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(context));
Xinghua Caob1239382016-12-13 15:07:05 +08001810
Xinghua Caof3179a62018-07-12 16:22:06 +08001811 updateCachedImage2DBindLayoutFromComputeShader();
Xinghua Caob1239382016-12-13 15:07:05 +08001812
1813 ShaderExecutableD3D *computeExecutable = nullptr;
Xinghua Caof3179a62018-07-12 16:22:06 +08001814 ANGLE_TRY(getComputeExecutableForImage2DBindLayout(context, &computeExecutable, &infoLog));
Xinghua Caob1239382016-12-13 15:07:05 +08001815
Xinghua Caof3179a62018-07-12 16:22:06 +08001816 return computeExecutable ? angle::Result::Continue : angle::Result::Incomplete;
Xinghua Caob1239382016-12-13 15:07:05 +08001817}
1818
jchen107ae70d82018-07-06 13:47:01 +08001819std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
1820 const gl::ProgramLinkedResources &resources,
1821 gl::InfoLog &infoLog)
Brandon Jones22502d52014-08-29 16:58:36 -07001822{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001823 const auto &data = context->getState();
Jamie Madill8ecf7f92017-01-13 17:29:52 -05001824
Jamie Madill62d31cb2015-09-11 13:25:51 -04001825 reset();
1826
Jiawei Shao385b3e02018-03-21 09:43:28 +08001827 gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
Xinghua Caob1239382016-12-13 15:07:05 +08001828 if (computeShader)
Austin Kinross02df7962015-07-01 10:03:42 -07001829 {
Jiawei Shao54aafe52018-04-27 14:54:57 +08001830 mShaderSamplers[gl::ShaderType::Compute].resize(
1831 data.getCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]);
Xinghua Cao26143fd2017-11-01 18:19:05 +08001832 mImagesCS.resize(data.getCaps().maxImageUnits);
1833 mReadonlyImagesCS.resize(data.getCaps().maxImageUnits);
Xinghua Caob1239382016-12-13 15:07:05 +08001834
Jiawei Shao3dd8d2912018-03-30 09:39:09 +08001835 mShaderUniformsDirty.set(gl::ShaderType::Compute);
Xinghua Caob1239382016-12-13 15:07:05 +08001836
jchen103fd614d2018-08-13 12:21:58 +08001837 linkResources(resources);
jchen107ae70d82018-07-06 13:47:01 +08001838
Xinghua Caof3179a62018-07-12 16:22:06 +08001839 for (const sh::Uniform &uniform : computeShader->getUniforms())
1840 {
1841 if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
1842 {
1843 mImage2DUniforms.push_back(uniform);
1844 }
1845 }
1846
1847 defineUniformsAndAssignRegisters();
1848
Jamie Madill785e8a02018-10-04 17:42:00 -04001849 angle::Result result = compileComputeExecutable(GetImplAs<ContextD3D>(context), infoLog);
Jamie Madill7c985f52018-11-29 18:16:17 -05001850 if (result != angle::Result::Continue)
Xinghua Caob1239382016-12-13 15:07:05 +08001851 {
1852 infoLog << "Failed to create D3D compute shader.";
Xinghua Caob1239382016-12-13 15:07:05 +08001853 }
jchen107ae70d82018-07-06 13:47:01 +08001854 return std::make_unique<LinkEventDone>(result);
Xinghua Caob1239382016-12-13 15:07:05 +08001855 }
1856 else
1857 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001858 gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
Jiawei Shao467c15f2018-04-24 15:04:26 +08001859 for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
1860 {
1861 if (mState.getAttachedShader(shaderType))
1862 {
1863 shadersD3D[shaderType] = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
Xinghua Caob1239382016-12-13 15:07:05 +08001864
Jiawei Shao467c15f2018-04-24 15:04:26 +08001865 mShaderSamplers[shaderType].resize(
Jiawei Shao54aafe52018-04-27 14:54:57 +08001866 data.getCaps().maxShaderTextureImageUnits[shaderType]);
Xinghua Caob1239382016-12-13 15:07:05 +08001867
Jiawei Shao467c15f2018-04-24 15:04:26 +08001868 shadersD3D[shaderType]->generateWorkarounds(&mShaderWorkarounds[shaderType]);
1869
1870 mShaderUniformsDirty.set(shaderType);
1871 }
1872 }
Xinghua Caob1239382016-12-13 15:07:05 +08001873
1874 if (mRenderer->getNativeLimitations().noFrontFacingSupport)
1875 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001876 if (shadersD3D[gl::ShaderType::Fragment]->usesFrontFacing())
Xinghua Caob1239382016-12-13 15:07:05 +08001877 {
1878 infoLog << "The current renderer doesn't support gl_FrontFacing";
Jamie Madill7c985f52018-11-29 18:16:17 -05001879 return std::make_unique<LinkEventDone>(angle::Result::Incomplete);
Xinghua Caob1239382016-12-13 15:07:05 +08001880 }
1881 }
1882
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001883 ProgramD3DMetadata metadata(mRenderer, shadersD3D);
Jamie Madillc9727f32017-11-07 12:37:07 -05001884 BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking);
Xinghua Caob1239382016-12-13 15:07:05 +08001885
jchen103fd614d2018-08-13 12:21:58 +08001886 mDynamicHLSL->generateShaderLinkHLSL(context->getCaps(), mState, metadata,
1887 resources.varyingPacking, builtins, &mShaderHLSL);
Xinghua Caob1239382016-12-13 15:07:05 +08001888
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001889 mUsesPointSize = shadersD3D[gl::ShaderType::Vertex]->usesPointSize();
Xinghua Caob1239382016-12-13 15:07:05 +08001890 mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
Xinghua Cao26143fd2017-11-01 18:19:05 +08001891 mUsesFragDepth = metadata.usesFragDepth();
Martin Radev41ac68e2017-06-06 12:16:58 +03001892 mUsesViewID = metadata.usesViewID();
1893 mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
Xinghua Caob1239382016-12-13 15:07:05 +08001894
1895 // Cache if we use flat shading
jchen103fd614d2018-08-13 12:21:58 +08001896 mUsesFlatInterpolation = FindFlatInterpolationVarying(mState.getAttachedShaders());
Xinghua Caob1239382016-12-13 15:07:05 +08001897
1898 if (mRenderer->getMajorShaderModel() >= 4)
1899 {
Martin Radev41ac68e2017-06-06 12:16:58 +03001900 mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
Jamie Madillc9727f32017-11-07 12:37:07 -05001901 resources.varyingPacking, builtins, mHasANGLEMultiviewEnabled,
Martin Radevc1d4e552017-08-21 12:01:10 +03001902 metadata.canSelectViewInVertexShader());
Xinghua Caob1239382016-12-13 15:07:05 +08001903 }
1904
jchen103fd614d2018-08-13 12:21:58 +08001905 initAttribLocationsToD3DSemantic();
Xinghua Caob1239382016-12-13 15:07:05 +08001906
jchen103fd614d2018-08-13 12:21:58 +08001907 defineUniformsAndAssignRegisters();
Xinghua Caob1239382016-12-13 15:07:05 +08001908
Jiawei Shao385b3e02018-03-21 09:43:28 +08001909 gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::ShaderType::Vertex]);
Xinghua Caob1239382016-12-13 15:07:05 +08001910
jchen103fd614d2018-08-13 12:21:58 +08001911 linkResources(resources);
jchen107ae70d82018-07-06 13:47:01 +08001912
1913 return compileProgramExecutables(context, infoLog);
Austin Kinross02df7962015-07-01 10:03:42 -07001914 }
Brandon Jones22502d52014-08-29 16:58:36 -07001915}
1916
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001917GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
Jamie Madill36cfd6a2015-08-18 10:46:20 -04001918{
Jamie Madill3d3d2f22015-09-23 16:47:51 -04001919 // TODO(jmadill): Do something useful here?
1920 return GL_TRUE;
Jamie Madill36cfd6a2015-08-18 10:46:20 -04001921}
1922
Qin Jiajiaa602f902018-09-11 14:40:24 +08001923void ProgramD3D::initializeShaderStorageBlocks()
1924{
1925 if (mState.getShaderStorageBlocks().empty())
1926 {
1927 return;
1928 }
1929
1930 ASSERT(mD3DShaderStorageBlocks.empty());
1931
1932 // Assign registers and update sizes.
1933 gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
1934 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1935 {
1936 shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
1937 }
1938
1939 for (const gl::InterfaceBlock &shaderStorageBlock : mState.getShaderStorageBlocks())
1940 {
1941 unsigned int shaderStorageBlockElement =
1942 shaderStorageBlock.isArray ? shaderStorageBlock.arrayElement : 0;
1943
1944 D3DInterfaceBlock d3dShaderStorageBlock;
1945
1946 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1947 {
1948 if (shaderStorageBlock.isActive(shaderType))
1949 {
1950 ASSERT(shadersD3D[shaderType]);
1951 unsigned int baseRegister =
1952 shadersD3D[shaderType]->getShaderStorageBlockRegister(shaderStorageBlock.name);
1953 d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] =
1954 baseRegister + shaderStorageBlockElement;
1955 }
1956 }
1957
1958 mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock);
1959 }
1960}
1961
Jamie Madill6db1c2e2017-11-08 09:17:40 -05001962void ProgramD3D::initializeUniformBlocks()
Jamie Madill62d31cb2015-09-11 13:25:51 -04001963{
Jamie Madill6db1c2e2017-11-08 09:17:40 -05001964 if (mState.getUniformBlocks().empty())
Jamie Madill51f522f2016-12-21 15:10:55 -05001965 {
1966 return;
1967 }
Jamie Madill62d31cb2015-09-11 13:25:51 -04001968
Jamie Madill6db1c2e2017-11-08 09:17:40 -05001969 ASSERT(mD3DUniformBlocks.empty());
1970
Jamie Madill62d31cb2015-09-11 13:25:51 -04001971 // Assign registers and update sizes.
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001972 gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
1973 for (gl::ShaderType shaderType : gl::AllShaderTypes())
1974 {
1975 shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
1976 }
Jamie Madill62d31cb2015-09-11 13:25:51 -04001977
Jiajia Qin729b2c62017-08-14 09:36:11 +08001978 for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
Jamie Madill62d31cb2015-09-11 13:25:51 -04001979 {
1980 unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
1981
Qin Jiajiaa602f902018-09-11 14:40:24 +08001982 D3DInterfaceBlock d3dUniformBlock;
Jamie Madill4a3c2342015-10-08 12:58:45 -04001983
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001984 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madill62d31cb2015-09-11 13:25:51 -04001985 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08001986 if (uniformBlock.isActive(shaderType))
1987 {
1988 ASSERT(shadersD3D[shaderType]);
1989 unsigned int baseRegister =
1990 shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name);
1991 d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
1992 baseRegister + uniformBlockElement;
1993 }
Xinghua Caob1239382016-12-13 15:07:05 +08001994 }
1995
Jamie Madill4a3c2342015-10-08 12:58:45 -04001996 mD3DUniformBlocks.push_back(d3dUniformBlock);
Jamie Madill62d31cb2015-09-11 13:25:51 -04001997 }
1998}
1999
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002000void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages)
Brandon Jonesc9610c52014-08-25 17:02:59 -07002001{
2002 // Compute total default block size
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002003 gl::ShaderMap<unsigned int> shaderRegisters = {};
Jamie Madill62d31cb2015-09-11 13:25:51 -04002004 for (const D3DUniform *d3dUniform : mD3DUniforms)
Brandon Jonesc9610c52014-08-25 17:02:59 -07002005 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002006 if (d3dUniform->isSampler())
Brandon Jonesc9610c52014-08-25 17:02:59 -07002007 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002008 continue;
2009 }
2010
Jiawei Shao0661eb82018-06-13 10:51:54 +08002011 for (gl::ShaderType shaderType : availableShaderStages)
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002012 {
2013 if (d3dUniform->isReferencedByShader(shaderType))
Brandon Jonesc9610c52014-08-25 17:02:59 -07002014 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002015 shaderRegisters[shaderType] = std::max(
2016 shaderRegisters[shaderType],
2017 d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount);
Xinghua Caob1239382016-12-13 15:07:05 +08002018 }
Brandon Jonesc9610c52014-08-25 17:02:59 -07002019 }
2020 }
2021
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002022 // We only reset uniform storages for the shader stages available in the program (attached
2023 // shaders in ProgramD3D::link() and linkedShaderStages in ProgramD3D::load()).
Jiawei Shao0661eb82018-06-13 10:51:54 +08002024 for (gl::ShaderType shaderType : availableShaderStages)
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002025 {
Jiawei Shao0661eb82018-06-13 10:51:54 +08002026 mShaderUniformStorages[shaderType].reset(
2027 mRenderer->createUniformStorage(shaderRegisters[shaderType] * 16u));
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002028 }
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002029
2030 // Iterate the uniforms again to assign data pointers to default block uniforms.
2031 for (D3DUniform *d3dUniform : mD3DUniforms)
2032 {
2033 if (d3dUniform->isSampler())
2034 {
Olli Etuaho465835d2017-09-26 13:34:10 +03002035 d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0);
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002036 continue;
2037 }
2038
Jiawei Shao0661eb82018-06-13 10:51:54 +08002039 for (gl::ShaderType shaderType : availableShaderStages)
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002040 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002041 if (d3dUniform->isReferencedByShader(shaderType))
2042 {
2043 d3dUniform->mShaderData[shaderType] =
2044 mShaderUniformStorages[shaderType]->getDataPointer(
2045 d3dUniform->mShaderRegisterIndexes[shaderType],
2046 d3dUniform->registerElement);
2047 }
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002048 }
2049 }
Brandon Jonesc9610c52014-08-25 17:02:59 -07002050}
2051
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002052void ProgramD3D::updateUniformBufferCache(
2053 const gl::Caps &caps,
2054 const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes)
Brandon Jones18bd4102014-09-22 14:21:44 -07002055{
Jamie Madill48ef11b2016-04-27 15:21:52 -04002056 if (mState.getUniformBlocks().empty())
Jamie Madill4a3c2342015-10-08 12:58:45 -04002057 {
Jamie Madilld63961d2017-09-12 15:22:57 -04002058 return;
Jamie Madill4a3c2342015-10-08 12:58:45 -04002059 }
2060
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002061 for (gl::ShaderType shaderType : gl::AllShaderTypes())
2062 {
2063 mShaderUBOCaches[shaderType].clear();
2064 }
Brandon Jones18bd4102014-09-22 14:21:44 -07002065
Jamie Madill4a3c2342015-10-08 12:58:45 -04002066 for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
Jamie Madill62d31cb2015-09-11 13:25:51 -04002067 uniformBlockIndex++)
Brandon Jones18bd4102014-09-22 14:21:44 -07002068 {
Qin Jiajiaa602f902018-09-11 14:40:24 +08002069 const D3DInterfaceBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
Jamie Madillb980c562018-11-27 11:34:27 -05002070 GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex);
Brandon Jones18bd4102014-09-22 14:21:44 -07002071
Brandon Jones18bd4102014-09-22 14:21:44 -07002072 // Unnecessary to apply an unreferenced standard or shared UBO
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002073 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Brandon Jones18bd4102014-09-22 14:21:44 -07002074 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002075 if (!uniformBlock.activeInShader(shaderType))
2076 {
2077 continue;
2078 }
Brandon Jones18bd4102014-09-22 14:21:44 -07002079
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002080 unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType] -
2081 reservedShaderRegisterIndexes[shaderType];
Jiawei Shao54aafe52018-04-27 14:54:57 +08002082 ASSERT(registerIndex < caps.maxShaderUniformBlocks[shaderType]);
Jamie Madill03260fa2015-06-22 13:57:22 -04002083
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002084 std::vector<int> &shaderUBOcache = mShaderUBOCaches[shaderType];
2085 if (shaderUBOcache.size() <= registerIndex)
Jamie Madill03260fa2015-06-22 13:57:22 -04002086 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002087 shaderUBOcache.resize(registerIndex + 1, -1);
Jamie Madill03260fa2015-06-22 13:57:22 -04002088 }
2089
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002090 ASSERT(shaderUBOcache[registerIndex] == -1);
2091 shaderUBOcache[registerIndex] = blockBinding;
Brandon Jones18bd4102014-09-22 14:21:44 -07002092 }
2093 }
Jamie Madilld63961d2017-09-12 15:22:57 -04002094}
Brandon Jones18bd4102014-09-22 14:21:44 -07002095
Qin Jiajiaa602f902018-09-11 14:40:24 +08002096unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex,
2097 gl::ShaderType shaderType) const
2098{
2099 return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
2100}
2101
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002102const std::vector<GLint> &ProgramD3D::getShaderUniformBufferCache(gl::ShaderType shaderType) const
Jamie Madilld63961d2017-09-12 15:22:57 -04002103{
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002104 return mShaderUBOCaches[shaderType];
Brandon Jones18bd4102014-09-22 14:21:44 -07002105}
2106
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002107void ProgramD3D::dirtyAllUniforms()
Brandon Jones18bd4102014-09-22 14:21:44 -07002108{
Jiawei Shao3dd8d2912018-03-30 09:39:09 +08002109 mShaderUniformsDirty = mState.getLinkedShaderStages();
Jamie Madill4148fd72017-09-14 15:46:20 -04002110}
2111
2112void ProgramD3D::markUniformsClean()
2113{
Jiawei Shao3dd8d2912018-03-30 09:39:09 +08002114 mShaderUniformsDirty.reset();
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002115}
2116
Jamie Madill334d6152015-10-22 14:00:28 -04002117void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002118{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002119 setUniformInternal(location, count, v, GL_FLOAT);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002120}
2121
2122void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
2123{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002124 setUniformInternal(location, count, v, GL_FLOAT_VEC2);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002125}
2126
2127void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
2128{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002129 setUniformInternal(location, count, v, GL_FLOAT_VEC3);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002130}
2131
2132void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
2133{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002134 setUniformInternal(location, count, v, GL_FLOAT_VEC4);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002135}
2136
Jamie Madill334d6152015-10-22 14:00:28 -04002137void ProgramD3D::setUniformMatrix2fv(GLint location,
2138 GLsizei count,
2139 GLboolean transpose,
2140 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002141{
Luc Ferron46bcea52018-05-31 09:48:36 -04002142 setUniformMatrixfvInternal<2, 2>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002143}
2144
Jamie Madill334d6152015-10-22 14:00:28 -04002145void ProgramD3D::setUniformMatrix3fv(GLint location,
2146 GLsizei count,
2147 GLboolean transpose,
2148 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002149{
Luc Ferron46bcea52018-05-31 09:48:36 -04002150 setUniformMatrixfvInternal<3, 3>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002151}
2152
Jamie Madill334d6152015-10-22 14:00:28 -04002153void ProgramD3D::setUniformMatrix4fv(GLint location,
2154 GLsizei count,
2155 GLboolean transpose,
2156 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002157{
Luc Ferron46bcea52018-05-31 09:48:36 -04002158 setUniformMatrixfvInternal<4, 4>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002159}
2160
Jamie Madill334d6152015-10-22 14:00:28 -04002161void ProgramD3D::setUniformMatrix2x3fv(GLint location,
2162 GLsizei count,
2163 GLboolean transpose,
2164 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002165{
Luc Ferron46bcea52018-05-31 09:48:36 -04002166 setUniformMatrixfvInternal<2, 3>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002167}
2168
Jamie Madill334d6152015-10-22 14:00:28 -04002169void ProgramD3D::setUniformMatrix3x2fv(GLint location,
2170 GLsizei count,
2171 GLboolean transpose,
2172 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002173{
Luc Ferron46bcea52018-05-31 09:48:36 -04002174 setUniformMatrixfvInternal<3, 2>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002175}
2176
Jamie Madill334d6152015-10-22 14:00:28 -04002177void ProgramD3D::setUniformMatrix2x4fv(GLint location,
2178 GLsizei count,
2179 GLboolean transpose,
2180 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002181{
Luc Ferron46bcea52018-05-31 09:48:36 -04002182 setUniformMatrixfvInternal<2, 4>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002183}
2184
Jamie Madill334d6152015-10-22 14:00:28 -04002185void ProgramD3D::setUniformMatrix4x2fv(GLint location,
2186 GLsizei count,
2187 GLboolean transpose,
2188 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002189{
Luc Ferron46bcea52018-05-31 09:48:36 -04002190 setUniformMatrixfvInternal<4, 2>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002191}
2192
Jamie Madill334d6152015-10-22 14:00:28 -04002193void ProgramD3D::setUniformMatrix3x4fv(GLint location,
2194 GLsizei count,
2195 GLboolean transpose,
2196 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002197{
Luc Ferron46bcea52018-05-31 09:48:36 -04002198 setUniformMatrixfvInternal<3, 4>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002199}
2200
Jamie Madill334d6152015-10-22 14:00:28 -04002201void ProgramD3D::setUniformMatrix4x3fv(GLint location,
2202 GLsizei count,
2203 GLboolean transpose,
2204 const GLfloat *value)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002205{
Luc Ferron46bcea52018-05-31 09:48:36 -04002206 setUniformMatrixfvInternal<4, 3>(location, count, transpose, value);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002207}
2208
2209void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
2210{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002211 setUniformInternal(location, count, v, GL_INT);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002212}
2213
2214void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
2215{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002216 setUniformInternal(location, count, v, GL_INT_VEC2);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002217}
2218
2219void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
2220{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002221 setUniformInternal(location, count, v, GL_INT_VEC3);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002222}
2223
2224void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
2225{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002226 setUniformInternal(location, count, v, GL_INT_VEC4);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002227}
2228
2229void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
2230{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002231 setUniformInternal(location, count, v, GL_UNSIGNED_INT);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002232}
2233
2234void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
2235{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002236 setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002237}
2238
2239void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
2240{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002241 setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002242}
2243
2244void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
2245{
Jamie Madill33bb7c42017-09-09 23:32:51 -04002246 setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002247}
2248
jchen103fd614d2018-08-13 12:21:58 +08002249void ProgramD3D::defineUniformsAndAssignRegisters()
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002250{
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002251 D3DUniformMap uniformMap;
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002252
2253 gl::ShaderBitSet attachedShaders;
Jiawei Shao385b3e02018-03-21 09:43:28 +08002254 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madill417df922017-01-12 09:23:07 -05002255 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08002256 gl::Shader *shader = mState.getAttachedShader(shaderType);
2257 if (shader)
Jamie Madillfb536032015-09-11 13:19:49 -04002258 {
jchen103fd614d2018-08-13 12:21:58 +08002259 for (const sh::Uniform &uniform : shader->getUniforms())
Xinghua Caob1239382016-12-13 15:07:05 +08002260 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08002261 if (uniform.active)
2262 {
2263 defineUniformBase(shader, uniform, &uniformMap);
2264 }
Xinghua Caob1239382016-12-13 15:07:05 +08002265 }
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002266
2267 attachedShaders.set(shader->getType());
Jamie Madillfb536032015-09-11 13:19:49 -04002268 }
2269 }
2270
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002271 // Initialize the D3DUniform list to mirror the indexing of the GL layer.
Jamie Madill48ef11b2016-04-27 15:21:52 -04002272 for (const gl::LinkedUniform &glUniform : mState.getUniforms())
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002273 {
2274 if (!glUniform.isInDefaultBlock())
2275 continue;
2276
Olli Etuahod2551232017-10-26 20:03:33 +03002277 std::string name = glUniform.name;
2278 if (glUniform.isArray())
2279 {
2280 // In the program state, array uniform names include [0] as in the program resource
2281 // spec. Here we don't include it.
2282 // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL
2283 // layer.
2284 ASSERT(angle::EndsWith(name, "[0]"));
2285 name.resize(name.length() - 3);
2286 }
2287 auto mapEntry = uniformMap.find(name);
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002288 ASSERT(mapEntry != uniformMap.end());
2289 mD3DUniforms.push_back(mapEntry->second);
2290 }
2291
Jamie Madill62d31cb2015-09-11 13:25:51 -04002292 assignAllSamplerRegisters();
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002293 // Samplers and readonly images share shader input resource slot, adjust low value of
2294 // readonly image range.
2295 mUsedComputeReadonlyImageRange =
2296 gl::RangeUI(mUsedShaderSamplerRanges[gl::ShaderType::Compute].high(),
2297 mUsedShaderSamplerRanges[gl::ShaderType::Compute].high());
Xinghua Cao26143fd2017-11-01 18:19:05 +08002298 assignAllImageRegisters();
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002299 initializeUniformStorage(attachedShaders);
Jamie Madillfb536032015-09-11 13:19:49 -04002300}
2301
Jamie Madill91445bc2015-09-23 16:47:53 -04002302void ProgramD3D::defineUniformBase(const gl::Shader *shader,
Jamie Madill3d3d2f22015-09-23 16:47:51 -04002303 const sh::Uniform &uniform,
2304 D3DUniformMap *uniformMap)
Jamie Madillfb536032015-09-11 13:19:49 -04002305{
Jamie Madill8c78ce42018-12-16 19:14:58 -05002306 sh::DummyBlockEncoder dummyEncoder;
2307
Xinghua Cao26143fd2017-11-01 18:19:05 +08002308 // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their
2309 // registers assigned in assignAllImageRegisters.
2310 if (gl::IsSamplerType(uniform.type))
Jamie Madillfb536032015-09-11 13:19:49 -04002311 {
Jamie Madill8c78ce42018-12-16 19:14:58 -05002312 UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
2313 &dummyEncoder, uniformMap);
2314 sh::TraverseShaderVariable(uniform, false, &visitor);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002315 return;
2316 }
Jamie Madill8c78ce42018-12-16 19:14:58 -05002317
2318 if (gl::IsImageType(uniform.type))
Xinghua Cao26143fd2017-11-01 18:19:05 +08002319 {
2320 if (uniform.readonly)
2321 {
Jamie Madill8c78ce42018-12-16 19:14:58 -05002322 UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
2323 &dummyEncoder, uniformMap);
2324 sh::TraverseShaderVariable(uniform, false, &visitor);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002325 }
2326 else
2327 {
Jamie Madill8c78ce42018-12-16 19:14:58 -05002328 UniformEncodingVisitorD3D visitor(shader->getType(),
2329 HLSLRegisterType::UnorderedAccessView, &dummyEncoder,
2330 uniformMap);
2331 sh::TraverseShaderVariable(uniform, false, &visitor);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002332 }
2333 mImageBindingMap[uniform.name] = uniform.binding;
2334 return;
2335 }
Jamie Madill8c78ce42018-12-16 19:14:58 -05002336
2337 if (uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn())
Xinghua Cao26143fd2017-11-01 18:19:05 +08002338 {
Jamie Madill8c78ce42018-12-16 19:14:58 -05002339 UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &dummyEncoder,
2340 uniformMap);
2341 sh::TraverseShaderVariable(uniform, false, &visitor);
Jamie Madill55def582015-05-04 11:24:57 -04002342 return;
2343 }
2344
Jamie Madill91445bc2015-09-23 16:47:53 -04002345 const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shader);
Jamie Madill91445bc2015-09-23 16:47:53 -04002346 unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002347 ShShaderOutput outputType = shaderD3D->getCompilerOutputType();
Jamie Madillcc2ed612017-03-14 15:59:00 -04002348 sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true);
Jamie Madill62d31cb2015-09-11 13:25:51 -04002349 encoder.skipRegisters(startRegister);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002350
Jamie Madill8c78ce42018-12-16 19:14:58 -05002351 UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &encoder,
2352 uniformMap);
2353 sh::TraverseShaderVariable(uniform, false, &visitor);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002354}
2355
Xinghua Caof3179a62018-07-12 16:22:06 +08002356bool ProgramD3D::hasNamedUniform(const std::string &name)
Jamie Madill62d31cb2015-09-11 13:25:51 -04002357{
2358 for (D3DUniform *d3dUniform : mD3DUniforms)
2359 {
2360 if (d3dUniform->name == name)
2361 {
Xinghua Caof3179a62018-07-12 16:22:06 +08002362 return true;
Jamie Madill62d31cb2015-09-11 13:25:51 -04002363 }
2364 }
2365
Xinghua Caof3179a62018-07-12 16:22:06 +08002366 return false;
Jamie Madill62d31cb2015-09-11 13:25:51 -04002367}
2368
Jamie Madill134f93d2017-08-31 17:11:00 -04002369// Assume count is already clamped.
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002370template <typename T>
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002371void ProgramD3D::setUniformImpl(const gl::VariableLocation &locationInfo,
Jamie Madill134f93d2017-08-31 17:11:00 -04002372 GLsizei count,
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002373 const T *v,
2374 uint8_t *targetData,
Jamie Madill33bb7c42017-09-09 23:32:51 -04002375 GLenum uniformType)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002376{
Jamie Madill493f9572018-05-24 19:52:15 -04002377 D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
2378 const int components = targetUniform->typeInfo.componentCount;
Olli Etuaho1734e172017-10-27 15:30:27 +03002379 const unsigned int arrayElementOffset = locationInfo.arrayIndex;
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002380
Jamie Madill33bb7c42017-09-09 23:32:51 -04002381 if (targetUniform->typeInfo.type == uniformType)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002382 {
Olli Etuahoc8538042017-09-27 11:20:15 +03002383 T *dest = reinterpret_cast<T *>(targetData) + arrayElementOffset * 4;
Jamie Madill33bb7c42017-09-09 23:32:51 -04002384 const T *source = v;
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002385
Jamie Madill33bb7c42017-09-09 23:32:51 -04002386 for (GLint i = 0; i < count; i++, dest += 4, source += components)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002387 {
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002388 memcpy(dest, source, components * sizeof(T));
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002389 }
2390 }
Jamie Madill33bb7c42017-09-09 23:32:51 -04002391 else
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002392 {
Jamie Madill33bb7c42017-09-09 23:32:51 -04002393 ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType));
Olli Etuahoc8538042017-09-27 11:20:15 +03002394 GLint *boolParams = reinterpret_cast<GLint *>(targetData) + arrayElementOffset * 4;
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002395
Jamie Madill134f93d2017-08-31 17:11:00 -04002396 for (GLint i = 0; i < count; i++)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002397 {
Jamie Madill334d6152015-10-22 14:00:28 -04002398 GLint *dest = boolParams + (i * 4);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002399 const T *source = v + (i * components);
2400
2401 for (int c = 0; c < components; c++)
2402 {
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002403 dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002404 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002405 }
Brandon Jones18bd4102014-09-22 14:21:44 -07002406 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002407}
2408
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002409template <typename T>
Jamie Madill33bb7c42017-09-09 23:32:51 -04002410void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002411{
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002412 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
2413 D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
2414
Jamie Madill33bb7c42017-09-09 23:32:51 -04002415 if (targetUniform->typeInfo.isSampler)
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002416 {
Jamie Madill33bb7c42017-09-09 23:32:51 -04002417 ASSERT(uniformType == GL_INT);
Jamie Madill80823cc2017-09-14 15:46:21 -04002418 size_t size = count * sizeof(T);
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002419 GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex];
Jamie Madill80823cc2017-09-14 15:46:21 -04002420 if (memcmp(dest, v, size) != 0)
2421 {
2422 memcpy(dest, v, size);
2423 mDirtySamplerMapping = true;
2424 }
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002425 return;
2426 }
2427
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002428 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002429 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002430 if (targetUniform->mShaderData[shaderType])
2431 {
2432 setUniformImpl(locationInfo, count, v, targetUniform->mShaderData[shaderType],
2433 uniformType);
2434 mShaderUniformsDirty.set(shaderType);
2435 }
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002436 }
2437}
2438
2439template <int cols, int rows>
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002440void ProgramD3D::setUniformMatrixfvInternal(GLint location,
2441 GLsizei countIn,
2442 GLboolean transpose,
Luc Ferron46bcea52018-05-31 09:48:36 -04002443 const GLfloat *value)
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002444{
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002445 D3DUniform *targetUniform = getD3DUniformFromLocation(location);
Luc Ferron46bcea52018-05-31 09:48:36 -04002446 const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location];
2447 unsigned int arrayElementOffset = uniformLocation.arrayIndex;
2448 unsigned int elementCount = targetUniform->getArraySizeProduct();
2449
2450 // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
2451 transpose = !transpose;
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002452
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002453 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002454 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002455 if (targetUniform->mShaderData[shaderType])
Jamie Madill80823cc2017-09-14 15:46:21 -04002456 {
Luc Ferron46bcea52018-05-31 09:48:36 -04002457 if (SetFloatUniformMatrix<cols, rows>(arrayElementOffset, elementCount, countIn,
2458 transpose, value,
2459 targetUniform->mShaderData[shaderType]))
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002460 {
2461 mShaderUniformsDirty.set(shaderType);
2462 }
Jamie Madill80823cc2017-09-14 15:46:21 -04002463 }
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002464 }
2465}
2466
Jamie Madill62d31cb2015-09-11 13:25:51 -04002467void ProgramD3D::assignAllSamplerRegisters()
Jamie Madilla2eb02c2015-09-11 12:31:41 +00002468{
Olli Etuaho465835d2017-09-26 13:34:10 +03002469 for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
Jamie Madilla2eb02c2015-09-11 12:31:41 +00002470 {
Olli Etuaho465835d2017-09-26 13:34:10 +03002471 if (mD3DUniforms[uniformIndex]->isSampler())
Jamie Madillfb536032015-09-11 13:19:49 -04002472 {
Olli Etuaho465835d2017-09-26 13:34:10 +03002473 assignSamplerRegisters(uniformIndex);
Jamie Madillfb536032015-09-11 13:19:49 -04002474 }
Jamie Madilla2eb02c2015-09-11 12:31:41 +00002475 }
2476}
2477
Olli Etuaho465835d2017-09-26 13:34:10 +03002478void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
Jamie Madillfb536032015-09-11 13:19:49 -04002479{
Olli Etuaho465835d2017-09-26 13:34:10 +03002480 D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
Jamie Madill62d31cb2015-09-11 13:25:51 -04002481 ASSERT(d3dUniform->isSampler());
Olli Etuaho465835d2017-09-26 13:34:10 +03002482 // If the uniform is an array of arrays, then we have separate entries for each inner array in
2483 // mD3DUniforms. However, the sampler register info is stored in the shader only for the
2484 // outermost array.
2485 std::vector<unsigned int> subscripts;
Jamie Madill8c78ce42018-12-16 19:14:58 -05002486 const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
2487 unsigned int registerOffset =
2488 mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
Olli Etuaho465835d2017-09-26 13:34:10 +03002489
Jiawei Shao467c15f2018-04-24 15:04:26 +08002490 bool hasUniform = false;
2491 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madillfb536032015-09-11 13:19:49 -04002492 {
Jiawei Shao467c15f2018-04-24 15:04:26 +08002493 if (!mState.getAttachedShader(shaderType))
Xinghua Caob1239382016-12-13 15:07:05 +08002494 {
Jiawei Shao467c15f2018-04-24 15:04:26 +08002495 continue;
Xinghua Caob1239382016-12-13 15:07:05 +08002496 }
Jiawei Shao467c15f2018-04-24 15:04:26 +08002497
2498 const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
2499 if (shaderD3D->hasUniform(baseName))
Xinghua Caob1239382016-12-13 15:07:05 +08002500 {
Jiawei Shao467c15f2018-04-24 15:04:26 +08002501 d3dUniform->mShaderRegisterIndexes[shaderType] =
2502 shaderD3D->getUniformRegister(baseName) + registerOffset;
2503 ASSERT(d3dUniform->mShaderRegisterIndexes[shaderType] != GL_INVALID_VALUE);
2504
2505 AssignSamplers(d3dUniform->mShaderRegisterIndexes[shaderType], d3dUniform->typeInfo,
2506 d3dUniform->getArraySizeProduct(), mShaderSamplers[shaderType],
2507 &mUsedShaderSamplerRanges[shaderType]);
2508 hasUniform = true;
Xinghua Caob1239382016-12-13 15:07:05 +08002509 }
Jamie Madillfb536032015-09-11 13:19:49 -04002510 }
Jiawei Shao467c15f2018-04-24 15:04:26 +08002511
2512 ASSERT(hasUniform);
Jamie Madillfb536032015-09-11 13:19:49 -04002513}
2514
Jamie Madill62d31cb2015-09-11 13:25:51 -04002515// static
2516void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
Jamie Madill33bb7c42017-09-09 23:32:51 -04002517 const gl::UniformTypeInfo &typeInfo,
Jamie Madilld3dfda22015-07-06 08:28:49 -04002518 unsigned int samplerCount,
2519 std::vector<Sampler> &outSamplers,
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002520 gl::RangeUI *outUsedRange)
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002521{
2522 unsigned int samplerIndex = startSamplerIndex;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002523 unsigned int low = outUsedRange->low();
2524 unsigned int high = outUsedRange->high();
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002525
2526 do
2527 {
Jamie Madill62d31cb2015-09-11 13:25:51 -04002528 ASSERT(samplerIndex < outSamplers.size());
2529 Sampler *sampler = &outSamplers[samplerIndex];
2530 sampler->active = true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002531 sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
Jamie Madill62d31cb2015-09-11 13:25:51 -04002532 sampler->logicalTextureUnit = 0;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002533 low = std::min(samplerIndex, low);
2534 high = std::max(samplerIndex + 1, high);
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002535 samplerIndex++;
2536 } while (samplerIndex < startSamplerIndex + samplerCount);
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002537
2538 ASSERT(low < high);
2539 *outUsedRange = gl::RangeUI(low, high);
Brandon Jones18bd4102014-09-22 14:21:44 -07002540}
2541
Xinghua Cao26143fd2017-11-01 18:19:05 +08002542void ProgramD3D::assignAllImageRegisters()
2543{
2544 for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
2545 {
Xinghua Caof3179a62018-07-12 16:22:06 +08002546 if (mD3DUniforms[uniformIndex]->isImage() && !mD3DUniforms[uniformIndex]->isImage2D())
Xinghua Cao26143fd2017-11-01 18:19:05 +08002547 {
2548 assignImageRegisters(uniformIndex);
2549 }
2550 }
2551}
2552
2553void ProgramD3D::assignImageRegisters(size_t uniformIndex)
2554{
2555 D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
2556 ASSERT(d3dUniform->isImage());
2557 // If the uniform is an array of arrays, then we have separate entries for each inner array in
2558 // mD3DUniforms. However, the image register info is stored in the shader only for the
2559 // outermost array.
2560 std::vector<unsigned int> subscripts;
Jamie Madill8c78ce42018-12-16 19:14:58 -05002561 const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
2562 unsigned int registerOffset =
2563 mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
Xinghua Cao26143fd2017-11-01 18:19:05 +08002564
Jiawei Shao385b3e02018-03-21 09:43:28 +08002565 const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002566 if (computeShader)
2567 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08002568 const ShaderD3D *computeShaderD3D =
2569 GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
Xinghua Cao26143fd2017-11-01 18:19:05 +08002570 ASSERT(computeShaderD3D->hasUniform(baseName));
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002571 d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
Xinghua Cao26143fd2017-11-01 18:19:05 +08002572 computeShaderD3D->getUniformRegister(baseName) + registerOffset;
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002573 ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002574 auto bindingIter = mImageBindingMap.find(baseName);
2575 ASSERT(bindingIter != mImageBindingMap.end());
2576 if (d3dUniform->regType == HLSLRegisterType::Texture)
2577 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002578 AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
2579 bindingIter->second, d3dUniform->getArraySizeProduct(), mReadonlyImagesCS,
Xinghua Cao26143fd2017-11-01 18:19:05 +08002580 &mUsedComputeReadonlyImageRange);
2581 }
2582 else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
2583 {
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002584 AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
2585 bindingIter->second, d3dUniform->getArraySizeProduct(), mImagesCS,
2586 &mUsedComputeImageRange);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002587 }
2588 else
2589 {
2590 UNREACHABLE();
2591 }
2592 }
2593 else
2594 {
2595 // TODO(xinghua.cao@intel.com): Implement image variables in vertex shader and pixel shader.
2596 UNIMPLEMENTED();
2597 }
2598}
2599
2600// static
2601void ProgramD3D::AssignImages(unsigned int startImageIndex,
2602 int startLogicalImageUnit,
2603 unsigned int imageCount,
2604 std::vector<Image> &outImages,
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002605 gl::RangeUI *outUsedRange)
Xinghua Cao26143fd2017-11-01 18:19:05 +08002606{
2607 unsigned int imageIndex = startImageIndex;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002608 unsigned int low = outUsedRange->low();
2609 unsigned int high = outUsedRange->high();
2610
Xinghua Cao26143fd2017-11-01 18:19:05 +08002611 // If declare without a binding qualifier, any uniform image variable (include all elements of
2612 // unbound image array) shoud be bound to unit zero.
2613 if (startLogicalImageUnit == -1)
2614 {
2615 ASSERT(imageIndex < outImages.size());
2616 Image *image = &outImages[imageIndex];
2617 image->active = true;
2618 image->logicalImageUnit = 0;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002619 low = std::min(imageIndex, low);
2620 high = std::max(imageIndex + 1, high);
2621 ASSERT(low < high);
2622 *outUsedRange = gl::RangeUI(low, high);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002623 return;
2624 }
2625
2626 unsigned int logcalImageUnit = startLogicalImageUnit;
2627 do
2628 {
2629 ASSERT(imageIndex < outImages.size());
2630 Image *image = &outImages[imageIndex];
2631 image->active = true;
2632 image->logicalImageUnit = logcalImageUnit;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002633 low = std::min(imageIndex, low);
2634 high = std::max(imageIndex + 1, high);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002635 imageIndex++;
2636 logcalImageUnit++;
2637 } while (imageIndex < startImageIndex + imageCount);
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002638
2639 ASSERT(low < high);
2640 *outUsedRange = gl::RangeUI(low, high);
Xinghua Cao26143fd2017-11-01 18:19:05 +08002641}
2642
Xinghua Caof3179a62018-07-12 16:22:06 +08002643void ProgramD3D::assignImage2DRegisters(unsigned int startImageIndex,
2644 int startLogicalImageUnit,
2645 bool readonly)
2646{
2647 if (readonly)
2648 {
2649 AssignImages(startImageIndex, startLogicalImageUnit, 1, mReadonlyImagesCS,
2650 &mUsedComputeReadonlyImageRange);
2651 }
2652 else
2653 {
2654 AssignImages(startImageIndex, startLogicalImageUnit, 1, mImagesCS, &mUsedComputeImageRange);
2655 }
2656}
2657
Brandon Jonesc9610c52014-08-25 17:02:59 -07002658void ProgramD3D::reset()
2659{
Xinghua Caob1239382016-12-13 15:07:05 +08002660 mVertexExecutables.clear();
2661 mPixelExecutables.clear();
Xinghua Caof3179a62018-07-12 16:22:06 +08002662 mComputeExecutables.clear();
Jamie Madill4e31ad52015-10-29 10:32:57 -04002663
Xinghua Caob1239382016-12-13 15:07:05 +08002664 for (auto &geometryExecutable : mGeometryExecutables)
Jamie Madill4e31ad52015-10-29 10:32:57 -04002665 {
Xinghua Caob1239382016-12-13 15:07:05 +08002666 geometryExecutable.reset(nullptr);
Jamie Madill4e31ad52015-10-29 10:32:57 -04002667 }
Brandon Joneseb994362014-09-24 10:27:28 -07002668
Jiawei Shao467c15f2018-04-24 15:04:26 +08002669 for (gl::ShaderType shaderType : gl::AllShaderTypes())
2670 {
2671 mShaderHLSL[shaderType].clear();
2672 mShaderWorkarounds[shaderType] = CompilerWorkaroundsD3D();
2673 }
Brandon Jones22502d52014-08-29 16:58:36 -07002674
Xinghua Cao26143fd2017-11-01 18:19:05 +08002675 mUsesFragDepth = false;
Martin Radev41ac68e2017-06-06 12:16:58 +03002676 mHasANGLEMultiviewEnabled = false;
2677 mUsesViewID = false;
Brandon Jones22502d52014-08-29 16:58:36 -07002678 mPixelShaderKey.clear();
Xinghua Cao26143fd2017-11-01 18:19:05 +08002679 mUsesPointSize = false;
Jamie Madill3e14e2b2015-10-29 14:38:53 -04002680 mUsesFlatInterpolation = false;
Brandon Jones22502d52014-08-29 16:58:36 -07002681
Jamie Madill62d31cb2015-09-11 13:25:51 -04002682 SafeDeleteContainer(mD3DUniforms);
Jamie Madill4a3c2342015-10-08 12:58:45 -04002683 mD3DUniformBlocks.clear();
Qin Jiajiaa602f902018-09-11 14:40:24 +08002684 mD3DShaderStorageBlocks.clear();
Jamie Madill62d31cb2015-09-11 13:25:51 -04002685
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002686 for (gl::ShaderType shaderType : gl::AllShaderTypes())
2687 {
2688 mShaderUniformStorages[shaderType].reset();
Jiawei Shao467c15f2018-04-24 15:04:26 +08002689 mShaderSamplers[shaderType].clear();
Jiawei Shaoaf2b33b2018-04-19 10:01:52 +08002690 }
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002691
Xinghua Cao26143fd2017-11-01 18:19:05 +08002692 mImagesCS.clear();
2693 mReadonlyImagesCS.clear();
Brandon Jones1a8a7e32014-10-01 12:49:30 -07002694
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002695 mUsedShaderSamplerRanges.fill({0, 0});
Xinghua Cao26143fd2017-11-01 18:19:05 +08002696 mDirtySamplerMapping = true;
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002697 mUsedComputeImageRange = {0, 0};
2698 mUsedComputeReadonlyImageRange = {0, 0};
Jamie Madill437d2662014-12-05 14:23:35 -05002699
Jamie Madill8047c0d2016-03-07 13:02:12 -05002700 mAttribLocationToD3DSemantic.fill(-1);
Jamie Madillccdf74b2015-08-18 10:46:12 -04002701
Jamie Madill9fc36822015-11-18 13:08:07 -05002702 mStreamOutVaryings.clear();
Jamie Madill4e31ad52015-10-29 10:32:57 -04002703
2704 mGeometryShaderPreamble.clear();
Jamie Madill561ed3a2017-08-31 16:48:09 -04002705
Jiawei Shao3dd8d2912018-03-30 09:39:09 +08002706 markUniformsClean();
Jamie Madill0e7f1732017-09-09 23:32:50 -04002707
2708 mCachedPixelExecutableIndex.reset();
2709 mCachedVertexExecutableIndex.reset();
Brandon Jonesc9610c52014-08-25 17:02:59 -07002710}
2711
Geoff Lang7dd2e102014-11-10 15:19:26 -05002712unsigned int ProgramD3D::getSerial() const
2713{
2714 return mSerial;
2715}
2716
2717unsigned int ProgramD3D::issueSerial()
2718{
2719 return mCurrentSerial++;
2720}
2721
jchen103fd614d2018-08-13 12:21:58 +08002722void ProgramD3D::initAttribLocationsToD3DSemantic()
Jamie Madill63805b42015-08-25 13:17:39 -04002723{
Jiawei Shao385b3e02018-03-21 09:43:28 +08002724 gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
Jamie Madill63805b42015-08-25 13:17:39 -04002725 ASSERT(vertexShader != nullptr);
2726
2727 // Init semantic index
Jamie Madill34ca4f52017-06-13 11:49:39 -04002728 int semanticIndex = 0;
jchen103fd614d2018-08-13 12:21:58 +08002729 for (const sh::Attribute &attribute : vertexShader->getActiveAttributes())
Jamie Madill63805b42015-08-25 13:17:39 -04002730 {
Jamie Madill8047c0d2016-03-07 13:02:12 -05002731 int regCount = gl::VariableRegisterCount(attribute.type);
Jamie Madill34ca4f52017-06-13 11:49:39 -04002732 GLuint location = mState.getAttributeLocation(attribute.name);
2733 ASSERT(location != std::numeric_limits<GLuint>::max());
Jamie Madill63805b42015-08-25 13:17:39 -04002734
Jamie Madill8047c0d2016-03-07 13:02:12 -05002735 for (int reg = 0; reg < regCount; ++reg)
Jamie Madill63805b42015-08-25 13:17:39 -04002736 {
Jamie Madill34ca4f52017-06-13 11:49:39 -04002737 mAttribLocationToD3DSemantic[location + reg] = semanticIndex++;
Jamie Madill63805b42015-08-25 13:17:39 -04002738 }
2739 }
Jamie Madill437d2662014-12-05 14:23:35 -05002740}
2741
Jamie Madilla779b612017-07-24 11:46:05 -04002742void ProgramD3D::updateCachedInputLayout(Serial associatedSerial, const gl::State &state)
Jamie Madilld3dfda22015-07-06 08:28:49 -04002743{
Jamie Madilla779b612017-07-24 11:46:05 -04002744 if (mCurrentVertexArrayStateSerial == associatedSerial)
2745 {
2746 return;
2747 }
2748
2749 mCurrentVertexArrayStateSerial = associatedSerial;
Jamie Madillbd136f92015-08-10 14:51:37 -04002750 mCachedInputLayout.clear();
Jamie Madill0e7f1732017-09-09 23:32:50 -04002751
Jamie Madilld3dfda22015-07-06 08:28:49 -04002752 const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
Jamie Madillf8dd7b12015-08-05 13:50:08 -04002753
Jamie Madill6de51852017-04-12 09:53:01 -04002754 for (size_t locationIndex : mState.getActiveAttribLocationsMask())
Jamie Madilld3dfda22015-07-06 08:28:49 -04002755 {
Jamie Madill8047c0d2016-03-07 13:02:12 -05002756 int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
Jamie Madilld3dfda22015-07-06 08:28:49 -04002757
Jamie Madill8047c0d2016-03-07 13:02:12 -05002758 if (d3dSemantic != -1)
Jamie Madilld3dfda22015-07-06 08:28:49 -04002759 {
Jamie Madill8047c0d2016-03-07 13:02:12 -05002760 if (mCachedInputLayout.size() < static_cast<size_t>(d3dSemantic + 1))
Jamie Madillbd136f92015-08-10 14:51:37 -04002761 {
Frank Henigmand633b152018-10-04 23:34:31 -04002762 mCachedInputLayout.resize(d3dSemantic + 1, angle::FormatID::NONE);
Jamie Madillbd136f92015-08-10 14:51:37 -04002763 }
Jamie Madill8047c0d2016-03-07 13:02:12 -05002764 mCachedInputLayout[d3dSemantic] =
Frank Henigmand633b152018-10-04 23:34:31 -04002765 GetVertexFormatID(vertexAttributes[locationIndex],
2766 state.getVertexAttribCurrentValue(locationIndex).Type);
Jamie Madilld3dfda22015-07-06 08:28:49 -04002767 }
2768 }
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002769
2770 VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
Jamie Madill0e7f1732017-09-09 23:32:50 -04002771
2772 updateCachedVertexExecutableIndex();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002773}
2774
2775void ProgramD3D::updateCachedOutputLayout(const gl::Context *context,
2776 const gl::Framebuffer *framebuffer)
2777{
Jamie Madill0e7f1732017-09-09 23:32:50 -04002778 mPixelShaderOutputLayoutCache.clear();
2779
2780 FramebufferD3D *fboD3D = GetImplAs<FramebufferD3D>(framebuffer);
2781 const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context);
2782
2783 for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
2784 {
2785 const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
2786
2787 if (colorbuffer)
2788 {
2789 auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0
2790 : colorbuffer->getBinding();
2791 mPixelShaderOutputLayoutCache.push_back(binding);
2792 }
2793 else
2794 {
2795 mPixelShaderOutputLayoutCache.push_back(GL_NONE);
2796 }
2797 }
2798
2799 updateCachedPixelExecutableIndex();
Jamie Madilld3dfda22015-07-06 08:28:49 -04002800}
2801
Xinghua Caof3179a62018-07-12 16:22:06 +08002802void ProgramD3D::updateCachedComputeImage2DBindLayout(const gl::Context *context)
2803{
2804 const auto &glState = context->getState();
2805 for (auto &image2DBindLayout : mComputeShaderImage2DBindLayoutCache)
2806 {
2807 const gl::ImageUnit &imageUnit = glState.getImageUnit(image2DBindLayout.first);
2808 if (imageUnit.texture.get())
2809 {
2810 image2DBindLayout.second = imageUnit.texture->getType();
2811 }
2812 else
2813 {
2814 image2DBindLayout.second = gl::TextureType::_2D;
2815 }
2816 }
2817
2818 updateCachedComputeExecutableIndex();
2819}
2820
Jamie Madill192745a2016-12-22 15:58:21 -05002821void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyingPacking,
2822 const BuiltinInfo &builtins)
Jamie Madillccdf74b2015-08-18 10:46:12 -04002823{
Jamie Madill9fc36822015-11-18 13:08:07 -05002824 const std::string &varyingSemantic =
2825 GetVaryingSemantic(mRenderer->getMajorShaderModel(), usesPointSize());
2826
Jamie Madillccdf74b2015-08-18 10:46:12 -04002827 // Gather the linked varyings that are used for transform feedback, they should all exist.
Jamie Madill9fc36822015-11-18 13:08:07 -05002828 mStreamOutVaryings.clear();
2829
Jamie Madill48ef11b2016-04-27 15:21:52 -04002830 const auto &tfVaryingNames = mState.getTransformFeedbackVaryingNames();
Jamie Madill9fc36822015-11-18 13:08:07 -05002831 for (unsigned int outputSlot = 0; outputSlot < static_cast<unsigned int>(tfVaryingNames.size());
2832 ++outputSlot)
Jamie Madillccdf74b2015-08-18 10:46:12 -04002833 {
Jamie Madill9fc36822015-11-18 13:08:07 -05002834 const auto &tfVaryingName = tfVaryingNames[outputSlot];
2835 if (tfVaryingName == "gl_Position")
Jamie Madillccdf74b2015-08-18 10:46:12 -04002836 {
Jamie Madill9fc36822015-11-18 13:08:07 -05002837 if (builtins.glPosition.enabled)
Jamie Madillccdf74b2015-08-18 10:46:12 -04002838 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002839 mStreamOutVaryings.emplace_back(builtins.glPosition.semantic,
2840 builtins.glPosition.index, 4, outputSlot);
Jamie Madill9fc36822015-11-18 13:08:07 -05002841 }
2842 }
2843 else if (tfVaryingName == "gl_FragCoord")
2844 {
2845 if (builtins.glFragCoord.enabled)
2846 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002847 mStreamOutVaryings.emplace_back(builtins.glFragCoord.semantic,
2848 builtins.glFragCoord.index, 4, outputSlot);
Jamie Madill9fc36822015-11-18 13:08:07 -05002849 }
2850 }
2851 else if (tfVaryingName == "gl_PointSize")
2852 {
2853 if (builtins.glPointSize.enabled)
2854 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002855 mStreamOutVaryings.emplace_back("PSIZE", 0, 1, outputSlot);
Jamie Madill9fc36822015-11-18 13:08:07 -05002856 }
2857 }
2858 else
2859 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002860 const auto &registerInfos = varyingPacking.getRegisterList();
2861 for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
Jamie Madill9fc36822015-11-18 13:08:07 -05002862 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002863 const auto &registerInfo = registerInfos[registerIndex];
Xinghua Cao6dfdca82018-08-03 17:10:55 +08002864 const auto &varying = *registerInfo.packedVarying->varying;
2865 GLenum transposedType = gl::TransposeMatrixType(varying.type);
2866 int componentCount = gl::VariableColumnCount(transposedType);
jchen108225e732017-11-14 16:29:03 +08002867 ASSERT(!varying.isBuiltIn() && !varying.isStruct());
Jamie Madill55c25d02015-11-18 13:08:08 -05002868
Jamie Madill9fc36822015-11-18 13:08:07 -05002869 // There can be more than one register assigned to a particular varying, and each
2870 // register needs its own stream out entry.
jchen108225e732017-11-14 16:29:03 +08002871 if (registerInfo.tfVaryingName() == tfVaryingName)
Jamie Madill9fc36822015-11-18 13:08:07 -05002872 {
Jiawei Shaoda92a472018-07-02 15:55:19 +08002873 mStreamOutVaryings.emplace_back(varyingSemantic, registerIndex, componentCount,
2874 outputSlot);
Jamie Madill9fc36822015-11-18 13:08:07 -05002875 }
Jamie Madillccdf74b2015-08-18 10:46:12 -04002876 }
2877 }
2878 }
2879}
Jamie Madill62d31cb2015-09-11 13:25:51 -04002880
2881D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location)
2882{
Jamie Madill48ef11b2016-04-27 15:21:52 -04002883 return mD3DUniforms[mState.getUniformLocations()[location].index];
Jamie Madill62d31cb2015-09-11 13:25:51 -04002884}
Jamie Madill4a3c2342015-10-08 12:58:45 -04002885
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002886const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const
2887{
2888 return mD3DUniforms[mState.getUniformLocations()[location].index];
2889}
2890
Sami Väisänen46eaa942016-06-29 10:26:37 +03002891void ProgramD3D::setPathFragmentInputGen(const std::string &inputName,
2892 GLenum genMode,
2893 GLint components,
2894 const GLfloat *coeffs)
2895{
2896 UNREACHABLE();
2897}
2898
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002899bool ProgramD3D::hasVertexExecutableForCachedInputLayout()
2900{
Jamie Madill0e7f1732017-09-09 23:32:50 -04002901 return mCachedVertexExecutableIndex.valid();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002902}
2903
Jamie Madill493f9572018-05-24 19:52:15 -04002904bool ProgramD3D::hasGeometryExecutableForPrimitiveType(gl::PrimitiveMode drawMode)
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002905{
2906 if (!usesGeometryShader(drawMode))
2907 {
2908 // No shader necessary mean we have the required (null) executable.
2909 return true;
2910 }
2911
Jamie Madill04796cd2018-05-24 19:52:16 -04002912 gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002913 return mGeometryExecutables[geometryShaderType].get() != nullptr;
2914}
2915
2916bool ProgramD3D::hasPixelExecutableForCachedOutputLayout()
2917{
Jamie Madill0e7f1732017-09-09 23:32:50 -04002918 return mCachedPixelExecutableIndex.valid();
Jamie Madill4c19a8a2017-07-24 11:46:06 -04002919}
2920
Xinghua Caof3179a62018-07-12 16:22:06 +08002921bool ProgramD3D::hasComputeExecutableForCachedImage2DBindLayout()
2922{
2923 return mCachedComputeExecutableIndex.valid();
2924}
2925
Jamie Madill54164b02017-08-28 15:17:37 -04002926template <typename DestT>
2927void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
2928{
2929 const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
2930 const gl::LinkedUniform &uniform = mState.getUniforms()[locationInfo.index];
2931
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002932 const D3DUniform *targetUniform = getD3DUniformFromLocation(location);
Olli Etuaho1734e172017-10-27 15:30:27 +03002933 const uint8_t *srcPointer = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002934
2935 if (gl::IsMatrixType(uniform.type))
2936 {
Luc Ferron48cdc2e2018-05-31 09:58:34 -04002937 GetMatrixUniform(uniform.type, dataOut, reinterpret_cast<const DestT *>(srcPointer), true);
Jamie Madillbe5e2ec2017-08-31 13:28:28 -04002938 }
2939 else
2940 {
2941 memcpy(dataOut, srcPointer, uniform.getElementSize());
2942 }
Jamie Madill54164b02017-08-28 15:17:37 -04002943}
2944
2945void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
2946{
2947 getUniformInternal(location, params);
2948}
2949
2950void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
2951{
2952 getUniformInternal(location, params);
2953}
2954
2955void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
2956{
2957 getUniformInternal(location, params);
2958}
2959
Jamie Madill0e7f1732017-09-09 23:32:50 -04002960void ProgramD3D::updateCachedVertexExecutableIndex()
2961{
2962 mCachedVertexExecutableIndex.reset();
2963 for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
2964 {
2965 if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature))
2966 {
2967 mCachedVertexExecutableIndex = executableIndex;
2968 break;
2969 }
2970 }
2971}
2972
2973void ProgramD3D::updateCachedPixelExecutableIndex()
2974{
2975 mCachedPixelExecutableIndex.reset();
2976 for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
2977 {
2978 if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache))
2979 {
2980 mCachedPixelExecutableIndex = executableIndex;
2981 break;
2982 }
2983 }
2984}
2985
Xinghua Caof3179a62018-07-12 16:22:06 +08002986void ProgramD3D::updateCachedComputeExecutableIndex()
2987{
2988 mCachedComputeExecutableIndex.reset();
2989 for (size_t executableIndex = 0; executableIndex < mComputeExecutables.size();
2990 executableIndex++)
2991 {
2992 if (mComputeExecutables[executableIndex]->matchesSignature(
2993 mComputeShaderImage2DBindLayoutCache))
2994 {
2995 mCachedComputeExecutableIndex = executableIndex;
2996 break;
2997 }
2998 }
2999}
3000
jchen103fd614d2018-08-13 12:21:58 +08003001void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources)
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003002{
Qin Jiajia3026f112018-10-09 12:13:38 +08003003 InterfaceBlockInfo uniformBlockInfo;
Jiawei Shao385b3e02018-03-21 09:43:28 +08003004 for (gl::ShaderType shaderType : gl::AllShaderTypes())
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003005 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08003006 gl::Shader *shader = mState.getAttachedShader(shaderType);
3007 if (shader)
3008 {
Qin Jiajia3026f112018-10-09 12:13:38 +08003009 uniformBlockInfo.getShaderBlockInfo(shader->getUniformBlocks());
Jiawei Shao385b3e02018-03-21 09:43:28 +08003010 }
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003011 }
3012
3013 // Gather interface block info.
3014 auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name,
3015 const std::string &mappedName, size_t *sizeOut) {
3016 return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut);
3017 };
3018
3019 auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name,
3020 const std::string &mappedName,
3021 sh::BlockMemberInfo *infoOut) {
3022 return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
3023 };
3024
3025 resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
3026 initializeUniformBlocks();
3027
Qin Jiajia3026f112018-10-09 12:13:38 +08003028 InterfaceBlockInfo shaderStorageBlockInfo;
3029 for (gl::ShaderType shaderType : gl::AllShaderTypes())
3030 {
3031 gl::Shader *shader = mState.getAttachedShader(shaderType);
3032 if (shader)
3033 {
3034 shaderStorageBlockInfo.getShaderBlockInfo(shader->getShaderStorageBlocks());
3035 }
3036 }
3037 auto getShaderStorageBlockSize = [&shaderStorageBlockInfo](const std::string &name,
3038 const std::string &mappedName,
3039 size_t *sizeOut) {
3040 return shaderStorageBlockInfo.getBlockSize(name, mappedName, sizeOut);
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003041 };
3042
Qin Jiajia3026f112018-10-09 12:13:38 +08003043 auto getShaderStorageBlockMemberInfo = [&shaderStorageBlockInfo](const std::string &name,
3044 const std::string &mappedName,
3045 sh::BlockMemberInfo *infoOut) {
3046 return shaderStorageBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
3047 };
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003048
3049 resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
3050 getShaderStorageBlockMemberInfo);
Qin Jiajiaa602f902018-09-11 14:40:24 +08003051 initializeShaderStorageBlocks();
Enrico Gallia3b2e712018-12-08 16:46:48 -08003052
3053 std::map<int, unsigned int> sizeMap;
3054 getAtomicCounterBufferSizeMap(sizeMap);
3055 resources.atomicCounterBufferLinker.link(sizeMap);
3056}
3057
3058void ProgramD3D::getAtomicCounterBufferSizeMap(std::map<int, unsigned int> &sizeMapOut) const
3059{
3060 for (unsigned int index : mState.getAtomicCounterUniformRange())
3061 {
3062 const gl::LinkedUniform &glUniform = mState.getUniforms()[index];
3063
3064 auto &bufferDataSize = sizeMapOut[glUniform.binding];
3065
3066 // Calculate the size of the buffer by finding the end of the last uniform with the same
3067 // binding. The end of the uniform is calculated by finding the initial offset of the
3068 // uniform and adding size of the uniform. For arrays, the size is the number of elements
3069 // times the element size (should always by 4 for atomic_units).
3070 unsigned dataOffset =
3071 glUniform.offset + (glUniform.getBasicTypeElementCount() * glUniform.getElementSize());
3072 if (dataOffset > bufferDataSize)
3073 {
3074 bufferDataSize = dataOffset;
3075 }
3076 }
Jamie Madill6db1c2e2017-11-08 09:17:40 -05003077}
3078
Jamie Madill8047c0d2016-03-07 13:02:12 -05003079} // namespace rx