• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_PIPELINE_H_
16 #define SRC_PIPELINE_H_
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 #include <unordered_map>
22 #include <utility>
23 #include <vector>
24 
25 #include "amber/result.h"
26 #include "src/buffer.h"
27 #include "src/shader.h"
28 
29 namespace amber {
30 
31 enum class PipelineType { kCompute = 0, kGraphics };
32 
33 /// Stores all information related to a pipeline.
34 class Pipeline {
35  public:
36   /// Information on a shader attached to this pipeline.
37   class ShaderInfo {
38    public:
39     ShaderInfo(Shader*, ShaderType type);
40     ShaderInfo(const ShaderInfo&);
41     ~ShaderInfo();
42 
43     ShaderInfo& operator=(const ShaderInfo&) = default;
44 
45     // Set the optimization options for this shader. Optimizations are
46     // specified like command-line arguments to spirv-opt (see its --help).
47     // Parsing is done by spvtools::Optimizer::RegisterPassesFromFlags (see
48     // SPIRV-Tools include/spirv-tools/optimizer.hpp).
SetShaderOptimizations(const std::vector<std::string> & opts)49     void SetShaderOptimizations(const std::vector<std::string>& opts) {
50       shader_optimizations_ = opts;
51     }
GetShaderOptimizations()52     const std::vector<std::string>& GetShaderOptimizations() const {
53       return shader_optimizations_;
54     }
55 
SetCompileOptions(const std::vector<std::string> & options)56     void SetCompileOptions(const std::vector<std::string>& options) {
57       compile_options_ = options;
58     }
GetCompileOptions()59     const std::vector<std::string>& GetCompileOptions() const {
60       return compile_options_;
61     }
62 
SetShader(Shader * shader)63     void SetShader(Shader* shader) { shader_ = shader; }
GetShader()64     const Shader* GetShader() const { return shader_; }
65 
SetEntryPoint(const std::string & ep)66     void SetEntryPoint(const std::string& ep) { entry_point_ = ep; }
GetEntryPoint()67     const std::string& GetEntryPoint() const { return entry_point_; }
68 
SetShaderType(ShaderType type)69     void SetShaderType(ShaderType type) { shader_type_ = type; }
GetShaderType()70     ShaderType GetShaderType() const { return shader_type_; }
71 
GetData()72     const std::vector<uint32_t> GetData() const { return data_; }
SetData(std::vector<uint32_t> && data)73     void SetData(std::vector<uint32_t>&& data) { data_ = std::move(data); }
74 
GetSpecialization()75     const std::map<uint32_t, uint32_t>& GetSpecialization() const {
76       return specialization_;
77     }
AddSpecialization(uint32_t spec_id,uint32_t value)78     void AddSpecialization(uint32_t spec_id, uint32_t value) {
79       specialization_[spec_id] = value;
80     }
81 
82     /// Descriptor information for an OpenCL-C shader.
83     struct DescriptorMapEntry {
84       std::string arg_name = "";
85 
86       enum class Kind : int {
87         UNKNOWN,
88         SSBO,
89         UBO,
90         POD,
91         POD_UBO,
92       } kind;
93 
94       uint32_t descriptor_set = 0;
95       uint32_t binding = 0;
96       uint32_t arg_ordinal = 0;
97       uint32_t pod_offset = 0;
98       uint32_t pod_arg_size = 0;
99     };
100 
AddDescriptorEntry(const std::string & kernel,DescriptorMapEntry && entry)101     void AddDescriptorEntry(const std::string& kernel,
102                             DescriptorMapEntry&& entry) {
103       descriptor_map_[kernel].emplace_back(std::move(entry));
104     }
105     const std::unordered_map<std::string, std::vector<DescriptorMapEntry>>&
GetDescriptorMap()106     GetDescriptorMap() const {
107       return descriptor_map_;
108     }
109 
110    private:
111     Shader* shader_ = nullptr;
112     ShaderType shader_type_;
113     std::vector<std::string> shader_optimizations_;
114     std::string entry_point_;
115     std::vector<uint32_t> data_;
116     std::map<uint32_t, uint32_t> specialization_;
117     std::unordered_map<std::string, std::vector<DescriptorMapEntry>>
118         descriptor_map_;
119     std::vector<std::string> compile_options_;
120   };
121 
122   /// Information on a buffer attached to the pipeline.
123   ///
124   /// The BufferInfo will have either (descriptor_set, binding) or location
125   /// attached.
126   struct BufferInfo {
127     BufferInfo() = default;
BufferInfoBufferInfo128     explicit BufferInfo(Buffer* buf) : buffer(buf) {}
129 
130     Buffer* buffer = nullptr;
131     uint32_t descriptor_set = 0;
132     uint32_t binding = 0;
133     uint32_t location = 0;
134     std::string arg_name = "";
135     uint32_t arg_no = 0;
136   };
137 
138   static const char* kGeneratedColorBuffer;
139   static const char* kGeneratedDepthBuffer;
140 
141   explicit Pipeline(PipelineType type);
142   ~Pipeline();
143 
144   std::unique_ptr<Pipeline> Clone() const;
145 
IsGraphics()146   bool IsGraphics() const { return pipeline_type_ == PipelineType::kGraphics; }
IsCompute()147   bool IsCompute() const { return pipeline_type_ == PipelineType::kCompute; }
148 
GetType()149   PipelineType GetType() const { return pipeline_type_; }
150 
SetName(const std::string & name)151   void SetName(const std::string& name) { name_ = name; }
GetName()152   const std::string& GetName() const { return name_; }
153 
SetFramebufferWidth(uint32_t fb_width)154   void SetFramebufferWidth(uint32_t fb_width) {
155     fb_width_ = fb_width;
156     UpdateFramebufferSizes();
157   }
GetFramebufferWidth()158   uint32_t GetFramebufferWidth() const { return fb_width_; }
159 
SetFramebufferHeight(uint32_t fb_height)160   void SetFramebufferHeight(uint32_t fb_height) {
161     fb_height_ = fb_height;
162     UpdateFramebufferSizes();
163   }
GetFramebufferHeight()164   uint32_t GetFramebufferHeight() const { return fb_height_; }
165 
166   /// Adds |shader| of |type| to the pipeline.
167   Result AddShader(Shader* shader, ShaderType type);
168   /// Returns information on all bound shaders in this pipeline.
GetShaders()169   std::vector<ShaderInfo>& GetShaders() { return shaders_; }
170   /// Returns information on all bound shaders in this pipeline.
GetShaders()171   const std::vector<ShaderInfo>& GetShaders() const { return shaders_; }
172 
173   /// Sets the |type| of |shader| in the pipeline.
174   Result SetShaderType(const Shader* shader, ShaderType type);
175   /// Sets the entry point |name| for |shader| in this pipeline.
176   Result SetShaderEntryPoint(const Shader* shader, const std::string& name);
177   /// Sets the optimizations (|opts|) for |shader| in this pipeline.
178   Result SetShaderOptimizations(const Shader* shader,
179                                 const std::vector<std::string>& opts);
180   /// Sets the compile options for |shader| in this pipeline.
181   Result SetShaderCompileOptions(const Shader* shader,
182                                  const std::vector<std::string>& options);
183 
184   /// Returns a list of all colour attachments in this pipeline.
GetColorAttachments()185   const std::vector<BufferInfo>& GetColorAttachments() const {
186     return color_attachments_;
187   }
188   /// Adds |buf| as a colour attachment at |location| in the pipeline.
189   Result AddColorAttachment(Buffer* buf, uint32_t location);
190   /// Retrieves the location that |buf| is bound to in the pipeline. The
191   /// location will be written to |loc|. An error result will be return if
192   /// something goes wrong.
193   Result GetLocationForColorAttachment(Buffer* buf, uint32_t* loc) const;
194 
195   /// Sets |buf| as the depth buffer for this pipeline.
196   Result SetDepthBuffer(Buffer* buf);
197   /// Returns information on the depth buffer bound to the pipeline. If no
198   /// depth buffer is bound the |BufferInfo::buffer| parameter will be nullptr.
GetDepthBuffer()199   const BufferInfo& GetDepthBuffer() const { return depth_buffer_; }
200 
201   /// Returns information on all vertex buffers bound to the pipeline.
GetVertexBuffers()202   const std::vector<BufferInfo>& GetVertexBuffers() const {
203     return vertex_buffers_;
204   }
205   /// Adds |buf| as a vertex buffer at |location| in the pipeline.
206   Result AddVertexBuffer(Buffer* buf, uint32_t location);
207 
208   /// Binds |buf| as the index buffer for this pipeline.
209   Result SetIndexBuffer(Buffer* buf);
210   /// Returns the index buffer bound to this pipeline or nullptr if no index
211   /// buffer bound.
GetIndexBuffer()212   Buffer* GetIndexBuffer() const { return index_buffer_; }
213 
214   /// Adds |buf| to the pipeline at the given |descriptor_set| and |binding|.
215   void AddBuffer(Buffer* buf, uint32_t descriptor_set, uint32_t binding);
216   /// Adds |buf| to the pipeline at the given |arg_name|.
217   void AddBuffer(Buffer* buf, const std::string& arg_name);
218   /// Adds |buf| to the pipeline at the given |arg_no|.
219   void AddBuffer(Buffer* buf, uint32_t arg_no);
220   /// Returns information on all buffers in this pipeline.
GetBuffers()221   const std::vector<BufferInfo>& GetBuffers() const { return buffers_; }
222 
223   /// Updates the descriptor set and binding info for the OpenCL-C kernel bound
224   /// to the pipeline. No effect for other shader formats.
225   Result UpdateOpenCLBufferBindings();
226 
227   /// Returns the buffer which is currently bound to this pipeline at
228   /// |descriptor_set| and |binding|.
229   Buffer* GetBufferForBinding(uint32_t descriptor_set, uint32_t binding) const;
230 
231   Result SetPushConstantBuffer(Buffer* buf);
GetPushConstantBuffer()232   const BufferInfo& GetPushConstantBuffer() const {
233     return push_constant_buffer_;
234   }
235 
236   /// Validates that the pipeline has been created correctly.
237   Result Validate() const;
238 
239   /// Generates a default color attachment in B8G8R8A8_UNORM.
240   std::unique_ptr<Buffer> GenerateDefaultColorAttachmentBuffer();
241   /// Generates a default depth attachment in D32_SFLOAT_S8_UINT format.
242   std::unique_ptr<Buffer> GenerateDefaultDepthAttachmentBuffer();
243 
244   /// Information on values set for OpenCL-C plain-old-data args.
245   struct ArgSetInfo {
246     std::string name;
247     uint32_t ordinal = 0;
248     Format* fmt = nullptr;
249     Value value;
250   };
251 
252   /// Adds value from SET command.
SetArg(ArgSetInfo && info)253   void SetArg(ArgSetInfo&& info) { set_arg_values_.push_back(std::move(info)); }
SetArgValues()254   const std::vector<ArgSetInfo>& SetArgValues() const {
255     return set_arg_values_;
256   }
257 
258   /// Generate the buffers necessary for OpenCL PoD arguments populated via SET
259   /// command. This should be called after all other buffers are bound.
260   Result GenerateOpenCLPodBuffers();
261 
262  private:
263   void UpdateFramebufferSizes();
264 
265   Result ValidateGraphics() const;
266   Result ValidateCompute() const;
267 
268   PipelineType pipeline_type_ = PipelineType::kCompute;
269   std::string name_;
270   std::vector<ShaderInfo> shaders_;
271   std::vector<BufferInfo> color_attachments_;
272   std::vector<BufferInfo> vertex_buffers_;
273   std::vector<BufferInfo> buffers_;
274   std::vector<std::unique_ptr<type::Type>> types_;
275   std::vector<std::unique_ptr<Format>> formats_;
276   BufferInfo depth_buffer_;
277   BufferInfo push_constant_buffer_;
278   Buffer* index_buffer_ = nullptr;
279 
280   uint32_t fb_width_ = 250;
281   uint32_t fb_height_ = 250;
282 
283   std::vector<ArgSetInfo> set_arg_values_;
284   std::vector<std::unique_ptr<Buffer>> opencl_pod_buffers_;
285   /// Maps (descriptor set, binding) to the buffer for that binding pair.
286   std::map<std::pair<uint32_t, uint32_t>, Buffer*> opencl_pod_buffer_map_;
287 };
288 
289 }  // namespace amber
290 
291 #endif  // SRC_PIPELINE_H_
292