blob: a19b636f3d5206e603cc2e4fc6e4fe5b024d06d1 [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 Madill9e54b5a2016-05-25 12:57:39 -040015#include "libANGLE/renderer/ProgramImpl.h"
Jamie Madilldc65c5b2018-11-21 11:07:26 -050016#include "libANGLE/renderer/vulkan/ContextVk.h"
Luc Ferron6ea1b412018-03-21 16:13:01 -040017#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill6c7ab7f2018-03-31 14:19:15 -040018#include "libANGLE/renderer/vulkan/vk_helpers.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040019
20namespace rx
21{
Jamie Madill9e54b5a2016-05-25 12:57:39 -040022class ProgramVk : public ProgramImpl
23{
24 public:
25 ProgramVk(const gl::ProgramState &state);
26 ~ProgramVk() override;
Jamie Madillf4a789f2018-10-18 16:56:20 -040027 void destroy(const gl::Context *context) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040028
Jamie Madill785e8a02018-10-04 17:42:00 -040029 angle::Result load(const gl::Context *context,
30 gl::InfoLog &infoLog,
31 gl::BinaryInputStream *stream) override;
Jamie Madill27a60632017-06-30 15:12:01 -040032 void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040033 void setBinaryRetrievableHint(bool retrievable) override;
Yunchao He61afff12017-03-14 15:34:03 +080034 void setSeparable(bool separable) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040035
jchen107ae70d82018-07-06 13:47:01 +080036 std::unique_ptr<LinkEvent> link(const gl::Context *context,
37 const gl::ProgramLinkedResources &resources,
38 gl::InfoLog &infoLog) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040039 GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
40
41 void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
42 void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
43 void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
44 void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
45 void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
46 void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
47 void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
48 void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
49 void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
50 void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
51 void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
52 void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
53 void setUniformMatrix2fv(GLint location,
54 GLsizei count,
55 GLboolean transpose,
56 const GLfloat *value) override;
57 void setUniformMatrix3fv(GLint location,
58 GLsizei count,
59 GLboolean transpose,
60 const GLfloat *value) override;
61 void setUniformMatrix4fv(GLint location,
62 GLsizei count,
63 GLboolean transpose,
64 const GLfloat *value) override;
65 void setUniformMatrix2x3fv(GLint location,
66 GLsizei count,
67 GLboolean transpose,
68 const GLfloat *value) override;
69 void setUniformMatrix3x2fv(GLint location,
70 GLsizei count,
71 GLboolean transpose,
72 const GLfloat *value) override;
73 void setUniformMatrix2x4fv(GLint location,
74 GLsizei count,
75 GLboolean transpose,
76 const GLfloat *value) override;
77 void setUniformMatrix4x2fv(GLint location,
78 GLsizei count,
79 GLboolean transpose,
80 const GLfloat *value) override;
81 void setUniformMatrix3x4fv(GLint location,
82 GLsizei count,
83 GLboolean transpose,
84 const GLfloat *value) override;
85 void setUniformMatrix4x3fv(GLint location,
86 GLsizei count,
87 GLboolean transpose,
88 const GLfloat *value) override;
89
Jamie Madill54164b02017-08-28 15:17:37 -040090 void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
91 void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
92 void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
93
Sami Väisänen46eaa942016-06-29 10:26:37 +030094 void setPathFragmentInputGen(const std::string &inputName,
95 GLenum genMode,
96 GLint components,
97 const GLfloat *coeffs) override;
Jamie Madill8ecf7f92017-01-13 17:29:52 -050098
Jamie Madill06ca6342018-07-12 15:56:53 -040099 // Also initializes the pipeline layout, descriptor set layouts, and used descriptor ranges.
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500100
Jamie Madill21061022018-07-12 23:56:30 -0400101 angle::Result updateUniforms(ContextVk *contextVk);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400102 angle::Result updateTexturesDescriptorSet(ContextVk *contextVk);
Jamie Madill76e471e2017-10-21 09:56:01 -0400103
Jamie Madill77abad82018-10-25 17:03:48 -0400104 angle::Result updateDescriptorSets(ContextVk *contextVk, vk::CommandBuffer *commandBuffer);
Jamie Madill9b168d02018-06-13 13:25:32 -0400105
Luc Ferron7a06ac12018-03-15 10:17:04 -0400106 // For testing only.
107 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
108
Jamie Madill88fc6da2018-08-30 16:18:36 -0400109 const vk::PipelineLayout &getPipelineLayout() const { return mPipelineLayout.get(); }
110
111 bool hasTextures() const { return !mState.getSamplerBindings().empty(); }
112
Jamie Madill2b858c22018-09-03 13:58:14 -0400113 bool dirtyUniforms() const { return mDefaultUniformBlocksDirty.any(); }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400114
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500115 angle::Result getGraphicsPipeline(ContextVk *contextVk,
116 gl::PrimitiveMode mode,
117 const vk::GraphicsPipelineDesc &desc,
118 const gl::AttributesMask &activeAttribLocations,
119 vk::PipelineAndSerial **pipelineOut)
120 {
121 vk::ShaderProgramHelper *shaderProgram;
122 ANGLE_TRY(initShaders(contextVk, mode, &shaderProgram));
123 ASSERT(shaderProgram->isGraphicsProgram());
124 return shaderProgram->getGraphicsPipeline(contextVk, mPipelineLayout.get(), desc,
125 activeAttribLocations, pipelineOut);
126 }
127
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500128 private:
Luc Ferron48cdc2e2018-05-31 09:58:34 -0400129 template <int cols, int rows>
130 void setUniformMatrixfv(GLint location,
131 GLsizei count,
132 GLboolean transpose,
133 const GLfloat *value);
134
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500135 void reset(RendererVk *renderer);
Jamie Madill21061022018-07-12 23:56:30 -0400136 angle::Result allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
Jamie Madill242c4fe2018-07-12 15:56:56 -0400137 angle::Result initDefaultUniformBlocks(const gl::Context *glContext);
138
Jamie Madill21061022018-07-12 23:56:30 -0400139 angle::Result updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
Jamie Madill76e471e2017-10-21 09:56:01 -0400140
Luc Ferron7cec3352018-03-13 13:29:34 -0400141 template <class T>
142 void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
143
Jamie Madill76e471e2017-10-21 09:56:01 -0400144 template <typename T>
145 void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
Jamie Madill785e8a02018-10-04 17:42:00 -0400146 angle::Result linkImpl(const gl::Context *glContext,
147 const gl::ProgramLinkedResources &resources,
148 gl::InfoLog &infoLog);
Jamie Madillc5143482017-10-15 20:20:06 -0400149
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500150 angle::Result initShaders(ContextVk *contextVk,
151 gl::PrimitiveMode mode,
152 vk::ShaderProgramHelper **shaderProgramOut);
153
Jamie Madill76e471e2017-10-21 09:56:01 -0400154 // State for the default uniform blocks.
155 struct DefaultUniformBlock final : private angle::NonCopyable
156 {
157 DefaultUniformBlock();
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500158 ~DefaultUniformBlock();
Jamie Madill76e471e2017-10-21 09:56:01 -0400159
Jamie Madill6c7ab7f2018-03-31 14:19:15 -0400160 vk::DynamicBuffer storage;
Jamie Madill76e471e2017-10-21 09:56:01 -0400161
162 // Shadow copies of the shader uniform data.
163 angle::MemoryBuffer uniformData;
Jamie Madill76e471e2017-10-21 09:56:01 -0400164
165 // Since the default blocks are laid out in std140, this tells us where to write on a call
166 // to a setUniform method. They are arranged in uniform location order.
167 std::vector<sh::BlockMemberInfo> uniformLayout;
168 };
169
Shahbaz Youssefidf066e92018-11-13 15:39:47 -0500170 gl::ShaderMap<DefaultUniformBlock> mDefaultUniformBlocks;
171 gl::ShaderBitSet mDefaultUniformBlocksDirty;
172 gl::ShaderMap<uint32_t> mUniformBlocksOffsets;
Jamie Madill76e471e2017-10-21 09:56:01 -0400173
174 // This is a special "empty" placeholder buffer for when a shader has no uniforms.
175 // It is necessary because we want to keep a compatible pipeline layout in all cases,
176 // and Vulkan does not tolerate having null handles in a descriptor set.
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500177 vk::BufferHelper mEmptyUniformBlockStorage;
Jamie Madill76e471e2017-10-21 09:56:01 -0400178
Jamie Madill5547b382017-10-23 18:16:01 -0400179 // Descriptor sets for uniform blocks and textures for this program.
180 std::vector<VkDescriptorSet> mDescriptorSets;
Jamie Madill8c3988c2017-12-21 14:44:56 -0500181 gl::RangeUI mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400182
Jamie Madill9b168d02018-06-13 13:25:32 -0400183 // We keep a reference to the pipeline and descriptor set layouts. This ensures they don't get
184 // deleted while this program is in use.
185 vk::BindingPointer<vk::PipelineLayout> mPipelineLayout;
186 vk::DescriptorSetLayoutPointerArray mDescriptorSetLayouts;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400187
Jamie Madill78bcd2b2018-10-16 15:05:20 -0400188 // Keep bindings to the descriptor pools. This ensures the pools stay valid while the Program
189 // is in use.
190 vk::DescriptorSetLayoutArray<vk::SharedDescriptorPoolBinding> mDescriptorPoolBindings;
191
Jamie Madill242c4fe2018-07-12 15:56:56 -0400192 class ShaderInfo final : angle::NonCopyable
193 {
194 public:
195 ShaderInfo();
196 ~ShaderInfo();
197
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500198 angle::Result initShaders(ContextVk *contextVk,
199 const std::string &vertexSource,
200 const std::string &fragmentSource,
201 bool enableLineRasterEmulation);
202 void release(RendererVk *renderer);
Jamie Madill242c4fe2018-07-12 15:56:56 -0400203 bool valid() const;
204
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500205 vk::ShaderProgramHelper &getShaderProgram() { return mProgramHelper; }
206
Jamie Madill242c4fe2018-07-12 15:56:56 -0400207 private:
Jamie Madilldc65c5b2018-11-21 11:07:26 -0500208 vk::ShaderProgramHelper mProgramHelper;
209 gl::ShaderMap<vk::RefCounted<vk::ShaderAndSerial>> mShaders;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400210 };
211
Jamie Madill242c4fe2018-07-12 15:56:56 -0400212 ShaderInfo mDefaultShaderInfo;
Jamie Madillb36a4812018-09-25 10:15:11 -0400213 ShaderInfo mLineRasterShaderInfo;
Jamie Madill242c4fe2018-07-12 15:56:56 -0400214
215 // We keep the translated linked shader sources to use with shader draw call patching.
216 std::string mVertexSource;
217 std::string mFragmentSource;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400218};
219
220} // namespace rx
221
222#endif // LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_