1 //
2 // Copyright 2016 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 // ProgramVk.h:
7 // Defines the class interface for ProgramVk, implementing ProgramImpl.
8 //
9
10 #ifndef LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
12
13 #include <array>
14
15 #include "common/utilities.h"
16 #include "libANGLE/renderer/ProgramImpl.h"
17 #include "libANGLE/renderer/glslang_wrapper_utils.h"
18 #include "libANGLE/renderer/vulkan/ContextVk.h"
19 #include "libANGLE/renderer/vulkan/ProgramExecutableVk.h"
20 #include "libANGLE/renderer/vulkan/RendererVk.h"
21 #include "libANGLE/renderer/vulkan/TransformFeedbackVk.h"
22 #include "libANGLE/renderer/vulkan/vk_helpers.h"
23
24 namespace rx
25 {
UseLineRaster(const ContextVk * contextVk,gl::PrimitiveMode mode)26 ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
27 {
28 return contextVk->getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
29 }
30
31 class ProgramVk : public ProgramImpl
32 {
33 public:
34 ProgramVk(const gl::ProgramState &state);
35 ~ProgramVk() override;
36 void destroy(const gl::Context *context) override;
37
38 std::unique_ptr<LinkEvent> load(const gl::Context *context,
39 gl::BinaryInputStream *stream,
40 gl::InfoLog &infoLog) override;
41 void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
42 void setBinaryRetrievableHint(bool retrievable) override;
43 void setSeparable(bool separable) override;
44
45 void fillProgramStateMap(gl::ShaderMap<const gl::ProgramState *> *programStatesOut);
46
47 std::unique_ptr<LinkEvent> link(const gl::Context *context,
48 const gl::ProgramLinkedResources &resources,
49 gl::InfoLog &infoLog) override;
50 GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
51
52 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
53 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
54 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
55 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
56 void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
57 void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
58 void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
59 void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
60 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
61 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
62 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
63 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
64 void setUniformMatrix2fv(GLint location,
65 GLsizei count,
66 GLboolean transpose,
67 const GLfloat *value) override;
68 void setUniformMatrix3fv(GLint location,
69 GLsizei count,
70 GLboolean transpose,
71 const GLfloat *value) override;
72 void setUniformMatrix4fv(GLint location,
73 GLsizei count,
74 GLboolean transpose,
75 const GLfloat *value) override;
76 void setUniformMatrix2x3fv(GLint location,
77 GLsizei count,
78 GLboolean transpose,
79 const GLfloat *value) override;
80 void setUniformMatrix3x2fv(GLint location,
81 GLsizei count,
82 GLboolean transpose,
83 const GLfloat *value) override;
84 void setUniformMatrix2x4fv(GLint location,
85 GLsizei count,
86 GLboolean transpose,
87 const GLfloat *value) override;
88 void setUniformMatrix4x2fv(GLint location,
89 GLsizei count,
90 GLboolean transpose,
91 const GLfloat *value) override;
92 void setUniformMatrix3x4fv(GLint location,
93 GLsizei count,
94 GLboolean transpose,
95 const GLfloat *value) override;
96 void setUniformMatrix4x3fv(GLint location,
97 GLsizei count,
98 GLboolean transpose,
99 const GLfloat *value) override;
100
101 void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
102 void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
103 void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
104
105 angle::Result updateShaderUniforms(ContextVk *contextVk,
106 gl::ShaderType shaderType,
107 uint32_t *outOffset,
108 bool *anyNewBufferAllocated);
109 angle::Result updateUniforms(ContextVk *contextVk);
110
111 // For testing only.
112 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
113
dirtyUniforms()114 bool dirtyUniforms() const { return mDefaultUniformBlocksDirty.any(); }
115
116 // Used in testing only.
getDynamicDescriptorPool(uint32_t poolIndex)117 vk::DynamicDescriptorPool *getDynamicDescriptorPool(uint32_t poolIndex)
118 {
119 return &mExecutable.mDynamicDescriptorPools[poolIndex];
120 }
121
getExecutable()122 const ProgramExecutableVk &getExecutable() const { return mExecutable; }
getExecutable()123 ProgramExecutableVk &getExecutable() { return mExecutable; }
124
getDefaultUniformBlocks()125 gl::ShaderMap<DefaultUniformBlock> &getDefaultUniformBlocks() { return mDefaultUniformBlocks; }
126
initGraphicsShaderProgram(ContextVk * contextVk,const gl::ShaderType shaderType,ProgramTransformOptionBits optionBits,ProgramInfo & programInfo)127 ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk,
128 const gl::ShaderType shaderType,
129 ProgramTransformOptionBits optionBits,
130 ProgramInfo &programInfo)
131 {
132 return initProgram(contextVk, shaderType, optionBits, &programInfo);
133 }
134
initComputeProgram(ContextVk * contextVk,ProgramInfo & programInfo)135 ANGLE_INLINE angle::Result initComputeProgram(ContextVk *contextVk, ProgramInfo &programInfo)
136 {
137 ProgramTransformOptionBits optionBits;
138 return initProgram(contextVk, gl::ShaderType::Compute, optionBits, &programInfo);
139 }
140
getShaderInfo()141 ShaderInfo &getShaderInfo() { return mShaderInfo; }
142
getGlslangProgramInterfaceInfo()143 GlslangProgramInterfaceInfo &getGlslangProgramInterfaceInfo()
144 {
145 return mGlslangProgramInterfaceInfo;
146 }
147
148 private:
149 template <int cols, int rows>
150 void setUniformMatrixfv(GLint location,
151 GLsizei count,
152 GLboolean transpose,
153 const GLfloat *value);
154
155 void reset(ContextVk *contextVk);
156 angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
157 void generateUniformLayoutMapping(gl::ShaderMap<sh::BlockLayoutMap> &layoutMap,
158 gl::ShaderMap<size_t> &requiredBufferSize);
159 void initDefaultUniformLayoutMapping(gl::ShaderMap<sh::BlockLayoutMap> &layoutMap);
160 angle::Result resizeUniformBlockMemory(ContextVk *contextVk,
161 gl::ShaderMap<size_t> &requiredBufferSize);
162
163 template <class T>
164 void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
165
166 template <typename T>
167 void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
168 angle::Result linkImpl(const gl::Context *glContext, gl::InfoLog &infoLog);
169 void linkResources(const gl::ProgramLinkedResources &resources);
170
initProgram(ContextVk * contextVk,const gl::ShaderType shaderType,ProgramTransformOptionBits optionBits,ProgramInfo * programInfo)171 ANGLE_INLINE angle::Result initProgram(ContextVk *contextVk,
172 const gl::ShaderType shaderType,
173 ProgramTransformOptionBits optionBits,
174 ProgramInfo *programInfo)
175 {
176 ASSERT(mShaderInfo.valid());
177
178 // Create the program pipeline. This is done lazily and once per combination of
179 // specialization constants.
180 if (!programInfo->valid(shaderType))
181 {
182 ANGLE_TRY(programInfo->initProgram(contextVk, shaderType, mShaderInfo,
183 mExecutable.mVariableInfoMap, optionBits));
184 }
185 ASSERT(programInfo->valid(shaderType));
186
187 return angle::Result::Continue;
188 }
189
190 gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
191 gl::ShaderBitSet mDefaultUniformBlocksDirty;
192
193 // We keep the SPIR-V code to use for draw call pipeline creation.
194 ShaderInfo mShaderInfo;
195
196 GlslangProgramInterfaceInfo mGlslangProgramInterfaceInfo;
197
198 ProgramExecutableVk mExecutable;
199 };
200
201 } // namespace rx
202
203 #endif // LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_
204