blob: 4d039c0d45954b1d9d73c7f2f67fb9be05071dd4 [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
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/renderer/ProgramImpl.h"
13#include "libANGLE/renderer/Workarounds.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050014#include "libANGLE/renderer/d3d/DynamicHLSL.h"
Brandon Jonesc9610c52014-08-25 17:02:59 -070015
Brandon Jones22502d52014-08-29 16:58:36 -070016#include <string>
17#include <vector>
18
Brandon Jonesc9610c52014-08-25 17:02:59 -070019namespace gl
20{
21struct LinkedUniform;
Brandon Jones22502d52014-08-29 16:58:36 -070022struct VariableLocation;
Brandon Jonesc9610c52014-08-25 17:02:59 -070023struct VertexFormat;
24}
25
26namespace rx
27{
Jamie Madill93e13fb2014-11-06 15:27:25 -050028class RendererD3D;
Brandon Jonesc9610c52014-08-25 17:02:59 -070029class UniformStorage;
Geoff Lang7dd2e102014-11-10 15:19:26 -050030class ShaderExecutable;
Brandon Jonesc9610c52014-08-25 17:02:59 -070031
Jamie Madill2db1fbb2014-12-03 10:58:55 -050032#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
33// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
34// It should only be used selectively to work around specific bugs.
35#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
36#endif
37
Brandon Jonesc9610c52014-08-25 17:02:59 -070038class ProgramD3D : public ProgramImpl
39{
40 public:
Jamie Madill30d6c252014-11-13 10:03:33 -050041 ProgramD3D(RendererD3D *renderer);
Brandon Jonesc9610c52014-08-25 17:02:59 -070042 virtual ~ProgramD3D();
43
44 static ProgramD3D *makeProgramD3D(ProgramImpl *impl);
45 static const ProgramD3D *makeProgramD3D(const ProgramImpl *impl);
46
Jamie Madill30d6c252014-11-13 10:03:33 -050047 const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
Brandon Jones44151a92014-09-10 11:32:25 -070048 int getShaderVersion() const { return mShaderVersion; }
Brandon Joneseb994362014-09-24 10:27:28 -070049 GLenum getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
Brandon Jones1a8a7e32014-10-01 12:49:30 -070050
51 GLint getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const;
52 GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const;
53 GLint getUsedSamplerRange(gl::SamplerType type) const;
54 void updateSamplerMapping();
55 bool validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps);
Brandon Jones44151a92014-09-10 11:32:25 -070056
Brandon Joneseb994362014-09-24 10:27:28 -070057 bool usesPointSize() const { return mUsesPointSize; }
Brandon Jones44151a92014-09-10 11:32:25 -070058 bool usesPointSpriteEmulation() const;
59 bool usesGeometryShader() const;
Brandon Jones22502d52014-08-29 16:58:36 -070060
61 GLenum getBinaryFormat() { return GL_PROGRAM_BINARY_ANGLE; }
Geoff Lang7dd2e102014-11-10 15:19:26 -050062 LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream);
Geoff Langb543aff2014-09-30 14:52:54 -040063 gl::Error save(gl::BinaryOutputStream *stream);
Brandon Jones22502d52014-08-29 16:58:36 -070064
Geoff Langb543aff2014-09-30 14:52:54 -040065 gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, ShaderExecutable **outExectuable);
66 gl::Error getPixelExecutableForOutputLayout(const std::vector<GLenum> &outputLayout, ShaderExecutable **outExectuable);
67 gl::Error getVertexExecutableForInputLayout(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS], ShaderExecutable **outExectuable);
Brandon Joneseb994362014-09-24 10:27:28 -070068 ShaderExecutable *getGeometryExecutable() const { return mGeometryExecutable; }
69
Geoff Lang7dd2e102014-11-10 15:19:26 -050070 LinkResult compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
71 int registers);
Brandon Jones22502d52014-08-29 16:58:36 -070072
Geoff Lang7dd2e102014-11-10 15:19:26 -050073 LinkResult link(const gl::Data &data, gl::InfoLog &infoLog,
74 gl::Shader *fragmentShader, gl::Shader *vertexShader,
75 const std::vector<std::string> &transformFeedbackVaryings,
76 GLenum transformFeedbackBufferMode,
77 int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
78 std::map<int, gl::VariableLocation> *outputVariables);
Brandon Jonesc9610c52014-08-25 17:02:59 -070079
Brandon Jones44151a92014-09-10 11:32:25 -070080 void getInputLayoutSignature(const gl::VertexFormat inputLayout[], GLenum signature[]) const;
81
Brandon Jones1a8a7e32014-10-01 12:49:30 -070082 void initializeUniformStorage();
83 gl::Error applyUniforms();
84 gl::Error applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers, const gl::Caps &caps);
Brandon Jones18bd4102014-09-22 14:21:44 -070085 bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
86 unsigned int registerIndex, 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
115 const UniformStorage &getVertexUniformStorage() const { return *mVertexUniformStorage; }
116 const UniformStorage &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
117
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700118 bool linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
119 const gl::Caps &caps);
120 bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
121
Brandon Jonesc9610c52014-08-25 17:02:59 -0700122 void reset();
123
Geoff Lang7dd2e102014-11-10 15:19:26 -0500124 unsigned int getSerial() const;
125
Brandon Jonesc9610c52014-08-25 17:02:59 -0700126 private:
127 DISALLOW_COPY_AND_ASSIGN(ProgramD3D);
128
Brandon Joneseb994362014-09-24 10:27:28 -0700129 class VertexExecutable
130 {
131 public:
132 VertexExecutable(const gl::VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS],
133 const GLenum signature[gl::MAX_VERTEX_ATTRIBS],
Jamie Madill30d6c252014-11-13 10:03:33 -0500134 ShaderExecutable *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700135 ~VertexExecutable();
136
137 bool matchesSignature(const GLenum convertedLayout[gl::MAX_VERTEX_ATTRIBS]) const;
138
139 const gl::VertexFormat *inputs() const { return mInputs; }
140 const GLenum *signature() const { return mSignature; }
Jamie Madill30d6c252014-11-13 10:03:33 -0500141 ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700142
143 private:
144 gl::VertexFormat mInputs[gl::MAX_VERTEX_ATTRIBS];
145 GLenum mSignature[gl::MAX_VERTEX_ATTRIBS];
Jamie Madill30d6c252014-11-13 10:03:33 -0500146 ShaderExecutable *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700147 };
148
149 class PixelExecutable
150 {
151 public:
Jamie Madill30d6c252014-11-13 10:03:33 -0500152 PixelExecutable(const std::vector<GLenum> &outputSignature, ShaderExecutable *shaderExecutable);
Brandon Joneseb994362014-09-24 10:27:28 -0700153 ~PixelExecutable();
154
155 bool matchesSignature(const std::vector<GLenum> &signature) const { return mOutputSignature == signature; }
156
157 const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
Jamie Madill30d6c252014-11-13 10:03:33 -0500158 ShaderExecutable *shaderExecutable() const { return mShaderExecutable; }
Brandon Joneseb994362014-09-24 10:27:28 -0700159
160 private:
161 std::vector<GLenum> mOutputSignature;
Jamie Madill30d6c252014-11-13 10:03:33 -0500162 ShaderExecutable *mShaderExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700163 };
164
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700165 struct Sampler
166 {
167 Sampler();
168
169 bool active;
170 GLint logicalTextureUnit;
171 GLenum textureType;
172 };
173
174 void defineUniformBase(GLenum shader, const sh::Uniform &uniform, unsigned int uniformRegister);
175 void defineUniform(GLenum shader, const sh::ShaderVariable &uniform, const std::string &fullName,
176 sh::HLSLBlockEncoder *encoder);
177 bool indexSamplerUniform(const gl::LinkedUniform &uniform, gl::InfoLog &infoLog, const gl::Caps &caps);
178 bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps);
179 static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
180 std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
181
182 template <typename T>
183 void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
184
185 template <int cols, int rows>
186 void setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
187
188 template <typename T>
189 void getUniformv(GLint location, T *params, GLenum uniformType);
190
191 template <typename VarT>
192 void defineUniformBlockMembers(const std::vector<VarT> &fields, const std::string &prefix, int blockIndex,
193 sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
194 bool inRowMajorLayout);
195
Jamie Madill93e13fb2014-11-06 15:27:25 -0500196 RendererD3D *mRenderer;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700197 DynamicHLSL *mDynamicHLSL;
198
Brandon Joneseb994362014-09-24 10:27:28 -0700199 std::vector<VertexExecutable *> mVertexExecutables;
200 std::vector<PixelExecutable *> mPixelExecutables;
Jamie Madill30d6c252014-11-13 10:03:33 -0500201 ShaderExecutable *mGeometryExecutable;
Brandon Joneseb994362014-09-24 10:27:28 -0700202
Brandon Jones22502d52014-08-29 16:58:36 -0700203 std::string mVertexHLSL;
Jamie Madill30d6c252014-11-13 10:03:33 -0500204 D3DWorkaroundType mVertexWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700205
206 std::string mPixelHLSL;
Jamie Madill30d6c252014-11-13 10:03:33 -0500207 D3DWorkaroundType mPixelWorkarounds;
Brandon Jones22502d52014-08-29 16:58:36 -0700208 bool mUsesFragDepth;
Jamie Madill30d6c252014-11-13 10:03:33 -0500209 std::vector<PixelShaderOutputVariable> mPixelShaderKey;
Brandon Jones22502d52014-08-29 16:58:36 -0700210
Brandon Jones44151a92014-09-10 11:32:25 -0700211 bool mUsesPointSize;
212
Brandon Jonesc9610c52014-08-25 17:02:59 -0700213 UniformStorage *mVertexUniformStorage;
214 UniformStorage *mFragmentUniformStorage;
Brandon Jones44151a92014-09-10 11:32:25 -0700215
Brandon Joneseb994362014-09-24 10:27:28 -0700216 GLenum mTransformFeedbackBufferMode;
Brandon Joneseb994362014-09-24 10:27:28 -0700217
Brandon Jones1a8a7e32014-10-01 12:49:30 -0700218 std::vector<Sampler> mSamplersPS;
219 std::vector<Sampler> mSamplersVS;
220 GLuint mUsedVertexSamplerRange;
221 GLuint mUsedPixelSamplerRange;
222 bool mDirtySamplerMapping;
Brandon Joneseb994362014-09-24 10:27:28 -0700223
Brandon Jones44151a92014-09-10 11:32:25 -0700224 int mShaderVersion;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500225
226 unsigned int mSerial;
227
228 static unsigned int issueSerial();
229 static unsigned int mCurrentSerial;
Brandon Jonesc9610c52014-08-25 17:02:59 -0700230};
231
232}
233
Geoff Lang0a73dd82014-11-19 16:18:08 -0500234#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_