blob: e99e7f609eb2dea8492c36b78593b3304d585a7e [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 Madill437d2662014-12-05 14:23:35 -050012#include "libANGLE/Constants.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050013#include "libANGLE/renderer/ProgramImpl.h"
14#include "libANGLE/renderer/Workarounds.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050015#include "libANGLE/renderer/d3d/DynamicHLSL.h"
Brandon Jonesc9610c52014-08-25 17:02:59 -070016
Brandon Jones22502d52014-08-29 16:58:36 -070017#include <string>
18#include <vector>
19
Brandon Jonesc9610c52014-08-25 17:02:59 -070020namespace gl
21{
22struct LinkedUniform;
Brandon Jones22502d52014-08-29 16:58:36 -070023struct VariableLocation;
Brandon Jonesc9610c52014-08-25 17:02:59 -070024struct VertexFormat;
25}
26
27namespace rx
28{
Jamie Madill93e13fb2014-11-06 15:27:25 -050029class RendererD3D;
Geoff Lang359ef262015-01-05 14:42:29 -050030class UniformStorageD3D;
31class ShaderExecutableD3D;
Brandon Jonesc9610c52014-08-25 17:02:59 -070032
Jamie Madill2db1fbb2014-12-03 10:58:55 -050033#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
34// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
35// It should only be used selectively to work around specific bugs.
36#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
37#endif
38
Brandon Jonesc9610c52014-08-25 17:02:59 -070039class ProgramD3D : public ProgramImpl
40{
41 public:
Jamie Madill30d6c252014-11-13 10:03:33 -050042 ProgramD3D(RendererD3D *renderer);
Brandon Jonesc9610c52014-08-25 17:02:59 -070043 virtual ~ProgramD3D();
44
Jamie Madill30d6c252014-11-13 10:03:33 -050045 const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
Brandon Jones44151a92014-09-10 11:32:25 -070046 int getShaderVersion() const { return mShaderVersion; }
Brandon Joneseb994362014-09-24 10:27:28 -070047 GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
Brandon Jones1a8a7e32014-10-01 12:49:30 -070048
49 GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
50 GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
51 GLint getUsedSamplerRange(gl::SamplerType type) const;
52 void updateSamplerMapping();
53 bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
Brandon Jones44151a92014-09-10 11:32:25 -070054
Brandon Joneseb994362014-09-24 10:27:28 -070055 bool usesPointSize() const { return mUsesPointSize; }
Brandon Jones44151a92014-09-10 11:32:25 -070056 bool usesPointSpriteEmulation() const;
57 bool usesGeometryShader() const;
Cooper Partine6664f02015-01-09 16:22:24 -080058 bool usesInstancedPointSpriteEmulation() const;
Brandon Jones22502d52014-08-29 16:58:36 -070059
60 GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
Geoff Lang7dd2e102014-11-10 15:19:26 -050061 LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
Geoff Langb543aff2014-09-30 14:52:54 -040062 gl::Error save(gl::BinaryOutputStream *stream);
Brandon Jones22502d52014-08-29 16:58:36 -070063
Geoff Lang359ef262015-01-05 14:42:29 -050064 gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutableD3D **outExectuable);
65 gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
66 gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutableD3D **outExectuable, gl::InfoLog *infoLog);
67 ShaderExecutableD3D *getGeometryExecutable() const { return mGeometryExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -070068
Geoff Lang7dd2e102014-11-10 15:19:26 -050069 LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
70 int registers);
Brandon Jones22502d52014-08-29 16:58:36 -070071
Geoff Lang7dd2e102014-11-10 15:19:26 -050072 LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
73 gl::Shader *fragmentShader, gl::Shader *vertexShader,
74 const std::vector<std::string> &transformFeedbackVaryings,
75 GLenum transformFeedbackBufferMode,
76 int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
77 std::map<int, gl::VariableLocation> *outputVariables);
Brandon Jonesc9610c52014-08-25 17:02:59 -070078
Brandon Jones44151a92014-09-10 11:32:25 -070079 void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
80
Brandon Jones1a8a7e32014-10-01 12:49:30 -070081 void initializeUniformStorage();
82 gl::Error applyUniforms();
83 gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps);
Brandon Jones18bd4102014-09-22 14:21:44 -070084 bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
85 unsigned int registerIndex, const gl::Caps &caps);
Brandon Jones1a8a7e32014-10-01 12:49:30 -070086 void dirtyAllUniforms();
87
88 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
89 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
90 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
91 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
92 void setUniform1iv(GLint location, GLsizei count, const GLint *v);
93 void setUniform2iv(GLint location, GLsizei count, const GLint *v);
94 void setUniform3iv(GLint location, GLsizei count, const GLint *v);
95 void setUniform4iv(GLint location, GLsizei count, const GLint *v);
96 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v);
97 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v);
98 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v);
99 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v);
100 void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
101 void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
102 void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
103 void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
104 void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
105 void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
106 void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
107 void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
108 void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
109
110 void getUniformfv(GLint location, GLfloat *params);
111 void getUniformiv(GLint location, GLint *params);
112 void getUniformuiv(GLint location, GLuint *params);
Brandon Jonesc9610c52014-08-25 17:02:59 -0700113
Geoff Lang359ef262015-01-05 14:42:29 -0500114 const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
115 const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
Brandon Jonesc9610c52014-08-25 17:02:59 -0700116
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700117 bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
118 const gl::Caps &caps);
119 bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
120
Brandon Jonesc9610c52014-08-25 17:02:59 -0700121 void reset();
122
Geoff Lang7dd2e102014-11-10 15:19:26 -0500123 unsigned int getSerial() const;
124
Jamie Madill437d2662014-12-05 14:23:35 -0500125 void initAttributesByLayout();
126 void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
127 int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]) const;
128
Brandon Jonesc9610c52014-08-25 17:02:59 -0700129 private:
130 DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
131
Brandon Joneseb994362014-09-24 10:27:28 -0700132 class VertexExecutable
133 {
134 public:
135 VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
136 const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
Geoff Lang359ef262015-01-05 14:42:29 -0500137 ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700138 ~VertexExecutable();
139
140 bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
141
142 const gl::VertexFormat *inputs() const { return mInputs; }
143 const GLenum *signature() const { return mSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500144 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700145
146 private:
147 gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
148 GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
Geoff Lang359ef262015-01-05 14:42:29 -0500149 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700150 };
151
152 class PixelExecutable
153 {
154 public:
Geoff Lang359ef262015-01-05 14:42:29 -0500155 PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutableD3D *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700156 ~PixelExecutable();
157
158 bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
159
160 const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
Geoff Lang359ef262015-01-05 14:42:29 -0500161 ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700162
163 private:
164 std::vector<GLenum> mOutputSignature;
Geoff Lang359ef262015-01-05 14:42:29 -0500165 ShaderExecutableD3D *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700166 };
167
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700168 struct Sampler
169 {
170 Sampler();
171
172 bool active;
173 GLint logicalTextureUnit;
174 GLenum textureType;
175 };
176
Geoff Lang492a7e42014-11-05 13:27:06 -0500177 void defineUniformBase(const ShaderD3D *shader, const sh::Uniform &uniform, unsigned int uniformRegister);
178 void defineUniform(const ShaderD3D *shader, const sh::ShaderVariable &uniform, const std::string &fullName,
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700179 sh::HLSLBlockEncoder *encoder);
180 bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
181 bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
182 static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
183 std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
184
185 template <typename T>
186 void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
187
188 template <int cols, int rows>
189 void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
190
191 template <typename T>
192 void getUniformv(GLint location, T *params, GLenum uniformType);
193
194 template <typename VarT>
195 void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
196 sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
197 bool inRowMajorLayout);
198
Jamie Madill93e13fb2014-11-06 15:27:25 -0500199 RendererD3D *mRenderer;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700200 DynamicHLSL *mDynamicHLSL;
201
Brandon Joneseb994362014-09-24 10:27:28 -0700202 std::vector<VertexExecutable *> mVertexExecutables;
203 std::vector<PixelExecutable *> mPixelExecutables;
Geoff Lang359ef262015-01-05 14:42:29 -0500204 ShaderExecutableD3D *mGeometryExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700205
Brandon Jones22502d52014-08-29 16:58:36 -0700206 std::string mVertexHLSL;
Jamie Madill30d6c252014-11-13 10:03:33 -0500207 D3DWorkaroundType mVertexWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700208
209 std::string mPixelHLSL;
Jamie Madill30d6c252014-11-13 10:03:33 -0500210 D3DWorkaroundType mPixelWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700211 bool mUsesFragDepth;
Jamie Madill30d6c252014-11-13 10:03:33 -0500212 std::vector<PixelShaderOutputVariable> mPixelShaderKey;
Brandon Jones22502d52014-08-29 16:58:36 -0700213
Brandon Jones44151a92014-09-10 11:32:25 -0700214 bool mUsesPointSize;
215
Geoff Lang359ef262015-01-05 14:42:29 -0500216 UniformStorageD3D *mVertexUniformStorage;
217 UniformStorageD3D *mFragmentUniformStorage;
Brandon Jones44151a92014-09-10 11:32:25 -0700218
Brandon Joneseb994362014-09-24 10:27:28 -0700219 GLenum mTransformFeedbackBufferMode;
Brandon Joneseb994362014-09-24 10:27:28 -0700220
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700221 std::vector<Sampler> mSamplersPS;
222 std::vector<Sampler> mSamplersVS;
223 GLuint mUsedVertexSamplerRange;
224 GLuint mUsedPixelSamplerRange;
225 bool mDirtySamplerMapping;
Brandon Joneseb994362014-09-24 10:27:28 -0700226
Brandon Jones44151a92014-09-10 11:32:25 -0700227 int mShaderVersion;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500228
Jamie Madill437d2662014-12-05 14:23:35 -0500229 int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS];
230
Geoff Lang7dd2e102014-11-10 15:19:26 -0500231 unsigned int mSerial;
232
233 static unsigned int issueSerial();
234 static unsigned int mCurrentSerial;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700235};
236
237}
238
Geoff Lang0a73dd82014-11-19 16:18:08 -0500239#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_