blob: 9ce3b0d7949f56db6bedd02909925f52d1246faf [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
Jamie Madill13776892015-04-28 12:39:06 -040015#include "common/Optional.h"
Daniel Bratell73941de2015-02-25 14:34:49 +010016#include "compiler/translator/blocklayoutHLSL.h"
Jamie Madill437d2662014-12-05 14:23:35 -050017#include "libANGLE/Constants.h"
Jamie Madilld3dfda22015-07-06 08:28:49 -040018#include "libANGLE/formatutils.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050019#include "libANGLE/renderer/ProgramImpl.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050020#include "libANGLE/renderer/d3d/DynamicHLSL.h"
Geoff Lang6941a552015-07-27 11:06:45 -040021#include "libANGLE/renderer/d3d/WorkaroundsD3D.h"
Brandon Jonesc9610c52014-08-25 17:02:59 -070022
23namespace gl
24{
25struct LinkedUniform;
Brandon Jones22502d52014-08-29 16:58:36 -070026struct VariableLocation;
Brandon Jonesc9610c52014-08-25 17:02:59 -070027struct VertexFormat;
28}
29
30namespace rx
31{
Jamie Madill93e13fb2014-11-06 15:27:25 -050032class RendererD3D;
Geoff Lang359ef262015-01-05 14:42:29 -050033class UniformStorageD3D;
34class ShaderExecutableD3D;
Brandon Jonesc9610c52014-08-25 17:02:59 -070035
Jamie Madill2db1fbb2014-12-03 10:58:55 -050036#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
37// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
38// It should only be used selectively to work around specific bugs.
39#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
40#endif
41
Brandon Jonesc9610c52014-08-25 17:02:59 -070042class ProgramD3D : public ProgramImpl
43{
44 public:
Jamie Madill63805b42015-08-25 13:17:39 -040045 typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS];
46
Jamie Madill5c6b7bf2015-08-17 12:53:35 -040047 ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer);
Brandon Jonesc9610c52014-08-25 17:02:59 -070048 virtual ~ProgramD3D();
49
Jamie Madill30d6c252014-11-13 10:03:33 -050050 const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
Brandon Jones44151a92014-09-10 11:32:25 -070051 int getShaderVersion() const { return mShaderVersion; }
Brandon Jones1a8a7e32014-10-01 12:49:30 -070052
53 GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
54 GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
55 GLint getUsedSamplerRange(gl::SamplerType type) const;
56 void updateSamplerMapping();
57 bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
Brandon Jones44151a92014-09-10 11:32:25 -070058
Brandon Joneseb994362014-09-24 10:27:28 -070059 bool usesPointSize() const { return mUsesPointSize; }
Brandon Jones44151a92014-09-10 11:32:25 -070060 bool usesPointSpriteEmulation() const;
61 bool usesGeometryShader() const;
Cooper Partine6664f02015-01-09 16:22:24 -080062 bool usesInstancedPointSpriteEmulation() const;
Brandon Jones22502d52014-08-29 16:58:36 -070063
64 GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
Geoff Lang7dd2e102014-11-10 15:19:26 -050065 LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
Geoff Langb543aff2014-09-30 14:52:54 -040066 gl::Error save(gl::BinaryOutputStream *stream);
Brandon Jones22502d52014-08-29 16:58:36 -070067
Geoff Lang359ef262015-01-05 14:42:29 -050068 gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable);
69 gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
Jamie Madilld3dfda22015-07-06 08:28:49 -040070 gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
Geoff Lang359ef262015-01-05 14:42:29 -050071 ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -070072
Jamie Madill63069df2015-09-01 17:26:41 +000073 LinkResult link(const gl::Data &data,
74 gl::InfoLog &infoLog,
75 gl::Shader *fragmentShader,
76 gl::Shader *vertexShader) override;
77
Jamie Madill36cfd6a2015-08-18 10:46:20 -040078 GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
Brandon Jonesc9610c52014-08-25 17:02:59 -070079
Brandon Jones1a8a7e32014-10-01 12:49:30 -070080 void initializeUniformStorage();
81 gl::Error applyUniforms();
Jamie Madilld1fe1642015-08-21 16:26:04 -040082 gl::Error applyUniformBuffers(const gl::Data &data);
Jamie Madille473dee2015-08-18 14:49:01 -040083 void assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
84 GLenum shader,
85 unsigned int registerIndex,
86 const gl::Caps &caps);
Brandon Jones1a8a7e32014-10-01 12:49:30 -070087 void dirtyAllUniforms();
88
89 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
90 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
91 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
92 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
93 void setUniform1iv(GLint location, GLsizei count, const GLint *v);
94 void setUniform2iv(GLint location, GLsizei count, const GLint *v);
95 void setUniform3iv(GLint location, GLsizei count, const GLint *v);
96 void setUniform4iv(GLint location, GLsizei count, const GLint *v);
97 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
98 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
99 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
100 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
101 void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
102 void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
103 void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
104 void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
105 void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
106 void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
107 void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
108 void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
109 void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
110
111 void getUniformfv(GLint location, GLfloat *params);
112 void getUniformiv(GLint location, GLint *params);
113 void getUniformuiv(GLint location, GLuint *params);
Brandon Jonesc9610c52014-08-25 17:02:59 -0700114
Geoff Lang359ef262015-01-05 14:42:29 -0500115 const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
116 const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
Brandon Jonesc9610c52014-08-25 17:02:59 -0700117
118 void reset();
119
Geoff Lang7dd2e102014-11-10 15:19:26 -0500120 unsigned int getSerial() const;
121
Jamie Madill476682e2015-06-30 10:04:29 -0400122 void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
Jamie Madillf9327d32015-06-22 13:57:16 -0400123 int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
124 const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
Jamie Madill63805b42015-08-25 13:17:39 -0400125 const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndexes; }
Jamie Madillc349ec02015-08-21 16:53:12 -0400126 const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; }
Jamie Madill437d2662014-12-05 14:23:35 -0500127
Jamie Madill63805b42015-08-25 13:17:39 -0400128 void updateCachedInputLayout(const gl::State &state);
Jamie Madilld3dfda22015-07-06 08:28:49 -0400129 const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
130
Brandon Jonesc9610c52014-08-25 17:02:59 -0700131 private:
Brandon Joneseb994362014-09-24 10:27:28 -0700132 class VertexExecutable
133 {
134 public:
Jamie Madillf8dd7b12015-08-05 13:50:08 -0400135 typedef std::vector<bool> Signature;
Jamie Madilld3dfda22015-07-06 08:28:49 -0400136
137 VertexExecutable(const gl::InputLayout &inputLayout,
138 const Signature &signature,
Geoff Lang359ef262015-01-05 14:42:29 -0500139 ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700140 ~VertexExecutable();
141
Jamie Madilld3dfda22015-07-06 08:28:49 -0400142 bool matchesSignature(const Signature &signature) const;
143 static void getSignature(RendererD3D *renderer,
144 const gl::InputLayout &inputLayout,
145 Signature *signatureOut);
Brandon Joneseb994362014-09-24 10:27:28 -0700146
Jamie Madilld3dfda22015-07-06 08:28:49 -0400147 const gl::InputLayout &inputs() const { return mInputs; }
148 const Signature &signature() const { return mSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500149 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700150
151 private:
Jamie Madilld3dfda22015-07-06 08:28:49 -0400152 gl::InputLayout mInputs;
153 Signature mSignature;
Geoff Lang359ef262015-01-05 14:42:29 -0500154 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700155 };
156
157 class PixelExecutable
158 {
159 public:
Geoff Lang359ef262015-01-05 14:42:29 -0500160 PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700161 ~PixelExecutable();
162
163 bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
164
165 const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500166 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700167
168 private:
169 std::vector<GLenum> mOutputSignature;
Geoff Lang359ef262015-01-05 14:42:29 -0500170 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700171 };
172
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700173 struct Sampler
174 {
175 Sampler();
176
177 bool active;
178 GLint logicalTextureUnit;
179 GLenum textureType;
180 };
181
Jamie Madillea918db2015-08-18 14:48:59 -0400182 bool defineUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
Geoff Lang492a7e42014-11-05 13:27:06 -0500183 void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
184 void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700185 sh::HLSLBlockEncoder *encoder);
186 bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
187 bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
188 static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
189 std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
190
Jamie Madille473dee2015-08-18 14:49:01 -0400191 void defineUniformBlocks(const gl::Caps &caps);
192 void defineUniformBlock(const gl::Shader &shader,
193 const sh::InterfaceBlock &interfaceBlock,
194 const gl::Caps &caps);
195
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700196 template <typename T>
197 void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
198
199 template <int cols, int rows>
200 void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
201
202 template <typename T>
203 void getUniformv(GLint location, T *params, GLenum uniformType);
204
205 template <typename VarT>
206 void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
207 sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
208 bool inRowMajorLayout);
209
Jamie Madillca03b352015-09-02 12:38:13 -0400210 LinkResult compileProgramExecutables(gl::InfoLog &infoLog,
211 int registers,
212 const std::vector<PackedVarying> &packedVaryings);
Jamie Madill31c8c562015-08-19 14:08:03 -0400213
Jamie Madillccdf74b2015-08-18 10:46:12 -0400214 void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
215
Jamie Madill63805b42015-08-25 13:17:39 -0400216 void initSemanticIndex();
217 void initAttributesByLayout();
218
Jamie Madill93e13fb2014-11-06 15:27:25 -0500219 RendererD3D *mRenderer;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700220 DynamicHLSL *mDynamicHLSL;
221
Brandon Joneseb994362014-09-24 10:27:28 -0700222 std::vector<VertexExecutable *> mVertexExecutables;
223 std::vector<PixelExecutable *> mPixelExecutables;
Geoff Lang359ef262015-01-05 14:42:29 -0500224 ShaderExecutableD3D *mGeometryExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700225
Brandon Jones22502d52014-08-29 16:58:36 -0700226 std::string mVertexHLSL;
Arun Patole44efa0b2015-03-04 17:11:05 +0530227 D3DCompilerWorkarounds mVertexWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700228
229 std::string mPixelHLSL;
Arun Patole44efa0b2015-03-04 17:11:05 +0530230 D3DCompilerWorkarounds mPixelWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700231 bool mUsesFragDepth;
Jamie Madill30d6c252014-11-13 10:03:33 -0500232 std::vector<PixelShaderOutputVariable> mPixelShaderKey;
Brandon Jones22502d52014-08-29 16:58:36 -0700233
Brandon Jones44151a92014-09-10 11:32:25 -0700234 bool mUsesPointSize;
235
Geoff Lang359ef262015-01-05 14:42:29 -0500236 UniformStorageD3D *mVertexUniformStorage;
237 UniformStorageD3D *mFragmentUniformStorage;
Brandon Jones44151a92014-09-10 11:32:25 -0700238
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700239 std::vector<Sampler> mSamplersPS;
240 std::vector<Sampler> mSamplersVS;
241 GLuint mUsedVertexSamplerRange;
242 GLuint mUsedPixelSamplerRange;
243 bool mDirtySamplerMapping;
Brandon Joneseb994362014-09-24 10:27:28 -0700244
Geoff Lang7a26a1a2015-03-25 12:29:06 -0400245 // Cache for validateSamplers
246 std::vector<GLenum> mTextureUnitTypesCache;
247
248 // Cache for getPixelExecutableForFramebuffer
249 std::vector<GLenum> mPixelShaderOutputFormatCache;
250
Brandon Jones44151a92014-09-10 11:32:25 -0700251 int mShaderVersion;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500252
Jamie Madill63805b42015-08-25 13:17:39 -0400253 SemanticIndexArray mSemanticIndexes;
Jamie Madillc349ec02015-08-21 16:53:12 -0400254 SemanticIndexArray mAttributesByLayout;
Jamie Madill437d2662014-12-05 14:23:35 -0500255
Geoff Lang7dd2e102014-11-10 15:19:26 -0500256 unsigned int mSerial;
257
Jamie Madill13776892015-04-28 12:39:06 -0400258 Optional<bool> mCachedValidateSamplersResult;
259
Jamie Madill03260fa2015-06-22 13:57:22 -0400260 std::vector<GLint> mVertexUBOCache;
261 std::vector<GLint> mFragmentUBOCache;
Jamie Madilld3dfda22015-07-06 08:28:49 -0400262 VertexExecutable::Signature mCachedVertexSignature;
263 gl::InputLayout mCachedInputLayout;
Jamie Madill03260fa2015-06-22 13:57:22 -0400264
Jamie Madillccdf74b2015-08-18 10:46:12 -0400265 std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
266
Geoff Lang7dd2e102014-11-10 15:19:26 -0500267 static unsigned int issueSerial();
268 static unsigned int mCurrentSerial;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700269};
270
271}
272
Geoff Lang0a73dd82014-11-19 16:18:08 -0500273#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_