blob: 001d5bc7db2062971332d4edab06cae4c2ab3b19 [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 Madill5547b382017-10-23 18:16:01 -040015#include "libANGLE/Constants.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040016#include "libANGLE/renderer/ProgramImpl.h"
Luc Ferron6ea1b412018-03-21 16:13:01 -040017#include "libANGLE/renderer/vulkan/RendererVk.h"
Luc Ferron7a06ac12018-03-15 10:17:04 -040018#include "libANGLE/renderer/vulkan/StreamingBuffer.h"
Jamie Madill3c424b42018-01-19 12:35:09 -050019#include "libANGLE/renderer/vulkan/vk_utils.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040020
21namespace rx
22{
Luc Ferron7a06ac12018-03-15 10:17:04 -040023namespace
24{
25constexpr uint32_t kShaderTypeCount = 2;
26} // anonymous namespace.
Jamie Madill9e54b5a2016-05-25 12:57:39 -040027
28class ProgramVk : public ProgramImpl
29{
30 public:
31 ProgramVk(const gl::ProgramState &state);
32 ~ProgramVk() override;
Jamie Madillb7d924a2018-03-10 11:16:54 -050033 gl::Error destroy(const gl::Context *context) override;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040034
Jamie Madill9cf9e872017-06-05 12:59:25 -040035 gl::LinkResult load(const gl::Context *context,
36 gl::InfoLog &infoLog,
37 gl::BinaryInputStream *stream) 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
Jamie Madill9cf9e872017-06-05 12:59:25 -040042 gl::LinkResult link(const gl::Context *context,
Jamie Madillc9727f32017-11-07 12:37:07 -050043 const gl::ProgramLinkedResources &resources,
Jamie Madill9cf9e872017-06-05 12:59:25 -040044 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
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400100 // TODO: synchronize in syncState when dirty bits exist.
101 void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
102
Sami Väisänen46eaa942016-06-29 10:26:37 +0300103 void setPathFragmentInputGen(const std::string &inputName,
104 GLenum genMode,
105 GLint components,
106 const GLfloat *coeffs) override;
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500107
108 const vk::ShaderModule &getLinkedVertexModule() const;
Jamie Madillf2f6d372018-01-10 21:37:23 -0500109 Serial getVertexModuleSerial() const;
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500110 const vk::ShaderModule &getLinkedFragmentModule() const;
Jamie Madillf2f6d372018-01-10 21:37:23 -0500111 Serial getFragmentModuleSerial() const;
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500112
Jamie Madill76e471e2017-10-21 09:56:01 -0400113 vk::Error updateUniforms(ContextVk *contextVk);
114
Jamie Madill5547b382017-10-23 18:16:01 -0400115 const std::vector<VkDescriptorSet> &getDescriptorSets() const;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400116 const uint32_t *getDynamicOffsets();
117 uint32_t getDynamicOffsetsCount();
Jamie Madill5547b382017-10-23 18:16:01 -0400118
119 // In Vulkan, it is invalid to pass in a NULL descriptor set to vkCmdBindDescriptorSets.
120 // However, it's valid to leave them in an undefined, unbound state, if they are never used.
121 // This means when we want to ignore a descriptor set index, we need to pass in an offset
122 // parameter to BindDescriptorSets, which is an offset into the getDescriptorSets array.
Jamie Madill8c3988c2017-12-21 14:44:56 -0500123 // This allows us to skip binding blank descriptor sets when the Program doesn't use Uniforms
124 // or Textures.
125 const gl::RangeUI &getUsedDescriptorSetRange() const;
Jamie Madill5547b382017-10-23 18:16:01 -0400126
Luc Ferron6ea1b412018-03-21 16:13:01 -0400127 vk::Error updateTexturesDescriptorSet(ContextVk *contextVk);
Jamie Madill5547b382017-10-23 18:16:01 -0400128 void invalidateTextures();
Jamie Madill76e471e2017-10-21 09:56:01 -0400129
Luc Ferron7a06ac12018-03-15 10:17:04 -0400130 // For testing only.
131 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
132
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500133 private:
Jamie Madillb7d924a2018-03-10 11:16:54 -0500134 vk::Error reset(ContextVk *contextVk);
Luc Ferron6ea1b412018-03-21 16:13:01 -0400135 vk::Error allocateDescriptorSet(ContextVk *contextVk, uint32_t descriptorSetIndex);
Jamie Madill76e471e2017-10-21 09:56:01 -0400136 gl::Error initDefaultUniformBlocks(const gl::Context *glContext);
137 vk::Error updateDefaultUniformsDescriptorSet(ContextVk *contextVk);
138
Luc Ferron7cec3352018-03-13 13:29:34 -0400139 template <class T>
140 void getUniformImpl(GLint location, T *v, GLenum entryPointType) const;
141
Jamie Madill76e471e2017-10-21 09:56:01 -0400142 template <typename T>
143 void setUniformImpl(GLint location, GLsizei count, const T *v, GLenum entryPointType);
Jamie Madillc5143482017-10-15 20:20:06 -0400144
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500145 vk::ShaderModule mLinkedVertexModule;
Jamie Madillf2f6d372018-01-10 21:37:23 -0500146 Serial mVertexModuleSerial;
Jamie Madill8ecf7f92017-01-13 17:29:52 -0500147 vk::ShaderModule mLinkedFragmentModule;
Jamie Madillf2f6d372018-01-10 21:37:23 -0500148 Serial mFragmentModuleSerial;
Jamie Madill76e471e2017-10-21 09:56:01 -0400149
150 // State for the default uniform blocks.
151 struct DefaultUniformBlock final : private angle::NonCopyable
152 {
153 DefaultUniformBlock();
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500154 ~DefaultUniformBlock();
Jamie Madill76e471e2017-10-21 09:56:01 -0400155
Luc Ferron7a06ac12018-03-15 10:17:04 -0400156 StreamingBuffer storage;
Jamie Madill76e471e2017-10-21 09:56:01 -0400157
158 // Shadow copies of the shader uniform data.
159 angle::MemoryBuffer uniformData;
160 bool uniformsDirty;
161
162 // Since the default blocks are laid out in std140, this tells us where to write on a call
163 // to a setUniform method. They are arranged in uniform location order.
164 std::vector<sh::BlockMemberInfo> uniformLayout;
165 };
166
Luc Ferron7a06ac12018-03-15 10:17:04 -0400167 std::array<DefaultUniformBlock, kShaderTypeCount> mDefaultUniformBlocks;
168 std::array<uint32_t, kShaderTypeCount> mUniformBlocksOffsets;
Jamie Madill76e471e2017-10-21 09:56:01 -0400169
170 // This is a special "empty" placeholder buffer for when a shader has no uniforms.
171 // It is necessary because we want to keep a compatible pipeline layout in all cases,
172 // and Vulkan does not tolerate having null handles in a descriptor set.
173 vk::BufferAndMemory mEmptyUniformBlockStorage;
174
Jamie Madill5547b382017-10-23 18:16:01 -0400175 // Descriptor sets for uniform blocks and textures for this program.
176 std::vector<VkDescriptorSet> mDescriptorSets;
Jamie Madill8c3988c2017-12-21 14:44:56 -0500177 gl::RangeUI mUsedDescriptorSetRange;
Jamie Madill5547b382017-10-23 18:16:01 -0400178 bool mDirtyTextures;
179
180 template <typename T>
181 using ShaderTextureArray = std::array<T, gl::IMPLEMENTATION_MAX_SHADER_TEXTURES>;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400182};
183
184} // namespace rx
185
186#endif // LIBANGLE_RENDERER_VULKAN_PROGRAMVK_H_