blob: e59feefe10f248b73cfbe3648dbf0878af3fa25b [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
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
Luc Ferron7a06ac12018-03-15 10:17:04 -040013#include <array>
14
Jamie Madilldbc605c2019-01-04 16:39:14 -050015#include "common/utilities.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040016#include "libANGLE/renderer/ProgramImpl.h"
Jamie Madilldc65c5b2018-11-21 11:07:26 -050017#include "libANGLE/renderer/vulkan/ContextVk.h"
Luc Ferron6ea1b412018-03-21 16:13:01 -040018#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill6c7ab7f2018-03-31 14:19:15 -040019#include "libANGLE/renderer/vulkan/vk_helpers.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040020
21namespace rx
22{
Jamie Madilldbc605c2019-01-04 16:39:14 -050023ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
24{
25 return contextVk->getFeatures().basicGLLineRasterization && gl::IsLineMode(mode);
26}
27
Jamie Madill9e54b5a2016-05-25 12:57:39 -040028class ProgramVk : public ProgramImpl
29{
30 public:
31 ProgramVk(const gl::ProgramState &state);
32 ~ProgramVk() override;
Jamie Madillf4a789f2018-10-18 16:56:20 -040033 void destroy(const gl::Context *context) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040034
Geoff Lange332e622019-02-14 12:53:04 -050035 std::unique_ptr<LinkEvent> load(const gl::Context *context,
36 gl::BinaryInputStream *stream,
37 gl::InfoLog &infoLog) override;
Jamie Madill27a60632017-06-30 15:12:01 -040038 void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040039 void setBinaryRetrievableHint(bool retrievable) override;
Yunchao He61afff12017-03-14 15:34:03 +080040 void setSeparable(bool separable) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040041
jchen107ae70d82018-07-06 13:47:01 +080042 std::unique_ptr<LinkEvent> link(const gl::Context *context,
43 const gl::ProgramLinkedResources &resources,
44 gl::InfoLog &infoLog) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040045 GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
46
47 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
48 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
49 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
50 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
51 void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
52 void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
53 void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
54 void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
55 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
56 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
57 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
58 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
59 void setUniformMatrix2fv(GLint location,
60 GLsizei count,
61 GLboolean transpose,
62 const GLfloat *value) override;
63 void setUniformMatrix3fv(GLint location,
64 GLsizei count,
65 GLboolean transpose,
66 const GLfloat *value) override;
67 void setUniformMatrix4fv(GLint location,
68 GLsizei count,
69 GLboolean transpose,
70 const GLfloat *value) override;
71 void setUniformMatrix2x3fv(GLint location,
72 GLsizei count,
73 GLboolean transpose,
74 const GLfloat *value) override;
75 void setUniformMatrix3x2fv(GLint location,
76 GLsizei count,
77 GLboolean transpose,
78 const GLfloat *value) override;
79 void setUniformMatrix2x4fv(GLint location,
80 GLsizei count,
81 GLboolean transpose,
82 const GLfloat *value) override;
83 void setUniformMatrix4x2fv(GLint location,
84 GLsizei count,
85 GLboolean transpose,
86 const GLfloat *value) override;
87 void setUniformMatrix3x4fv(GLint location,
88 GLsizei count,
89 GLboolean transpose,
90 const GLfloat *value) override;
91 void setUniformMatrix4x3fv(GLint location,
92 GLsizei count,
93 GLboolean transpose,
94 const GLfloat *value) override;
95
Jamie Madill54164b02017-08-28 15:17:37 -040096 void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
97 void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
98 void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
99
Sami Väisänen46eaa942016-06-29 10:26:37 +0300100 void setPathFragmentInputGen(const std::string &inputName,
101 GLenum genMode,
102 GLint components,
103 const GLfloat *coeffs) override;
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500104
Jamie Madill06ca6342018-07-12 15:56:53 -0400105 // Also initializes the pipeline layout, descriptor set layouts, and used descriptor ranges.
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500106
Jamie Madill21061022018-07-12 23:56:30 -0400107 angle::Result updateUniforms(ContextVk *contextVk);
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +0100108 angle::Result updateTexturesDescriptorSet(ContextVk *contextVk,
109 vk::FramebufferHelper *framebuffer);
Jamie Madill76e471e2017-10-21 09:56:01 -0400110
Jamie Madill77abad82018-10-25 17:03:48 -0400111 angle::Result updateDescriptorSets(ContextVk *contextVk, vk::CommandBuffer *commandBuffer);
Jamie Madill9b168d02018-06-13 13:25:32 -0400112
Luc Ferron7a06ac12018-03-15 10:17:04 -0400113 // For testing only.
114 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
115
Jamie Madill88fc6da2018-08-30 16:18:36 -0400116 const vk::PipelineLayout &getPipelineLayout() const { return mPipelineLayout.get(); }
117
118 bool hasTextures() const { return !mState.getSamplerBindings().empty(); }
119
Jamie Madill2b858c22018-09-03 13:58:14 -0400120 bool dirtyUniforms() const { return mDefaultUniformBlocksDirty.any(); }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400121
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500122 angle::Result getGraphicsPipeline(ContextVk *contextVk,
123 gl::PrimitiveMode mode,
124 const vk::GraphicsPipelineDesc &desc,
125 const gl::AttributesMask &activeAttribLocations,
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500126 const vk::GraphicsPipelineDesc **descPtrOut,
127 vk::PipelineHelper **pipelineOut)
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500128 {
129 vk::ShaderProgramHelper *shaderProgram;
130 ANGLE_TRY(initShaders(contextVk, mode, &shaderProgram));
131 ASSERT(shaderProgram->isGraphicsProgram());
Jamie Madilldbc605c2019-01-04 16:39:14 -0500132 RendererVk *renderer = contextVk->getRenderer();
133 return shaderProgram->getGraphicsPipeline(
134 contextVk, &renderer->getRenderPassCache(), renderer->getPipelineCache(),
135 renderer->getCurrentQueueSerial(), mPipelineLayout.get(), desc, activeAttribLocations,
Jamie Madill3f0c4a52019-01-10 10:20:35 -0500136 descPtrOut, pipelineOut);
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500137 }
138
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500139 private:
Luc Ferron48cdc2e2018-05-31 09:58:34 -0400140 template <int cols, int rows>
141 void setUniformMatrixfv(GLint location,
142 GLsizei count,
143 GLboolean transpose,
144 const GLfloat *value);
145
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500146 void reset(RendererVk *renderer);
Jamie Madill21061022018-07-12 23:56:30 -0400147 angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
Jamie Madill242c4fe2018-07-12 15:56:56 -0400148 angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
149
Jamie Madill21061022018-07-12 23:56:30 -0400150 angle::Result updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
Jamie Madill76e471e2017-10-21 09:56:01 -0400151
Luc Ferron7cec3352018-03-13 13:29:34 -0400152 template <class T>
153 void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
154
Jamie Madill76e471e2017-10-21 09:56:01 -0400155 template <typename T>
156 void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
Jamie Madill785e8a02018-10-04 17:42:00 -0400157 angle::Result linkImpl(const gl::Context *glContext,
158 const gl::ProgramLinkedResources &resources,
159 gl::InfoLog &infoLog);
Jamie Madillc5143482017-10-15 20:20:06 -0400160
Jamie Madilldbc605c2019-01-04 16:39:14 -0500161 ANGLE_INLINE angle::Result initShaders(ContextVk *contextVk,
162 gl::PrimitiveMode mode,
163 vk::ShaderProgramHelper **shaderProgramOut)
164 {
165 if (UseLineRaster(contextVk, mode))
166 {
167 if (!mLineRasterShaderInfo.valid())
168 {
169 ANGLE_TRY(mLineRasterShaderInfo.initShaders(contextVk, mVertexSource,
170 mFragmentSource, true));
171 }
172
173 ASSERT(mLineRasterShaderInfo.valid());
174 *shaderProgramOut = &mLineRasterShaderInfo.getShaderProgram();
175 }
176 else
177 {
178 if (!mDefaultShaderInfo.valid())
179 {
180 ANGLE_TRY(mDefaultShaderInfo.initShaders(contextVk, mVertexSource, mFragmentSource,
181 false));
182 }
183
184 ASSERT(mDefaultShaderInfo.valid());
185 *shaderProgramOut = &mDefaultShaderInfo.getShaderProgram();
186 }
187
188 return angle::Result::Continue;
189 }
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500190
Jamie Madill76e471e2017-10-21 09:56:01 -0400191 // State for the default uniform blocks.
192 struct DefaultUniformBlock final : private angle::NonCopyable
193 {
194 DefaultUniformBlock();
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500195 ~DefaultUniformBlock();
Jamie Madill76e471e2017-10-21 09:56:01 -0400196
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400197 vk::DynamicBuffer storage;
Jamie Madill76e471e2017-10-21 09:56:01 -0400198
199 // Shadow copies of the shader uniform data.
200 angle::MemoryBuffer uniformData;
Jamie Madill76e471e2017-10-21 09:56:01 -0400201
202 // Since the default blocks are laid out in std140, this tells us where to write on a call
203 // to a setUniform method. They are arranged in uniform location order.
204 std::vector<sh::BlockMemberInfo> uniformLayout;
205 };
206
Shahbaz Youssefidf066e92018-11-13 15:39:47 -0500207 gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
208 gl::ShaderBitSet mDefaultUniformBlocksDirty;
209 gl::ShaderMap<uint32_t> mUniformBlocksOffsets;
Jamie Madill76e471e2017-10-21 09:56:01 -0400210
211 // This is a special "empty" placeholder buffer for when a shader has no uniforms.
212 // It is necessary because we want to keep a compatible pipeline layout in all cases,
213 // and Vulkan does not tolerate having null handles in a descriptor set.
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500214 vk::BufferHelper mEmptyUniformBlockStorage;
Jamie Madill76e471e2017-10-21 09:56:01 -0400215
Jamie Madill5547b382017-10-23 18:16:01 -0400216 // Descriptor sets for uniform blocks and textures for this program.
217 std::vector<VkDescriptorSet> mDescriptorSets;
Jamie Madill8c3988c2017-12-21 14:44:56 -0500218 gl::RangeUI mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400219
Jamie Madill9b168d02018-06-13 13:25:32 -0400220 // We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get
221 // deleted while this program is in use.
222 vk::BindingPointer<vk::PipelineLayout> mPipelineLayout;
223 vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400224
Jamie Madill78bcd2b2018-10-16 15:05:20 -0400225 // Keep bindings to the descriptor pools. This ensures the pools stay valid while the Program
226 // is in use.
Shahbaz Youssefid8381782019-03-04 11:07:47 -0500227 vk::DescriptorSetLayoutArray<vk::RefCountedDescriptorPoolBinding> mDescriptorPoolBindings;
Jamie Madill78bcd2b2018-10-16 15:05:20 -0400228
Jamie Madill242c4fe2018-07-12 15:56:56 -0400229 class ShaderInfo final : angle::NonCopyable
230 {
231 public:
232 ShaderInfo();
233 ~ShaderInfo();
234
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500235 angle::Result initShaders(ContextVk *contextVk,
236 const std::string &vertexSource,
237 const std::string &fragmentSource,
238 bool enableLineRasterEmulation);
239 void release(RendererVk *renderer);
Jamie Madilldbc605c2019-01-04 16:39:14 -0500240
241 ANGLE_INLINE bool valid() const { return mShaders[gl::ShaderType::Vertex].get().valid(); }
Jamie Madill242c4fe2018-07-12 15:56:56 -0400242
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500243 vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; }
244
Jamie Madill242c4fe2018-07-12 15:56:56 -0400245 private:
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500246 vk::ShaderProgramHelper mProgramHelper;
247 gl::ShaderMap<vk::RefCounted<vk::ShaderAndSerial>> mShaders;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400248 };
249
Jamie Madill242c4fe2018-07-12 15:56:56 -0400250 ShaderInfo mDefaultShaderInfo;
Jamie Madillb36a4812018-09-25 10:15:11 -0400251 ShaderInfo mLineRasterShaderInfo;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400252
253 // We keep the translated linked shader sources to use with shader draw call patching.
254 std::string mVertexSource;
255 std::string mFragmentSource;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400256};
257
258} // namespace rx
259
260#endif // LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_