blob: 21839618c121cbf6423c7866ef19da436fdcee3d [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.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
8
Geoff Lang0a73dd82014-11-19 16:18:08 -05009#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
10#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
Brandon Jonesc9610c52014-08-25 17:02:59 -070011
Jamie Madilld3dfda22015-07-06 08:28:49 -040012#include <string>
13#include <vector>
14
Daniel Bratell73941de2015-02-25 14:34:49 +010015#include "compiler/translator/blocklayoutHLSL.h"
Jamie Madill437d2662014-12-05 14:23:35 -050016#include "libANGLE/Constants.h"
Jamie Madilld3dfda22015-07-06 08:28:49 -040017#include "libANGLE/formatutils.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050018#include "libANGLE/renderer/ProgramImpl.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050019#include "libANGLE/renderer/d3d/DynamicHLSL.h"
Geoff Lang6941a552015-07-27 11:06:45 -040020#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
Brandon Jonesc9610c52014-08-25 17:02:59 -070021
Brandon Jonesc9610c52014-08-25 17:02:59 -070022namespace rx
23{
Jamie Madill93e13fb2014-11-06 15:27:25 -050024class RendererD3D;
Geoff Lang359ef262015-01-05 14:42:29 -050025class UniformStorageD3D;
26class ShaderExecutableD3D;
Brandon Jonesc9610c52014-08-25 17:02:59 -070027
Jamie Madill2db1fbb2014-12-03 10:58:55 -050028#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
29// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
30// It should only be used selectively to work around specific bugs.
31#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
32#endif
33
Jamie Madill62d31cb2015-09-11 13:25:51 -040034// Helper struct representing a single shader uniform
Jamie Madill6cbf4382015-09-22 19:12:11 -040035struct D3DUniform : angle::NonCopyable
Jamie Madill62d31cb2015-09-11 13:25:51 -040036{
37 D3DUniform(GLenum typeIn,
38 const std::string &nameIn,
39 unsigned int arraySizeIn,
40 bool defaultBlock);
41 ~D3DUniform();
42
43 bool isSampler() const;
44 unsigned int elementCount() const { return std::max(1u, arraySize); }
45 bool isReferencedByVertexShader() const;
46 bool isReferencedByFragmentShader() const;
47
48 // Duplicated from the GL layer
49 GLenum type;
50 std::string name;
51 unsigned int arraySize;
52
53 // Pointer to a system copy of the data.
54 // TODO(jmadill): remove this in favor of gl::LinkedUniform::data().
55 uint8_t *data;
56
57 // Has the data been updated since the last sync?
58 bool dirty;
59
60 // Register information.
61 unsigned int vsRegisterIndex;
62 unsigned int psRegisterIndex;
63 unsigned int registerCount;
64
65 // Register "elements" are used for uniform structs in ES3, to appropriately identify single
66 // uniforms
67 // inside aggregate types, which are packed according C-like structure rules.
68 unsigned int registerElement;
69};
70
Brandon Jonesc9610c52014-08-25 17:02:59 -070071class ProgramD3D : public ProgramImpl
72{
73 public:
Jamie Madill63805b42015-08-25 13:17:39 -040074 typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS];
75
Jamie Madill5c6b7bf2015-08-17 12:53:35 -040076 ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer);
Brandon Jonesc9610c52014-08-25 17:02:59 -070077 virtual ~ProgramD3D();
78
Jamie Madill30d6c252014-11-13 10:03:33 -050079 const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
Brandon Jones44151a92014-09-10 11:32:25 -070080 int getShaderVersion() const { return mShaderVersion; }
Brandon Jones1a8a7e32014-10-01 12:49:30 -070081
82 GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
83 GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
84 GLint getUsedSamplerRange(gl::SamplerType type) const;
85 void updateSamplerMapping();
Brandon Jones44151a92014-09-10 11:32:25 -070086
Brandon Joneseb994362014-09-24 10:27:28 -070087 bool usesPointSize() const { return mUsesPointSize; }
Brandon Jones44151a92014-09-10 11:32:25 -070088 bool usesPointSpriteEmulation() const;
89 bool usesGeometryShader() const;
Cooper Partine6664f02015-01-09 16:22:24 -080090 bool usesInstancedPointSpriteEmulation() const;
Brandon Jones22502d52014-08-29 16:58:36 -070091
92 GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
Geoff Lang7dd2e102014-11-10 15:19:26 -050093 LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
Geoff Langb543aff2014-09-30 14:52:54 -040094 gl::Error save(gl::BinaryOutputStream *stream);
Brandon Jones22502d52014-08-29 16:58:36 -070095
Geoff Lang359ef262015-01-05 14:42:29 -050096 gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable);
97 gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
Jamie Madilld3dfda22015-07-06 08:28:49 -040098 gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
Geoff Lang359ef262015-01-05 14:42:29 -050099 ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700100
Jamie Madillf5f4ad22015-09-02 18:32:38 +0000101 LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
Jamie Madill36cfd6a2015-08-18 10:46:20 -0400102 GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700103
Jamie Madill62d31cb2015-09-11 13:25:51 -0400104 void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks,
105 std::vector<gl::LinkedUniform> *uniforms) override;
106
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700107 void initializeUniformStorage();
108 gl::Error applyUniforms();
Jamie Madilld1fe1642015-08-21 16:26:04 -0400109 gl::Error applyUniformBuffers(const gl::Data &data);
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700110 void dirtyAllUniforms();
111
112 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
113 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
114 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
115 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
116 void setUniform1iv(GLint location, GLsizei count, const GLint *v);
117 void setUniform2iv(GLint location, GLsizei count, const GLint *v);
118 void setUniform3iv(GLint location, GLsizei count, const GLint *v);
119 void setUniform4iv(GLint location, GLsizei count, const GLint *v);
120 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
121 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
122 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
123 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
124 void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
125 void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
126 void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
127 void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
128 void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
129 void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
130 void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
131 void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
132 void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
133
Geoff Lang359ef262015-01-05 14:42:29 -0500134 const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
135 const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
Brandon Jonesc9610c52014-08-25 17:02:59 -0700136
Geoff Lang7dd2e102014-11-10 15:19:26 -0500137 unsigned int getSerial() const;
138
Jamie Madill476682e2015-06-30 10:04:29 -0400139 void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
Jamie Madillf9327d32015-06-22 13:57:16 -0400140 int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
141 const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
Jamie Madill63805b42015-08-25 13:17:39 -0400142 const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndexes; }
Jamie Madillc349ec02015-08-21 16:53:12 -0400143 const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; }
Jamie Madill437d2662014-12-05 14:23:35 -0500144
Jamie Madill63805b42015-08-25 13:17:39 -0400145 void updateCachedInputLayout(const gl::State &state);
Jamie Madilld3dfda22015-07-06 08:28:49 -0400146 const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
147
Brandon Jonesc9610c52014-08-25 17:02:59 -0700148 private:
Brandon Joneseb994362014-09-24 10:27:28 -0700149 class VertexExecutable
150 {
151 public:
Jamie Madillf8dd7b12015-08-05 13:50:08 -0400152 typedef std::vector<bool> Signature;
Jamie Madilld3dfda22015-07-06 08:28:49 -0400153
154 VertexExecutable(const gl::InputLayout &inputLayout,
155 const Signature &signature,
Geoff Lang359ef262015-01-05 14:42:29 -0500156 ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700157 ~VertexExecutable();
158
Jamie Madilld3dfda22015-07-06 08:28:49 -0400159 bool matchesSignature(const Signature &signature) const;
160 static void getSignature(RendererD3D *renderer,
161 const gl::InputLayout &inputLayout,
162 Signature *signatureOut);
Brandon Joneseb994362014-09-24 10:27:28 -0700163
Jamie Madilld3dfda22015-07-06 08:28:49 -0400164 const gl::InputLayout &inputs() const { return mInputs; }
165 const Signature &signature() const { return mSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500166 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700167
168 private:
Jamie Madilld3dfda22015-07-06 08:28:49 -0400169 gl::InputLayout mInputs;
170 Signature mSignature;
Geoff Lang359ef262015-01-05 14:42:29 -0500171 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700172 };
173
174 class PixelExecutable
175 {
176 public:
Geoff Lang359ef262015-01-05 14:42:29 -0500177 PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700178 ~PixelExecutable();
179
180 bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
181
182 const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500183 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700184
185 private:
186 std::vector<GLenum> mOutputSignature;
Geoff Lang359ef262015-01-05 14:42:29 -0500187 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700188 };
189
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700190 struct Sampler
191 {
192 Sampler();
193
194 bool active;
195 GLint logicalTextureUnit;
196 GLenum textureType;
197 };
198
Jamie Madill6cbf4382015-09-22 19:12:11 -0400199 typedef std::map<std::string, D3DUniform *> D3DUniformMap;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400200 typedef std::map<std::string, sh::BlockMemberInfo> BlockInfoMap;
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700201
Jamie Madill6cbf4382015-09-22 19:12:11 -0400202 void defineUniformsAndAssignRegisters();
203 void defineUniformBase(const ShaderD3D *shader,
204 const sh::Uniform &uniform,
205 D3DUniformMap *uniformMap);
206 void defineUniform(const ShaderD3D *shader,
207 const sh::ShaderVariable &uniform,
208 const std::string &fullName,
209 sh::HLSLBlockEncoder *encoder,
210 D3DUniformMap *uniformMap);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400211 void assignAllSamplerRegisters();
212 void assignSamplerRegisters(const D3DUniform *d3dUniform);
213
214 static void AssignSamplers(unsigned int startSamplerIndex,
215 GLenum samplerType,
216 unsigned int samplerCount,
217 std::vector<Sampler> &outSamplers,
218 GLuint *outUsedRange);
219
220 size_t defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, BlockInfoMap *blockInfoOut);
Jamie Madille473dee2015-08-18 14:49:01 -0400221
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700222 template <typename T>
223 void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
224
225 template <int cols, int rows>
226 void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
227
Jamie Madillca03b352015-09-02 12:38:13 -0400228 LinkResult compileProgramExecutables(gl::InfoLog &infoLog,
229 int registers,
230 const std::vector<PackedVarying> &packedVaryings);
Jamie Madill31c8c562015-08-19 14:08:03 -0400231
Jamie Madillccdf74b2015-08-18 10:46:12 -0400232 void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
Jamie Madill62d31cb2015-09-11 13:25:51 -0400233 D3DUniform *getD3DUniformByName(const std::string &name);
234 D3DUniform *getD3DUniformFromLocation(GLint location);
Jamie Madillccdf74b2015-08-18 10:46:12 -0400235
Jamie Madill63805b42015-08-25 13:17:39 -0400236 void initSemanticIndex();
237 void initAttributesByLayout();
238
Jamie Madill62d31cb2015-09-11 13:25:51 -0400239 void reset();
240
Jamie Madill93e13fb2014-11-06 15:27:25 -0500241 RendererD3D *mRenderer;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700242 DynamicHLSL *mDynamicHLSL;
243
Brandon Joneseb994362014-09-24 10:27:28 -0700244 std::vector<VertexExecutable *> mVertexExecutables;
245 std::vector<PixelExecutable *> mPixelExecutables;
Geoff Lang359ef262015-01-05 14:42:29 -0500246 ShaderExecutableD3D *mGeometryExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700247
Brandon Jones22502d52014-08-29 16:58:36 -0700248 std::string mVertexHLSL;
Arun Patole44efa0b2015-03-04 17:11:05 +0530249 D3DCompilerWorkarounds mVertexWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700250
251 std::string mPixelHLSL;
Arun Patole44efa0b2015-03-04 17:11:05 +0530252 D3DCompilerWorkarounds mPixelWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700253 bool mUsesFragDepth;
Jamie Madill30d6c252014-11-13 10:03:33 -0500254 std::vector<PixelShaderOutputVariable> mPixelShaderKey;
Brandon Jones22502d52014-08-29 16:58:36 -0700255
Brandon Jones44151a92014-09-10 11:32:25 -0700256 bool mUsesPointSize;
257
Geoff Lang359ef262015-01-05 14:42:29 -0500258 UniformStorageD3D *mVertexUniformStorage;
259 UniformStorageD3D *mFragmentUniformStorage;
Brandon Jones44151a92014-09-10 11:32:25 -0700260
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700261 std::vector<Sampler> mSamplersPS;
262 std::vector<Sampler> mSamplersVS;
263 GLuint mUsedVertexSamplerRange;
264 GLuint mUsedPixelSamplerRange;
265 bool mDirtySamplerMapping;
Brandon Joneseb994362014-09-24 10:27:28 -0700266
Geoff Lang7a26a1a2015-03-25 12:29:06 -0400267 // Cache for getPixelExecutableForFramebuffer
268 std::vector<GLenum> mPixelShaderOutputFormatCache;
269
Brandon Jones44151a92014-09-10 11:32:25 -0700270 int mShaderVersion;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500271
Jamie Madill63805b42015-08-25 13:17:39 -0400272 SemanticIndexArray mSemanticIndexes;
Jamie Madillc349ec02015-08-21 16:53:12 -0400273 SemanticIndexArray mAttributesByLayout;
Jamie Madill437d2662014-12-05 14:23:35 -0500274
Geoff Lang7dd2e102014-11-10 15:19:26 -0500275 unsigned int mSerial;
276
Jamie Madill03260fa2015-06-22 13:57:22 -0400277 std::vector<GLint> mVertexUBOCache;
278 std::vector<GLint> mFragmentUBOCache;
Jamie Madilld3dfda22015-07-06 08:28:49 -0400279 VertexExecutable::Signature mCachedVertexSignature;
280 gl::InputLayout mCachedInputLayout;
Jamie Madill03260fa2015-06-22 13:57:22 -0400281
Jamie Madillccdf74b2015-08-18 10:46:12 -0400282 std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
Jamie Madill62d31cb2015-09-11 13:25:51 -0400283 std::vector<D3DUniform *> mD3DUniforms;
Jamie Madillccdf74b2015-08-18 10:46:12 -0400284
Geoff Lang7dd2e102014-11-10 15:19:26 -0500285 static unsigned int issueSerial();
286 static unsigned int mCurrentSerial;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700287};
288
289}
290
Geoff Lang0a73dd82014-11-19 16:18:08 -0500291#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_